{"id":15492250,"url":"https://github.com/danielaparker/acons","last_synced_at":"2025-04-22T19:26:20.419Z","repository":{"id":142025815,"uuid":"143372840","full_name":"danielaparker/acons","owner":"danielaparker","description":"A modern C++ header-only library for constructing N-dimensional arrays","archived":false,"fork":false,"pushed_at":"2019-09-27T00:16:09.000Z","size":30462,"stargazers_count":8,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T18:11:21.183Z","etag":null,"topics":["array","cpp","cpp11","header-only","multi-dimensional-array","n-dimensional","no-dependencies","numerical-methods","scientific-computing","single-file"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danielaparker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-03T03:26:23.000Z","updated_at":"2024-07-01T18:54:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"73d53d49-0fc1-4c4f-9f14-59f9516b378a","html_url":"https://github.com/danielaparker/acons","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielaparker%2Facons","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielaparker%2Facons/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielaparker%2Facons/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielaparker%2Facons/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielaparker","download_url":"https://codeload.github.com/danielaparker/acons/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250307679,"owners_count":21409116,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["array","cpp","cpp11","header-only","multi-dimensional-array","n-dimensional","no-dependencies","numerical-methods","scientific-computing","single-file"],"created_at":"2024-10-02T07:59:47.174Z","updated_at":"2025-04-22T19:26:20.404Z","avatar_url":"https://github.com/danielaparker.png","language":"C++","readme":"# acons\n\nacons is a modern C++ header-only library for constructing N-dimensional arrays.\n\nIt is distributed under the [MIT License](https://opensource.org/licenses/MIT).\n\n## Get acons\n\nDownload the latest [single header file](https://raw.githubusercontent.com/danielaparker/acons/master/include/acons/ndarray.hpp). \n\n## How to use it\n\n[Examples](#ExamplesLabel)  \n[Reference](doc/ref/index.md)\n\n## Supported compilers\n\n Compiler     | Versions      | Operating System\n--------------|---------------|-----------------\n VS           | 14.0          | Windows 10       \n g++-         | 4.8, 6, 7,8   | Ubuntu           \n clang        | 3.8, 5.0. 6.0 |\n\n\u003cdiv id=\"ExamplesLabel\"/\u003e\n\n### Examples\n\n#### Construct an array with zeros\n\n```c++\n#include \u003ciostream\u003e\n#include \u003cacons/ndarray.hpp\u003e\n\nint main()\n{\n    // Construct an array of shape 2 x 3 with zeros\n    acons::ndarray\u003cdouble,2\u003e a(2,3,0.0);\n\n    std::cout \u003c\u003c a \u003c\u003c \"\\n\\n\";\n}\n```\nOutput:\n```\n[[0,0,0],[0,0,0]]\n```\n\n#### Construct a 3-dim array\n\n```c++\n#include \u003ciostream\u003e\n#include \u003cacons/ndarray.hpp\u003e\n\nint main()\n{\n    // Create a 3-dim array of shape 3 x 4 x 2\n    acons::ndarray\u003cdouble,3\u003e a(3,4,2);\n\n    // Assign values to the elements\n    int x = 0;\n    for (size_t i = 0; i \u003c a.shape(0); ++i)\n    {\n        for (size_t j = 0; j \u003c a.shape(1); ++j)\n        {\n            for (size_t k = 0; k \u003c a.shape(2); ++k)\n            {\n                a(i,j,k) = x++;\n            }\n        }\n    }\n\n    // Print\n    std::cout \u003c\u003c a \u003c\u003c \"\\n\";\n}\n```\nOutput:\n```\n[[[0,1],[2,3],[4,5],[6,7]],[[8,9],[10,11],[12,13],[14,15]],[[16,17],[18,19],[20,21],[22,23]]]\n```\n\n#### Wrap a C-array\n\n```c++\n#include \u003ciostream\u003e\n#include \u003cacons/ndarray.hpp\u003e\n\nint main()\n{\n    double a[] = {0,1,2,3,4,5,6};\n\n    // Elements of a can be modified through this 2 x 3 interface\n    acons::ndarray_view\u003cdouble,2\u003e v(a,2,3); \n    v(0,2) = 9;\n\n    // Elements of a cannot be modified through this 2 x 3 interface\n    acons::const_ndarray_view\u003cdouble,2\u003e cv(a,2,3);\n\n    std::cout \u003c\u003c cv \u003c\u003c \"\\n\\n\";\n}\n```\nOutput:\n```\n[[0,1,9],[3,4,5]]\n```\n\n#### Slicing a 1-dimensional array\n\nA `slice` object can be constructed with `start`, `stop` and `step` parameters. \n```c++\n#include \u003ciostream\u003e\n#include \u003cacons/ndarray.hpp\u003e\n\nint main()\n{\n    acons::ndarray\u003cdouble,1\u003e a = {0,1,2,3,4,5,6,7,8,9};\n\n    // Extracting a part of the array with a slice object\n    acons::ndarray_view\u003cdouble,1\u003e v(a, {acons::slice(2,7,2)});\n    std::cout \u003c\u003c v \u003c\u003c \"\\n\\n\";\n}\n```\nOutput:\n```\n[2,4,6]\n```\n\n#### Slicing a 2-dimensional array\n\nA `slice` object constructed with no parameters identifies all the elements along the dimension of an array.\nIf `stop` and `step` are not given, `stop` defaults to one past the last element along the dimension,\nand `step` defaults to 1.\n\n```c++\n#include \u003ciostream\u003e\n#include \u003cacons/ndarray.hpp\u003e\n\nint main()\n{\n    // Construct a 2-dimensional 3 x 4 array \n    acons::ndarray\u003cdouble,2\u003e a = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};\n\n    // All items from row 1 and columns 0 and 1\n    acons::ndarray_view\u003cdouble,2\u003e v1(a, {acons::slice(1,2),acons::slice(0,2)});\n    std::cout \u003c\u003c \"(1) \" \u003c\u003c v1 \u003c\u003c \"\\n\\n\";\n\n    // All items from column 1 onwards\n    acons::ndarray_view\u003cdouble,2\u003e v2(a, {acons::slice(),acons::slice(1)});\n    std::cout \u003c\u003c \"(2) \" \u003c\u003c v2 \u003c\u003c \"\\n\\n\";\n}\n```\nOutput:\n```\n(1) [[4,5]]\n\n(2) [[1,2,3],[5,6,7],[9,10,11]]\n```\n\n#### Reduction\n\nConstruct a view on an array (or another view) that has fewer dimensions than the original.\n\n```c++\n#include \u003ciostream\u003e\n#include \u003cacons/ndarray.hpp\u003e\n\nint main()\n{\n    // Construct a 2-dimensional 3 x 4 array \n    acons::ndarray\u003cdouble,2\u003e a = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};\n\n    // Reduce the 2-dimensional array to a 1-dimensional array, along row 0\n    acons::ndarray_view\u003cdouble,1\u003e v1(a, acons::indices_t\u003c1\u003e{0});\n    std::cout \u003c\u003c \"(1) \" \u003c\u003c v1 \u003c\u003c \"\\n\\n\";\n\n    // Reduce the 2-dimensional array to a 1-dimensional array, along column 2\n    acons::ndarray_view\u003cdouble,1\u003e v2(a, {acons::slice()}, acons::indices_t\u003c1\u003e{2});\n    std::cout \u003c\u003c \"(2) \" \u003c\u003c v2 \u003c\u003c \"\\n\\n\";\n}\n```\nOutput:\n```\n(1) [[12,13,14,15],[16,17,18,19],[20,21,22,23]]\n\n(2) [14,18,22]\n```\n\n#### Creating ndarrays in managed shared memory with Boost interprocess allocators\n\n```c++\n#include \u003cboost/interprocess/managed_shared_memory.hpp\u003e\n#include \u003cboost/interprocess/containers/vector.hpp\u003e\n#include \u003cboost/interprocess/allocators/allocator.hpp\u003e\n#include \u003cboost/interprocess/containers/string.hpp\u003e\n#include \u003ccstdlib\u003e //std::system\n#include \u003cacons/ndarray.hpp\u003e\n#include \u003ciostream\u003e\n\ntypedef boost::interprocess::allocator\u003cdouble,\n        boost::interprocess::managed_shared_memory::segment_manager\u003e shmem_allocator;\n\ntypedef acons::ndarray\u003cdouble,2,acons::row_major,zero_based,shmem_allocator\u003e ndarray_shm;\n\nint main(int argc, char *argv[])\n{\n    typedef std::pair\u003cdouble, int\u003e MyType;\n\n    if(argc == 1) //Parent process\n    {  \n       //Remove shared memory on construction and destruction\n       struct shm_remove\n       {\n          shm_remove() { boost::interprocess::shared_memory_object::remove(\"MySharedMemory\"); }\n          ~shm_remove(){ boost::interprocess::shared_memory_object::remove(\"MySharedMemory\"); }\n       } \n       remover;\n\n       //Construct managed shared memory\n       boost::interprocess::managed_shared_memory segment(boost::interprocess::create_only, \n                                                          \"MySharedMemory\", 65536);\n\n       //Initialize shared memory STL-compatible allocator\n       const shmem_allocator allocator(segment.get_segment_manager());\n\n       // Create ndarray with all dynamic allocations in shared memory\n       ndarray_shm* pA = segment.construct\u003cndarray_shm\u003e(\"my ndarray\")(std::allocator_arg, allocator, 2, 2, 0.0);\n       ndarray_shm\u0026 a = *pA;\n\n       a(0,0) = 0;\n       a(0,1) = 1;\n       a(1,0) = 2;\n       a(1,1) = 3;\n\n       std::pair\u003cndarray_shm*, boost::interprocess::managed_shared_memory::size_type\u003e res;\n       res = segment.find\u003cndarray_shm\u003e(\"my ndarray\");\n\n       std::cout \u003c\u003c \"Parent process:\\n\";\n       std::cout \u003c\u003c *(res.first) \u003c\u003c \"\\n\";\n\n       //Launch child process\n       std::string s(argv[0]); s += \" child \";\n       if(0 != std::system(s.c_str()))\n          return 1;\n\n       //Check child has destroyed all objects\n       if(segment.find\u003cMyType\u003e(\"my ndarray\").first)\n          return 1;\n    }\n    else\n    {\n       //Open managed shared memory\n       boost::interprocess::managed_shared_memory segment(boost::interprocess::open_only, \n                                                          \"MySharedMemory\");\n\n       std::pair\u003cndarray_shm*, boost::interprocess::managed_shared_memory::size_type\u003e res;\n       res = segment.find\u003cndarray_shm\u003e(\"my ndarray\");\n\n       if (res.first != nullptr)\n       {\n           std::cout \u003c\u003c \"\\nChild process:\\n\";\n           std::cout \u003c\u003c *(res.first) \u003c\u003c \"\\n\";\n       }\n       else\n       {\n           std::cout \u003c\u003c \"Result is null\\n\";\n       }\n\n       //We're done, delete all the objects\n       segment.destroy\u003cndarray_shm\u003e(\"my ndarray\");\n    }\n}\n```\nOutput:\n```\nParent process:\n[[0,1],[2,3]]\n\nChild process:\n[[0,1],[2,3]]\n```\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielaparker%2Facons","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielaparker%2Facons","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielaparker%2Facons/lists"}