├── test ├── test_main.cpp ├── CMakeLists.txt ├── test_internal_op.cpp └── test_constructors.cpp ├── paper ├── head.png ├── plot2d.png └── paper.bib ├── doc ├── source │ ├── img │ │ ├── head.png │ │ ├── 3body.png │ │ ├── basic.png │ │ ├── boids.png │ │ ├── advanced_mesh.png │ │ ├── heatexplicit.png │ │ ├── heatimplicit.png │ │ ├── nodal_values.png │ │ ├── montecarloresult.png │ │ ├── replicatormutator.png │ │ ├── results5eigenmodes.png │ │ ├── surface_plot_surface.png │ │ └── surface_plot_wireframe.png │ ├── _static │ │ ├── 3body.mp4 │ │ ├── 3bodyvtk.mp4 │ │ ├── boidsflight.mp4 │ │ └── main_stylesheet.css │ ├── castor_logo.png │ ├── fembem.rst │ ├── class_smatrix.rst │ ├── analyticalscattering.rst │ ├── class_bintree.rst │ ├── class_figure.rst │ ├── castorfftw.rst │ ├── graphical_tools.rst │ ├── developpers.rst │ ├── class_view_cview.rst │ ├── graphical_io.rst │ ├── conf.py │ ├── transforms.rst │ ├── class_hmatrix.rst │ ├── mesh_management.rst │ ├── class_matrix.rst │ ├── io.rst │ ├── basic_plot.rst │ ├── dimensions.rst │ ├── mesh_plot.rst │ ├── tools.rst │ ├── linear_solver.rst │ ├── kissfft.rst │ ├── getting_started.rst │ ├── factorization.rst │ ├── builders.rst │ ├── geometry.rst │ ├── singular_eig_values.rst │ ├── montecarlo.rst │ ├── api_hmatrix.rst │ ├── index.rst │ ├── manipulations.rst │ ├── replicatormutator.rst │ ├── operators.rst │ ├── lowlevel_linalg_func.rst │ ├── linalg.rst │ ├── math.rst │ ├── sparse_matrix.rst │ ├── api_smatrix.rst │ ├── advanced.rst │ ├── heat.rst │ ├── installation.rst │ ├── graphics.rst │ ├── algorithm.rst │ └── eigenmode.rst ├── Doxyfile ├── environment.yml └── Makefile ├── extern └── CMakeLists.txt ├── .gitignore ├── castor.pc.in ├── getting_started ├── CMakeLists.txt └── main.cpp ├── include └── CMakeLists.txt ├── misc ├── CMakeLists.txt ├── perf_hmat.cpp └── some_fractals.cpp ├── castorConfig.cmake.in ├── README.md ├── .gitlab-ci.yml ├── demo ├── CMakeLists.txt ├── demo_kissfft.cpp ├── demo_smatrix.cpp └── demo_graphics.cpp ├── CONTRIBUTING.md ├── CMakeLists.txt └── LICENSE /test/test_main.cpp: -------------------------------------------------------------------------------- 1 | #define CATCH_CONFIG_MAIN 2 | #include 3 | -------------------------------------------------------------------------------- /paper/head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/paper/head.png -------------------------------------------------------------------------------- /paper/plot2d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/paper/plot2d.png -------------------------------------------------------------------------------- /doc/source/img/head.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/head.png -------------------------------------------------------------------------------- /doc/source/img/3body.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/3body.png -------------------------------------------------------------------------------- /doc/source/img/basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/basic.png -------------------------------------------------------------------------------- /doc/source/img/boids.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/boids.png -------------------------------------------------------------------------------- /doc/source/_static/3body.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/_static/3body.mp4 -------------------------------------------------------------------------------- /doc/source/castor_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/castor_logo.png -------------------------------------------------------------------------------- /extern/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(catch INTERFACE) 2 | target_include_directories(catch INTERFACE catch2) 3 | -------------------------------------------------------------------------------- /doc/source/_static/3bodyvtk.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/_static/3bodyvtk.mp4 -------------------------------------------------------------------------------- /doc/source/img/advanced_mesh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/advanced_mesh.png -------------------------------------------------------------------------------- /doc/source/img/heatexplicit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/heatexplicit.png -------------------------------------------------------------------------------- /doc/source/img/heatimplicit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/heatimplicit.png -------------------------------------------------------------------------------- /doc/source/img/nodal_values.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/nodal_values.png -------------------------------------------------------------------------------- /doc/source/_static/boidsflight.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/_static/boidsflight.mp4 -------------------------------------------------------------------------------- /doc/source/img/montecarloresult.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/montecarloresult.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build directory 2 | build/ 3 | xcode/ 4 | xml/ 5 | .vscode/ 6 | 7 | # Desktop Services Store (macOS) 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /doc/source/img/replicatormutator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/replicatormutator.png -------------------------------------------------------------------------------- /doc/source/img/results5eigenmodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/results5eigenmodes.png -------------------------------------------------------------------------------- /doc/source/img/surface_plot_surface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/surface_plot_surface.png -------------------------------------------------------------------------------- /doc/source/img/surface_plot_wireframe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leprojetcastor/castor/HEAD/doc/source/img/surface_plot_wireframe.png -------------------------------------------------------------------------------- /doc/Doxyfile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = "castor" 2 | INPUT = ../include/castor 3 | GENERATE_XML = YES 4 | GENERATE_LATEX = NO 5 | GENERATE_HTML = NO 6 | -------------------------------------------------------------------------------- /doc/source/fembem.rst: -------------------------------------------------------------------------------- 1 | .. _label-fembem: 2 | 3 | FEM BEM 4 | ======= 5 | 6 | The project can be found here : ``_. 7 | -------------------------------------------------------------------------------- /doc/source/class_smatrix.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _label-class-smatrix: 3 | 4 | Class smatrix 5 | +++++++++++++ 6 | 7 | .. doxygenclass:: castor::smatrix 8 | :project: castor 9 | :members: 10 | -------------------------------------------------------------------------------- /castor.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@CMAKE_INSTALL_PREFIX@ 2 | libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ 3 | includedir=${prefix}/include 4 | 5 | Name: castor 6 | Description: Castor 7 | Version: 1.0.0 8 | Cflags: -I${includedir} 9 | -------------------------------------------------------------------------------- /doc/environment.yml: -------------------------------------------------------------------------------- 1 | name: doc 2 | 3 | channels: 4 | - conda-forge 5 | 6 | dependencies: 7 | - make 8 | - doxygen 9 | - sphinx 10 | - sphinx-copybutton 11 | - sphinx_rtd_theme 12 | - breathe 13 | -------------------------------------------------------------------------------- /doc/source/analyticalscattering.rst: -------------------------------------------------------------------------------- 1 | .. _label-analyticalscattering: 2 | 3 | Analytical Scattering 4 | ===================== 5 | 6 | The project can be found `here `_. -------------------------------------------------------------------------------- /doc/source/_static/main_stylesheet.css: -------------------------------------------------------------------------------- 1 | .wy-nav-content { 2 | max-width: 1500px; 3 | margin: auto; 4 | } 5 | 6 | .red { 7 | color: red; 8 | } 9 | 10 | .warning { 11 | font-weight: bold; 12 | color: red; 13 | } 14 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_STANDARD 14) 2 | 3 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES test_main.cpp test_constructors.cpp test_internal_op.cpp) 4 | 5 | add_executable(test test_main.cpp test_constructors.cpp test_internal_op.cpp) 6 | target_link_libraries(test castor catch) 7 | -------------------------------------------------------------------------------- /doc/source/class_bintree.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _label-class-bintree: 3 | 4 | Class bintree 5 | +++++++++++++ 6 | 7 | This class is used by :ref:`label-class-hmatrix` for space partitioning. 8 | 9 | .. doxygenclass:: castor::bintree 10 | :project: castor 11 | :members: 12 | :undoc-members: 13 | -------------------------------------------------------------------------------- /doc/source/class_figure.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _label-class-figure: 3 | 4 | Class figure 5 | ============ 6 | 7 | The ``figure`` class implements a container which is able to display data. See :ref:`label-graphics-advanced` for some examples of use. 8 | 9 | .. doxygenclass:: castor::figure 10 | :project: castor 11 | :members: 12 | -------------------------------------------------------------------------------- /getting_started/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES main.cpp) 2 | 3 | add_executable(main main.cpp) 4 | target_link_libraries(main castor) 5 | set_target_properties(main PROPERTIES FOLDER "getting_started") 6 | 7 | if(VTK_FOUND) 8 | vtk_module_autoinit(TARGETS main MODULES ${VTK_LIBRARIES}) 9 | endif() 10 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/castor FILES castor/matrix.hpp castor/linalg.hpp castor/graphics.hpp castor/smatrix.hpp castor/hmatrix.hpp castor/kissfft.hpp) 2 | 3 | add_custom_target(include SOURCES castor/matrix.hpp castor/linalg.hpp castor/graphics.hpp castor/smatrix.hpp castor/hmatrix.hpp castor/kissfft.hpp) 4 | -------------------------------------------------------------------------------- /doc/source/castorfftw.rst: -------------------------------------------------------------------------------- 1 | .. _label-castorfftw: 2 | 3 | Castor FFTW 4 | =========== 5 | 6 | **Castor FFTW** is the **castor** wrapper for the well-known FFTW3 library. The *git* repository can be found `here `_ and the documentation at `https://marcbakry.github.io/castor-fftw/ `_. -------------------------------------------------------------------------------- /doc/source/graphical_tools.rst: -------------------------------------------------------------------------------- 1 | .. _label-graphical-tools: 2 | 3 | Graphical tools 4 | +++++++++++++++ 5 | 6 | .. _label-caxis: 7 | 8 | caxis 9 | ----- 10 | .. doxygenfunction:: caxis(figure &fig, matrix const &val) 11 | :project: castor 12 | 13 | .. _label-drawnow: 14 | 15 | drawnow 16 | ------- 17 | .. doxygenfunction:: drawnow(figure &fig) 18 | :project: castor 19 | 20 | -------------------------------------------------------------------------------- /doc/source/developpers.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _label-developpers: 3 | 4 | Developers 5 | ========== 6 | 7 | - Matthieu Aussal, research engineer at `CMAP `_, École polytechnique : matthieu.aussal at polytechnique.edu 8 | - Marc Bakry, research engineer at `CEA `_, (former post-doc at Ecole polytechnique) : marc.bakry at gmail dot com 9 | - Laurent Series, research engineer at `CMAP `_, École polytechnique : laurent.series at polytechnique.edu 10 | -------------------------------------------------------------------------------- /misc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES perf_hmat.cpp some_fractals.cpp) 2 | 3 | add_executable(perf_hmat perf_hmat.cpp) 4 | target_link_libraries(perf_hmat castor) 5 | set_target_properties(perf_hmat PROPERTIES FOLDER "misc") 6 | 7 | if(VTK_FOUND) 8 | add_executable(some_fractals some_fractals.cpp) 9 | target_link_libraries(some_fractals castor) 10 | set_target_properties(some_fractals PROPERTIES FOLDER "misc") 11 | vtk_module_autoinit(TARGETS some_fractals MODULES ${VTK_LIBRARIES}) 12 | endif() 13 | -------------------------------------------------------------------------------- /doc/source/class_view_cview.rst: -------------------------------------------------------------------------------- 1 | Classes view and cview 2 | ++++++++++++++++++++++ 3 | 4 | Classes ``view`` and ``cview`` are used to extract a submatrix from matrix instance or to assign value to submatrix of matrix instance. 5 | 6 | .. _label-view: 7 | 8 | view 9 | ---- 10 | 11 | .. doxygenclass:: castor::view 12 | :project: castor 13 | :members: 14 | :undoc-members: 15 | 16 | .. _label-cview: 17 | 18 | cview 19 | ----- 20 | 21 | .. doxygenclass:: castor::cview 22 | :project: castor 23 | :members: 24 | :undoc-members: 25 | -------------------------------------------------------------------------------- /doc/source/graphical_io.rst: -------------------------------------------------------------------------------- 1 | .. _label-graphical-io: 2 | 3 | Graphical input/output 4 | ++++++++++++++++++++++ 5 | 6 | .. _label-triread: 7 | 8 | triread 9 | ------- 10 | .. doxygenfunction:: triread(std::string const &path, std::string const &name) 11 | :project: castor 12 | 13 | See :ref:`label-triwrite`. 14 | 15 | 16 | .. _label-triwrite: 17 | 18 | triwrite 19 | -------- 20 | .. doxygenfunction:: triwrite(std::string const &path, std::string const &name, matrix const &tri, matrix const &vtx, matrix const &val = {}) 21 | :project: castor 22 | 23 | See :ref:`label-triread`. 24 | 25 | -------------------------------------------------------------------------------- /doc/source/conf.py: -------------------------------------------------------------------------------- 1 | import sphinx_rtd_theme 2 | #import os 3 | 4 | html_theme = "sphinx_rtd_theme" 5 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 6 | 7 | def setup(app): 8 | app.add_css_file("main_stylesheet.css") 9 | 10 | extensions = ['breathe', 'sphinx_copybutton'] 11 | breathe_projects = { 'castor': '../xml' } 12 | templates_path = ['_templates'] 13 | html_static_path = ['_static'] 14 | source_suffix = '.rst' 15 | project = 'castor' 16 | copyright = '2020, Ecole Polytechnique, Matthieu Aussal, Marc Bakry, Laurent Series' 17 | author = 'Matthieu Aussal, Marc Bakry, Laurent Series' 18 | html_logo = 'castor_logo.png' 19 | 20 | exclude_patterns = [] 21 | -------------------------------------------------------------------------------- /castorConfig.cmake.in: -------------------------------------------------------------------------------- 1 | # samurai cmake module 2 | # This module sets the following variables in your project:: 3 | # 4 | # samurai_FOUND - true if samurai found on the system 5 | # samurai_INCLUDE_DIRS - the directory containing samurai headers 6 | # samurai_LIBRARY - empty 7 | 8 | @PACKAGE_INIT@ 9 | 10 | #include(CMakeFindDependencyMacro) 11 | #if(@LAPACK_FOUND@) 12 | # find_dependency(BLAS @BLAS_REQUIRED_VERSION@) 13 | # find_dependency(LAPACK @LAPACK_REQUIRED_VERSION@) 14 | #endif() 15 | 16 | if(NOT TARGET @PROJECT_NAME@) 17 | include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") 18 | get_target_property(@PROJECT_NAME@_INCLUDE_DIRS @PROJECT_NAME@ INTERFACE_INCLUDE_DIRECTORIES) 19 | endif() 20 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS = 7 | SPHINXBUILD = sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | $(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | doxygen 21 | $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 22 | -------------------------------------------------------------------------------- /doc/source/transforms.rst: -------------------------------------------------------------------------------- 1 | .. _label-transforms: 2 | 3 | Transforms 4 | ++++++++++ 5 | 6 | This section describes functions concerning Fourier transform. 7 | 8 | .. _label-dft: 9 | 10 | dft 11 | --- 12 | .. doxygenfunction:: dft 13 | :project: castor 14 | 15 | See :ref:`label-idft`, :ref:`label-fft`. 16 | 17 | .. _label-fft: 18 | 19 | fft 20 | --- 21 | .. doxygenfunction:: fft 22 | :project: castor 23 | 24 | See :ref:`label-dft`, :ref:`label-ifft`. 25 | 26 | .. _label-idft: 27 | 28 | idft 29 | ---- 30 | .. doxygenfunction:: idft 31 | :project: castor 32 | 33 | See :ref:`label-dft`, :ref:`label-ifft`. 34 | 35 | .. _label-ifft: 36 | 37 | ifft 38 | ---- 39 | .. doxygenfunction:: ifft 40 | :project: castor 41 | 42 | See :ref:`label-idft`, :ref:`label-fft`. -------------------------------------------------------------------------------- /doc/source/class_hmatrix.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _label-class-hmatrix: 3 | 4 | Class hmatrix 5 | +++++++++++++ 6 | 7 | As part of **castor**, the ``hmatrix`` class provides a **fully abstract interface** for the manipulation of hierarchical matrices [1]_. The class itself and the related functions can be found in :ref:`label-class-hmatrix`. It uses another class :ref:`label-class-bintree` dedicated to binary space partitioning. 8 | 9 | 10 | **This is work-in-progress! The descriptions of the different features and examples will be added to this section progressively.** 11 | 12 | .. [1] S. Börm, L. Grasedyck and W. Hackbusch, *Hierarchical Matrices*, 2015 (technical report) 13 | 14 | .. doxygenclass:: castor::hmatrix 15 | :project: castor 16 | :members: 17 | :undoc-members: 18 | -------------------------------------------------------------------------------- /doc/source/mesh_management.rst: -------------------------------------------------------------------------------- 1 | .. _label-mesh-management: 2 | 3 | Mesh management 4 | +++++++++++++++ 5 | 6 | Functions helpers to create simple volume or surface meshes from sets of nodes. 7 | 8 | .. _label-tetboundary: 9 | 10 | tetboundary 11 | ----------- 12 | .. doxygenfunction:: tetboundary(matrix const &tet, matrix const &vtx) 13 | :project: castor 14 | 15 | See :ref:`label-tetdelaunay`. 16 | 17 | 18 | .. _label-tetdelaunay: 19 | 20 | tetdelaunay 21 | ----------- 22 | .. doxygenfunction:: tetdelaunay(matrix const &X, matrix const &Y, matrix const &Z) 23 | :project: castor 24 | 25 | See :ref:`label-tetboundary`. 26 | 27 | 28 | .. _label-tridelaunay: 29 | 30 | tridelaunay 31 | ----------- 32 | .. doxygenfunction:: tridelaunay(matrix const &X, matrix const &Y, matrix const &Z = {}) 33 | :project: castor 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # THE CASTOR LIBRARY 2 | 3 | The objective of the **castor** library is to propose **high-level semantics**, inspired by the Matlab language, allowing fast software prototyping in a low-level compiled language. It is nothing more than a matrix management layer using the tools of the **standard C++ library**, in different storage formats (full, sparse and hierarchical). Indeed, the use of IDEs 1 such as Xcode, Visual studio, Eclipse, etc. allows today to execute compiled code (C, C++, fortran, etc.) with the same **flexibility as interpreted languages** (Matlab, Python, Julia, etc.). 4 | 5 | Full documentation is available here : http://leprojetcastor.gitlab.labos.polytechnique.fr/castor/index.html 6 | 7 | Presentation in JOSS (Journal of Open Source Software) : [![DOI](https://joss.theoj.org/papers/10.21105/joss.03965/status.svg)](https://doi.org/10.21105/joss.03965) 8 | -------------------------------------------------------------------------------- /doc/source/class_matrix.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _label-class-matrix: 3 | 4 | Class matrix 5 | +++++++++++++ 6 | 7 | The **castor** framework implements its own templatized class ``matrix`` where ``T`` can be *for example* a ``float``, ``int``, ``std::complex``, etc. At its core, it is built over a ``std::vector`` which holds the values. The class ``matrix`` itself provides many useful functions and operators (addition, multiplication, indexing, etc.). It is designed such that it should feel like using `Matlab `_ or `Numpy arrays `_. The user will find here all the available constructors. Specific builders (:ref:`label-ones`, :ref:`label-eye`, etc.) may be found at :ref:`label-builders`. 8 | 9 | .. doxygenclass:: castor::matrix 10 | :project: castor 11 | :members: 12 | 13 | See :ref:`label-view`, :ref:`label-cview`. 14 | 15 | -------------------------------------------------------------------------------- /doc/source/io.rst: -------------------------------------------------------------------------------- 1 | .. _label-input-output: 2 | 3 | Input/Output 4 | ++++++++++++ 5 | 6 | The ``matrix`` object can be saved on the drive either as a text file or a binary file. 7 | 8 | 9 | .. _label-readbin: 10 | 11 | readbin 12 | ------- 13 | .. doxygenfunction:: readbin 14 | :project: castor 15 | 16 | See :ref:`label-writebin`, :ref:`label-readtxt`. 17 | 18 | 19 | .. _label-readtxt: 20 | 21 | readtxt 22 | ------- 23 | .. doxygenfunction:: readtxt 24 | :project: castor 25 | 26 | See :ref:`label-writetxt`, :ref:`label-readbin`. 27 | 28 | 29 | .. _label-writebin: 30 | 31 | writebin 32 | -------- 33 | .. doxygenfunction:: writebin 34 | :project: castor 35 | 36 | See :ref:`label-readbin`, :ref:`label-writetxt`. 37 | 38 | 39 | .. _label-writetxt: 40 | 41 | writetxt 42 | -------- 43 | .. doxygenfunction:: writetxt 44 | :project: castor 45 | 46 | See :ref:`label-readtxt`, :ref:`label-writebin`. -------------------------------------------------------------------------------- /doc/source/basic_plot.rst: -------------------------------------------------------------------------------- 1 | .. _label-basic-plot: 2 | 3 | 4 | Basic plot 5 | ++++++++++ 6 | 7 | These functions allow to display curves or values of a ``matrix``. 8 | 9 | 10 | 11 | .. _label-imagesc: 12 | 13 | imagesc 14 | ------- 15 | .. doxygenfunction:: imagesc(figure &fig, matrix const &M) 16 | :project: castor 17 | 18 | .. _label-plot: 19 | 20 | plot 21 | ---- 22 | .. doxygenfunction:: plot(figure &fig, matrix const &X, matrix const &Y, std::vector const &style = {""}, std::vector const &label = {""}) 23 | :project: castor 24 | 25 | See :ref:`label-plot3` 26 | 27 | .. _label-plot3: 28 | 29 | plot3 30 | ----- 31 | .. doxygenfunction:: plot3(figure &fig, matrix const &X, matrix const &Y, matrix const &Z, std::string const &style = "") 32 | :project: castor 33 | 34 | See :ref:`label-plot` 35 | 36 | .. _label-spy: 37 | 38 | spy 39 | --- 40 | .. doxygenfunction:: spy 41 | :project: castor -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: gcc 2 | 3 | build: 4 | stage: build 5 | before_script: 6 | - apt-get update --yes 7 | - apt-get install --yes cmake 8 | - apt-get install --yes libopenblas-dev 9 | script: 10 | - mkdir build 11 | - cd build 12 | - cmake .. 13 | - make 14 | artifacts: 15 | paths: 16 | - build 17 | 18 | 19 | #test: 20 | # stage: test 21 | # script: 22 | # - ./build/test/test -o test_res.txt --use-colour no 23 | # artifacts: 24 | # when: always 25 | # paths: 26 | # - test_res.txt 27 | 28 | deploy: 29 | stage: deploy 30 | script: 31 | - cp -r include/castor . 32 | artifacts: 33 | name: "castor" 34 | paths: 35 | - castor 36 | 37 | 38 | 39 | pages: 40 | image: continuumio/miniconda3 41 | script: 42 | - conda env create -f doc/environment.yml 43 | - source activate doc 44 | - cd doc 45 | - make html 46 | - mv build/html ../public 47 | artifacts: 48 | paths: 49 | - public 50 | only: 51 | - master 52 | -------------------------------------------------------------------------------- /doc/source/dimensions.rst: -------------------------------------------------------------------------------- 1 | .. _label-matrix-dimensions: 2 | 3 | Matrix dimensions 4 | +++++++++++++++++ 5 | 6 | These functions allow to recover the dimensions of a matrix : total number of elements (see :ref:`label-numel`), dimensions (see :ref:`label-size`), etc. 7 | 8 | .. _label-length: 9 | 10 | length 11 | ------ 12 | .. doxygenfunction:: length(matrix const &A) 13 | :project: castor 14 | 15 | See :ref:`label-numel`, :ref:`label-size`. 16 | 17 | .. _label-nnz: 18 | 19 | nnz 20 | --- 21 | .. doxygenfunction:: nnz(matrix const &A) 22 | :project: castor 23 | 24 | See :ref:`label-find`, :ref:`label-size`. 25 | 26 | .. _label-numel: 27 | 28 | numel 29 | ----- 30 | .. doxygenfunction:: numel(matrix const &A) 31 | :project: castor 32 | 33 | See :ref:`label-length`, :ref:`label-size`. 34 | 35 | .. _label-size: 36 | 37 | size 38 | ---- 39 | .. doxygenfunction:: size(matrix const &A, int dim) 40 | :project: castor 41 | 42 | .. doxygenfunction:: size(matrix const &A) 43 | :project: castor 44 | 45 | See :ref:`label-length`, :ref:`label-numel`. 46 | -------------------------------------------------------------------------------- /doc/source/mesh_plot.rst: -------------------------------------------------------------------------------- 1 | .. _label-mesh-plot: 2 | 3 | Mesh plot 4 | +++++++++ 5 | 6 | 7 | .. _label-edgmesh: 8 | 9 | edgmesh 10 | ------- 11 | .. doxygenfunction:: edgmesh(figure &fig, matrix const &edg, matrix const &vtx, matrix const &val = {}) 12 | :project: castor 13 | 14 | 15 | .. _label-mesh: 16 | 17 | mesh 18 | ---- 19 | .. doxygenfunction:: mesh(figure &fig, matrix const &X, matrix const &Y, matrix const &Z, std::string const &options = "") 20 | :project: castor 21 | 22 | 23 | .. _label-quiver: 24 | 25 | quiver 26 | ------ 27 | .. doxygenfunction:: quiver(figure &fig, matrix const &vtx, matrix const &dir, matrix const &val = {}) 28 | :project: castor 29 | 30 | 31 | .. _label-tetmesh: 32 | 33 | tetmesh 34 | ------- 35 | .. doxygenfunction:: tetmesh(figure &fig, matrix const &tet, matrix const &vtx, matrix const &val = {}) 36 | :project: castor 37 | 38 | 39 | .. _label-trimesh: 40 | 41 | trimesh 42 | ------- 43 | .. doxygenfunction:: trimesh(figure &fig, matrix const &tri, matrix const &vtx, matrix const &val = {}) 44 | :project: castor 45 | 46 | 47 | .. _label-vermesh: 48 | 49 | vermesh 50 | ------- 51 | .. doxygenfunction:: vermesh(figure &fig, matrix const &ver, matrix const &vtx, matrix const &val = {}) 52 | :project: castor 53 | -------------------------------------------------------------------------------- /demo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES demo_matrix.cpp demo_smatrix.cpp demo_hmatrix.cpp 2 | demo_kissfft.cpp demo_linalg.cpp demo_graphics.cpp) 3 | 4 | add_executable(demo_matrix demo_matrix.cpp) 5 | target_link_libraries(demo_matrix castor) 6 | set_target_properties(demo_matrix PROPERTIES FOLDER "demo") 7 | 8 | add_executable(demo_smatrix demo_smatrix.cpp) 9 | target_link_libraries(demo_smatrix castor) 10 | set_target_properties(demo_smatrix PROPERTIES FOLDER "demo") 11 | 12 | add_executable(demo_hmatrix demo_hmatrix.cpp) 13 | target_link_libraries(demo_hmatrix castor) 14 | set_target_properties(demo_hmatrix PROPERTIES FOLDER "demo") 15 | 16 | add_executable(demo_kissfft demo_kissfft.cpp) 17 | target_link_libraries(demo_kissfft castor) 18 | set_target_properties(demo_kissfft PROPERTIES FOLDER "demo") 19 | 20 | if(LAPACK_FOUND) 21 | add_executable(demo_linalg demo_linalg.cpp) 22 | target_link_libraries(demo_linalg castor) 23 | set_target_properties(demo_linalg PROPERTIES FOLDER "demo") 24 | endif() 25 | 26 | if(VTK_FOUND) 27 | add_executable(demo_graphics demo_graphics.cpp) 28 | target_link_libraries(demo_graphics castor) 29 | set_target_properties(demo_graphics PROPERTIES FOLDER "demo") 30 | vtk_module_autoinit( 31 | TARGETS demo_graphics 32 | MODULES ${VTK_LIBRARIES} 33 | ) 34 | endif() 35 | -------------------------------------------------------------------------------- /doc/source/tools.rst: -------------------------------------------------------------------------------- 1 | .. _label-tools: 2 | 3 | Tools 4 | +++++ 5 | 6 | In this section, we describe some useful tools provided with the **castor** framework. For example, it is possible to produce formatted output with :ref:`label-disp`. It is also possible to get :ref:`label-help` or measure the execution time with :ref:`label-tic` and :ref:`label-toc`. 7 | 8 | 9 | .. _label-disp: 10 | 11 | disp 12 | ---- 13 | .. doxygenfunction:: disp(matrix const &A, int info = 2, std::ostream &flux = std::cout, std::size_t m = 3, std::size_t n = 3) 14 | :project: castor 15 | 16 | .. doxygenfunction:: disp(T A, int info = 1, std::ostream &flux = std::cout) 17 | :project: castor 18 | 19 | See :ref:`label-help`, :ref:`label-error`, :ref:`label-warning`. 20 | 21 | .. _label-help: 22 | 23 | help 24 | ----- 25 | .. doxygenfunction:: help 26 | :project: castor 27 | 28 | See :ref:`label-disp`, :ref:`label-error`, :ref:`label-warning`. 29 | 30 | .. _label-error: 31 | 32 | error 33 | ----- 34 | .. doxygenfunction:: error 35 | :project: castor 36 | 37 | See :ref:`label-warning`, :ref:`label-disp`, :ref:`label-help`. 38 | 39 | .. _label-tic: 40 | 41 | tic 42 | --- 43 | .. doxygenfunction:: tic 44 | :project: castor 45 | 46 | See :ref:`label-toc`. 47 | 48 | .. _label-toc: 49 | 50 | toc 51 | --- 52 | .. doxygenfunction:: toc 53 | :project: castor 54 | 55 | See :ref:`label-tic`. 56 | 57 | .. _label-warning: 58 | 59 | warning 60 | ------- 61 | .. doxygenfunction:: warning 62 | :project: castor 63 | 64 | See :ref:`label-error`, :ref:`label-disp`, :ref:`label-help`. 65 | -------------------------------------------------------------------------------- /test/test_internal_op.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace castor; 5 | 6 | TEST_CASE( "Internal operator : matrix& operator+=(matrixconst& A)", "[Internal operator]" ) 7 | { 8 | matrix V = {0,1,2,3}; 9 | V += matrix(1,4,1); 10 | REQUIRE( V(0) == 1 ); 11 | REQUIRE( V(1) == 2 ); 12 | REQUIRE( V(2) == 3 ); 13 | REQUIRE( V(3) == 4 ); 14 | } 15 | 16 | TEST_CASE( "Internal operator : matrix& operator-=(matrixconst& A)", "[Internal operator]" ) 17 | { 18 | matrix V = {0,1,2,3}; 19 | V -= matrix(1,4,1); 20 | REQUIRE( V(0) == -1 ); 21 | REQUIRE( V(1) == 0 ); 22 | REQUIRE( V(2) == 1 ); 23 | REQUIRE( V(3) == 2 ); 24 | } 25 | 26 | TEST_CASE( "Internal operator : matrix& operator*=(matrixconst& A)", "[Internal operator]" ) 27 | { 28 | matrix V = {0,1,2,3}; 29 | V *= matrix(1,4,2); 30 | REQUIRE( V(0) == 0 ); 31 | REQUIRE( V(1) == 2 ); 32 | REQUIRE( V(2) == 4 ); 33 | REQUIRE( V(3) == 6 ); 34 | } 35 | 36 | TEST_CASE( "Internal operator : matrix& operator/=(matrixconst& A)", "[Internal operator]" ) 37 | { 38 | matrix V = {0,2,4,6}; 39 | V /= matrix(1,4,2); 40 | REQUIRE( V(0) == 0 ); 41 | REQUIRE( V(1) == 1 ); 42 | REQUIRE( V(2) == 2 ); 43 | REQUIRE( V(3) == 3 ); 44 | } 45 | 46 | TEST_CASE( "Internal operator : std::size_t size(int dim=0) const", "[Internal operator]" ) 47 | { 48 | matrix A({{0,1,2,3},{4,5,6,7},{8,9,10,11}}); 49 | REQUIRE( A.size() == 12 ); 50 | REQUIRE( A.size(1) == 3 ); 51 | REQUIRE( A.size(2) == 4 ); 52 | } 53 | -------------------------------------------------------------------------------- /doc/source/linear_solver.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _label-linear-solver-func: 3 | 4 | Linear solver 5 | +++++++++++++ 6 | 7 | This section regroups all of the linear algebra functions concerning linear solver which are currently implemented within **castor**. In order to access these functions, **the user must include** ``castor/linalg.hpp``. Two levels of interface are available. The high-level interface provides functions with simplified arguments while the low-level interface is much closer to the BLAS/LAPACK API. 8 | 9 | The user will find here high-level linear algebra functions. Some examples of use may also be found at :ref:`label-linear-algebra-advanced`. 10 | 11 | 12 | .. _label-inv: 13 | 14 | inv 15 | --- 16 | .. doxygenfunction:: inv(matrix const &A) 17 | :project: castor 18 | 19 | See :ref:`label-linsolve`, :ref:`label-pinv`, :ref:`label-gmres`. 20 | 21 | 22 | .. _label-linsolve: 23 | 24 | linsolve 25 | -------- 26 | .. doxygenfunction:: linsolve(matrix> const &A, matrix> const &B) 27 | :project: castor 28 | .. doxygenfunction:: linsolve(matrix const &A, matrix const &B) 29 | :project: castor 30 | .. doxygenfunction:: linsolve(matrix> const &A, matrix> const &B) 31 | :project: castor 32 | .. doxygenfunction:: linsolve(matrix const &A, matrix const &B) 33 | :project: castor 34 | 35 | See :ref:`label-inv`, :ref:`label-pinv`, :ref:`label-gmres`. 36 | 37 | 38 | .. _label-pinv: 39 | 40 | pinv 41 | ---- 42 | .. doxygenfunction:: pinv(matrix const &A) 43 | :project: castor 44 | 45 | See :ref:`label-inv`, :ref:`label-pinv`. 46 | -------------------------------------------------------------------------------- /doc/source/kissfft.rst: -------------------------------------------------------------------------------- 1 | .. _label-using-kissfft: 2 | 3 | Fast Fourier Transform 4 | ====================== 5 | 6 | The **castor** framework wraps the `kissfft library `_ in a standalone ``kissfft.hpp`` header file so it is not necessary to download it. Currently, only **single precision** arithmetic is supported. We describe below a basic example. 7 | 8 | A minimum working file can be found below. 9 | 10 | .. code:: c++ 11 | 12 | #include "castor/matrix.hpp" 13 | #include "castor/kissfft.hpp" 14 | 15 | int main() 16 | { 17 | matrix> A = rand(3,4) + M_1I*rand(3,4); 18 | // your code here 19 | return 0; 20 | } 21 | 22 | In the code above, we created a random complex single precision matrix with twelve elements. Since only the one-dimensional fft is supported, the matrix ``A`` will be treated as a one-dimensional array where the first row comes first, etc. Now we declare a second matrix ``B`` where we store the result of the forward-backward discrete Fourier transform. 23 | 24 | .. code:: c++ 25 | 26 | matrix> ifft(fft(A)); 27 | 28 | While ``A`` is a two-dimensional array, this is not the case for ``B``. In order to access the one-dimensional data of ``A``, we use a view on the 12 elements using ranged access (see :ref:`label-view`) and we compare it to ``B``. 29 | 30 | .. code:: c++ 31 | 32 | disp(norm(eval(A(range(0,12))) - B, "inf"); 33 | 34 | The output should be something more or less like 35 | 36 | .. code:: text 37 | 38 | (9.31323e-08,0) 39 | 40 | Please note that this code is part of the ``overview_kissfft.cpp`` file which can be found in the ``demo/demo_kissfft`` subfolder. -------------------------------------------------------------------------------- /doc/source/getting_started.rst: -------------------------------------------------------------------------------- 1 | Getting started 2 | =============== 3 | 4 | This section gives an example of use of **matrix** library and the procedure to compile it. 5 | 6 | Example 7 | ------- 8 | 9 | .. code:: 10 | 11 | #include 12 | #include "castor/matrix.hpp" 13 | 14 | using namespace castor; 15 | 16 | int main (int argc, char* argv[]) 17 | { 18 | matrix A = {{ 1.0, 2.0, 3.0, 4.0}, 19 | { 5.0, 6.0, 7.0, 8.0}, 20 | { 9.0, 10.0, 11.0, 12.0}}; 21 | 22 | matrix B = eye(3,4); 23 | 24 | auto C = A + B; 25 | 26 | disp(C); 27 | 28 | return 0; 29 | } 30 | 31 | This example displays the sum of two matrices with implicit cast : 32 | 33 | .. code:: text 34 | 35 | 2.00000 2.00000 3.00000 4.00000 36 | 5.00000 7.00000 7.00000 8.00000 37 | 9.00000 10.00000 12.00000 12.00000 38 | 39 | 40 | .. _label-compilation: 41 | 42 | Compilation 43 | ----------- 44 | 45 | Command line 46 | ++++++++++++ 47 | 48 | The library **matrix** is a header-only library. That actually means to compile program using **matrix**, you just have to specify to the compiler the path to the directory containing the headers. For instance, with GCC, the command to compile the above example (assuming it is contained in a file named ``main.cpp``) : 49 | 50 | .. code:: bash 51 | 52 | g++ -std=c++14 -I /path/to/castor/folder main.cpp -o main 53 | 54 | IDE 55 | +++ 56 | 57 | Simply enter the path to the directory containing the ``castor`` folder in your favorite IDE (VSCode, Xcode, CodeBlocks). 58 | 59 | `Video tutorial for XCode `_ 60 | -------------------------------------------------------------------------------- /getting_started/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | +========================================================================+ 3 | | (c) 2021 - PROPERTY OF ECOLE POLYTECHNIQUE - LGPL 3.0 | 4 | |________________________________________________________________________| 5 | | '&` | | 6 | | # | FILE : main.cpp | 7 | | # | VERSION : | 8 | | _#_ | AUTHOR(S) : | 9 | | ( # ) | CREATION : | 10 | | / 0 \ | LAST MODIF : | 11 | | ( === ) | SYNOPSIS : Working space, to be completed by your project| 12 | | `---' | | 13 | +========================================================================+ 14 | */ 15 | 16 | #include "castor/matrix.hpp" 17 | 18 | using namespace castor; 19 | 20 | int main (int argc, char* argv[]) 21 | { 22 | disp("+=====================+"); 23 | disp("| GETTING STARTED |"); 24 | disp("+=====================+"); 25 | 26 | // Configure documnentation file 27 | documentationFiles = 28 | { 29 | "/usr/local/include/castor/matrix.hpp" // Full name of your file matrix.hpp 30 | }; 31 | 32 | // Documentation of matrix class 33 | help("matrix"); 34 | 35 | // Timer 36 | tic(); 37 | while (toc(0)<0.314159) {} 38 | toc(); 39 | 40 | // Define matrix by values 41 | matrix<> A = {{ 1.0, 2.0, 3.0, 4.0}, 42 | { 5.0, 6.0, 7.0, 8.0}, 43 | { 9.0, 10.0, 11.0, 12.0}}; 44 | 45 | // Define matrix using builder 46 | auto B = eye(3,4); 47 | 48 | // Standard operation 49 | auto C = A + B; 50 | 51 | // Display 52 | disp("C = A+B :"); 53 | disp(C); 54 | 55 | disp("done !"); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /doc/source/factorization.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _label-factorization-func: 3 | 4 | Factorization 5 | +++++++++++++ 6 | 7 | This section regroups all of the linear algebra functions concerning factorization which are currently implemented within **castor**. In order to access these functions, **the user must include** ``castor/linalg.hpp``. Two levels of interface are available. The high-level interface provides functions with simplified arguments while the low-level interface is much closer to the BLAS/LAPACK API. 8 | 9 | Some examples of use may also be found at :ref:`label-linear-algebra-advanced`. 10 | 11 | 12 | .. _label-aca: 13 | 14 | aca 15 | --- 16 | .. doxygenfunction:: aca(matrix const &A, matrix const &B, double tol = 1e-6, std::size_t rmax = 1e6) 17 | :project: castor 18 | .. doxygenfunction:: aca(matrix const &M, double tol = 1e-6, std::size_t rmax = 1e6) 19 | :project: castor 20 | .. doxygenfunction:: aca(matrix I, matrix J, std::function>(matrix, matrix)> const &fct, double tol = 1e-6, std::size_t rmax = 1e6) 21 | :project: castor 22 | .. doxygenfunction:: aca(matrix I, matrix J, std::function(matrix, matrix)> const &fct, double tol = 1e-6, std::size_t rmax = 1e6) 23 | :project: castor 24 | 25 | See :ref:`label-svd`, :ref:`label-rank`. 26 | 27 | 28 | .. _label-lu: 29 | 30 | lu 31 | -- 32 | .. doxygenfunction:: lu(matrix> const &A) 33 | :project: castor 34 | .. doxygenfunction:: lu(matrix const &A) 35 | :project: castor 36 | .. doxygenfunction:: lu(matrix> const &A) 37 | :project: castor 38 | .. doxygenfunction:: lu(matrix const &A) 39 | :project: castor 40 | 41 | See :ref:`label-qr`, :ref:`label-linsolve`, :ref:`label-inv`. 42 | 43 | .. _label-qr: 44 | 45 | qr 46 | -- 47 | .. doxygenfunction:: qr(matrix> const &A) 48 | :project: castor 49 | .. doxygenfunction:: qr(matrix const &A) 50 | :project: castor 51 | .. doxygenfunction:: qr(matrix> const &A) 52 | :project: castor 53 | .. doxygenfunction:: qr(matrix const &A) 54 | :project: castor 55 | 56 | See :ref:`label-eig`, :ref:`label-svd`, :ref:`label-lu`. 57 | -------------------------------------------------------------------------------- /doc/source/builders.rst: -------------------------------------------------------------------------------- 1 | .. _label-builders: 2 | 3 | Builders 4 | ++++++++ 5 | 6 | In this section, the user will find all the possible builders other than the constructors for the ``matrix<>`` object. For the latter, please refer to constructors list in the :ref:`class matrix description `. For example, :ref:`label-eye` will return the idendity matrix while :ref:`label-ones` will return a matrix filled with ones. 7 | 8 | .. _label-colon: 9 | 10 | colon 11 | ----- 12 | .. doxygenfunction:: colon(U j, V k) 13 | :project: castor 14 | .. doxygenfunction:: colon(U j, V i, W k) 15 | :project: castor 16 | 17 | See :ref:`label-linspace`. 18 | 19 | .. _label-diag: 20 | 21 | diag 22 | ---- 23 | .. doxygenfunction:: diag 24 | :project: castor 25 | 26 | See :ref:`label-eye`. 27 | 28 | .. _label-eye: 29 | 30 | eye 31 | --- 32 | .. doxygenfunction:: eye(matrix const &S) 33 | :project: castor 34 | .. doxygenfunction:: eye(std::size_t m, long n = -1) 35 | :project: castor 36 | 37 | See :ref:`label-ones`, :ref:`label-zeros`, :ref:`label-rand`. 38 | 39 | .. _label-linspace: 40 | 41 | linspace 42 | -------- 43 | .. doxygenfunction:: linspace 44 | :project: castor 45 | 46 | See :ref:`label-logspace`, :ref:`label-colon`. 47 | 48 | .. _label-logspace: 49 | 50 | logspace 51 | -------- 52 | .. doxygenfunction:: logspace 53 | :project: castor 54 | 55 | See :ref:`label-linspace`, :ref:`label-colon`, :ref:`label-log`. 56 | 57 | .. _label-rand: 58 | 59 | rand 60 | ---- 61 | .. doxygenfunction:: rand(matrix const &S, bool seed = false) 62 | :project: castor 63 | .. doxygenfunction:: rand(std::size_t m, long n = -1, bool seed = false) 64 | :project: castor 65 | 66 | See :ref:`label-zeros`, :ref:`label-eye`, :ref:`label-ones`. 67 | 68 | .. _label-ones: 69 | 70 | ones 71 | ---- 72 | .. doxygenfunction:: ones(matrix const &S) 73 | :project: castor 74 | .. doxygenfunction:: ones(std::size_t m, long n = -1) 75 | :project: castor 76 | 77 | See :ref:`label-zeros`, :ref:`label-eye`, :ref:`label-rand`. 78 | 79 | .. _label-zeros: 80 | 81 | zeros 82 | ----- 83 | .. doxygenfunction:: zeros(matrix const &S) 84 | :project: castor 85 | .. doxygenfunction:: zeros(std::size_t m, long n = -1) 86 | :project: castor 87 | 88 | See :ref:`label-ones`, :ref:`label-eye`, :ref:`label-rand`. 89 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | The preferred way to contribute to Castor is to fork the [main repository](https://github.com/leprojetcastor/castor) on Github. 4 | 5 | 1. *Search or open an [issue](https://github.com/leprojetcastor/castor/issues) for this project*: 6 | * Search for and click into a related issue that you would like to contribute to. If the issue has not been assigned to anyone, leave a comment and assign the issue to yourself by clicking on the 'Assignees' button on the right. 7 | 8 | * If no such issues have been raised, open a new issue by clicking on the 'New issue' on the top right corner. Write a brief description of the issue and wait for the feedbacks from core developers before moving on to the next steps. 9 | 10 | 2. *Fork the [project repository](https://github.com/leprojetcastor/castor)*: Click on the 'Fork' button on the top right corner of the page. This creates a copy of the code under your account on the GitHub server. 11 | 12 | 3. *Clone this copy to your local disk*: Open up a terminal on your computer, navigate to your preferred directory, and copy the following. 13 | ``` 14 | $ git clone git@github.com:/castor.git 15 | $ cd castor 16 | ``` 17 | 18 | 4. *Instantiate the project*: Install Castor and dependencies and compile the demos following the [user guide](https://leprojetcastor.gitlab.labos.polytechnique.fr/castor/installation.html). 19 | 20 | 5. *Create a branch to hold your changes*: 21 | ``` 22 | git checkout -b my-feature 23 | ``` 24 | 25 | 6. Work on this copy on your computer using your preferred code editor such as Xcode, Visual Studio, VSCode, etc. Make sure you add the [corresponding tests] in the appropriate `demo_xxx.cpp` file. Use Git to do the version control. When you're done editing, do the following to record your changes in Git: 26 | ``` 27 | $ git add modified_files 28 | $ git commit 29 | ``` 30 | 31 | 7. *Push your changes* to Github with: 32 | ``` 33 | $ git push -u origin my-feature 34 | ``` 35 | 36 | 8. Finally, go to the web page of your fork of the castor repository, and *click 'Pull request'* to send your changes to the maintainers for review. This will send an email to the committers. 37 | 38 | If any of the above seems like magic to you, then look up the [Git documentation](https://git-scm.com/doc) on the web. It is recommended to check that your contribution complies with the following rule before submitting a pull request: all public methods should have informative docstrings with sample usage presented, compatible with the documentation process. 39 | 40 | -------------------------------------------------------------------------------- /doc/source/geometry.rst: -------------------------------------------------------------------------------- 1 | .. _label-geometry: 2 | 3 | Geometry 4 | ++++++++ 5 | 6 | The functions from the **Geometry** category are useful to perform transformations between cartesian and polar or spherical coordinates. It is also possible to compute a cartesian 2-dimensional grid with :ref:`label-meshgrid` or to scatter three-dimensional nodes over a sphere with the :ref:`label-sphere` and :ref:`label-sphere2` (Fibonacci sphere) functions. 7 | 8 | 9 | .. _label-cart2pol: 10 | 11 | cart2pol 12 | -------- 13 | .. doxygenfunction:: cart2pol(R const &X, S const &Y) 14 | :project: castor 15 | .. doxygenfunction:: cart2pol(matrix const &X, matrix const &Y) 16 | :project: castor 17 | 18 | See :ref:`label-pol2cart`, :ref:`label-cart2sph`, :ref:`label-sph2cart`. 19 | 20 | .. _label-cart2sph: 21 | 22 | cart2sph 23 | -------- 24 | .. doxygenfunction:: cart2sph(Q const &X, R const &Y, S const &Z) 25 | :project: castor 26 | .. doxygenfunction:: cart2sph(matrix const &X, matrix const &Y, matrix const &Z) 27 | :project: castor 28 | 29 | See :ref:`label-sph2cart`, :ref:`label-cart2pol`, :ref:`label-pol2cart`. 30 | 31 | .. _label-idx2sph: 32 | 33 | idx2sph 34 | -------- 35 | .. doxygenfunction:: idx2sph 36 | :project: castor 37 | 38 | See :ref:`label-sph2idx`, :ref:`label-sphere`. 39 | 40 | .. _label-meshgrid: 41 | 42 | meshgrid 43 | -------- 44 | .. doxygenfunction:: meshgrid 45 | :project: castor 46 | 47 | See :ref:`label-kron`. 48 | 49 | .. _label-pol2cart: 50 | 51 | pol2cart 52 | -------- 53 | .. doxygenfunction:: pol2cart(R const &THE, S const &RHO) 54 | :project: castor 55 | .. doxygenfunction:: pol2cart(matrix const &THE, matrix const &RHO) 56 | :project: castor 57 | 58 | See :ref:`label-cart2pol`, :ref:`label-cart2sph`, :ref:`label-sph2cart`. 59 | 60 | .. _label-sph2cart: 61 | 62 | sph2cart 63 | -------- 64 | .. doxygenfunction:: sph2cart(Q const &THE, R const &PHI, S const &RHO) 65 | :project: castor 66 | .. doxygenfunction:: sph2cart(matrix const &THE, matrix const &PHI, matrix const &RHO) 67 | :project: castor 68 | 69 | See :ref:`label-cart2sph`, :ref:`label-cart2pol`, :ref:`label-pol2cart`. 70 | 71 | .. _label-sph2idx: 72 | 73 | sph2idx 74 | -------- 75 | .. doxygenfunction:: sph2idx 76 | :project: castor 77 | 78 | See :ref:`label-idx2sph`, :ref:`label-sphere`. 79 | 80 | .. _label-sphere: 81 | 82 | sphere 83 | ------ 84 | .. doxygenfunction:: sphere 85 | :project: castor 86 | 87 | See :ref:`label-idx2sph`, :ref:`label-sph2idx`. 88 | 89 | .. _label-sphere2: 90 | 91 | sphere2 92 | ------- 93 | .. doxygenfunction:: sphere2 94 | :project: castor 95 | 96 | See :ref:`label-sphere`. -------------------------------------------------------------------------------- /doc/source/singular_eig_values.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _label-singular-eig-values-func: 3 | 4 | Singular and eigen values 5 | +++++++++++++++++++++++++ 6 | 7 | This section regroups all of the linear algebra functions concerning singular and eigen values which are currently implemented within **castor**. In order to access these functions, **the user must include** ``castor/linalg.hpp``. Two levels of interface are available. The high-level interface provides functions with simplified arguments while the low-level interface is much closer to the BLAS/LAPACK API. 8 | 9 | The user will find here high-level linear algebra functions. Some examples of use may also be found at :ref:`label-linear-algebra-advanced`. 10 | 11 | .. _label-eig: 12 | 13 | eig 14 | --- 15 | .. doxygenfunction:: eig(matrix const &A, matrix const &B) 16 | :project: castor 17 | .. doxygenfunction:: eig(matrix> const &A, matrix> const &B, std::string typ) 18 | :project: castor 19 | .. doxygenfunction:: eig(matrix> const &A, matrix> const &B, std::string typ) 20 | :project: castor 21 | .. doxygenfunction:: eig(matrix const &A, matrix const &B, std::string typ) 22 | :project: castor 23 | .. doxygenfunction:: eig(matrix const &A, matrix const &B, std::string typ) 24 | :project: castor 25 | .. doxygenfunction:: eig(matrix const &A) 26 | :project: castor 27 | .. doxygenfunction:: eig(matrix> const &A, std::string typ) 28 | :project: castor 29 | .. doxygenfunction:: eig(matrix> const &A, std::string typ) 30 | :project: castor 31 | .. doxygenfunction:: eig(matrix const &A, std::string typ) 32 | :project: castor 33 | .. doxygenfunction:: eig(matrix const &A, std::string typ) 34 | :project: castor 35 | 36 | See :ref:`label-qr`, :ref:`label-svd`. 37 | 38 | .. _label-qrsvd: 39 | 40 | qrsvd 41 | ----- 42 | .. doxygenfunction:: qrsvd(matrix const &A, matrix const &B, float tol) 43 | :project: castor 44 | 45 | See :ref:`label-svd`, :ref:`label-qr`. 46 | 47 | .. _label-rank: 48 | 49 | rank 50 | ---- 51 | 52 | .. doxygenfunction:: rank() 53 | :project: castor 54 | 55 | See :ref:`label-svd`, :ref:`label-aca`. 56 | 57 | 58 | .. _label-svd: 59 | 60 | svd 61 | --- 62 | .. doxygenfunction:: svd(matrix const &A) 63 | :project: castor 64 | .. doxygenfunction:: svd(matrix> const &A, std::string typ) 65 | :project: castor 66 | .. doxygenfunction:: svd(matrix const &A, std::string typ) 67 | :project: castor 68 | .. doxygenfunction:: svd(matrix> const &A, std::string typ) 69 | :project: castor 70 | .. doxygenfunction:: svd(matrix const &A, std::string typ) 71 | :project: castor 72 | 73 | See :ref:`label-rank`, :ref:`label-eig`, :ref:`label-qr`, :ref:`label-qrsvd`, :ref:`label-aca`. 74 | -------------------------------------------------------------------------------- /paper/paper.bib: -------------------------------------------------------------------------------- 1 | @article{bezanson2012julia, 2 | title={{Julia:} {A} fast dynamic language for technical computing}, 3 | author={{Bezanson}, Jeff and {Karpinski}, Stefan and {Shah}, Viral B. and {Edelman}, Alan}, 4 | journal={arXiv preprint arXiv:1209.5145}, 5 | year={2012} 6 | } 7 | 8 | @BOOK{blaslapack:00, 9 | AUTHOR = {{Anderson}, E. and {Bai}, Z. and {Bischof}, C. and 10 | {Blackford}, S. and {Demmel}, J. and {Dongarra}, J. and 11 | {Du Croz}, J. and {Greenbaum}, A. and {Hammarling}, S. and 12 | {McKenney}, A. and {Sorensen}, D.}, 13 | TITLE = {{LAPACK} {Users'} guide}, 14 | EDITION = {Third}, 15 | PUBLISHER = {{Society for Industrial and Applied Mathematics}}, 16 | YEAR = {1999}, 17 | ADDRESS = {Philadelphia, PA}, 18 | ISBN = {0-89871-447-8} 19 | } 20 | 21 | @article{cpp:14, 22 | author = {ISO/IEC}, 23 | title = {International standard ISO/IEC 14882:2014(E) – {Programming} language {C}++}, 24 | year = {2014}, 25 | journal = {Geneva, Switzerland: International Organization for Standardization}, 26 | } 27 | 28 | @article{hackbush:1999, 29 | author = {{Hackbusch}, W.}, 30 | journal = {Computing, 62(2), 89–108}, 31 | title = {{A sparse matrix arithmetic based on H-matrices. Part 1: Introduction to H-matrices}}, 32 | year = {1999} 33 | } 34 | 35 | @book{MATLAB:2010, 36 | year = {2010}, 37 | author = {MATLAB}, 38 | title = {version 7.10.0 (R2010a)}, 39 | publisher = {The MathWorks Inc.}, 40 | address = {Natick, Massachusetts} 41 | } 42 | 43 | @article{sparse:1973, 44 | author = {{Tewarson}, R. P.}, 45 | title = {Sparse matrices}, 46 | journal = {New York: Academic press, Vol. 69}, 47 | year = 1973 48 | } 49 | 50 | @article{rjasanow:2002, 51 | author = {{Rjasanow}, S.}, 52 | title = {Adaptive cross approximation of dense matrices}, 53 | journal = {{Int. Association Boundary Element Methods Conf., IABEM (pp. 28-30)}}, 54 | year = 2002 55 | } 56 | 57 | @article{symare:2013, 58 | author = {{Jin}, C. T. and {Guillon}, P. and {Epain}, N. and {Zolfaghari}, R. and {van Schaik}, A. and {Tew}, A. I. and {Thorpe}, J.}, 59 | title = {{Creating the Sydney York morphological and acoustic recordings of ears database}}, 60 | journal = {IEEE Transactions on Multimedia, 16(1), 37-46}, 61 | doi = {10.1109/icme.2012.93}, 62 | year = 2013 63 | } 64 | 65 | @article{terasse:2007, 66 | author = {{Terrasse}, I. and {Abboud}, T.}, 67 | title = {Modélisation des phénomènes de propagation d’ondes.}, 68 | journal = {École polytechnique}, 69 | year = 2013 70 | } 71 | 72 | @article{vtk:2000, 73 | author = {{Schroeder}, W. J. and {Avila}, L. S. and {Hoffman}, W.}, 74 | title = {Visualizing with VTK: a tutorial}, 75 | year = {2000}, 76 | doi = {10.1109/38.865875}, 77 | journal = {IEEE Computer graphics and applications, 20(5), 20-27}, 78 | } 79 | 80 | @misc{eigenweb, 81 | author = {{Guennebaud}, Ga\"{e}l and {Jacob}, Beno\^{i}t and et al.}, 82 | title = {Eigen v3}, 83 | howpublished = {http://eigen.tuxfamily.org}, 84 | year = {2010} 85 | } 86 | 87 | @misc{fembem:21, 88 | author = {{Aussal}, M. and {Bakry}, M.}, 89 | year = {2021}, 90 | url = {https://gitlab.labos.polytechnique.fr/leprojetcastor/fembem}, 91 | } 92 | -------------------------------------------------------------------------------- /test/test_constructors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace castor; 5 | 6 | TEST_CASE( "Constructor : matrix(T v) ", "[constructor]" ) 7 | { 8 | matrix A(1); 9 | REQUIRE( A.size() == 1 ); 10 | REQUIRE( A.size(1) == 1 ); 11 | REQUIRE( A.size(2) == 1 ); 12 | REQUIRE( A(0) == 1 ); 13 | } 14 | 15 | TEST_CASE( "Constructor : matrix(std::initializer_listconst& v)", "[constructor]" ) 16 | { 17 | matrix A({0,1,2,M_PI}); 18 | REQUIRE( A.size() == 4 ); 19 | REQUIRE( A.size(1) == 1 ); 20 | REQUIRE( A.size(2) == 4 ); 21 | REQUIRE( A(0) == 0 ); 22 | REQUIRE( A(1) == 1 ); 23 | REQUIRE( A(2) == 2 ); 24 | REQUIRE( A(3) == Approx(M_PI) ); 25 | } 26 | 27 | TEST_CASE( "Constructor : matrix(std::initializer_list>const& v)", "[constructor]" ) 28 | { 29 | matrix A({{0,1,2,M_PI},{4,5,6,7},{8,9,10,11}}); 30 | REQUIRE( A.size() == 12 ); 31 | REQUIRE( A.size(1) == 3 ); 32 | REQUIRE( A.size(2) == 4 ); 33 | REQUIRE( A(0) == 0 ); 34 | REQUIRE( A(1) == 1 ); 35 | REQUIRE( A(2) == 2 ); 36 | REQUIRE( A(3) == M_PI ); 37 | REQUIRE( A(4) == 4 ); 38 | REQUIRE( A(5) == 5 ); 39 | REQUIRE( A(6) == 6 ); 40 | REQUIRE( A(7) == 7); 41 | REQUIRE( A(8) == 8 ); 42 | REQUIRE( A(9) == 9 ); 43 | REQUIRE( A(10) == 10 ); 44 | REQUIRE( A(11) == 11); 45 | } 46 | 47 | TEST_CASE( "Constructor : matrix(std::size_t m, std::size_t n, T v=0)", "[constructor]") 48 | { 49 | matrix> A(2,3,std::complex(1,M_PI)); 50 | REQUIRE( A.size() == 6 ); 51 | REQUIRE( A.size(1) == 2 ); 52 | REQUIRE( A.size(2) == 3 ); 53 | for (std::size_t i=0; iconst& v)", "[constructor]") 60 | { 61 | matrix A(std::vector({0, 1, 2, 3})); 62 | REQUIRE( A.size() == 4 ); 63 | REQUIRE( A.size(1) == 1 ); 64 | REQUIRE( A.size(2) == 4 ); 65 | REQUIRE( A(0) == 0 ); 66 | REQUIRE( A(1) == 1 ); 67 | REQUIRE( A(2) == 2 ); 68 | REQUIRE( A(3) == 3 ); 69 | } 70 | 71 | TEST_CASE( "Constructor : matrix(std::size_t m, std::size_t n, std::vectorconst& v)", "[constructor]") 72 | { 73 | matrix A(2,2,{0, 1, 2, 3}); 74 | REQUIRE( A.size() == 4 ); 75 | REQUIRE( A.size(1) == 2 ); 76 | REQUIRE( A.size(2) == 2 ); 77 | REQUIRE( A(0) == 0 ); 78 | REQUIRE( A(1) == 1 ); 79 | REQUIRE( A(2) == 2 ); 80 | REQUIRE( A(3) == 3 ); 81 | } 82 | 83 | TEST_CASE( "Constructor : matrix(std::size_t m, std::size_t n, std::vector>const& v)", "[constructor]") 84 | { 85 | matrix<> A(2,2,{{0, 1},{2,3}}); 86 | REQUIRE( A.size() == 4 ); 87 | REQUIRE( A.size(1) == 2 ); 88 | REQUIRE( A.size(2) == 2 ); 89 | REQUIRE( A(0) == 0 ); 90 | REQUIRE( A(1) == 1 ); 91 | REQUIRE( A(2) == 2 ); 92 | REQUIRE( A(3) == 3 ); 93 | } 94 | 95 | TEST_CASE( "Constructor : matrix(matrixconst& A)", "[constructor]") 96 | { 97 | matrix<> B(2,2,{{0, 1},{2,3}}); 98 | matrix<> A(B); 99 | REQUIRE( A.size() == 4 ); 100 | REQUIRE( A.size(1) == 2 ); 101 | REQUIRE( A.size(2) == 2 ); 102 | REQUIRE( A(0) == 0 ); 103 | REQUIRE( A(1) == 1 ); 104 | REQUIRE( A(2) == 2 ); 105 | REQUIRE( A(3) == 3 ); 106 | } 107 | -------------------------------------------------------------------------------- /doc/source/montecarlo.rst: -------------------------------------------------------------------------------- 1 | Monte Carlo method 2 | ================== 3 | *Shared by Antoine Rideau* 4 | 5 | On this page you will find how to calculate using **Castor** the value of :math:`\pi` with Monte Carlo method. 6 | 7 | Monte Carlo methods are a broad class of computational algorithms that rely on repeated random sampling to obtain numerical results. 8 | The underlying concept is to use randomness to solve problems that might be deterministic in principle. 9 | They are mainly used in physical and mathematical problems related to optimization, numerical integration, and generating draws from a probability distribution. 10 | 11 | First, draw 1 by 1 square and inscribe a quadrant within it. 12 | 13 | 14 | Then ``n`` points are scattered randomly with :math:`(x,y)` coordinate over the square. 15 | 16 | .. code-block:: c++ 17 | 18 | // Parameters 19 | double n = 5000.; //Number of points 20 | auto MX = rand(1, n); 21 | auto MY = rand(1, n); 22 | 23 | 24 | As the quadrant's surface is equal to 25 | 26 | .. math:: 27 | 28 | \sigma = \frac{R^2 \pi}{4} = \frac{\pi}{4} \text{ as } R = 1 , 29 | 30 | and the square's surface is 31 | 32 | .. math:: 33 | 34 | S = R^2 = 1 , 35 | 36 | the probability to be in the quadrant is 37 | 38 | .. math:: 39 | 40 | \mathbb{P} = \frac{N_{in}}{n} = \frac{\sigma}{S} = \frac{\pi}{4} , 41 | 42 | | with :math:`N_{in}` number of points inside the quadrant. 43 | | Hence, 44 | 45 | .. math:: 46 | 47 | \pi = 4 * \frac{N_{in}}{n} . 48 | 49 | 50 | So, points inside the quadrant i.e points with :math:`x^2 + y^2 \leq 1` are counted. 51 | 52 | .. code-block:: c++ 53 | 54 | // Pi computation 55 | matrix Incircle; 56 | Incircle = find(pow(MX, 2) + pow(MY, 2) <= 1); 57 | double Pi = 4. * (numel(Incircle) / n); 58 | 59 | See :ref:`label-find-smatrix` , :ref:`label-numel` 60 | 61 | Another way of doing it is by using ``sum`` 62 | 63 | .. code-block:: c++ 64 | 65 | size_t Nin = sum(pow(MX, 2) + pow(MY, 2) <= 1); 66 | double Pi = 4. * (Nin / n); 67 | 68 | See :ref:`label-sum` 69 | 70 | Code 71 | ---- 72 | 73 | .. code-block:: c++ 74 | 75 | #include "castor/matrix.hpp" 76 | #include "castor/graphics.hpp" 77 | 78 | using namespace castor; 79 | 80 | int main(int argc, char const *argv[]) 81 | { 82 | 83 | // Parameters 84 | double n = 5000.; //Number of points 85 | auto MX = rand(1, n); 86 | auto MY = rand(1, n); 87 | 88 | // Pi computation 89 | matrix Incircle; 90 | Incircle = find(pow(MX, 2) + pow(MY, 2) <= 1); 91 | double Pi = 4. * (numel(Incircle) / n); 92 | std::cout << "Calculated value of pi: " << Pi << endl; 93 | 94 | // Visu 95 | auto X = linspace(0, 1, 1000); 96 | auto Y = sqrt(1 - pow(X, 2)); 97 | figure fig; 98 | plot(fig, MX, MY, {"b"}); 99 | plot(fig, eval(MX(Incircle)), eval(MY(Incircle)), {"r"}); 100 | plot(fig, X, Y, {"r-"}); 101 | drawnow(fig); 102 | 103 | return 0; 104 | } 105 | 106 | With this code you should get these outputs : 107 | 108 | .. code-block:: text 109 | 110 | Calculated value of pi: 3.148 111 | 112 | 113 | .. image:: img/montecarloresult.png 114 | :width: 400 115 | :align: center 116 | 117 | 118 | References 119 | ---------- 120 | 121 | https://en.wikipedia.org/wiki/Monte_Carlo_method -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.18) 2 | 3 | project(castor LANGUAGES CXX VERSION 1.0.0) 4 | 5 | set(CASTOR_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include) 6 | 7 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 8 | 9 | message(STATUS "Building castor v${${PROJECT_NAME}_VERSION}") 10 | 11 | ############################### 12 | # dependencies 13 | 14 | find_package(LAPACK) 15 | if(LAPACK_FOUND) 16 | message(STATUS "BLAS and LAPACK found") 17 | else() 18 | message(STATUS "BLAS and LAPACK not found") 19 | set(BLAS_LIBRARIES "") 20 | endif() 21 | message(STATUS "BLAS_LIBRARIES : " ${BLAS_LIBRARIES}) 22 | message(STATUS "LAPACK_LIBRARIES : " ${LAPACK_LIBRARIES}) 23 | 24 | find_package(VTK COMPONENTS 25 | vtkChartsCore 26 | vtkCommonColor 27 | vtkCommonCore 28 | vtkCommonDataModel 29 | vtkInteractionStyle 30 | vtkRenderingContext2D 31 | vtkRenderingContextOpenGL2 32 | vtkRenderingCore 33 | vtkRenderingFreeType 34 | vtkRenderingGL2PSOpenGL2 35 | vtkRenderingOpenGL2 36 | vtkViewsContext2D 37 | 38 | vtkRenderingAnnotation 39 | vtkIOImage 40 | vtkIOPLY 41 | vtkIOLegacy 42 | vtkIOOggTheora 43 | vtkFiltersGeometry 44 | QUIET 45 | ) 46 | if(VTK_FOUND) 47 | message(STATUS "Find VTK version : ${VTK_VERSION}") 48 | else() 49 | message(STATUS "VTK not found") 50 | endif() 51 | message(STATUS "VTK_LIBRARIES : ${VTK_LIBRARIES}") 52 | 53 | ############################### 54 | # target 55 | 56 | add_library(castor INTERFACE) 57 | 58 | if(LAPACK_FOUND) 59 | if(BLAS_LIBRARIES MATCHES "Accelerate") 60 | target_compile_definitions(castor INTERFACE -D__CLAPACK_H) 61 | else() 62 | find_path(CBLAS_INCLUDE_DIR cblas.h) 63 | endif() 64 | endif() 65 | 66 | target_include_directories(castor INTERFACE 67 | $ 68 | $ 69 | $ 70 | $ 71 | $ 72 | $) 73 | 74 | target_link_libraries(castor INTERFACE ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES} ${VTK_LIBRARIES}) 75 | 76 | target_compile_features(castor INTERFACE cxx_std_14) 77 | 78 | add_subdirectory(include) 79 | add_subdirectory(extern) 80 | add_subdirectory(test) 81 | add_subdirectory(demo) 82 | add_subdirectory(misc) 83 | add_subdirectory(getting_started) 84 | 85 | ############################### 86 | # installation 87 | 88 | include(GNUInstallDirs) 89 | include(CMakePackageConfigHelpers) 90 | 91 | install(TARGETS castor 92 | EXPORT ${PROJECT_NAME}-targets) 93 | 94 | # Makes the project importable from the build directory 95 | export(EXPORT ${PROJECT_NAME}-targets 96 | FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake") 97 | 98 | install(DIRECTORY ${CASTOR_INCLUDE_DIRS}/castor 99 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 100 | ####install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/castor/matrix.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/castor) 101 | 102 | set(CASTOR_CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" CACHE 103 | STRING "install path for matrixConfig.cmake") 104 | 105 | configure_package_config_file(${PROJECT_NAME}Config.cmake.in 106 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 107 | INSTALL_DESTINATION ${CASTOR_CMAKECONFIG_INSTALL_DIR}) 108 | 109 | write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake 110 | VERSION ${${PROJECT_NAME}_VERSION} 111 | COMPATIBILITY AnyNewerVersion) 112 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake 113 | ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake 114 | DESTINATION ${CASTOR_CMAKECONFIG_INSTALL_DIR}) 115 | install(EXPORT ${PROJECT_NAME}-targets 116 | FILE ${PROJECT_NAME}Targets.cmake 117 | DESTINATION ${CASTOR_CMAKECONFIG_INSTALL_DIR}) 118 | 119 | configure_file(${PROJECT_NAME}.pc.in 120 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" 121 | @ONLY) 122 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc" 123 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig/") 124 | -------------------------------------------------------------------------------- /doc/source/api_hmatrix.rst: -------------------------------------------------------------------------------- 1 | 2 | API 3 | === 4 | 5 | .. _label-full-hmatrix: 6 | 7 | full 8 | ---- 9 | .. doxygenfunction:: full(hmatrix const &Ah) 10 | :project: castor 11 | 12 | .. _label-gmres-hmatrix: 13 | 14 | gmres 15 | ----- 16 | .. doxygenfunction:: gmres(hmatrix const &Ah, matrix const &B, double tol, std::size_t maxit, hmatrix const &Lh, hmatrix const &Uh, matrix const &X0 = matrix()) 17 | :project: castor 18 | .. doxygenfunction:: gmres(hmatrix const &Ah, matrix const &B, double tol, std::size_t maxit, hmatrix const &Ahm1, matrix const &X0 = matrix()) 19 | :project: castor 20 | .. doxygenfunction:: gmres(hmatrix const &Ah, matrix const &B, double tol = 1e-6, std::size_t maxit = 10, std::function(matrix const&)> const &Am1 = std::function(matrix const&)>(), matrix const &X0 = matrix()) 21 | :project: castor 22 | 23 | .. _label-inv-hmatrix: 24 | 25 | inv 26 | --- 27 | .. doxygenfunction:: inv(hmatrix const &Ah) 28 | :project: castor 29 | 30 | 31 | .. _label-linsolve-hmatrix: 32 | 33 | linsolve 34 | -------- 35 | .. doxygenfunction:: linsolve(hmatrix const &Ah, matrix const &B) 36 | :project: castor 37 | 38 | 39 | .. _label-lu-hmatrix: 40 | 41 | lu 42 | -- 43 | .. doxygenfunction:: lu(hmatrix const &Ah, double tol = 0) 44 | :project: castor 45 | 46 | 47 | .. _label-mtimes-hmatrix: 48 | 49 | mtimes 50 | ------ 51 | .. doxygenfunction:: mtimes(hmatrix const &Ah, hmatrix const &Bh) 52 | :project: castor 53 | .. doxygenfunction:: mtimes(matrix const &A, hmatrix const &Bh) 54 | :project: castor 55 | .. doxygenfunction:: mtimes(hmatrix const &Ah, matrix const &B) 56 | :project: castor 57 | 58 | 59 | .. _label-size_hmatrix: 60 | 61 | size 62 | ---- 63 | .. doxygenfunction:: size(hmatrix const &Ah) 64 | :project: castor 65 | 66 | See :ref:`label-length`, :ref:`label-numel`. 67 | 68 | .. _label-spydata: 69 | 70 | spydata 71 | ------- 72 | .. doxygenfunction:: spydata(hmatrix const &Ah) 73 | :project: castor 74 | 75 | .. _label-tgeabm-hmatrix: 76 | 77 | tgeabm 78 | ------ 79 | .. doxygenfunction:: tgeabm(T alpha, matrix const &A, matrix const &B, T beta, hmatrix &Ch) 80 | :project: castor 81 | 82 | 83 | .. _label-tgemm-hmatrix: 84 | 85 | tgemm 86 | ----- 87 | .. doxygenfunction:: tgemm(T alpha, hmatrix const &Ah, hmatrix const &Bh, T beta, hmatrix &Ch) 88 | :project: castor 89 | 90 | 91 | .. _label-transpose-hmatrix: 92 | 93 | transpose 94 | --------- 95 | .. doxygenfunction:: transpose(hmatrix const &Ah) 96 | :project: castor 97 | 98 | 99 | .. _label-operators-hmatrix: 100 | 101 | operators 102 | --------- 103 | 104 | .. _label-operator<<-hmatrix: 105 | 106 | operator<< 107 | ++++++++++ 108 | 109 | .. doxygenfunction:: operator<<(std::ostream &flux, hmatrix const &Ah) 110 | :project: castor 111 | 112 | 113 | .. _label-operator+-hmatrix: 114 | 115 | operator+ 116 | ++++++++++ 117 | 118 | .. doxygenfunction:: operator+(T a, hmatrix const &Bh) 119 | :project: castor 120 | .. doxygenfunction:: operator+(hmatrix const &Ah, hmatrix const &Bh) 121 | :project: castor 122 | .. doxygenfunction:: operator+(hmatrix const &Ah, T b) 123 | :project: castor 124 | 125 | 126 | .. _label-operator--hmatrix: 127 | 128 | operator- 129 | ++++++++++ 130 | 131 | .. doxygenfunction:: operator-(T a, hmatrix const &Bh) 132 | :project: castor 133 | .. doxygenfunction:: operator-(hmatrix const &Ah, hmatrix const &Bh) 134 | :project: castor 135 | .. doxygenfunction:: operator-(hmatrix const &Ah, T b) 136 | :project: castor 137 | .. doxygenfunction:: operator-(hmatrix const &Ah) 138 | :project: castor 139 | 140 | 141 | .. _label-operator*-hmatrix: 142 | 143 | operator* 144 | ++++++++++ 145 | 146 | .. doxygenfunction:: operator*(T a, hmatrix const &Bh) 147 | :project: castor 148 | .. doxygenfunction:: operator*(hmatrix const &Ah, T b) 149 | :project: castor 150 | 151 | 152 | .. _label-operator/-hmatrix: 153 | 154 | operator/ 155 | ++++++++++ 156 | 157 | .. doxygenfunction:: operator/(hmatrix const &Ah, T b) 158 | :project: castor 159 | 160 | 161 | .. _label-operator+=-hmatrix: 162 | 163 | operator+= 164 | ++++++++++ 165 | .. doxygenfunction:: operator+=(hmatrix const &Bh) 166 | :project: castor 167 | .. doxygenfunction:: operator+=(T b) 168 | :project: castor 169 | 170 | 171 | 172 | .. _label-operator*=-hmatrix: 173 | 174 | operator*= 175 | ++++++++++ 176 | .. doxygenfunction:: operator*=(T b) 177 | :project: castor 178 | -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to the castor library documentation 2 | =========================================== 3 | 4 | The objective of the **castor** library is to propose **high-level semantics**, inspired by the Matlab language, allowing fast software prototyping in a low-level compiled language. It is nothing more than a **matrix management layer** using the tools of the standard **C++** library, in different storage formats (full, sparse and hierarchical). Indeed, the use of IDEs 1 such as Xcode, Visual studio, Eclipse, etc. allows today to execute compiled code (C, C++, fortran, etc.) with the **same flexibility as interpreted languages** (Matlab, Python, Julia, etc.). 5 | 6 | A **header-only** template library for matrix management has been developed based on the standard C++ library, notably the std::vector class. Many tools and algorithms are provided to simplify the development of scientific computing programs. Particular attention has been paid to semantics, for a simplicity of use "à la matlab", but written in C++. This high-level semantic/low-level language coupling makes it possible to gain efficiency in the prototyping phase, while ensuring performance for applications. In addition, direct access to data allows users to optimize the most critical parts of their code in native C++. Finally, **complete documentation** is available, as well as continuous integration unit tests. All of this makes it possible to meet the needs of teaching, academic issues and industrial applications at the same time. 7 | 8 | The **castor** library provides tools to : 9 | 10 | - create and manipulate dense, sparse and hierarchical matrices 11 | - make linear algebra computations based on optimized BLAS library 12 | - make graphical representations based on VTK library 13 | 14 | These tools are used by applicative projects : 15 | 16 | - finite and boundary element method using Galerkin approximation 17 | - analytical solutions for scattering problems 18 | 19 | The source files of the library is available here : ``_. 20 | 21 | As the semantics offered by **castor** library being voluntarily close to the Matlab environment, there are functions signature and their documentation inspired by it. You can refer to https://fr.mathworks.com/help/matlab/index.html. 22 | 23 | Licensing 24 | --------- 25 | 26 | The **castor** library is provided in open source under LGPL 3.0. 27 | 28 | This program is free software, distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. Natively, you can use, redistribute and/or modify it under the terms of the GNU Lesser General Public License, as published by the Free Software Foundation (version 3 or later, http://www.gnu.org/licenses). 29 | 30 | 31 | Gallery 32 | ------- 33 | .. image:: img/head.png 34 | :width: 600 35 | :align: center 36 | 37 | Boundary element computation using le projet castor. Simulation of acoustic scattering by human head, excited by plane wave at 8Khz (20.000 degrees of freedom). Hierarchical solver is used on a standard laptop. 38 | 39 | .. toctree:: 40 | :caption: Installation 41 | :maxdepth: 1 42 | :hidden: 43 | 44 | installation 45 | 46 | .. toctree:: 47 | :caption: Examples 48 | :maxdepth: 1 49 | :hidden: 50 | 51 | heat 52 | eigenmode 53 | montecarlo 54 | replicatormutator 55 | nbody 56 | boids 57 | 58 | .. _label-user-guide: 59 | 60 | .. toctree:: 61 | :caption: User guide 62 | :maxdepth: 1 63 | :hidden: 64 | 65 | getting_started 66 | basics 67 | advanced 68 | linalg 69 | graphics 70 | sparse_matrix 71 | kissfft 72 | 73 | .. toctree:: 74 | :caption: Dense matrix 75 | :maxdepth: 1 76 | :hidden: 77 | 78 | class_matrix 79 | class_view_cview 80 | algorithm 81 | builders 82 | geometry 83 | io 84 | math 85 | dimensions 86 | manipulations 87 | operators 88 | tools 89 | transforms 90 | 91 | .. toctree:: 92 | :caption: Linear algebra 93 | :maxdepth: 1 94 | :hidden: 95 | 96 | factorization 97 | linear_solver 98 | singular_eig_values 99 | lowlevel_linalg_func 100 | 101 | .. toctree:: 102 | :caption: Graphical rendering 103 | :maxdepth: 1 104 | :hidden: 105 | 106 | class_figure 107 | basic_plot 108 | graphical_io 109 | graphical_tools 110 | mesh_management 111 | mesh_plot 112 | 113 | .. toctree:: 114 | :caption: Sparse matrix 115 | :maxdepth: 1 116 | :hidden: 117 | 118 | class_smatrix 119 | api_smatrix 120 | 121 | .. toctree:: 122 | :caption: Hierarchical matrix 123 | :maxdepth: 1 124 | :hidden: 125 | 126 | class_hmatrix 127 | class_bintree 128 | api_hmatrix 129 | 130 | .. toctree:: 131 | :caption: Applications 132 | :maxdepth: 1 133 | :hidden: 134 | 135 | fembem 136 | analyticalscattering 137 | castorfftw 138 | 139 | .. toctree:: 140 | :caption: Contacts 141 | :maxdepth: 1 142 | :hidden: 143 | 144 | developpers 145 | 146 | -------------------------------------------------------------------------------- /demo/demo_kissfft.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | +========================================================================+ 3 | | (c) 2020 - PROPERTY OF ECOLE POLYTECHNIQUE - LGPL 3.0 | 4 | |________________________________________________________________________| 5 | | '&` | | 6 | | # | FILE : demo_kissfft.cpp | 7 | | # | VERSION : 1.0.0 | 8 | | _#_ | AUTHOR(S) : Matthieu Aussal | 9 | | ( # ) | CREATION : 25.11.2020 | 10 | | / 0 \ | LAST MODIF : 25.11.2020 | 11 | | ( === ) | SYNOPSIS : Interface of kissfft library for complex and | 12 | | `---' | real fourier transform. | 13 | +========================================================================+ 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | using namespace castor; 20 | 21 | int main(int argc, const char * argv[]) 22 | { 23 | disp("+===============+"); 24 | disp("| CKISS |"); 25 | disp("+===============+"); 26 | 27 | // Define 28 | ckiss a(1,2), b(3,-4), c, d; 29 | 30 | // Math operators 31 | disp(a); 32 | a += b; 33 | disp(a); 34 | a -= b; 35 | disp(a); 36 | a *= b; 37 | disp(a); 38 | a /= b; 39 | disp(a); 40 | disp(a+b-b); 41 | disp(a*b/b); 42 | 43 | // Flux operators 44 | std::ofstream output("castor_kissfftIO.txt"); 45 | output << a << b << std::endl; 46 | output.close(); 47 | std::ifstream input("castor_kissfftIO.txt"); 48 | input >> c; 49 | input >> d; 50 | input.close(); 51 | disp(c); 52 | disp(d); 53 | 54 | disp("+===============+"); 55 | disp("| FFT |"); 56 | disp("+===============+"); 57 | 58 | matrix> A = rand(3,4) + M_1I*rand(3,4), B; 59 | 60 | // FFT for all values 61 | disp("FFT for all values :"); 62 | B = ifft(fft(A)); 63 | disp( norm(eval(A(range(0,12)))-B,"inf") ); 64 | B = ifft(fft(A,6),6); 65 | disp( norm(eval(A(range(0,6)))-B,"inf") ); 66 | B = ifft(fft(A,24)); 67 | disp( norm(eval(A(range(0,12)))-eval(B(range(0,12))),"inf") ); 68 | 69 | // FFT along first dimension 70 | disp("FFT WITH along 1st dimension :"); 71 | B = ifft(fft(A,0,1),0,1); 72 | disp( norm(A-B,"inf") ); 73 | B = ifft(fft(A,2,1),2,1); 74 | disp( norm(eval(A({0,1},col(A)))-B,"inf") ); 75 | B = ifft(fft(A,6,1),6,1); 76 | disp( norm(A-eval(B(row(A),col(A))),"inf") ); 77 | 78 | // FFT along second dimension 79 | disp("FFT WITH along 2nd dimension:"); 80 | B = ifft(fft(A,0,2),0,2); 81 | disp( norm(A-B,"inf") ); 82 | B = ifft(fft(A,2,2),2,2); 83 | disp( norm(eval(A(row(A),{0,1}))-B,"inf") ); 84 | B = ifft(fft(A,6,2),6,2); 85 | disp( norm(A-eval(B(row(A),col(A))),"inf") ); 86 | 87 | disp("+===============+"); 88 | disp("| DFT |"); 89 | disp("+===============+"); 90 | 91 | matrix> ref, sol; 92 | 93 | // FFT versus DFT for all values 94 | disp("DFT vs FFT for all values :"); 95 | A = rand(30,30); 96 | tic(); 97 | ref = dft(A); 98 | toc(); 99 | tic(); 100 | sol = fft(A); 101 | toc(); 102 | disp( norm(ref-sol,"inf") / norm(ref,"inf") ); 103 | 104 | // FFT versus DFT for first dimension 105 | disp("DFT vs FFT along 1st dimension :"); 106 | ref = dft(A,0,1); 107 | sol = fft(A,0,1); 108 | disp( norm(ref-sol,"inf") / norm(ref,"inf") ); 109 | 110 | // FFT versus DFT for second dimension 111 | disp("DFT vs FFT along 2nd dimension :"); 112 | ref = dft(A,0,2); 113 | sol = fft(A,0,2); 114 | disp( norm(ref-sol,"inf") / norm(ref,"inf") ); 115 | 116 | // DFT AND IDFT 117 | disp("Discrete fourier transform forward and backward : "); 118 | ref = A; 119 | sol = reshape(idft(dft(A)),size(A,1),size(A,2)); 120 | disp( norm(ref-sol,"inf") / norm(ref,"inf") ); 121 | 122 | disp("+==================+"); 123 | disp("| CONVOLUTION |"); 124 | disp("+==================+"); 125 | 126 | disp(conv(ones(2,2),ones(2,1))); 127 | disp(fftconv(ones(2,2),ones(2,1))); 128 | disp(conv(ones(4,3),eye(3,3),1)); 129 | disp(fftconv(ones(4,3),eye(3,3),1)); 130 | disp(conv(ones(3,3),eye(3,2),2)); 131 | disp(fftconv(ones(3,3),eye(3,2),2)); 132 | disp(fft(M_1I*ones(3))); 133 | 134 | disp("+===============+"); 135 | disp("| PERFO |"); 136 | disp("+===============+"); 137 | 138 | float time = 0; 139 | A = rand(1,1024) + M_1I*rand(1,1024); 140 | 141 | // Direct Fourier Transform 142 | disp("FFT forward (s) :"); 143 | for (int h=0; h<100; ++h) 144 | { 145 | tic(); 146 | B = fft(A); 147 | time += toc(0); 148 | } 149 | disp(time/100); 150 | 151 | // Inverse Fourier Transform 152 | disp("FFT backward (s) :"); 153 | time = 0; 154 | for (int h=0; h<100; ++h) 155 | { 156 | tic(); 157 | B = ifft(A); 158 | time += toc(0); 159 | } 160 | disp(time/100); 161 | 162 | 163 | disp("Done !"); 164 | return 0; 165 | } 166 | -------------------------------------------------------------------------------- /doc/source/manipulations.rst: -------------------------------------------------------------------------------- 1 | .. _label-matrix-manipulations: 2 | 3 | Matrix manipulations 4 | ++++++++++++++++++++ 5 | 6 | Many functions are provided for the manipulation of matrices. For instance, it is possible to :ref:`label-cast` a ``matrix`` object into a different type, to concatenate matrices in all dimensions (see :ref:`label-cat`, etc.), :ref:`label-find` the non-zero elements, or to :ref:`label-transpose` it. 7 | 8 | .. _label-all: 9 | 10 | all 11 | --- 12 | .. doxygenfunction:: all(matrix const &A) 13 | :project: castor 14 | 15 | See :ref:`label-row`, :ref:`label-col`, :ref:`label-get`, :ref:`label-set`, :ref:`label-view`, :ref:`label-cview`. 16 | 17 | 18 | .. _label-cast: 19 | 20 | cast 21 | ---- 22 | .. doxygenfunction:: cast 23 | :project: castor 24 | 25 | See :ref:`label-class-matrix`. 26 | 27 | 28 | .. _label-cat: 29 | 30 | cat 31 | --- 32 | .. doxygenfunction:: cat(int dim, R const &A, S const &B) 33 | :project: castor 34 | .. doxygenfunction:: cat(int dim, R A, matrix const &B) 35 | :project: castor 36 | .. doxygenfunction:: cat(int dim, matrix const &A, S B) 37 | :project: castor 38 | .. doxygenfunction:: cat(int dim, matrix const &A, matrix const &B) 39 | :project: castor 40 | 41 | See :ref:`label-vertcat`, :ref:`label-horzcat`. 42 | 43 | 44 | .. _label-clear: 45 | 46 | clear 47 | ----- 48 | .. doxygenfunction:: clear(matrix &A) 49 | :project: castor 50 | 51 | See :ref:`label-class-matrix`, :ref:`label-resize`. 52 | 53 | 54 | .. _label-col: 55 | 56 | col 57 | --- 58 | .. doxygenfunction:: col(matrix const &A) 59 | :project: castor 60 | 61 | See :ref:`label-row`, :ref:`label-all`, :ref:`label-get`, :ref:`label-set`, :ref:`label-view`, :ref:`label-cview`. 62 | 63 | 64 | .. _label-find: 65 | 66 | find 67 | ---- 68 | .. doxygenfunction:: find(matrix const &A) 69 | :project: castor 70 | 71 | See :ref:`label-nnz`, :ref:`label-ind2sub`. 72 | 73 | 74 | .. _label-get: 75 | 76 | get 77 | --- 78 | .. doxygenfunction:: get(matrix const &A, matrix const &I, matrix const &J) 79 | :project: castor 80 | .. doxygenfunction:: get(matrix const &A, matrix const &L) 81 | :project: castor 82 | 83 | See :ref:`label-set`, :ref:`label-all`, :ref:`label-row`, :ref:`label-col`, :ref:`label-view`, :ref:`label-cview`. 84 | 85 | 86 | .. _label-horzcat: 87 | 88 | horzcat 89 | ------- 90 | .. doxygenfunction:: horzcat 91 | :project: castor 92 | 93 | See :ref:`label-vertcat`, :ref:`label-cat`. 94 | 95 | 96 | .. _label-ind2sub: 97 | 98 | ind2sub 99 | ------- 100 | .. doxygenfunction:: ind2sub 101 | :project: castor 102 | 103 | See :ref:`label-sub2ind`, :ref:`label-find`. 104 | 105 | 106 | .. _label-isempty: 107 | 108 | isempty 109 | ------- 110 | .. doxygenfunction:: isempty 111 | :project: castor 112 | 113 | See :ref:`label-isequal`, :ref:`label-isvector`. 114 | 115 | 116 | .. _label-isequal: 117 | 118 | isequal 119 | ------- 120 | .. doxygenfunction:: isequal 121 | :project: castor 122 | 123 | See :ref:`label-isempty`, :ref:`label-isvector`. 124 | 125 | 126 | .. _label-isvector: 127 | 128 | isvector 129 | -------- 130 | .. doxygenfunction:: isvector 131 | :project: castor 132 | 133 | See :ref:`label-isequal`, :ref:`label-isempty`. 134 | 135 | .. _label-range: 136 | 137 | range 138 | ----- 139 | .. doxygenfunction:: range 140 | :project: castor 141 | 142 | See :ref:`label-colon`, :ref:`label-get`, :ref:`label-set`, :ref:`label-view`. 143 | 144 | .. _label-resize: 145 | 146 | resize 147 | ------ 148 | .. doxygenfunction:: resize(std::size_t m, std::size_t n, T v = (T)NAN) 149 | :project: castor 150 | 151 | See :ref:`label-reshape`. 152 | 153 | 154 | .. _label-reshape: 155 | 156 | reshape 157 | ------- 158 | .. doxygenfunction:: reshape(std::size_t m, std::size_t n) 159 | :project: castor 160 | 161 | See :ref:`label-resize`, :ref:`label-transpose`. 162 | 163 | 164 | .. _label-row: 165 | 166 | row 167 | --- 168 | .. doxygenfunction:: row(matrix const &A) 169 | :project: castor 170 | 171 | See :ref:`label-all`, :ref:`label-col`, :ref:`label-get`, :ref:`label-set`, :ref:`label-view`, :ref:`label-cview`. 172 | 173 | 174 | .. _label-set: 175 | 176 | set 177 | --- 178 | .. doxygenfunction:: set(matrix &A, matrix const &I, matrix const &J, U b) 179 | :project: castor 180 | .. doxygenfunction:: set(matrix &A, matrix const &L, matrix const &B) 181 | :project: castor 182 | .. doxygenfunction:: set(matrix &A, matrix const &I, matrix const &J, matrix const &B) 183 | :project: castor 184 | .. doxygenfunction:: set(matrix &A, matrix const &L, U b) 185 | :project: castor 186 | 187 | See :ref:`label-get`, :ref:`label-all`, :ref:`label-row`, :ref:`label-col`, ::ref:`label-view`, :ref:`label-cview`. 188 | 189 | 190 | .. _label-sub2ind: 191 | 192 | sub2ind 193 | ------- 194 | .. doxygenfunction:: sub2ind 195 | :project: castor 196 | 197 | See :ref:`label-ind2sub`, :ref:`label-find`. 198 | 199 | 200 | .. _label-transpose: 201 | 202 | transpose 203 | --------- 204 | .. doxygenfunction:: transpose(matrix const &A) 205 | :project: castor 206 | 207 | See :ref:`label-reshape`. 208 | 209 | 210 | .. _label-vertcat: 211 | 212 | vertcat 213 | ------- 214 | .. doxygenfunction:: vertcat 215 | :project: castor 216 | 217 | See :ref:`label-horzcat`, :ref:`label-cat`. 218 | -------------------------------------------------------------------------------- /doc/source/replicatormutator.rst: -------------------------------------------------------------------------------- 1 | Replicator mutator equation 2 | =========================== 3 | 4 | *Shared by Antoine Rideau thanks to Gael Raoul* 5 | 6 | On this page you will find how to simulate using **Castor** the replicator mutator equation 7 | 8 | The replicator-mutator equation is a classical model from evolutionary biology that describes how a species reacts to selection by increasing a phenotypic trait :math:`x`. The selection is represented by a reproduction rate that increases linearly with :math:`x` (the phenotype is actually the fitness of the individual), while the population is kept constant thanks to the continuous removal of individuals, uniformly among the traits present in the population. This is completed by a mutation term: the traits constantly mutate which is described by a diffusion term. This model is used to understand mutation-selection dynamics as a whole, even though it is more directly related to experimental setups used in experimental evolutionary biology, based on chemostats. This model has been used by R. Fisher to derive the so-called *fundamental theorem of natural selection*. 9 | 10 | 11 | .. math:: 12 | 13 | \partial_{t}u = \underbrace{\sigma \Delta_{x}u}_{mutations} + \underbrace{(x - \bar{x}(t))u}_{replication} \text{ , } t > 0, 14 | 15 | | where : 16 | | :math:`x \in \mathbb{R}` : a one dimension fitness space, 17 | | :math:`u(t,x)` : density of a population at time :math:`t` and per unit of fitness, 18 | | :math:`\bar{x}(t):= \int_{\mathbb{R}}xu(x,t)dx` : mean fitness at time :math:`t` . 19 | 20 | 21 | The population is considered constant, so 22 | 23 | .. math:: 24 | 25 | \int_{\mathbb{R}}u(x,t)dx = 1 . 26 | 27 | 28 | 29 | Numeric simulation 30 | ------------------ 31 | 32 | | ``N`` individuals are gathered within the population, each characterized by their fitness :math:`x_{i}`. 33 | | Ths population will evolve during ``gmax`` generations separated by ``dt`` . 34 | 35 | .. code-block:: c++ 36 | 37 | // Parameters 38 | int N = 1e3; // Population 39 | int gmax = 1e4; // Number of generations 40 | int Nplot = 1000; // Number of generations plotted 41 | double dt = 0.01; // Time disretization 42 | double sigma = 0.5; // Mutation 43 | 44 | 45 | Initially, the population is distributed following a Gaussian distribution using ``randn`` . 46 | 47 | .. code-block:: c++ 48 | 49 | // Initial data 50 | auto parent = randn(1, N); 51 | 52 | See :ref:`label-randn` . 53 | 54 | Each generation : 55 | 56 | 1. Each individual has a probability :math:`\mathbb{P} = (x_{i})_{+} \times \Delta t` ,where :math:`(x_{i})_{+}` stands for the positive part of :math:`x_{i}` , to give birth to a child 57 | 58 | .. code-block:: c++ 59 | 60 | // Probablity to give birth 61 | auto birth = dt * maximum(parent, 0); 62 | 63 | // Reproduction 64 | auto reprod = rand(size(parent)); 65 | 66 | See :ref:`label-maximum` , :ref:`label-rand` , :ref:`label-size` . 67 | 68 | who will inherit a fitness of :math:`x_{i} + X` with :math:`X \sim \mathcal{N}(0, \sigma^2 \Delta t)` . 69 | 70 | .. code-block:: c++ 71 | 72 | // Children 73 | auto children = parent + sigma * std::sqrt(dt) * randn(1, N); 74 | children = eval(children(find(reprod < birth))); 75 | 76 | // Update parent 77 | parent = cat(2, parent, children); 78 | 79 | See :ref:`label-find` , :ref:`label-view` , :ref:`label-cat` . 80 | 81 | 2. ``N`` individuals are uniformly choosen to survive. 82 | 83 | .. code-block:: c++ 84 | 85 | // Kill parent to get N individuals 86 | parent = eval(parent(randperm(numel(parent), N))); 87 | 88 | See :ref:`label-randperm` , :ref:`label-numel` . 89 | 90 | Code 91 | ---- 92 | 93 | .. code-block:: c++ 94 | 95 | #include 96 | #include 97 | 98 | using namespace castor; 99 | 100 | int main(int argc, char const *argv[]) 101 | { 102 | // Parameters 103 | int N = 1e3; // Population 104 | int gmax = 1e4; // Number of generations 105 | int Nplot = 1000; // Number of generations plotted 106 | double dt = 0.01; // Time disretization 107 | double sigma = 0.5; // Mutation 108 | 109 | // Initial data 110 | auto parent = randn(1, N); 111 | 112 | // Initialize figure 113 | figure fig; 114 | 115 | // For each generation 116 | tic(); 117 | for (int g = 1; g <= gmax; g++) 118 | { 119 | // Probablity to give birth 120 | auto birth = dt * maximum(parent, 0); 121 | 122 | // Reproduction 123 | auto reprod = rand(size(parent)); 124 | 125 | // Children 126 | auto children = parent + sigma * std::sqrt(dt) * randn(1, N); 127 | children = eval(children(find(reprod < birth))); 128 | 129 | // Update parent 130 | parent = cat(2, parent, children); 131 | 132 | // Kill parent to get N individuals 133 | parent = eval(parent(randperm(numel(parent), N))); 134 | 135 | // Plot 136 | if (g % (gmax / Nplot) == 0) 137 | { 138 | plot(fig, parent, g * dt * ones(size(parent)), {"b"}); 139 | } 140 | } 141 | toc(); 142 | 143 | // Visu 144 | drawnow(fig); 145 | return 0; 146 | } 147 | 148 | 149 | .. figure:: img/replicatormutator.png 150 | :width: 800 151 | :align: center 152 | :figclass: align-center 153 | 154 | Fitness evolution of a 1 000 individuals' population during 10 000 generations. 155 | 156 | Reference 157 | --------- 158 | 159 | https://openlibrary.org/books/OL7084333M/The_genetical_theory_of_natural_selection. 160 | 161 | https://www.cirm-math.fr/RepRenc/1315/PDFfiles1315.pdf 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /doc/source/operators.rst: -------------------------------------------------------------------------------- 1 | .. _label-operators: 2 | 3 | Operators 4 | +++++++++ 5 | 6 | This section describes all the conventional ``C++`` operators which have been overloaded in ``matrix``. To the exception of ``<<``, they all work element-wise. 7 | 8 | 9 | .. _label-operator<<: 10 | 11 | operator<< 12 | ---------- 13 | .. doxygenfunction:: operator<<(std::ostream &flux, matrix const &A) 14 | :project: castor 15 | 16 | See :ref:`label-disp`. 17 | 18 | 19 | .. _label-operator!: 20 | 21 | operator! 22 | --------- 23 | .. doxygenfunction:: operator! 24 | :project: castor 25 | 26 | See :ref:`label-operator&&`, :ref:`label-operator||`. 27 | 28 | 29 | .. _label-operator&&: 30 | 31 | operator&& 32 | ---------- 33 | .. doxygenfunction:: operator&&(R A, matrix const &B) 34 | :project: castor 35 | 36 | .. doxygenfunction:: operator&&(matrix const &A, S B) 37 | :project: castor 38 | 39 | .. doxygenfunction:: operator&&(matrix const &A, matrix const &B) 40 | :project: castor 41 | 42 | See :ref:`label-operator||`, :ref:`label-operator!`. 43 | 44 | 45 | .. _label-operator||: 46 | 47 | operator|| 48 | ---------- 49 | .. doxygenfunction:: operator||(R A, matrix const &B) 50 | :project: castor 51 | 52 | .. doxygenfunction:: operator||(matrix const &A, S B) 53 | :project: castor 54 | 55 | .. doxygenfunction:: operator||(matrix const &A, matrix const &B) 56 | :project: castor 57 | 58 | See :ref:`label-operator&&`, :ref:`label-operator!`. 59 | 60 | 61 | .. _label-operator==: 62 | 63 | operator== 64 | ---------- 65 | .. doxygenfunction:: operator==(R A, matrix const &B) 66 | :project: castor 67 | 68 | .. doxygenfunction:: operator==(matrix const &A, S B) 69 | :project: castor 70 | 71 | .. doxygenfunction:: operator==(matrix const &A, matrix const &B) 72 | :project: castor 73 | 74 | See :ref:`label-operator!=`, :ref:`label-operator<=`, :ref:`label-operator>=`. 75 | 76 | 77 | .. _label-operator!=: 78 | 79 | operator!= 80 | ---------- 81 | .. doxygenfunction:: operator!=(R A, matrix const &B) 82 | :project: castor 83 | 84 | .. doxygenfunction:: operator!=(matrix const &A, S B) 85 | :project: castor 86 | 87 | .. doxygenfunction:: operator!=(matrix const &A, matrix const &B) 88 | :project: castor 89 | 90 | See :ref:`label-operator==`, :ref:`label-operator<=`, :ref:`label-operator>=`. 91 | 92 | 93 | .. _label-operator<=: 94 | 95 | operator<= 96 | ---------- 97 | .. doxygenfunction:: operator<=(R A, matrix const &B) 98 | :project: castor 99 | 100 | .. doxygenfunction:: operator<=(matrix const &A, S B) 101 | :project: castor 102 | 103 | .. doxygenfunction:: operator<=(matrix const &A, matrix const &B) 104 | :project: castor 105 | 106 | See :ref:`label-operator==`, :ref:`label-operator>=`, :ref:`label-operator<`. 107 | 108 | 109 | .. _label-operator<: 110 | 111 | operator< 112 | --------- 113 | .. doxygenfunction:: operator<(R A, matrix const &B) 114 | :project: castor 115 | 116 | .. doxygenfunction:: operator<(matrix const &A, S B) 117 | :project: castor 118 | 119 | .. doxygenfunction:: operator<(matrix const &A, matrix const &B) 120 | :project: castor 121 | 122 | See :ref:`label-operator<=`, :ref:`label-operator>`, :ref:`label-operator>=`. 123 | 124 | 125 | .. _label-operator>=: 126 | 127 | operator>= 128 | ---------- 129 | .. doxygenfunction:: operator>=(R A, matrix const &B) 130 | :project: castor 131 | 132 | .. doxygenfunction:: operator>=(matrix const &A, S B) 133 | :project: castor 134 | 135 | .. doxygenfunction:: operator>=(matrix const &A, matrix const &B) 136 | :project: castor 137 | 138 | See :ref:`label-operator>`, :ref:`label-operator<=`, :ref:`label-operator<`. 139 | 140 | 141 | .. _label-operator>: 142 | 143 | operator> 144 | --------- 145 | .. doxygenfunction:: operator>(R A, matrix const &B) 146 | :project: castor 147 | 148 | .. doxygenfunction:: operator>(matrix const &A, S B) 149 | :project: castor 150 | 151 | .. doxygenfunction:: operator>(matrix const &A, matrix const &B) 152 | :project: castor 153 | 154 | See :ref:`label-operator>=`, :ref:`label-operator<`, :ref:`label-operator<=`. 155 | 156 | 157 | .. _label-operator+: 158 | 159 | operator+ 160 | --------- 161 | .. doxygenfunction:: operator+(R A, matrix const &B) 162 | :project: castor 163 | 164 | .. doxygenfunction:: operator+(matrix const &A, S B) 165 | :project: castor 166 | 167 | .. doxygenfunction:: operator+(matrix const &A, matrix const &B) 168 | :project: castor 169 | 170 | See :ref:`label-operator-`, :ref:`label-operator*`, :ref:`label-operator/`. 171 | 172 | 173 | .. _label-operator-: 174 | 175 | operator- 176 | --------- 177 | .. doxygenfunction:: operator-(R A, matrix const &B) 178 | :project: castor 179 | 180 | .. doxygenfunction:: operator-(matrix const &A, S B) 181 | :project: castor 182 | 183 | .. doxygenfunction:: operator-(matrix const &A, matrix const &B) 184 | :project: castor 185 | 186 | .. doxygenfunction:: operator-(matrix const &A) 187 | :project: castor 188 | 189 | See :ref:`label-operator+`, :ref:`label-operator*`, :ref:`label-operator/`. 190 | 191 | 192 | .. _label-operator*: 193 | 194 | operator* 195 | --------- 196 | .. doxygenfunction:: operator*(R A, matrix const &B) 197 | :project: castor 198 | 199 | .. doxygenfunction:: operator*(matrix const &A, S B) 200 | :project: castor 201 | 202 | .. doxygenfunction:: operator*(matrix const &A, matrix const &B) 203 | :project: castor 204 | 205 | See :ref:`label-operator+`, :ref:`label-operator-`, :ref:`label-operator/`. 206 | 207 | 208 | .. _label-operator/: 209 | 210 | operator/ 211 | --------- 212 | .. doxygenfunction:: operator/(R A, matrix const &B) 213 | :project: castor 214 | 215 | .. doxygenfunction:: operator/(matrix const &A, S B) 216 | :project: castor 217 | 218 | .. doxygenfunction:: operator/(matrix const &A, matrix const &B) 219 | :project: castor 220 | 221 | See :ref:`label-operator+`, :ref:`label-operator-`, :ref:`label-operator*`. -------------------------------------------------------------------------------- /doc/source/lowlevel_linalg_func.rst: -------------------------------------------------------------------------------- 1 | 2 | Low-level interface 3 | +++++++++++++++++++ 4 | 5 | The user will find here the low-level linear algebra interface. Most of the functions here are wrappers around the CBLAS or LAPACK API and the user should be careful when using them, see :ref:`label-blaslapack-issue` to understand why. 6 | 7 | .. _label-lpk2mat: 8 | 9 | lpk2mat 10 | ------- 11 | .. doxygenfunction:: lpk2mat(std::vectorconst &V, std::size_t m, std::size_t n) 12 | :project: castor 13 | 14 | See :ref:`label-mat2lpk`. 15 | 16 | 17 | .. _label-mat2lpk: 18 | 19 | mat2lpk 20 | ------- 21 | .. doxygenfunction:: mat2lpk(matrix const &A, std::size_t L) 22 | :project: castor 23 | 24 | See :ref:`label-lpk2mat`. 25 | 26 | 27 | .. _label-tgeev: 28 | 29 | tgeev 30 | ----- 31 | .. doxygenfunction:: tgeev(std::string typ, int &n, std::vector &A, std::vector &E, std::vector &V) 32 | :project: castor 33 | .. doxygenfunction:: xgeev(char &jobl, char &jobr, int &n, std::vector &A, std::vector &E, std::vector &V, zlpk &wkopt, int &lwork, int &info) 34 | :project: castor 35 | .. doxygenfunction:: xgeev(char &jobl, char &jobr, int &n, std::vector &A, std::vector &E, std::vector &V, clpk &wkopt, int &lwork, int &info) 36 | :project: castor 37 | 38 | 39 | .. _label_tgels: 40 | 41 | tgels 42 | ----- 43 | .. doxygenfunction:: tgels(int &m, int &n, int &nrhs, std::vector &A, std::vector &B) 44 | :project: castor 45 | .. doxygenfunction:: xgels(char &t, int &m, int &n, int &nrhs, std::vector &A, std::vector &B, int &l, zlpk &wkopt, int &lwork, int &info) 46 | :project: castor 47 | .. doxygenfunction:: xgels(char &t, int &m, int &n, int &nrhs, std::vector &A, std::vector &B, int &l, double &wkopt, int &lwork, int &info) 48 | :project: castor 49 | .. doxygenfunction:: xgels(char &t, int &m, int &n, int &nrhs, std::vector &A, std::vector &B, int &l, clpk &wkopt, int &lwork, int &info) 50 | :project: castor 51 | .. doxygenfunction:: xgels(char &t, int &m, int &n, int &nrhs, std::vector &A, std::vector &B, int &l, float &wkopt, int &lwork, int &info) 52 | :project: castor 53 | 54 | 55 | .. _label-tgemm-blas: 56 | 57 | tgemm 58 | ----- 59 | .. doxygenfunction:: tgemm(R alpha, matrix const &A, matrix const &B, S beta, matrix &C) 60 | :project: castor 61 | .. doxygenfunction:: tgemm(R alpha, matrix> const &A, matrix> const &B, S beta, matrix> &C) 62 | :project: castor 63 | .. doxygenfunction:: tgemm(R alpha, matrix> const &A, matrix> const &B, S beta, matrix> &C) 64 | :project: castor 65 | .. doxygenfunction:: tgemm(R alpha, matrix const &A, matrix const &B, S beta, matrix &C) 66 | :project: castor 67 | 68 | See :ref:`label-tgemm-naive`. 69 | 70 | 71 | .. _label-tgeqrf: 72 | 73 | tgeqrf 74 | ------ 75 | .. doxygenfunction:: tgeqrf(int &m, int &n, std::vector &A, std::vector &R) 76 | :project: castor 77 | .. doxygenfunction:: xgeqrf(int &m, int &n, int &l, std::vector &A, std::vector &tau, zlpk &wkopt, int &lwork, int &info) 78 | :project: castor 79 | .. doxygenfunction:: xgeqrf(int &m, int &n, int &l, std::vector &A, std::vector &tau, double &wkopt, int &lwork, int &info) 80 | :project: castor 81 | .. doxygenfunction:: xgeqrf(int &m, int &n, int &l, std::vector &A, std::vector &tau, clpk &wkopt, int &lwork, int &info) 82 | :project: castor 83 | .. doxygenfunction:: xgeqrf(int &m, int &n, int &l, std::vector &A, std::vector &tau, float &wkopt, int &lwork, int &info) 84 | :project: castor 85 | 86 | 87 | .. _label-tgesdd: 88 | 89 | tgesdd 90 | ------ 91 | .. doxygenfunction:: tgesdd(std::string typ, int &m, int &n, std::vector &A, std::vector &S, std::vector &U, std::vector &V) 92 | :project: castor 93 | .. doxygenfunction:: xgesdd(char &job, int &m, int &n, int &l, std::vector &A, std::vector &S, std::vector &U, std::vector &V, zlpk &wkopt, int &lwork, std::vector &iwork, int &info) 94 | :project: castor 95 | .. doxygenfunction:: xgesdd(char &job, int &m, int &n, int &l, std::vector &A, std::vector &S, std::vector &U, std::vector &V, double &wkopt, int &lwork, std::vector &iwork, int &info) 96 | :project: castor 97 | .. doxygenfunction:: xgesdd(char &job, int &m, int &n, int &l, std::vector &A, std::vector &S, std::vector &U, std::vector &V, clpk &wkopt, int &lwork, std::vector &iwork, int &info) 98 | :project: castor 99 | .. doxygenfunction:: xgesdd(char &job, int &m, int &n, int &l, std::vector &A, std::vector &S, std::vector &U, std::vector &V, float &wkopt, int &lwork, std::vector &iwork, int &info) 100 | :project: castor 101 | 102 | 103 | .. _label-tgesv: 104 | 105 | tgesv 106 | ----- 107 | .. doxygenfunction:: tgesv(int &n, int &nrhs, std::vector &A, std::vector &B) 108 | :project: castor 109 | .. doxygenfunction:: xgesv(int &n, int &nrhs, std::vector &A, std::vector &B, std::vector &ipiv, int &info) 110 | :project: castor 111 | .. doxygenfunction:: xgesv(int &n, int &nrhs, std::vector &A, std::vector &B, std::vector &ipiv, int &info) 112 | :project: castor 113 | .. doxygenfunction:: xgesv(int &n, int &nrhs, std::vector &A, std::vector &B, std::vector &ipiv, int &info) 114 | :project: castor 115 | .. doxygenfunction:: xgesv(int &n, int &nrhs, std::vector &A, std::vector &B, std::vector &ipiv, int &info) 116 | :project: castor 117 | 118 | 119 | .. _label-tgetrf: 120 | 121 | tgetrf 122 | ------ 123 | .. doxygenfunction:: tgetrf(int &m, int &n, std::vector &A, std::vector &P, matrix &U) 124 | :project: castor 125 | .. doxygenfunction:: xgetrf(int &m, int &n, std::vector &A, std::vector &ipiv, int &info) 126 | :project: castor 127 | .. doxygenfunction:: xgetrf(int &m, int &n, std::vector &A, std::vector &ipiv, int &info) 128 | :project: castor 129 | .. doxygenfunction:: xgetrf(int &m, int &n, std::vector &A, std::vector &ipiv, int &info) 130 | :project: castor 131 | .. doxygenfunction:: xgetrf(int &m, int &n, std::vector &A, std::vector &ipiv, int &info) 132 | :project: castor 133 | -------------------------------------------------------------------------------- /misc/perf_hmat.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | +========================================================================+ 3 | | (c) 2020 - PROPERTY OF ECOLE POLYTECHNIQUE - LGPL 3.0 | 4 | |________________________________________________________________________| 5 | | '&` | | 6 | | # | FILE : perf_hmat.cpp | 7 | | # | VERSION : 1.0.0 | 8 | | _#_ | AUTHOR(S) : Matthieu Aussal | 9 | | ( # ) | CREATION : 14.02.2021 | 10 | | / 0 \ | LAST MODIF : 14.02.2021 | 11 | | ( === ) | SYNOPSIS : H-matrix performances and precision test | 12 | | `---' | for particular kernel. | 13 | | | FOR PERFORMANCES, RELEASE COMPILATION REQUIRED| 14 | +========================================================================+ 15 | */ 16 | 17 | #include "castor/matrix.hpp" 18 | #include "castor/linalg.hpp" 19 | #include "castor/smatrix.hpp" 20 | #include "castor/hmatrix.hpp" 21 | 22 | using namespace castor; 23 | 24 | template 25 | matrix Gxy(matrixconst& X, matrixconst& Y, S wavenumber=0, matrix Ix={}, matrix Iy={}); 26 | 27 | int main (int argc, char* argv[]) 28 | { 29 | //=============================================================== 30 | std::cout << "+=====================+" << std::endl; 31 | std::cout << "| INITIALIZE |" << std::endl; 32 | std::cout << "+=====================+" << std::endl; 33 | 34 | // Documentation 35 | documentationFiles = 36 | { 37 | "/usr/local/include/castor/matrix.hpp", 38 | "/usr/local/include/castor/hmatrix.hpp" 39 | }; 40 | help("hmatrix"); 41 | 42 | // Parameters 43 | std::size_t Nx = 1e3; 44 | std::size_t Ny = Nx; // NUMBER OF EMMITERS 45 | std::size_t Nr = 100; // NUMBER OF EMMITERS 46 | double tol = 1e-3; // ACCURACY 47 | double f = 100; // FREQUENCY (Hz) 48 | double c = 343; // SOUND CELERITY (m.s-1) 49 | 50 | // Wave numbers 51 | double k = 2*M_PI*f/c; 52 | 53 | // Sphere X 54 | disp("---> DISCRETIZATION X <---"); 55 | matrix x, y, z, X; 56 | std::tie(x,y,z) = sphere2(Nx); 57 | X = horzcat(reshape(x,Nx,1),reshape(y,Nx,1)); 58 | X = horzcat(X,reshape(z,Nx,1)); 59 | disp(bbox(X)); 60 | 61 | // Sphere Y 62 | disp("---> DISCRETIZATION Y <---"); 63 | matrix Y; 64 | std::tie(x,y,z) = sphere2(Ny); 65 | Y = horzcat(reshape(x,Ny,1),reshape(y,Ny,1)); 66 | Y = horzcat(Y,reshape(z,Ny,1)); 67 | // Y = -5 + 0.5*Y; 68 | disp(bbox(Y)); 69 | disp(bbox(X).isfar(bbox(Y))); 70 | 71 | // Full computations 72 | if (Nx<=1e3) 73 | { 74 | // Full 75 | disp("---> FULL <---"); 76 | tic(); 77 | matrix> M = Gxy>(X,Y,k); 78 | toc(); 79 | 80 | // H-Matrix from full 81 | disp("---> FULL TO H-MATRIX <---"); 82 | tic(); 83 | hmatrix> Mh(X,Y,tol,M); 84 | toc(); 85 | disp(Mh); 86 | disp(norm(M-full(Mh),"inf")/norm(M,"inf")); 87 | 88 | // H-Matrix from sparse 89 | disp("---> SPARSE TO H-MATRIX <---"); 90 | tic(); 91 | Mh = hmatrix>(X,Y,tol,sparse(M)); 92 | toc(); 93 | disp(Mh); 94 | disp(norm(M-full(Mh),"inf")/norm(M,"inf")); 95 | } 96 | 97 | // FUll reference 98 | disp("---> FULL MATRIX REFERENCE <---"); 99 | matrix> V = rand(Ny,2) + M_1I*rand(Ny,2); 100 | matrix I = round(linspace(0,Nx-1,Nr)); 101 | tic(); 102 | matrix> Mr = Gxy>(X,Y,k,I,range(0,Ny)); 103 | matrix> MrV = mtimes(Mr,V); 104 | toc(); 105 | 106 | // H-Matrix from lambda 107 | disp("---> H-MATRIX <---"); 108 | auto fct = [&X,&Y,&k](matrix Ix, matrix Iy) 109 | { 110 | return Gxy>(X,Y,k,Ix,Iy); 111 | }; 112 | tic(); 113 | hmatrix> Mh(X,Y,tol,fct); 114 | toc(); 115 | disp(Mh); 116 | matrix> MhV = mtimes(Mh,V); 117 | disp(norm(MrV-eval(MhV(I,col(V))),"inf")/norm(MrV,"inf")); 118 | 119 | // H-Matrix LU 120 | disp("---> FACTO LU <---"); 121 | hmatrix> Lh, Uh; 122 | tic(); 123 | std::tie(Lh,Uh) = lu(Mh); 124 | toc(); 125 | disp(Lh); 126 | disp(Uh); 127 | matrix> LhUhV = mtimes(Lh,mtimes(Uh,V)); 128 | disp(norm(MrV-eval(LhUhV(I,col(V))),"inf")/norm(MrV,"inf")); 129 | 130 | // GMRES precond LU 131 | disp("---> GMRES + PRECOND LU <---"); 132 | tic(); 133 | std::tie(Lh,Uh) = lu(Mh,1e-1); 134 | toc(); 135 | disp(Lh); 136 | disp(Uh); 137 | LhUhV = mtimes(Lh,mtimes(Uh,V)); 138 | disp(norm(MrV-eval(LhUhV(I,col(V))),"inf")/norm(MrV,"inf")); 139 | gmres(Mh,V,tol,100,Lh,Uh); 140 | 141 | // Exit 142 | disp("done !"); 143 | return 0; 144 | } 145 | 146 | 147 | // Green kernel function 148 | template 149 | matrix Gxy(matrixconst& X, matrixconst& Y, S wavenumber, matrix Ix, matrix Iy) 150 | { 151 | // Initialize dof data 152 | if (numel(Ix)==0) {Ix = range(0,size(X,1));} 153 | if (numel(Iy)==0) {Iy = range(0,size(Y,1));} 154 | if (max(Ix)>size(X,1) || max(Iy)>size(Y,1)) 155 | { 156 | error(__FILE__, __LINE__, __FUNCTION__,"Indices are not in data bound."); 157 | } 158 | matrix M(numel(Ix),numel(Iy)); 159 | 160 | // Initialize local data 161 | std::size_t ix, iy; 162 | S rxy; 163 | T imk=std::sqrt(T(-1))*wavenumber; 164 | 165 | // Build 166 | for (std::size_t i=0; i1e-12)? (std::exp(imk*rxy)/rxy) : (1.); 176 | } 177 | } 178 | return M; 179 | } 180 | 181 | 182 | 183 | -------------------------------------------------------------------------------- /doc/source/linalg.rst: -------------------------------------------------------------------------------- 1 | .. _label-linear-algebra-advanced: 2 | 3 | Linear algebra 4 | ============== 5 | 6 | We provide a set of useful function to perform basic linear algebra manipulations available by including ``castor/linalg.hpp``. The **linear algebra** library is mostly based on the well-known BLAS and LAPACK APIs. As such, it may be interfaced with any library respecting the same naming convention like ``openblas`` or ``mkl``. 7 | 8 | We want to bring the attention of the user on the fact that BLAS and LAPACK are originally Fortran libraries and consequently use a column ordering storage convention, unlike ``matrix`` which uses a row-major storage. While this behavior is fully transparent for the user as long as he is using the high-level **castor** API, he may find more details at :ref:`label-blaslapack-issue`. 9 | 10 | We give below a few examples of use. More may be found in the ``demo/demo_linalg/`` subfolder. All linear algebra functions are described at :ref:`label-singular-eig-values-func`, :ref:`label-factorization-func` and :ref:`label-linear-solver-func` 11 | 12 | 13 | 14 | Singular Value Decomposition 15 | ---------------------------- 16 | It is very easy to compute the SVD of a given matrix. The function ``svd`` simply returns a tuple containing the singular values ``S``, the left singular vectors ``U`` and finally the transposed right singular vectors ``Vt``. 17 | 18 | .. code:: c++ 19 | 20 | matrix A({ 21 | {1,1,-2,1,3,-1}, 22 | {2,-1,1,2,1,-3}, 23 | {1,3,-3,-1,2,1}, 24 | {5,2,-1,-1,2,1}, 25 | {-3,-1,2,3,1,3}, 26 | {4,3,1,-6,-3,-2} 27 | }); 28 | matrix<> S, U, Vt; 29 | std::tie(S,U,Vt) = svd(A,"vect"); 30 | disp(norm(A - mtimes(U,mtimes(diag(S),Vt)),"inf")); 31 | 32 | .. code:: text 33 | 34 | 4.44089e-15 35 | 36 | Note that it is equally easy to compute the (eventually generalized) eigenvalues and eigenvectors (see :ref:`label-eig`) or the rank-revealing SVD (see :ref:`label-qrsvd`). 37 | 38 | 39 | Solving a linear system 40 | --------------------------- 41 | We provide two functions for the resolution of a linear system of equations. ``linsolve`` performs the exact inversion using the LAPACK library while ``gmres`` computes the solution iteratively using the GMRES algorithm. Note that **both** have support for multiple right-hand-sides. 42 | 43 | The use of ``linsolve`` is straightforward. The left- and right-hand-sides should be provided in full ``matrix`` form and the function returns the ``matrix`` containing the solutions. 44 | 45 | .. code:: c++ 46 | 47 | // left-hand-side 48 | matrix A({ 49 | {1,1,-2,1,3,-1}, 50 | {2,-1,1,2,1,-3}, 51 | {1,3,-3,-1,2,1}, 52 | {5,2,-1,-1,2,1}, 53 | {-3,-1,2,3,1,3}, 54 | {4,3,1,-6,-3,-2} 55 | }); 56 | // we change the original matrix for this demo 57 | for(auto i=0; i<6; ++i) A(i,i) = 20.; 58 | // right-hand-side, must be a column 59 | matrix B(6,1,{4,20,-15,-3,16,-27}); 60 | // solving 61 | auto X = linsolve(A,B); 62 | disp(X); 63 | 64 | .. code:: text 65 | 66 | -0.15882 67 | 0.83718 68 | -0.93171 69 | -0.29017 70 | 1.15147 71 | -1.31156 72 | 73 | Compared to ``linsolve``, one needs to specifiy the tolerance and the maximum number of iterations. The user may also provide a preconditionner, use its own definition of the matrix-vector product, etc., as specified in the documentation of :ref:`label-gmres`. 74 | 75 | .. code:: c++ 76 | 77 | X = gmres(A,B,1e-3,6); 78 | disp(X); 79 | 80 | .. code:: text 81 | 82 | Start GMRES using MGCR implementation (Multiple Generalized Conjugate Residual): 83 | + Iteration 1 in 3.5977e-05 seconds with relative residual 0.296391. 84 | + Iteration 2 in 2.8044e-05 seconds with relative residual 0.0545852. 85 | + Iteration 3 in 2.5446e-05 seconds with relative residual 0.0119836. 86 | + Iteration 4 in 3.3522e-05 seconds with relative residual 0.000506301. 87 | GMRES converged at iteration 4 to a solution with relative residual 0.000506301. 88 | -0.15823 89 | 0.83694 90 | -0.93228 91 | -0.29023 92 | 1.15188 93 | -1.31119 94 | 95 | **Remark:** Exact convergence is always achieved when the number of iterations reaches the dimension of the matrix. 96 | 97 | 98 | Adaptive Cross Approximation 99 | ---------------------------- 100 | The ACA algorithm performs a low-rank approximation of rank ``k`` a given matrix ``C`` of size ``m x n`` under the form ``C = mtimes(A,tranpose(B))`` where ``A`` is ``m x k`` and ``B`` is ``n x k``. The rank ``k`` is automatically obtained following a user-defined accuracy parameter ``tol``. Note that if ``tol`` is chosen too small, using the ACA algorithm may be useless ... 101 | **Warning** : our implementation directly returns ``Bt = tranpose(B)``. 102 | 103 | .. code:: c++ 104 | 105 | matrix<> A, Bt; 106 | matrix<> C = mtimes(rand(100,20),rand(20,50)); 107 | std::tie(A,Bt) = aca(C,1e-3); 108 | disp(size(A),2); 109 | disp(size(Bt),2); 110 | disp(norm(C - mtimes(A,Bt),"inf"),2); 111 | 112 | .. code:: text 113 | 114 | Matrix 1x2 of type 'm' (16 B): 115 | 100 21 116 | Matrix 1x2 of type 'm' (16 B): 117 | 21 50 118 | Object of type 'd': 119 | 3.81917e-14 120 | 121 | **Remark:** The result may vary depending on your random number generator. 122 | 123 | 124 | 125 | .. _label-blaslapack-issue: 126 | 127 | Overload of some BLAS and LAPACK functions 128 | ------------------------------------------ 129 | 130 | Some functions from the BLAS and LAPACK APIs have been directly interfaced using a similar naming convention. 131 | 132 | The BLAS-part is in fact a straightforward overlay over the C BLAS API which enables the possibility to use row-major ordering. For example, ``tgemm`` computes the matrix-matrix product using the C BLAS API (see :ref:`label-tgemm-blas`) and provides a unique interface to the four corresponding functions (each one corresponding to one of the four types: ``float``, ``std::complex``, ``double``, ``std::complex``). Its main purpose is to hide the use of raw pointers to the underlying data. For information, such raw pointers can be obtained as explained below. 133 | 134 | .. code:: c++ 135 | 136 | matrix A({1,2,3,4}); 137 | double *pA = &A(0); // returns the adress of the first element of A 138 | 139 | However, the LAPACK-part is a *direct* overlay over the Fortran LAPACK API. Under the hood, the functions of **castor** convert the ``matrix<>`` to a ``std::vector<>`` where the data is stored with the right ordering thanks to the ``mat2lpk`` function (see :ref:`label-mat2lpk`). The result is then converted back to a ``matrix<>`` with the ``lpk2mat`` function (see :ref:`label-lpk2mat`). The main consequence is that the functions following a naming convention close to the LAPACK one (see for example :ref:`label-tgesdd`, :ref:`label-tgeqrf`, etc.) only accept ``std::vector<>`` as input. 140 | -------------------------------------------------------------------------------- /doc/source/math.rst: -------------------------------------------------------------------------------- 1 | .. _label-mathematical-functions: 2 | 3 | Mathematical functions 4 | ++++++++++++++++++++++ 5 | 6 | The functions described below implement common mathematical functions which can be applied element-wise to the elements of a ``matrix`` such as :ref:`label-cos`, :ref:`label-sqrt`, etc. 7 | 8 | 9 | .. _label-abs: 10 | 11 | abs 12 | --- 13 | .. doxygenfunction:: abs 14 | :project: castor 15 | 16 | See :ref:`label-angle`, :ref:`label-sign`. 17 | 18 | 19 | .. _label-acos: 20 | 21 | acos 22 | ---- 23 | .. doxygenfunction:: acos 24 | :project: castor 25 | 26 | See :ref:`label-acosd`, :ref:`label-cos`. 27 | 28 | 29 | .. _label-acosd: 30 | 31 | acosd 32 | ----- 33 | .. doxygenfunction:: acosd 34 | :project: castor 35 | 36 | See :ref:`label-acos`, :ref:`label-cosd`. 37 | 38 | 39 | .. _label-acosh: 40 | 41 | acosh 42 | ----- 43 | .. doxygenfunction:: acosh 44 | :project: castor 45 | 46 | See :ref:`label-cosh`. 47 | 48 | 49 | .. _label-angle: 50 | 51 | angle 52 | ----- 53 | .. doxygenfunction:: angle 54 | :project: castor 55 | 56 | See :ref:`label-abs`. 57 | 58 | 59 | .. _label-asin: 60 | 61 | asin 62 | ---- 63 | .. doxygenfunction:: asin 64 | :project: castor 65 | 66 | See :ref:`label-sin`, :ref:`label-asind`. 67 | 68 | 69 | .. _label-asind: 70 | 71 | asind 72 | ----- 73 | .. doxygenfunction:: asind 74 | :project: castor 75 | 76 | See :ref:`label-sind`, :ref:`label-asin`. 77 | 78 | 79 | .. _label-asinh: 80 | 81 | asinh 82 | ----- 83 | .. doxygenfunction:: asinh 84 | :project: castor 85 | 86 | See :ref:`label-sinh`. 87 | 88 | 89 | .. _label-atan: 90 | 91 | atan 92 | ---- 93 | .. doxygenfunction:: atan 94 | :project: castor 95 | 96 | See :ref:`label-tan`, :ref:`label-atand`. 97 | 98 | 99 | .. _label-atand: 100 | 101 | atand 102 | ----- 103 | .. doxygenfunction:: atand 104 | :project: castor 105 | 106 | See :ref:`label-tand`, :ref:`label-atan`. 107 | 108 | 109 | .. _label-atanh: 110 | 111 | atanh 112 | ----- 113 | .. doxygenfunction:: atanh 114 | :project: castor 115 | 116 | See :ref:`label-tanh`. 117 | 118 | 119 | .. _label-ceil: 120 | 121 | ceil 122 | ---- 123 | .. doxygenfunction:: ceil 124 | :project: castor 125 | 126 | See :ref:`label-floor`, :ref:`label-round`. 127 | 128 | 129 | .. _label-conj: 130 | 131 | conj 132 | ---- 133 | .. doxygenfunction:: conj(matrix const &A) 134 | :project: castor 135 | .. doxygenfunction:: conj(matrix const &A) 136 | :project: castor 137 | .. doxygenfunction:: conj(matrix const &X) 138 | :project: castor 139 | 140 | See :ref:`label-real`, :ref:`label-imag`. 141 | 142 | 143 | .. _label-cos: 144 | 145 | cos 146 | --- 147 | .. doxygenfunction:: cos 148 | :project: castor 149 | 150 | See :ref:`label-acos`, :ref:`label-cosd`. 151 | 152 | 153 | .. _label-cosd: 154 | 155 | cosd 156 | ---- 157 | .. doxygenfunction:: cosd 158 | :project: castor 159 | 160 | See :ref:`label-acosd`, :ref:`label-cos`. 161 | 162 | 163 | .. _label-cosh: 164 | 165 | cosh 166 | ---- 167 | .. doxygenfunction:: cosh 168 | :project: castor 169 | 170 | See :ref:`label-acosh`. 171 | 172 | 173 | .. _label-deg2rad: 174 | 175 | deg2rad 176 | ------- 177 | .. doxygenfunction:: deg2rad(T x) 178 | :project: castor 179 | .. doxygenfunction:: deg2rad(matrix const &X) 180 | :project: castor 181 | 182 | See :ref:`label-rad2deg`. 183 | 184 | 185 | .. _label-exp: 186 | 187 | exp 188 | --- 189 | .. doxygenfunction:: exp 190 | :project: castor 191 | 192 | See :ref:`label-log`, :ref:`label-log10`. 193 | 194 | 195 | .. _label-floor: 196 | 197 | floor 198 | ----- 199 | .. doxygenfunction:: floor 200 | :project: castor 201 | 202 | See :ref:`label-ceil`, :ref:`label-round`. 203 | 204 | 205 | .. _label-imag: 206 | 207 | imag 208 | ---- 209 | .. doxygenfunction:: imag(matrix const &A) 210 | :project: castor 211 | .. doxygenfunction:: imag(matrix const &A) 212 | :project: castor 213 | .. doxygenfunction:: imag(matrix const &X) 214 | :project: castor 215 | 216 | See :ref:`label-real`, :ref:`label-conj`, :ref:`label-angle`, :ref:`label-abs`. 217 | 218 | 219 | .. _label-log: 220 | 221 | log 222 | --- 223 | .. doxygenfunction:: log 224 | :project: castor 225 | 226 | See :ref:`label-log2`, :ref:`label-log10`, :ref:`label-exp`. 227 | 228 | 229 | .. _label-log2: 230 | 231 | log2 232 | ---- 233 | .. doxygenfunction:: log2 234 | :project: castor 235 | 236 | See :ref:`label-log`, :ref:`label-log10`, :ref:`label-exp`. 237 | 238 | 239 | .. _label-log10: 240 | 241 | log10 242 | ----- 243 | .. doxygenfunction:: log10 244 | :project: castor 245 | 246 | See :ref:`label-log`, :ref:`label-log2`, :ref:`label-exp`. 247 | 248 | 249 | .. _label-pow: 250 | 251 | pow 252 | --- 253 | .. doxygenfunction:: pow(R x, matrix const &Y) 254 | :project: castor 255 | .. doxygenfunction:: pow(matrix const &X, S y) 256 | :project: castor 257 | .. doxygenfunction:: pow(matrix const &X, matrix const &Y) 258 | :project: castor 259 | 260 | See :ref:`label-exp`, :ref:`label-log`. 261 | 262 | 263 | .. _label-rad2deg: 264 | 265 | rad2deg 266 | ------- 267 | .. doxygenfunction:: rad2deg(T x) 268 | :project: castor 269 | .. doxygenfunction:: rad2deg(matrix const &X) 270 | :project: castor 271 | 272 | See :ref:`label-deg2rad`. 273 | 274 | 275 | .. _label-real: 276 | 277 | real 278 | ---- 279 | .. doxygenfunction:: real(matrix const &A) 280 | :project: castor 281 | .. doxygenfunction:: real(matrix const &A) 282 | :project: castor 283 | .. doxygenfunction:: real(matrix const &X) 284 | :project: castor 285 | 286 | See :ref:`label-imag`, :ref:`label-conj`, :ref:`label-angle`, :ref:`label-abs`. 287 | 288 | 289 | .. _label-round: 290 | 291 | round 292 | ----- 293 | .. doxygenfunction:: round 294 | :project: castor 295 | 296 | See :ref:`label-floor`, :ref:`label-ceil`. 297 | 298 | 299 | .. _label-sign: 300 | 301 | sign 302 | ---- 303 | .. doxygenfunction:: sign 304 | :project: castor 305 | 306 | See :ref:`label-abs`. 307 | 308 | 309 | .. _label-sin: 310 | 311 | sin 312 | --- 313 | .. doxygenfunction:: sin 314 | :project: castor 315 | 316 | See :ref:`label-asin`, :ref:`label-sind`. 317 | 318 | 319 | .. _label-sind: 320 | 321 | sind 322 | ---- 323 | .. doxygenfunction:: sind 324 | :project: castor 325 | 326 | See :ref:`label-asind`, :ref:`label-sin`. 327 | 328 | 329 | .. _label-sinh: 330 | 331 | sinh 332 | ---- 333 | .. doxygenfunction:: sinh 334 | :project: castor 335 | 336 | See :ref:`label-asinh`. 337 | 338 | 339 | .. _label-sqrt: 340 | 341 | sqrt 342 | ---- 343 | .. doxygenfunction:: sqrt 344 | :project: castor 345 | 346 | See :ref:`label-pow`. 347 | 348 | 349 | .. _label-tan: 350 | 351 | tan 352 | --- 353 | .. doxygenfunction:: tan 354 | :project: castor 355 | 356 | See :ref:`label-atan`, :ref:`label-tand`. 357 | 358 | 359 | .. _label-tand: 360 | 361 | tand 362 | ---- 363 | .. doxygenfunction:: tand 364 | :project: castor 365 | 366 | See :ref:`label-atand`, :ref:`label-tan`. 367 | 368 | 369 | .. _label-tanh: 370 | 371 | tanh 372 | ---- 373 | .. doxygenfunction:: tanh 374 | :project: castor 375 | 376 | See :ref:`label-atanh`. -------------------------------------------------------------------------------- /doc/source/sparse_matrix.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _label-sparse-matrix: 3 | 4 | Sparse matrix 5 | ============= 6 | 7 | This library implements a lightweight class ``smatrix`` for the manipulation of sparse matrices, using solely the ``castor::matrix`` class without other external libraries. Many builders, functions and operators are available in a similar fashion as for the :ref:`label-class-matrix`, see the ``smatrix`` :ref:`label-smatrix-API`. Most of the manipulations should be transparent to the user and the feeling should be really `Matlab-like `_. Basic examples are given in the corresponding :ref:`label-examples-smatrix` section. 8 | 9 | The ``smatrix`` class is installed automatically with the other headers of **castor** library. 10 | 11 | **This is work-in-progress** 12 | 13 | .. _label-examples-smatrix: 14 | 15 | Examples 16 | ........ 17 | 18 | In order to use a ``smatrix``, the corresponding header ``castor/smatrix.hpp`` needs to be included. A minimum working example would thus look like this: 19 | 20 | .. code:: c++ 21 | 22 | #include "castor/matrix.hpp" 23 | #include "castor/smatrix.hpp" 24 | 25 | int main() 26 | { 27 | smatrix<> s; 28 | // your code here 29 | return 0; 30 | } 31 | 32 | Building a smatrix 33 | ++++++++++++++++++ 34 | 35 | A ``smatrix`` will mostly behave like a normal dense ``matrix``. For example, let us create a ``4 x 4`` ``smatrix`` of ``double``. 36 | 37 | .. code:: c++ 38 | 39 | smatrix<> As; 40 | disp(As,2); 41 | 42 | .. code:: text 43 | 44 | Sparse matrix 4x4 of type 'd' with 0 elements (0 B): 45 | -empty- 46 | 47 | The newly created ``smatrix`` is empty. It is rather easy to set the values of the entries. For example: 48 | 49 | .. code:: c++ 50 | 51 | As(1,2) = -0.5; 52 | disp(As,2); 53 | 54 | .. code:: text 55 | 56 | Sparse matrix 4x4 of type 'd' with 1 elements (8 B): 57 | (1,2) -0.5 58 | 59 | Now ``As`` contains one non-zero element with the bilinear index ``(1,2)`` (second line, third column). However, this way of filling a ``smatrix`` **is definitely not recommended** as it involves a lot of memory management and may affect dramatically the performances. One way to do so is to first create the matrix in *triplet* format ``(I,J,VALUE)`` and only afterward build the corresponding ``smatrix`` as illustrated below: 60 | 61 | .. code:: c++ 62 | 63 | matrix I = {0,2,3}; 64 | matrix J = {1,1,2}; 65 | matrix<> V = {0.5, -1/3., M_PI}; 66 | 67 | As = smatrix<>(I,J,V,4,4); 68 | disp(As,2); 69 | 70 | .. code:: text 71 | 72 | Sparse matrix 4x4 of type 'd' with 3 elements (24 B): 73 | (0,1) 0.5 74 | (2,1) -0.333333 75 | (3,2) 3.14159 76 | 77 | Yes, we reaffected ``As`` to a new ``smatrix``. The old data is automatically discarded so one should be careful when performing such an action. As for ``matrix``, it is possible to :ref:`label-clear-smatrix` the content of a ``smatrix`` (the object is reinitialized). Let us now add a ``0``. 78 | 79 | .. code:: c++ 80 | 81 | As(3,3) = 0.; // but, why ? 82 | disp(As,2); 83 | 84 | .. code:: text 85 | 86 | Sparse matrix 4x4 of type 'd' with 4 elements (32 B): 87 | (0,1) 0.5 88 | (2,1) -0.333333 89 | (3,2) 3.14159 90 | (3,3) 0 91 | 92 | A zero value is added. In order to clean a ``smatrix``, a simple call to ``check`` is sufficient: 93 | 94 | .. code:: c++ 95 | 96 | check(As); 97 | disp(As,2); 98 | 99 | .. code:: text 100 | 101 | Sparse matrix 4x4 of type 'd' with 3 elements (24 B): 102 | (0,1) 0.5 103 | (2,1) -0.333333 104 | (3,2) 3.14159 105 | 106 | Everything went back to normal! Now, let us use one of the builders in order to create an identity sparse matrix. It is also possible to convert back to the *triplet* format. 107 | 108 | .. code:: c++ 109 | 110 | auto Bs = speye<>(4,4); 111 | disp(Bs,2); 112 | matrix IB,JB; 113 | matrix<> VB; 114 | std::tie(IB,JB,VB) = find(Bs); 115 | disp(transpose(vertcat(vertcat(IB,JB),VB)),2); 116 | 117 | .. code:: text 118 | 119 | Sparse matrix 4x4 of type 'd' with 4 elements (32 B): 120 | (0,0) 1 121 | (1,1) 1 122 | (2,2) 1 123 | (3,3) 1 124 | Matrix 4x3 of type 'd' (96 B): 125 | 0 0 1.00000 126 | 1.00000 1.00000 1.00000 127 | 2.00000 2.00000 1.00000 128 | 3.00000 3.00000 1.00000 129 | 130 | The matrices ``IB,JB,VB`` are returned as *line* vectors. To obtain a better display, we concatenated them vertically and tranposed the result. 131 | 132 | 133 | Basic manipulations 134 | +++++++++++++++++++ 135 | 136 | In this section, we start with start from scratch so everything written in the previous section should be discarded from your ``main`` function. Let us create two matrices 137 | 138 | .. code:: c++ 139 | 140 | smatrix<> As = speye(4,4); 141 | 142 | matrix I({1,1,2,2}), J({1,2,1,2}); 143 | matrix<> V({1.,1.,1.,1.}); 144 | smatrix<> Bs = smatrix<>(I,J,V,4,4); 145 | 146 | ``As`` is a ``4 x 4`` identity matrix and ``Bs`` is a matrix with the interior filled with ones. Here is an example of basic manipulations: 147 | 148 | .. code:: c++ 149 | 150 | auto Cs = 1.5*As - Bs/2.; 151 | disp(Cs,2); 152 | 153 | .. code:: text 154 | 155 | Sparse matrix 4x4 of type 'd' with 6 elements (48 B): 156 | (0,0) 1.5 157 | (1,1) 1 158 | (1,2) -0.5 159 | (2,1) -0.5 160 | (2,2) 1 161 | (3,3) 1.5 162 | 163 | What is the number of non-zero elements, again ? 164 | 165 | .. code:: c++ 166 | 167 | std::cout << "nnz(Cs) = " << nnz(Cs) << std::endl; 168 | 169 | .. code:: text 170 | 171 | nnz(Cs) = 6 172 | 173 | It is possible to get the value of any entry: 174 | 175 | .. code:: c++ 176 | 177 | std::cout << "Cs(1,2) = " << Cs(1,2) << std::endl; 178 | std::cout << "Cs(1,3) = " << Cs(1,3) << std::endl; 179 | 180 | .. code:: text 181 | 182 | Cs(1,2) = -0.5 183 | Cs(1,3) = 0 184 | 185 | Now, let us multiply ``Cs`` by a ``4 x 4`` dense ``matrix``: 186 | 187 | .. code:: c++ 188 | 189 | auto D = mtimes(Cs,ones<>(4)); 190 | disp(D,2); // :) 191 | 192 | .. code:: text 193 | 194 | Matrix 4x4 of type 'd' (128 B): 195 | 1.50000 1.50000 1.50000 1.50000 196 | 0.50000 0.50000 0.50000 0.50000 197 | 0.50000 0.50000 0.50000 0.50000 198 | 1.50000 1.50000 1.50000 1.50000 199 | 200 | One last manipulation and we are good for this example. 201 | 202 | .. code:: c++ 203 | 204 | Cs(0,3) = M_PI; 205 | auto Es = Cs - transpose(Cs); 206 | check(Es); // drop the zeros 207 | disp(Es,2); 208 | disp(full(Es,2)); 209 | 210 | .. code:: text 211 | 212 | Sparse matrix 4x4 of type 'd' with 2 elements (16 B): 213 | (0,3) 3.14159 214 | (3,0) -3.14159 215 | Matrix 4x4 of type 'd' (128 B): 216 | 0 0 0 3.14159 217 | 0 0 0 0 218 | 0 0 0 0 219 | -3.14159 0 0 0 220 | -------------------------------------------------------------------------------- /doc/source/api_smatrix.rst: -------------------------------------------------------------------------------- 1 | .. _label-smatrix-API: 2 | 3 | API 4 | === 5 | 6 | .. _label-check-smatrix: 7 | 8 | check 9 | ----- 10 | .. doxygenfunction:: check(smatrix &As) 11 | :project: castor 12 | 13 | See :ref:`label-class-matrix`. 14 | 15 | 16 | .. _label-clear-smatrix: 17 | 18 | clear 19 | ----- 20 | .. doxygenfunction:: clear(smatrix &As) 21 | :project: castor 22 | 23 | See :ref:`label-class-matrix`. 24 | 25 | 26 | .. _label-disp-smatrix: 27 | 28 | disp 29 | ---- 30 | .. doxygenfunction:: disp(smatrix const &As, int info = 2, std::ostream &flux = std::cout, std::size_t r = 3) 31 | :project: castor 32 | 33 | See :ref:`label-operator<<-smatrix`. 34 | 35 | 36 | .. _label-find-smatrix: 37 | 38 | find 39 | ---- 40 | .. doxygenfunction:: find(smatrix const &As) 41 | :project: castor 42 | 43 | See :ref:`label-index-smatrix`, :ref:`label-values-smatrix`. 44 | 45 | 46 | .. _label-full-smatrix: 47 | 48 | full 49 | ---- 50 | .. doxygenfunction:: full(smatrix const &As) 51 | :project: castor 52 | 53 | See :ref:`label-sparse-smatrix`. 54 | 55 | 56 | .. _label-index-smatrix: 57 | 58 | index 59 | ----- 60 | .. doxygenfunction:: index(smatrix const &As) 61 | :project: castor 62 | 63 | .. _label-mtimes-smatrix: 64 | 65 | mtimes 66 | ------ 67 | .. doxygenfunction:: mtimes(matrix const &A, smatrix const &Bs) 68 | :project: castor 69 | .. doxygenfunction:: mtimes(smatrix const &As, matrix const &B) 70 | :project: castor 71 | 72 | See :ref:`label-tgemm-naive`, :ref:`label-kron`. 73 | 74 | 75 | .. _label-nnz-smatrix: 76 | 77 | nnz 78 | --- 79 | .. doxygenfunction:: nnz(smatrix const &As) 80 | :project: castor 81 | 82 | See :ref:`label-find`, :ref:`label-size-smatrix`. 83 | 84 | 85 | .. _label-numel-smatrix: 86 | 87 | numel 88 | ----- 89 | .. doxygenfunction:: numel(smatrix const &As) 90 | :project: castor 91 | 92 | See :ref:`label-size-smatrix`, :ref:`label-nnz-smatrix`. 93 | 94 | 95 | .. _label-reshape-smatrix: 96 | 97 | reshape 98 | ------- 99 | .. doxygenfunction:: reshape(smatrix const &As, std::size_t m, std::size_t n) 100 | :project: castor 101 | 102 | See :ref:`label-transpose-smatrix`. 103 | 104 | .. _label-size-smatrix: 105 | 106 | size 107 | ---- 108 | .. doxygenfunction:: size(smatrix const &As, int dim) 109 | :project: castor 110 | .. doxygenfunction:: size(smatrix const &As) 111 | :project: castor 112 | 113 | See :ref:`label-numel-smatrix`, :ref:`label-nnz-smatrix`. 114 | 115 | 116 | .. _label-sparse-smatrix: 117 | 118 | sparse 119 | ------ 120 | 121 | .. doxygenfunction:: sparse(matrix const &L, matrix const &V, std::size_t m, std::size_t n) 122 | :project: castor 123 | .. doxygenfunction:: sparse(matrix const &I, matrix const &J, matrix const &V) 124 | :project: castor 125 | .. doxygenfunction:: sparse(matrix const &I, matrix const &J, matrix const &V, std::size_t m, std::size_t n) 126 | :project: castor 127 | .. doxygenfunction:: sparse(matrix const &A) 128 | :project: castor 129 | 130 | See :ref:`label-full-smatrix`. 131 | 132 | 133 | .. _label-speye-smatrix: 134 | 135 | speye 136 | ----- 137 | .. doxygenfunction:: speye(matrix const &S) 138 | :project: castor 139 | .. doxygenfunction:: speye(std::size_t m, long n = -1) 140 | :project: castor 141 | 142 | See :ref:`label-spzeros-smatrix`, :ref:`label-spones-smatrix`, :ref:`label-sprand-smatrix`, :ref:`label-eye`. 143 | 144 | 145 | .. _label-spones-smatrix: 146 | 147 | spones 148 | ------ 149 | .. doxygenfunction:: spones(matrix const &S) 150 | :project: castor 151 | .. doxygenfunction:: spones(std::size_t m, long n = -1) 152 | :project: castor 153 | 154 | See :ref:`label-spzeros-smatrix`, :ref:`label-speye-smatrix`, :ref:`label-sprand-smatrix`, :ref:`label-ones`. 155 | 156 | 157 | .. _label-sprand-smatrix: 158 | 159 | sprand 160 | ------ 161 | .. doxygenfunction:: sprand(matrix const &S, bool seed = false) 162 | :project: castor 163 | .. doxygenfunction:: sprand(std::size_t m, long n = -1, bool seed = false) 164 | :project: castor 165 | 166 | See :ref:`label-spzeros-smatrix`, :ref:`label-speye-smatrix`, :ref:`label-spones-smatrix`, :ref:`label-rand`. 167 | 168 | 169 | .. _label-spzeros-smatrix: 170 | 171 | spzeros 172 | ------- 173 | .. doxygenfunction:: spzeros(std::size_t m, long n = -1) 174 | :project: castor 175 | 176 | See :ref:`label-spones-smatrix`, :ref:`label-speye-smatrix`, :ref:`label-sprand-smatrix`, :ref:`label-zeros`. 177 | 178 | 179 | .. _label-transpose-smatrix: 180 | 181 | transpose 182 | --------- 183 | .. doxygenfunction:: transpose(smatrix const &As) 184 | :project: castor 185 | 186 | See :ref:`label-reshape-smatrix`. 187 | 188 | 189 | .. _label-values-smatrix: 190 | 191 | values 192 | ------ 193 | .. doxygenfunction:: values(smatrix const &As) 194 | :project: castor 195 | 196 | See :ref:`label-index-smatrix`, :ref:`label-find-smatrix`. 197 | 198 | 199 | 200 | .. _label-operator<<-smatrix: 201 | 202 | operator<< 203 | ---------- 204 | .. doxygenfunction:: operator<<(std::ostream &flux, smatrix const &As) 205 | :project: castor 206 | 207 | See :ref:`label-disp-smatrix`. 208 | 209 | 210 | .. _label-operator+-smatrix: 211 | 212 | operator+ 213 | --------- 214 | .. doxygenfunction:: operator+(smatrix const &As, S b) 215 | :project: castor 216 | .. doxygenfunction:: operator+(R a, smatrix const &Bs) 217 | :project: castor 218 | .. doxygenfunction:: operator+(smatrix const &As, matrix const &B) 219 | :project: castor 220 | .. doxygenfunction:: operator+(matrix const &A, smatrix const &Bs) 221 | :project: castor 222 | .. doxygenfunction:: operator+(smatrix const &As, smatrix const &Bs) 223 | :project: castor 224 | 225 | 226 | 227 | .. _label-operator--smatrix: 228 | 229 | operator- 230 | --------- 231 | .. doxygenfunction:: operator-(smatrix const &As, S b) 232 | :project: castor 233 | .. doxygenfunction:: operator-(R a, smatrix const &Bs) 234 | :project: castor 235 | .. doxygenfunction:: operator-(smatrix const &As, matrix const &B) 236 | :project: castor 237 | .. doxygenfunction:: operator-(matrix const &A, smatrix const &Bs) 238 | :project: castor 239 | .. doxygenfunction:: operator-(smatrix const &As, smatrix const &Bs) 240 | :project: castor 241 | .. doxygenfunction:: operator-(smatrix const &As) 242 | :project: castor 243 | 244 | 245 | 246 | .. _label-operator*-smatrix: 247 | 248 | operator* 249 | --------- 250 | .. doxygenfunction:: operator*(smatrix const &As, S Bs) 251 | :project: castor 252 | .. doxygenfunction:: operator*(R As, smatrix const &Bs) 253 | :project: castor 254 | .. doxygenfunction:: operator*(smatrix const &As, matrix const &B) 255 | :project: castor 256 | .. doxygenfunction:: operator*(matrix const &A, smatrix const &Bs) 257 | :project: castor 258 | .. doxygenfunction:: operator*(smatrix const &As, smatrix const &Bs) 259 | :project: castor 260 | 261 | 262 | .. _label-operator/-smatrix: 263 | 264 | operator/ 265 | --------- 266 | .. doxygenfunction:: operator/(smatrix const &As, S Bs) 267 | :project: castor 268 | .. doxygenfunction:: operator/(matrix const &As, smatrix const &Bs) 269 | :project: castor 270 | .. doxygenfunction:: operator/(smatrix const &As, matrix const &Bs) 271 | :project: castor 272 | .. doxygenfunction:: operator/(R As, smatrix const &Bs) 273 | :project: castor 274 | .. doxygenfunction:: operator/(smatrix const &As, smatrix const &Bs) 275 | :project: castor 276 | 277 | -------------------------------------------------------------------------------- /misc/some_fractals.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | +========================================================================+ 3 | | (c) 2020 - PROPERTY OF ECOLE POLYTECHNIQUE - LGPL 3.0 | 4 | |________________________________________________________________________| 5 | | '&` | | 6 | | # | FILE : some_fractals.cpp | 7 | | # | VERSION : 1.0.0 | 8 | | _#_ | AUTHOR(S) : Marc Bakry | 9 | | ( # ) | CREATION : 31.08.2020 | 10 | | / 0 \ | LAST MODIF : | 11 | | ( === ) | SYNOPSIS : Fractals computation and visualization using | 12 | | `---' | Castor | 13 | +========================================================================+ 14 | */ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "castor/matrix.hpp" 21 | #include "castor/graphics.hpp" 22 | 23 | using namespace castor; 24 | 25 | struct FractalPars 26 | { 27 | double xmin{0.}, ymin{0.}; 28 | double zoom{0}; 29 | std::size_t nx{0}, ny{0}; 30 | std::size_t itMax{0}; 31 | double divcrit{2.}; 32 | }; 33 | 34 | matrix julia(FractalPars const &pars, std::complex c); 35 | matrix mandelbrot(FractalPars const &pars); 36 | matrix generalized_mandelbrot(FractalPars const &pars, std::function(std::complex, std::complex)> const &_func); 37 | FractalPars getPars(short _fracType); // PRESET PARAMETERS FOR THIS EXAMPLE 38 | 39 | int main() 40 | { 41 | // GENERAL SETTINGS 42 | 43 | std::complex c(0.285,0.01); // ONLY RELEVANT FOR JULIA 44 | 45 | // CREATE PLOT 46 | std::vector
figs; 47 | for(short fractal_type: {0,1,2}) // 0: JULIA, 1: MANDELBROT, 2: GENERALIZED MANDELBROT 48 | { 49 | matrix fractal; 50 | auto pars = getPars(fractal_type); 51 | tic(); 52 | switch(fractal_type) 53 | { 54 | case 0: 55 | fractal = julia(pars, c); 56 | break; 57 | case 1: 58 | fractal = mandelbrot(pars); 59 | break; 60 | case 2: 61 | fractal = generalized_mandelbrot(pars, [](std::complex _z, std::complex _c) -> std::complex{return std::cos(_z) + 1./_c;}); 62 | break; 63 | default: 64 | return EXIT_FAILURE; 65 | } 66 | toc(); 67 | // INVERT COLORS 68 | fractal = pars.itMax - fractal; 69 | // ADD SOME PLOT 70 | figs.push_back(figure()); 71 | imagesc(figs.back(),fractal); 72 | } 73 | drawnow(figs.back()); 74 | return EXIT_SUCCESS; 75 | } 76 | 77 | FractalPars getPars(short fracType) 78 | { 79 | FractalPars pars; 80 | double xmax, ymax; 81 | switch(fracType) 82 | { 83 | case 0: 84 | pars.xmin = -1.; 85 | xmax = 1.; 86 | pars.ymin = -1.2; 87 | ymax = 1.2; 88 | pars.zoom = 500; 89 | pars.itMax = 150; 90 | pars.nx = static_cast((xmax - pars.xmin)*pars.zoom); 91 | pars.ny = static_cast((ymax - pars.ymin)*pars.zoom); 92 | pars.divcrit = 2.; 93 | break; 94 | case 1: 95 | pars.xmin = -2.1; 96 | xmax = 0.6; 97 | pars.ymin = -1.2; 98 | ymax = 1.2; 99 | pars.zoom = 500; 100 | pars.itMax = 150; 101 | pars.nx = static_cast((xmax - pars.xmin)*pars.zoom); 102 | pars.ny = static_cast((ymax - pars.ymin)*pars.zoom); 103 | pars.divcrit = 2.; 104 | break; 105 | case 2: 106 | pars.xmin = -1; 107 | xmax = 1; 108 | pars.ymin = -1; 109 | ymax = 1; 110 | pars.zoom = 500; 111 | pars.itMax = 50; 112 | pars.nx = static_cast((xmax - pars.xmin)*pars.zoom); 113 | pars.ny = static_cast((ymax - pars.ymin)*pars.zoom); 114 | pars.divcrit = 1024*1024; 115 | break; 116 | default: 117 | std::exit(EXIT_FAILURE); 118 | } 119 | return pars; 120 | } 121 | 122 | matrix julia(FractalPars const &pars, std::complex c) 123 | { 124 | std::cout << "+---------------------------+" << std::endl; 125 | std::cout << "| Computing Julia ensembles |" << std::endl; 126 | std::cout << "+---------------------------+" << std::endl; 127 | matrix frac = zeros(pars.ny,pars.nx); 128 | // 129 | for(auto iy = 0; iy(ix/pars.zoom+pars.xmin, iy/pars.zoom + pars.ymin); 135 | // 136 | do 137 | { 138 | z = z*z + c; 139 | ++frac(iy_,ix); 140 | } while (std::abs(z) mandelbrot(FractalPars const &pars) 147 | { 148 | std::cout << "+----------------------------------+" << std::endl; 149 | std::cout << "| Computing the Mandelbrot fractal |" << std::endl; 150 | std::cout << "+----------------------------------+" << std::endl; 151 | matrix frac = zeros(pars.ny,pars.nx); 152 | // 153 | for(auto iy = 0; iy(0,0); 159 | auto c = std::complex(ix/pars.zoom+pars.xmin, iy/pars.zoom + pars.ymin); 160 | // 161 | do 162 | { 163 | z = z*z + c; 164 | ++frac(iy_,ix); 165 | } while (std::abs(z) generalized_mandelbrot(FractalPars const &pars, std::function(std::complex, std::complex)> const &func) 172 | { 173 | // JUST LIKE MANDELBROT, BUT WE REPLACED z <- z*z + c BY SOME OTHER FUNCTION 174 | std::cout << "+--------------------------------------------+" << std::endl; 175 | std::cout << "| Computing a Generalized Mandelbrot fractal |" << std::endl; 176 | std::cout << "+--------------------------------------------+" << std::endl; 177 | matrix frac = zeros(pars.ny,pars.nx); 178 | // 179 | for(auto iy = 0; iy(0,0); 185 | auto c = std::complex(ix/pars.zoom+pars.xmin, iy/pars.zoom + pars.ymin); 186 | // 187 | do 188 | { 189 | z = func(z,c); 190 | ++frac(iy_,ix); 191 | } while (std::abs(z)(0,1)`` and two matrices containing respectively the real and the imaginary part. 12 | 13 | 14 | .. code:: c++ 15 | 16 | matrix<> Re = {1,0,-1,0}; 17 | matrix<> Im = {0,1,0,-1}; 18 | 19 | disp("Imaginary number matrix ('1i') : "); 20 | disp(M_1I); 21 | 22 | disp("Complex matrix : "); 23 | auto Ac = Re + M_1I*Im; 24 | disp(Ac); 25 | 26 | 27 | .. code:: text 28 | 29 | Imaginary number matrix ('1i') : 30 | (0,1) 31 | Complex matrix : 32 | (1.00000,0.00000) (0.00000,1.00000) (-1.00000,0.00000) (0.00000,-1.00000) 33 | 34 | We can compute the conjugate of the elements, the absolute value, or extract the imaginary part. 35 | 36 | .. code:: c++ 37 | 38 | disp(conj(Ac),2); 39 | disp(abs(Ac),2); 40 | disp(imag(Ac),2); 41 | 42 | .. code:: text 43 | 44 | Matrix 1x4 of type 'St7complexIdE' (64 B): 45 | (1.00000,-0.00000) (0.00000,-1.00000) (-1.00000,-0.00000) (0.00000,1.00000) 46 | Matrix 1x4 of type 'd' (32 B): 47 | 1.00000 1.00000 1.00000 1.00000 48 | Matrix 1x4 of type 'd' (32 B): 49 | 0 1.00000 0 -1.00000 50 | 51 | 52 | Logical matrices 53 | ++++++++++++++++ 54 | 55 | Because of the special behaviour of ``std::vector``, **matrix** does not use the native logical type ``bool`` of the C++ standard library, but uses instead ``std::uint8_t`` which corresponds to a ``unsigned short int``, or ``char``. Consequently, the ``bool`` values are converted to ``std::uint8_t`` where the value ``false`` is converted to the value ``0`` and ``true`` to the value ``1``. A logical ``matrix`` is displayed like: 56 | 57 | .. code:: c++ 58 | 59 | matrix A = eye(3); 60 | matrix B = ones(3); 61 | disp("A && B :"); 62 | disp(A && B); 63 | 64 | .. code:: text 65 | 66 | A && B : 67 | 1 0 0 68 | 0 1 0 69 | 0 0 1 70 | 71 | **WARNING (very important):** a ``matrix`` *remains intrinsically a* ``matrix`` meaning that it behaves like one. This behavior is not natural and will be corrected in a future release. 72 | 73 | 74 | Using some algorithms 75 | +++++++++++++++++++++ 76 | 77 | The ``matrix`` class comes with a lot of built-in algorithms (see :ref:`label-algorithms` for a full list). First, we create some random integer data in the range ``[0,10[``. 78 | 79 | .. code:: c++ 80 | 81 | auto A = cast(10*rand<>(1,10)); 82 | disp(A,2,std::cout,10,10); 83 | 84 | .. code:: text 85 | 86 | Matrix 1x10 of type 'i' (40 B): 87 | 8 3 7 7 9 1 3 7 2 5 88 | 89 | **Remark:** In the code above, we first call :ref:`label-rand` for the default ``double`` type, then we multiply by ``10`` and finally :ref:`label-cast` the result to integers. In fact, the :ref:`label-rand` function generates intrinsically numbers of type ``double`` in the range ``[0,1[`` which are converted afterward in the template type. Unfortunately, calling ``rand`` will cast those numbers to zero. What we did is first generate ``double`` numbers in the range ``[0,10[``, then cast them to ``int``. 90 | 91 | What are the minimum, average, standard deviation, and the maximum values of ``A`` ? 92 | 93 | .. code:: c++ 94 | 95 | disp(min(A)); 96 | disp(mean(A)); 97 | disp(stddev(A)); 98 | disp(max(A)); 99 | 100 | 101 | .. code:: text 102 | 103 | 1 104 | 5.2 105 | 2.63818 106 | 9 107 | 108 | **Remark:** Do not forget, in that particular case, to give the output type for the result of ``mean`` and ``stddev``. Otherwise, the result will be cast in the template type which is ``int``! 109 | 110 | The :ref:`label-unique` elements of ``A`` are 111 | 112 | .. code:: c++ 113 | 114 | disp(unique(A),2,std::cout,10,10); 115 | 116 | .. code:: text 117 | 118 | Matrix 1x7 of type 'i' (28 B): 119 | 1 2 3 5 7 8 9 120 | 121 | Now let us :ref:`label-sort` the elements. 122 | 123 | .. code:: c++ 124 | 125 | auto A_sorted = sort(A); 126 | disp(A_sorted,2,std::cout,10,10); 127 | 128 | .. code:: text 129 | 130 | Matrix 1x10 of type 'i' (40 B): 131 | 1 2 3 3 5 7 7 7 8 9 132 | 133 | We create a second smaller vector and we search the common elements. 134 | 135 | .. code:: c++ 136 | 137 | auto B = cast(10*rand<>(1,4)); 138 | disp(B,2); 139 | disp(intersect(A,B),2); 140 | 141 | .. code:: text 142 | 143 | Matrix 1x4 of type 'i' (16 B): 144 | 4 6 3 5 145 | Matrix 1x2 of type 'i' (8 B): 146 | 3 5 147 | 148 | We obtain the expected result. 149 | 150 | 151 | View 152 | ++++ 153 | 154 | The **matrix** provides operators to extract a submatrix from a matrix instance or to assign values of a submatrix to a matrix. 155 | The operator ``()`` can take a list of indices to return an instance of ``class view``. 156 | 157 | As the ``class view`` contains a reference to the set of values corresponding to the list of indices, it is **necessary** to call the method ``eval`` to use the viewed submatrix. 158 | 159 | It is possible to give the list of indices in linear indexing **A(L)** or bilinear indexing **A(I,J)**. The external functions all, col, range and row are useful to describe indices. 160 | 161 | .. code:: c++ 162 | 163 | matrix<> A = {{0, 1, 2, 4}, 164 | {4, 5, 6, 7}, 165 | {8, 9,10,11}}; 166 | 167 | disp("Linear indexing"); 168 | disp(" extracting :"); 169 | matrix<> B = eval(A({1,3,5})); 170 | disp(B); 171 | 172 | disp(" assigning :"); 173 | A(range(0,4)) = 0; 174 | disp(A); 175 | 176 | disp("Bilinear indexing"); 177 | disp(" extracting :"); 178 | B = eval(A(1,range(0,3)));; 179 | disp(B); 180 | 181 | disp(" assigning :"); 182 | A({0,2}, col(A)) = 10; 183 | disp(A); 184 | 185 | .. code:: text 186 | 187 | Linear indexing 188 | extracting : 189 | 1.00000 4.00000 5.00000 190 | assigning : 191 | 0 0 0 0 192 | 4.00000 5.00000 6.00000 7.00000 193 | 8.00000 9.00000 10.00000 11.00000 194 | Bilinear indexing 195 | extracting : 196 | 4.00000 5.00000 6.00000 197 | assigning : 198 | 10.00000 10.00000 10.00000 10.00000 199 | 4.00000 5.00000 6.00000 7.00000 200 | 10.00000 10.00000 10.00000 10.00000 201 | 202 | 203 | Internal matrix tools 204 | +++++++++++++++++++++ 205 | 206 | In addition to constructors and operators, the matrix class has few member functions (see internal tools list in :ref:`class matrix description `). The functions can be user-friendy for native C++ coding. 207 | 208 | Notes: 209 | 210 | - The method ``size`` differs from the external function ``size`` for the parameter dim=0. Indeed, in that case, the method ``size`` returns the total number of elements in the matrix while the external function ``size`` returns the two-element vector containing the number of rows and columns in the matrix. 211 | 212 | .. code:: c++ 213 | 214 | matrix<> A = {{1,2,3},{4,5,6}}; 215 | disp("Method size :"); 216 | disp(A.size(0)); 217 | disp(A.size(1)); 218 | disp(A.size(2)); 219 | disp("External function size :"); 220 | disp(size(A)); 221 | disp(size(A,1)); 222 | disp(size(A,2)); 223 | 224 | .. code:: text 225 | 226 | Method size : 227 | 6 228 | 2 229 | 3 230 | External function size : 231 | 2 3 232 | 2 233 | 3 234 | 235 | - The method ``resize`` is more efficient than the external function ``resize`` since the methode makes the maniplulation in-place which avoids a copy. 236 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /doc/source/heat.rst: -------------------------------------------------------------------------------- 1 | Heat equation 2 | ============= 3 | 4 | *Shared by Antoine Rideau* 5 | 6 | 7 | On this page you will find how to code using **Castor** an example as simple as heat diffusion in 1 dimension without heat source with Dirichlet boundary described by the following equation : 8 | 9 | 10 | .. math:: 11 | 12 | \left\{ \begin{matrix} \displaystyle \frac{\partial u }{\partial t} = d \frac{\partial^2 u}{\partial x^2} 13 | \\ u(x_{min},t) = u(x_{max}, t) = 0 14 | \\ u(x,0) = \sin(x\pi )^{2} \end{matrix} \right. 15 | 16 | 17 | The simulation is focuses on the interval :math:`\left [ x_{min}, x_{max}\right ]=\left [ 0,2 \right ]` for the space domain which is divided between ``Nx = 1000`` points . 18 | 19 | .. code-block:: c++ 20 | 21 | //Parameters 22 | int Nx = 1000; 23 | double xmin = 0; 24 | double xmax = 1; 25 | double tf = 0.1; 26 | double ti = 0; 27 | 28 | 29 | The space is discretized with ``dx`` steps and the time with ``dt`` steps. 30 | 31 | .. math:: 32 | 33 | \begin{matrix} x_{i} = i \Delta x \\ t_{n} = n \Delta t \end{matrix} 34 | 35 | The ``X`` vector stores the space grid 36 | 37 | .. math:: 38 | 39 | X = \begin{pmatrix} x_{0}\\ x_{1} \\ \vdots \\ x_{N_{x}-1} \end{pmatrix} , 40 | 41 | and the vector ``U0`` contains the initial heat distribution 42 | 43 | .. math:: 44 | 45 | U_{0} = \begin{pmatrix} u_{0}^{0} \\ u_{1}^{0} \\ \vdots \\ u_{N_{x}-1}^{0} \end{pmatrix} \text{ with } u_{i}^{0} = \sin(x_{i})^{2} \text{ for } i=0,...,N_{x} . 46 | 47 | 48 | .. code-block:: c++ 49 | 50 | //Discretization 51 | double dx = (xmax - xmin) / (Nx - 1); 52 | double dt = 0.5 * (dx * dx) / d; 53 | matrix<> X = linspace(xmin, xmax, Nx); 54 | matrix<> U0 = pow(sin(X * M_PI), 2); 55 | 56 | 57 | The second space derivative is approximated by : 58 | 59 | .. math:: 60 | 61 | \frac{\partial^2 u_{i}^{n}}{\partial x^2}\approx \frac{u_{i+1}^{n}-2u_{i}^{n}+u_{i-1}^{n}}{\Delta x^{2}} 62 | 63 | 64 | .. Analytical solution 65 | .. ------------------- 66 | 67 | .. With those parameters, the analytical solution is : 68 | 69 | .. .. math:: 70 | 71 | .. \text{ MATHS } 72 | 73 | 74 | Explicit Euler 75 | -------------- 76 | 77 | The specifity of the explicit Euler scheme is that the time derivative is calculated with the forward differential quotient approximation 78 | 79 | .. math:: 80 | 81 | \frac{\partial u_{i}^{n}}{\partial t}\approx \frac{u_{i}^{n+1}-u_{i}^{n}}{\Delta t} 82 | 83 | So as to maintain the stability of the simulation, the time step ``dt`` has to respect the following inequality 84 | 85 | .. math:: 86 | 87 | d \frac{\Delta t}{\Delta x^{2}} \leq \frac{1}{2} 88 | 89 | Finally, the following numerical scheme is obtained : 90 | 91 | .. math:: 92 | 93 | \frac{u_{i}^{n+1}-u_{i}^{n}}{\Delta t}- d \frac{u_{i+1}^{n}-2u_{i}^{n}+u_{i-1}^{n}}{\Delta x^{2}}=0 94 | 95 | When coming to the code, :math:`u_{i}^{n+1}` is expressed in function of the other dependencies of :math:`u` : 96 | 97 | .. math:: 98 | 99 | u_{i}^{n+1} = u_{i}^{n} + \alpha (u_{i+1}^{n}-2u_{i}^{n}+u_{i-1}^{n}) \text{ with } \alpha= \frac{d \Delta t}{\Delta x^{2}} 100 | 101 | .. code-block:: c++ 102 | 103 | double alpha = (dt * d / (dx * dx)); 104 | for (double t = 0; t <= tend; t += dt) 105 | { 106 | for (int i = 1; i < Nx - 1; i++) 107 | { 108 | U(i) += alpha * (U(i - 1) - 2 * U(i) + U(i + 1)); 109 | } 110 | } 111 | 112 | Here you have all the code at once : 113 | 114 | .. code-block:: c++ 115 | 116 | #include "castor/matrix.hpp" 117 | #include "castor/graphics.hpp" 118 | 119 | using namespace castor; 120 | 121 | int main(int argc, char *argv[]) 122 | { 123 | //Thermal diffusivity 124 | double d = 1.; 125 | 126 | //Parameters 127 | int Nx = 1000; 128 | double xmin = 0; 129 | double xmax = 2; 130 | double tend = 0.1; 131 | double ti = 0; 132 | 133 | //Discretization 134 | double dx = (xmax - xmin) / (Nx - 1); 135 | double dt = 0.5 * (dx * dx) / d; 136 | double alpha = (dt * d / (dx * dx)); 137 | matrix<> X = linspace(xmin, xmax, Nx); 138 | matrix<> U0 = pow(sin(X * M_PI), 2); 139 | 140 | std::cout << "--- Start explicit Euler scheme ---" << endl; 141 | tic(); 142 | auto U = U0; 143 | for (double t = 0; t <= tend; t += dt) 144 | { 145 | for (int i = 1; i < Nx - 1; i++) 146 | { 147 | U(i) += alpha * (U(i - 1) - 2 * U(i) + U(i + 1)); 148 | } 149 | } 150 | toc(); 151 | 152 | //Plot 153 | figure fig; 154 | plot(fig, X, U0, {"b-o"}, {"initial"}); 155 | plot(fig, X, S, {"g-s"}, {"solution"}); 156 | plot(fig, X, U, {"m-x"}, {"explicit"}); 157 | drawnow(fig); 158 | 159 | return 0; 160 | } 161 | 162 | With this code you should get these outputs : 163 | 164 | .. code-block:: text 165 | 166 | --- Start explicit Euler scheme --- 167 | Elapsed time is 0.213486 seconds. 168 | 169 | .. image:: img/heatexplicit.png 170 | :width: 400 171 | :align: center 172 | 173 | 174 | Implicit Euler 175 | -------------- 176 | 177 | The specifity of the implicit Euler scheme is that the time derivative is calculated with the backward differential quotient approximation 178 | 179 | .. math:: 180 | 181 | \frac{\partial u_{i}^{n}}{\partial t} \approx \frac{u_{i}^{n}-u_{i}^{n-1}}{\Delta t} 182 | 183 | | This scheme is stable for any ``dt`` . 184 | | The scheme can be written using vectors 185 | 186 | .. math:: 187 | 188 | \frac{U^{n+1}-U^{n}}{\Delta t} + \frac{d}{\Delta x}AU^{n+1} = 0 , 189 | 190 | where A is the :math:`N_{x}` x :math:`N_{x}` tridiagonal matrix 191 | 192 | .. math:: 193 | 194 | A = \begin{pmatrix} -2 & 1 & 0 & \cdots & 0 195 | \\ 1 & -2 & 1 & \cdots & 0 196 | \\ \vdots & \ddots & \ddots & \ddots & \vdots 197 | \\ 0 & \cdots & 1 & -2 & 1 198 | \\ 0 & \cdots & 0 & 1 & -2 \end{pmatrix} . 199 | 200 | 201 | This equation leads to the following linear equation 202 | 203 | .. math:: 204 | 205 | BU^{n+1} = U^{n} \text{ with } B = (I_{N_{x}} - \alpha A) . 206 | 207 | 208 | .. code-block:: c++ 209 | 210 | double alpha = (dt * d / (dx * dx)); 211 | matrix<> e = ones(Nx, 1); 212 | smatrix<> A = spdiags(cat(2, cat(2, e, -2 * e), e), colon(-1, 1), Nx, Nx); 213 | auto B = speye(Nx) - alpha * A; 214 | for (double t = 0; t <= tend; t += dt) 215 | { 216 | U = linsolve(B, U); 217 | } 218 | 219 | Here you have all the code at once : 220 | 221 | .. code-block:: c++ 222 | 223 | #include "castor/matrix.hpp" 224 | #include "castor/graphics.hpp" 225 | #include "castor/linalg.hpp" 226 | 227 | using namespace castor; 228 | 229 | int main(int argc, char *argv[]) 230 | { 231 | //Thermal diffusivity 232 | double d = 1.; 233 | 234 | //Parameters 235 | int Nx = 1000; 236 | double xmin = 0; 237 | double xmax = 2; 238 | double tend = 0.1; 239 | double ti = 0; 240 | 241 | //Discretization 242 | double dx = (xmax - xmin) / (Nx - 1); 243 | double dt = 5 * (dx * dx) / d; 244 | double alpha = (dt * d / (dx * dx)); 245 | matrix<> X = linspace(xmin, xmax, Nx); 246 | matrix<> U0 = pow(sin(X * M_PI), 2); 247 | 248 | std::cout << "--- Start implicit Euler scheme ---" << endl; 249 | auto U = transpose(U0); 250 | tic(); 251 | matrix<> e = ones(Nx, 1); 252 | smatrix<> A = spdiags(cat(2, cat(2, e, -2 * e), e), colon(-1, 1), Nx, Nx); 253 | auto B = speye(Nx) - alpha * A; 254 | for (double t = 0; t <= tend; t += dt) 255 | { 256 | U = linsolve(B, U); 257 | } 258 | toc(); 259 | 260 | U = transpose(U); 261 | 262 | //Plot 263 | figure fig; 264 | plot(fig, X, U0, {"b-o"}, {"initial"}); 265 | plot(fig, X, S, {"g-s"}, {"solution"}); 266 | plot(fig, X, U, {"r-+"}, {"implicit"}); 267 | drawnow(fig); 268 | 269 | return 0; 270 | } 271 | 272 | With this code you should get these results : 273 | 274 | .. code-block:: text 275 | 276 | --- Start implicit Euler scheme --- 277 | Elapsed time is 4.11192 seconds. 278 | 279 | .. image:: img/heatimplicit.png 280 | :width: 400 281 | :align: center 282 | 283 | References 284 | ---------- 285 | 286 | https://www.ljll.math.upmc.fr/ledret/M1English/M1ApproxPDE_Chapter6-2.pdf -------------------------------------------------------------------------------- /doc/source/installation.rst: -------------------------------------------------------------------------------- 1 | .. _label-installation: 2 | 3 | Installation 4 | ============ 5 | 6 | The simplest way to get the dense matrix part of the framework **castor** is to download the `latest version of header files `_ and include `matrix.hpp` during the compilation of your c++ program using the library, see :ref:`label-compilation` in the :ref:`label-basic` section. 7 | 8 | For a complete installation integrating check dependencies and examples compilation, we describe below the procedure. 9 | 10 | **MacOS** (11 and 12) and **Ubuntu** (20.04) 11 | ++++++++++++++++++++++++++++++++++++++++++++ 12 | 13 | Installing the dependencies 14 | --------------------------- 15 | 16 | The **castor** framework depends on two external dependencies : a BLAS/LAPACK implementation in order to use optimized linear algebra, and VTK for the graphical rendering. 17 | 18 | The BLAS/LAPACK implementation which has been tested are : 19 | 20 | - MKL 2020.0.166 : `MKL informations `_, 21 | - OpenBlas 0.3.19 : `OpenBLAS informations `_, 22 | - vecLib : from accelerate framework in MacOS. 23 | 24 | The version of VTK library which has been tested is `9.1.0 `_. 25 | 26 | The last tool to perform installation is ``CMake``, at least version `3.18 `_. 27 | 28 | **Note** : on macOS it is recommended to install these dependencies with `brew `_. 29 | 30 | From git repository with CMake 31 | ------------------------------ 32 | 33 | You can install the **castor** library from source with ``CMake``. The source files of the library is available here ``_. 34 | 35 | .. code:: 36 | 37 | $ git clone https://gitlab.labos.polytechnique.fr/leprojetcastor/castor.git 38 | $ cd castor 39 | $ mkdir build 40 | $ cd build 41 | $ cmake -DCMAKE_INSTALL_PREFIX=path/to/install/directory .. 42 | $ make install 43 | 44 | ``path/to/install/directory`` is the absolute path to the folder where **castor** header files are installed. ``CMake`` assumes this folder contains ``include`` subfolder. By default, ``CMAKE_INSTALL_PREFIX`` is set to ``/usr/local`` and header files are installed in ``/usr/local/include/castor`` directory. 45 | 46 | The linear algebra part and the visualization part of the library depend respectively on an optimized BLAS library (like OpenBLAS and MKL) and the VTK library. ``CMake`` tries to detect these required libraries in your system, if ``Cmake`` can not find these dependencies, you can indicate the paths to them by using ``-DCMAKE_PREFIX_PATH``: 47 | 48 | .. code:: 49 | 50 | $ cmake -DCMAKE_INSTALL_PREFIX=path/to/install/directory -DCMAKE_PREFIX_PATH="/path/to/optimized/blas;/path/to/vtk/" .. 51 | 52 | Xcode project for macOS 53 | ----------------------- 54 | 55 | To create a Xcode project with ``CMake``, add option `-G Xcode` in the `cmake` command : 56 | 57 | .. code:: 58 | 59 | $ cmake -G Xcode -DCMAKE_INSTALL_PREFIX=path/to/install/directory 60 | 61 | This project is created in the `build` directory. 62 | 63 | Windows (10) 64 | ++++++++++++ 65 | 66 | This solution has been tested on Windows 10 only (but may work on other version). Since there is no *built_in* available package manager, the different components will be installed *by-hands* using only *Windows-like* tools. 67 | 68 | C++ compiler and CMake 69 | ---------------------- 70 | 71 | The first step is to install a suitable C++ compiler. In the following instructions we will only use the compiler provided with `Visual Studio `_, version 2019 or later (previous version may work but have not been tested). The Visual Studio framework also provides a customized command prompt named `x64 Native Tools Command Prompt`. 72 | 73 | We will also install the `CMake `_ tools. Download the latest binary distribution for Windows. After installing CMake, open the `x64 Native Tools Command Prompt` and execute the command `cmake-gui`. If the command fails, find the install folder of CMake and add the `CMakeInstallFolder\bin` subfolder to the Windows `%PATH%` environment variable, restart the command prompt and try again. The graphical interface of CMake should open (close it for now). 74 | 75 | BLAS/LAPACK library 76 | ------------------- 77 | 78 | The simplest way is probably to install `OpenBLAS `_ which implements both interfaces. Compiling the library can quickly become painful as a Fortran compiler is required. Thankfully, the developers have made precompiled binaries available. Installing OpenBLAS can be done following these steps: 79 | 80 | 1. Go to `https://github.com/xianyi/OpenBLAS/releases `_, look for an archive named **OpenBLAS-0.x.x-x64.zip** (or **OpenBLAS-0.x.x-x86.zip** for older architectures) in the section **Assets** corresponding to the version you wish to use and download it. The demos were tested originally with `OpenBLAS 0.3.12` so any later version should be fine. 81 | 2. Extract the downloaded archive in a folder of your choice (for example, create a folder `openblas`). This folder should now contain three subdirectories: 82 | - `openblas\bin` should contain a file named `libopenblas.dll`. 83 | - `openblas\include` should contain the header files, including `cblas.h`. 84 | - `openblas\lib` should contain `.lib` files (including `libopenblas.lib`) and a `openblas\lib\cmake` subfolder. 85 | 3. Add the subfolder `openblas\bin` to Windows environment variable `%PATH%`. 86 | 87 | The BLAS and LAPACK are now ready to use. 88 | 89 | **Remark** It is also possible to download the Intel MKL library through the framework https://github.com/oneapi-src/oneMKL or the `Intel website `_. However, this implementation features different header names and requires a modification of the source files of **castor** (namely replace `cblas.h` by `mkl_cblas.h` wherever it appears). For this reason, we do not insist further. 90 | 91 | VTK framework 92 | ------------- 93 | 94 | Unfortunately, the developers of the VTK framework do not provide *ready-to-use* binaries meaning that we must compile the sources by ourselves. It is performed as follows: 95 | 96 | 1. Download the sources of VTK on the main website `https://vtk.org `_. Choose a version of the `9.x.x` branch. Uncompress the archive in a folder of your choice. 97 | 2. Open the `x64 Native Tools Command Prompt` and move to the newly created VTK folder (use the `dir pathToFolder` command). Create a *build* folder using `mkdir build` and move to this folder. 98 | 3. Execute `cmake-gui ..` which should open the CMake graphical interface. Click on `Configure`, choose the `ninja` generator and keep the default configuration. Finally, click on `Generate`. CMake will generate the build files. 99 | 4. Go back to the command prompt and execute the command `ninja`. The compilation of VTK begins and *may* take some time (a few minutes to a few dozen of minutes depending on the computer). 100 | 5. Once the compilation is over, execute `ninja install` which will install the library in the default directory `C:\Program Files (x86)\VTK`. 101 | 6. The last step is to add the subfolder `C:\Program Files (x86)\VTK\bin` to the Windows `%PATH%` environment variable. 102 | 103 | The installation of VTK is now completed. 104 | 105 | Compile the demos 106 | ----------------- 107 | 108 | In this section, we will give the instructions on how to compile the examples of castor. The steps are the following: 109 | 110 | 1. Download the sources of **castor** from the `main repo `_. 111 | 2. Open the `x64 Native Tools Command Prompt` and got to the `castor` folder. Create a `castor\build` directory and move to it. 112 | 3. Execute `cmake-gui ..` and click on the `Configure` button. Choose the `ninja` generator on the list and let all other options by default. This last operation *should fail* as CMake cannot find BLAS/LAPACK nor VTK. 113 | 4. In the list of CMake variables, look for `VTK_DIR` and set it to the `VTK\lib\cmake\vtk-9.x` folder. Do the same for the BLAS-related variables. Look for the variable `CBLAS_INCLUDE_DIR` and set it to the `openblas\include`subfolder. 114 | 5. Click again on `Configure` then on `Generate`. 115 | 6. Finally, execute `ninja` in the command prompt to start building the demo executable. The corresponding file can then be found in the `castor\build\demo` subfolder. 116 | -------------------------------------------------------------------------------- /demo/demo_smatrix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | +========================================================================+ 3 | | (c) 2020 - PROPERTY OF ECOLE POLYTECHNIQUE - LGPL 3.0 | 4 | |________________________________________________________________________| 5 | | '&` | | 6 | | # | FILE : demo_smatrix.cpp | 7 | | # | VERSION : 1.0.0 | 8 | | _#_ | AUTHOR(S) : Matthieu Aussal | 9 | | ( # ) | CREATION : 01.04.2020 | 10 | | / 0 \ | LAST MODIF : 31.10.2020 | 11 | | ( === ) | SYNOPSIS : Overview of sparse matrix operations | 12 | | `---' | | 13 | +========================================================================+ 14 | */ 15 | 16 | #include "castor/matrix.hpp" 17 | #include "castor/smatrix.hpp" 18 | 19 | using namespace castor; 20 | 21 | int main (int argc, char* argv[]) 22 | { 23 | //=============================================================== 24 | std::cout << "+=====================+" << std::endl; 25 | std::cout << "| INITIALIZE |" << std::endl; 26 | std::cout << "+=====================+" << std::endl; 27 | 28 | // Documentation 29 | documentationFiles = 30 | { 31 | "/usr/local/include/castor/matrix.hpp", 32 | "/usr/local/include/castor/smatrix.hpp" 33 | }; 34 | help("smatrix"); 35 | 36 | //=============================================================== 37 | std::cout << "+=====================+" << std::endl; 38 | std::cout << "| INTERNAL |" << std::endl; 39 | std::cout << "+=====================+" << std::endl; 40 | 41 | // Constructors 42 | smatrix s; 43 | disp(s); 44 | s = 1; 45 | disp(s); 46 | smatrix<> As = {1,2,3}; 47 | disp(As); 48 | As = {{1,2,3},{4,5,6}}; 49 | disp(As); 50 | As = smatrix<>(3,4); 51 | disp(As); 52 | As = smatrix<>(3,4,5); 53 | disp(As); 54 | As = smatrix<>(2,3,{1,0,3,2,5,4},std::vector({0.,0.,1.,2.,0.,3.})); 55 | disp(As); 56 | As = smatrix<>(2,3,{0,0,1,1},{0,1,0,1},std::vector({1,0,0,2})); 57 | disp(As); 58 | As = M_PI*eye(3,4); 59 | disp(As); 60 | smatrix Bs = As; 61 | disp(Bs); 62 | 63 | // Operators 64 | As = speye(2,3); 65 | disp(As); 66 | As += 1; 67 | disp(As); 68 | As += spones(2,3); 69 | disp(As); 70 | As -= 1; 71 | disp(As); 72 | As -= spones(2,3); 73 | disp(As); 74 | As *= 2; 75 | disp(As); 76 | As *= 2*spones(2,3); 77 | disp(As); 78 | As /= 2; 79 | disp(As); 80 | As /= 2*spones(2,3); 81 | disp(As); 82 | 83 | // As(l) and As(i,j) const 84 | smatrix<>const Fs(3,3,{1,1},{0,2},std::vector({1,1})); 85 | disp(Fs); 86 | disp(Fs(0,0)); 87 | disp(Fs(2,2)); 88 | disp(Fs(1,0)); 89 | disp(Fs(1,1)); 90 | disp(Fs(1,2)); 91 | disp(Fs); 92 | 93 | // As(l) and As(i,j) non const 94 | Bs = zeros(3,3); 95 | Bs(1,0) = 1; 96 | Bs(1,2) = 3; 97 | Bs(1,1) = 2; 98 | Bs(0,0) = 1; 99 | Bs(0,1) = 2; 100 | Bs(2,1) = 2; 101 | Bs(2,2) = 3; 102 | disp(Bs,2,std::cout,10); 103 | disp(Bs(0,2)); 104 | disp(Bs(1,0)); 105 | disp(Bs,2,std::cout,10); 106 | 107 | // As.ind(k) and As.val(k); 108 | Bs = speye(3,4); 109 | disp(Bs.ind(2)); 110 | disp(Bs.val(2)); 111 | 112 | // Tools 113 | int un = (int)s; 114 | disp(un); 115 | Bs = reshape(colon(1,12),3,4); 116 | Bs.reshape(4,3); 117 | disp(Bs); 118 | Bs.clear(); 119 | disp(Bs); 120 | Bs = zeros(2,2); 121 | Bs(2) = 0; Bs(0) = 1; Bs(3) = 2; Bs(1) = 0; 122 | disp(Bs); 123 | check(Bs); 124 | disp(Bs); 125 | 126 | // Complex 127 | smatrix> Zs = ones(2,3) + M_1I*ones(2,3); 128 | Zs(1) = 0; 129 | check(Zs); 130 | disp(Zs); 131 | 132 | //=============================================================== 133 | std::cout << "+=====================+" << std::endl; 134 | std::cout << "| EXTERNAL |" << std::endl; 135 | std::cout << "+=====================+" << std::endl; 136 | 137 | // Builders (m,n) 138 | disp(speye(3,4)); 139 | disp(spones(3,4)); 140 | disp(sprand(3,4)); 141 | disp(spzeros(3,4)); 142 | 143 | // Builders {m,n} 144 | disp(speye({3,4})); 145 | disp(spones({3,4})); 146 | disp(sprand({3,4})); 147 | disp(spzeros({3,4})); 148 | 149 | // Dimensions 150 | disp(size(speye(3,4))); 151 | disp(size(speye(3,4),1)); 152 | disp(size(speye(3,4),2)); 153 | disp(numel(speye(3,4))); 154 | disp(length(speye(3,4))); 155 | disp(nnz(speye(3,4))); 156 | 157 | // Transformation 158 | disp(full(speye(3,4))); 159 | disp(sparse(eye(3,4))); 160 | smatrix<> Ms = reshape(colon(1,12),3,4); 161 | disp(full(reshape(Ms,4,3))); 162 | disp(full(transpose(Ms))); 163 | clear(Ms); 164 | disp(Ms); 165 | 166 | // Operator+ 167 | disp(1+speye(2,3)); 168 | disp(speye(2,3)+1); 169 | disp(speye(2,3)+ones(2,3)); 170 | disp(ones(2,3)+speye(2,3)); 171 | disp(speye(2,3)+spones(2,3)); 172 | 173 | // Operator- 174 | disp(-speye(2,3)); 175 | disp(1-speye(2,3)); 176 | disp(speye(2,3)-1); 177 | disp(speye(2,3)-ones(2,3)); 178 | disp(ones(2,3)-speye(2,3)); 179 | disp(speye(2,3)-spones(2,3)); 180 | 181 | // Operator* 182 | disp(2*speye(2,3)); 183 | disp(speye(2,3)*2); 184 | disp(speye(2,3)*(2*ones(2,3))); 185 | disp((2*ones(2,3))*speye(2,3)); 186 | disp(speye(2,3)*(2*speye(2,3))); 187 | 188 | // Operator/ 189 | disp(2/speye(2,3)); 190 | disp(speye(2,3)/2); 191 | disp(speye(2,3)/(2*ones(2,3))); 192 | disp((2*ones(2,3))/speye(2,3)); 193 | disp(speye(2,3)/(2*speye(2,3))); 194 | 195 | // Sparse Full product 196 | matrix<> A=rand(4,3), B=rand(3,4); 197 | A = vertcat(A,zeros(1,3)); 198 | B = horzcat(zeros(3,1),B); 199 | matrix<> C=mtimes(A,B); 200 | disp(norm(mtimes(sparse(A),B)-C,"inf")); 201 | disp(norm(mtimes(A,sparse(B))-C,"inf")); 202 | disp(norm(mtimes(sparse(A),sparse(B))-C,"inf")); 203 | 204 | // Sparse to (bi-) linear index and values 205 | Ms = speye(3); 206 | disp(values(Ms)); 207 | disp(index(Ms)); 208 | matrix<> V; 209 | As = speye(3,4); 210 | As(2,3) = 1; 211 | matrix I, J; 212 | std::tie(I,J,V) = find(As); 213 | disp(full(sparse(I,J,V))); 214 | 215 | // Gmres 216 | As = speye(100) + 1e-3*rand(100); 217 | B = rand(100,4); 218 | matrix<> X = gmres(As,B); 219 | disp(norm(mtimes(As,X)-B,"inf")); 220 | smatrix<> Asm1 = gmres(As,eye(100)); 221 | X = gmres(As,B,1e-3,10,Asm1,X); 222 | disp(norm(mtimes(As,X)-B,"inf")); 223 | 224 | // Linsolve 225 | X = linsolve(As,B); 226 | disp(norm(mtimes(As,X)-B,"inf")); 227 | 228 | // Spdiags 229 | matrix<> e = reshape(colon(1,9),3,3); 230 | disp(full(spdiags(e,{-2,0,2},3,6))); 231 | disp(full(spdiags(e,{-2,0,2},3,3))); 232 | disp(full(spdiags(e,{-2,0,2},6,3))); 233 | 234 | //=============================================================== 235 | std::cout << "+=================+" << std::endl; 236 | std::cout << "| VIEW |" << std::endl; 237 | std::cout << "+=================+" << std::endl; 238 | 239 | matrix L; 240 | I = {0,1,0,1}; 241 | J = {1,2,2,1,0}; 242 | L = {{5,2,0},{5,4,5}}; 243 | 244 | As = matrix<>({{0,1,2},{3,4,5}}); 245 | disp(full(As)); 246 | 247 | Bs = get(As,L); 248 | disp(full(Bs)); 249 | 250 | Bs = get(As,I,J); 251 | disp(full(Bs)); 252 | 253 | As = spones(2,3); 254 | L = all(As); 255 | set(As,L,2*speye(1,6)); 256 | disp(full(As)); 257 | 258 | As = spones(2,3); 259 | I = row(As); 260 | J = col(As); 261 | set(As,I,J,2*speye(2,3)); 262 | disp(full(As)); 263 | 264 | As = spones(2,3); 265 | Bs = 2*speye(2,3); 266 | disp(eval(Bs(L))); 267 | disp(eval(Bs(I,J))); 268 | 269 | As = spones(2,3); 270 | As(L) = eval(Bs(L)); 271 | disp(As); 272 | 273 | As = spones(2,3); 274 | As(I,J) = eval(Bs(I,J)); 275 | disp(As); 276 | 277 | smatrix<>const Gs = 2*speye(2,3); 278 | disp(eval(Gs(L))); 279 | disp(eval(Gs(I,J))); 280 | 281 | As = ones(4,4); 282 | As({3,1,2},{3,1,2}) = smatrix<>(diag({1,2,3})); 283 | disp(full(As)); 284 | disp(full(eval(As({3,1,2},{3,1,2})))); 285 | 286 | //=============================================================== 287 | std::cout << "+=================+" << std::endl; 288 | std::cout << "| PERFO |" << std::endl; 289 | std::cout << "+=================+" << std::endl; 290 | 291 | As = eye(1e2); 292 | Bs = rand(1e2); 293 | tic(); 294 | smatrix<> Ds = mtimes(As,Bs); 295 | toc(); 296 | disp(norm(full(Ds)-full(Bs),"inf")); 297 | 298 | 299 | disp("done !"); 300 | return 0; 301 | } 302 | -------------------------------------------------------------------------------- /doc/source/graphics.rst: -------------------------------------------------------------------------------- 1 | .. role:: red 2 | 3 | .. _label-graphics-advanced: 4 | 5 | Plotting and much more 6 | ====================== 7 | 8 | We describe here some aspects of the **graphics** library available within the **castor** project. It is based on the well-known `VTK library `_ which must be installed by the user. Depending on the operating system, binary files *may* be directly available. However, one should pay attention to the fact that it is only compatible with version 9.x. 9 | 10 | After installing VTK (see :ref:`label-installation`), the user only needs to include the ``castor/graphics.hpp`` header file. 11 | 12 | The path is very close to the one chosen by `Matlab `_ or `Matplotlib `_ (for the Python language). First, the user creates a ``figure`` which is a container which will hold the plots. Then,he adds one or multiple plots to the ``figure``. Finally, he asks the system to display the figures (one window per ``figure`` will be created) with the ``drawnow(...)`` function. Each call to ``drawnow`` displays **all** the ``figure`` objects which have been defined since the last call. 13 | 14 | 15 | .. warning:: 16 | Each call to ``drawnow`` is **blocking**, meaning that it will suspend the execution of the program until all the opened ``figure`` are closed. 17 | This behavior cannot be modified as it is due to VTK. 18 | 19 | On Windows and linux, when the opened ``figure`` are closed, the program stops. A workaround consists in to call the `drawnow`` function at the end 20 | of the program. 21 | 22 | The **graphics** library features 2D/3D customizable plotting and basic triangular/tetrahedral mesh generation. We detail the use of some of these features below. The demo files may be found in the ``demo/demo_graphics/`` subfolder. 23 | 24 | It is possible to **interact with the figures** in multiple ways: 25 | 26 | - "right-click and hold" : *rotate the content* in the direction of the mouse-pointer for **3D** figures. For **2D** plots, the user can use it to drag the plots in the direction of choice. 27 | 28 | - "middle-click and hold": *translate the content* in the direction of the mouse-pointer. 29 | 30 | - "left-click and hold": *zoom-in* if the pointer is in the upper window, otherwise *zoom-out*. 31 | 32 | - "key-pressed **e** or **q**": close window. **Warning:** in some systems, it closes *all* windows. 33 | 34 | - "key-pressed **r**": resets the view. 35 | 36 | - "key-pressed **w**": switches to *wireframe* view when applicable. 37 | 38 | - "key-pressed **s**": switches to *surface* view when applicable. 39 | 40 | We advise the user to experiment with the different features mentioned above. The summary of all the available functions is available at :ref:`label-basic-plot`, :ref:`label-graphical-io`, :ref:`label-graphical-tools`, :ref:`label-mesh-management` and :ref:`label-mesh-plot`. 41 | 42 | 43 | Basic 2D plotting 44 | ----------------- 45 | 46 | In this example, we will plot a *sine* and a *square root* function with different styles but on the same display. First, we initialize some data and we create a ``figure`` object. The full code is available at ``demo/demo_graphics/basic.cpp``. 47 | 48 | .. code:: c++ 49 | 50 | matrix<> X = linspace(0,10,100); 51 | matrix<> Y = cos(X); 52 | figure fig; 53 | 54 | Then, we add our first plot as a red solid line with diamond markers with the correct legend. 55 | 56 | .. code:: c++ 57 | 58 | plot(fig,X,Y,{"r-d"},{"sin(x)"}); 59 | 60 | 61 | Now we create a second set of data, reusing the already-defined variables. This is possible because the inputs are copied. This time, we plot it as a simple dotted blue line. 62 | 63 | .. code:: c++ 64 | 65 | X = linspace(-2,2,30); 66 | Y = sqrt(X); 67 | plot(fig,X,Y,{"b"},{"sqrt(x)"}); 68 | // display 69 | drawnow(fig); 70 | 71 | The figure should look like this: 72 | 73 | .. image:: img/basic.png 74 | :width: 400 75 | :align: center 76 | 77 | **Remark:** Currently, it is not possible to save the output to a graphic file. 78 | 79 | Surface plot 80 | ------------ 81 | 82 | Surface plotting consists in plotting a surface defined by the equation ``Z = f(X,Y)``. First we create the *grid* (X,Y). The full code is available at ``demo/demo_graphics/surface_plot.cpp``. 83 | 84 | .. code:: c++ 85 | 86 | matrix<> X,Y; 87 | std::tie(X,Y) = meshgrid(linspace(-M_PI,M_PI,100)); 88 | 89 | Then, we create the surface which we want to plot, create a ``figure``, adjust the color axis and display everything. 90 | 91 | .. code:: c++ 92 | 93 | matrix<> Z = 2*sin(X)/X * sin(Y)/Y; 94 | // create the figure 95 | figure fig; 96 | caxis(fig,{-1,1}); // scaled color in the range [-1,1] 97 | mesh(fig,X,Y,Z); 98 | // display 99 | drawnow(fig); 100 | 101 | The result is a 3-dimensional plot which should look like this : 102 | 103 | .. image:: img/surface_plot_wireframe.png 104 | :width: 400 105 | :align: center 106 | 107 | **TIP:** It is possible to switch to a full *surface* plot by pressing the **s** key and switch back to a *wireframe* display by pressing the **w** key. 108 | 109 | .. image:: img/surface_plot_surface.png 110 | :width: 400 111 | :align: center 112 | 113 | Displaying nodal values 114 | ----------------------- 115 | 116 | This feature is particularly useful if, for example, one needs to display the result of a finite element computation where the data is known at the vertices. In the following example, we create a planar mesh with triangular elements. Then we define a linearly increasing nodal data along the *x*-axis. The full code is available at ``demo/demo_graphics/nodal_values.cpp``. 117 | 118 | .. code:: c++ 119 | 120 | // geometric data 121 | matrix<> X,Y; 122 | std::tie(X,Y) = meshgrid(linspace(-1,1,10),linspace(-1,1,5)); 123 | X = vertcat(X,X); 124 | Y = vertcat(Y,Y); 125 | matrix<> Z = zeros(size(X)); 126 | 127 | // create mesh 128 | matrix<> vtx; 129 | matrix elt; 130 | std::tie(elt,vtx) = tridelaunay(X,Y,Z); 131 | 132 | // display 133 | figure fig; 134 | trimesh(fig,elt,vtx,eval(vtx(row(vtx),0))); 135 | drawnow(fig); 136 | 137 | The result should look like this: 138 | 139 | .. image:: img/nodal_values.png 140 | :width: 400 141 | :align: center 142 | 143 | 144 | From mesh generation to file output 145 | ----------------------------------- 146 | 147 | In this example, we create a spherical mesh and compute the normals to the triangles. We plot both on the same figure. Finally, we save the mesh to a *.ply* file. We also illustrate the use of the :ref:`label-quiver` function. The full code is available at ``demo/demo_graphics/advanced_mesh.cpp``. 148 | 149 | First, we create the mesh using the :ref:`label-sphere2` function which creates a Fibonacci sphere. 150 | 151 | .. code:: c++ 152 | 153 | std::size_t nvtx=100; 154 | // 1. Create the mesh 155 | matrix<> vtx; 156 | matrix elt; 157 | 158 | matrix<> X,Y,Z; 159 | std::tie(X,Y,Z) = sphere2(nvtx); // Fibonacci sphere 160 | // Delaunay tetrahedrisation 161 | std::tie(elt,vtx) = tetdelaunay(X,Y,Z); 162 | // Boundary extraction 163 | std::tie(elt,vtx) = tetboundary(elt,vtx); 164 | 165 | Then, we compute the center ``ctr`` of the triangles and the normal vector ``nrm``. We recall that the coordinates of ``ctr`` are simply the averaged sum of the coordinates of the vertices of the triangles. The coordinates of ``nrm`` may be determined by computing the cross-product between the tangent of, two consecutive edges. In this example we normalize the length to 0.25 to get an equilibrated display. 166 | 167 | .. code:: c++ 168 | 169 | // 2. Compute the normal vectors and the centers of the triangles 170 | std::size_t nelt = size(elt,1); 171 | matrix<> nrm = zeros(nelt,3); 172 | matrix<> ctr = zeros(nelt,3); 173 | for(std::size_t ie=0; ie AB=zeros(1,3), BC=zeros(1,3), nv = zeros(1,3); 182 | for(std::size_t i=0; i<3; ++i) 183 | { 184 | // tangent to first edge 185 | AB(i) = vtx(elt(ie,1),i) - vtx(elt(ie,0),i); 186 | tangent to second edge 187 | BC(i) = vtx(elt(ie,2),i) - vtx(elt(ie,1),i); 188 | } 189 | // for single vectors, this code is faster than 190 | // a call to 'cross' (for the cross-product) or 'norm'. 191 | nv(0) = AB(1)*BC(2) - AB(2)*BC(1); 192 | nv(1) = AB(2)*BC(0) - AB(0)*BC(2); 193 | nv(2) = AB(0)*BC(1) - AB(1)*BC(0); 194 | double l = std::sqrt(nv(0)*nv(0)+nv(1)*nv(1)+nv(2)*nv(2)); 195 | // normalization 196 | for(std::size_t i=0; i<3; ++i) 197 | { 198 | nrm(ie,i) = nv(i)/(2*l); // arrows of length 0.5 199 | } 200 | } 201 | 202 | Now, we plot the result. 203 | 204 | .. code:: c++ 205 | 206 | // 3. Plot everything 207 | figure fig; 208 | trimesh(fig,elt,vtx); // plot the mesh 209 | quiver(fig,ctr,nrm); // plot the normal vectors at the centers 210 | drawnow(fig); 211 | 212 | Finally, save the mesh into the current directory in the *.ply* format. 213 | 214 | .. code:: c++ 215 | 216 | // 4. save to .ply 217 | std::string path="./", name="testfile.ply"; 218 | triwrite(path,name,elt,vtx); 219 | 220 | The result should look like an urchin, see below. **Please note that the normal vectors may not appear when the window appears. In that case, simply clicking inside the window should do the trick.** 221 | 222 | .. image:: img/advanced_mesh.png 223 | :width: 400 224 | :align: center 225 | -------------------------------------------------------------------------------- /doc/source/algorithm.rst: -------------------------------------------------------------------------------- 1 | .. _label-algorithms: 2 | 3 | Algorithms 4 | ++++++++++ 5 | 6 | Standard algorithms over data stored in matrices may be found here. Among *many* others, it is possible to :ref:`label-sort` a ``matrix``, find the :ref:`label-unique` elements, the :ref:`label-median` of the data, perform the :ref:`label-dot` product between two matrices, find the maximum value with :ref:`label-max`, etc. 7 | 8 | 9 | .. _label-argintersect: 10 | 11 | argintersect 12 | ------------ 13 | .. doxygenfunction:: argintersect 14 | :project: castor 15 | 16 | See :ref:`label-intersect`, :ref:`label-argsetdiff`, :ref:`label-argunique`. 17 | 18 | .. _label-argmax: 19 | 20 | argmax 21 | ------ 22 | .. doxygenfunction:: argmax(matrix const &A) 23 | :project: castor 24 | .. doxygenfunction:: argmax(matrix const &A, int dim) 25 | :project: castor 26 | 27 | See :ref:`label-max`, :ref:`label-maximum`, :ref:`label-argmin`, :ref:`label-argsort`. 28 | 29 | .. _label-argmin: 30 | 31 | argmin 32 | ------ 33 | .. doxygenfunction:: argmin(matrix const &A) 34 | :project: castor 35 | .. doxygenfunction:: argmin(matrix const &A, int dim) 36 | :project: castor 37 | 38 | See :ref:`label-min`, :ref:`label-minimum`, :ref:`label-argmax`, :ref:`label-argsort`. 39 | 40 | .. _label-argsetdiff: 41 | 42 | argsetdiff 43 | ---------- 44 | .. doxygenfunction:: argsetdiff 45 | :project: castor 46 | 47 | See :ref:`label-setdiff`, :ref:`label-argintersect`, :ref:`label-argunique`. 48 | 49 | .. _label-argsort: 50 | 51 | argsort 52 | ------- 53 | .. doxygenfunction:: argsort 54 | :project: castor 55 | 56 | See :ref:`label-sort`, :ref:`label-argmin`, :ref:`label-argmax`. 57 | 58 | .. _label-argunique: 59 | 60 | argunique 61 | --------- 62 | .. doxygenfunction:: argunique 63 | :project: castor 64 | 65 | See :ref:`label-unique`, :ref:`label-argsetdiff`, :ref:`label-argintersect`. 66 | 67 | .. _label-conv: 68 | 69 | conv 70 | ---- 71 | .. doxygenfunction:: conv 72 | :project: castor 73 | 74 | See :ref:`label-fftconv`. 75 | 76 | .. _label-cross: 77 | 78 | cross 79 | ----- 80 | .. doxygenfunction:: cross 81 | :project: castor 82 | 83 | See :ref:`label-dot`. 84 | 85 | .. _label-cumprod: 86 | 87 | cumprod 88 | ------- 89 | .. doxygenfunction:: cumprod(matrix const &A) 90 | :project: castor 91 | .. doxygenfunction:: cumprod(matrix const &A, int dim) 92 | :project: castor 93 | 94 | See :ref:`label-cumsum`, :ref:`label-prod`. 95 | 96 | .. _label-cumsum: 97 | 98 | cumsum 99 | ------ 100 | .. doxygenfunction:: cumsum(matrix const &A) 101 | :project: castor 102 | .. doxygenfunction:: cumsum(matrix const &A, int dim) 103 | :project: castor 104 | 105 | See :ref:`label-cumprod`, :ref:`label-sum`. 106 | 107 | .. _label-diff: 108 | 109 | diff 110 | ---- 111 | .. doxygenfunction:: diff(matrix const &A) 112 | :project: castor 113 | .. doxygenfunction:: diff(matrix const &A, int dim) 114 | :project: castor 115 | 116 | See :ref:`label-sum`, :ref:`label-prod`. 117 | 118 | .. _label-dot: 119 | 120 | dot 121 | --- 122 | .. doxygenfunction:: dot 123 | :project: castor 124 | 125 | See :ref:`label-cross`. 126 | 127 | .. _label-fftconv: 128 | 129 | fftconv 130 | ------- 131 | .. doxygenfunction:: fftconv 132 | :project: castor 133 | 134 | See :ref:`label-conv`, :ref:`label-fft`. 135 | 136 | 137 | .. _label-gmres: 138 | 139 | gmres 140 | ----- 141 | .. doxygenfunction:: gmres(matrix const &A, matrix const &B, double tol = 1e-6, std::size_t maxit = 10, std::function(matrix const&)> const &Am1 = std::function(matrix const&)>(), matrix const &X0 = matrix()) 142 | :project: castor 143 | .. doxygenfunction:: gmres(matrix const &A, matrix const &B, double tol, std::size_t maxit, matrix const &Am1, matrix const &X0 = matrix()) 144 | :project: castor 145 | .. doxygenfunction:: gmres(std::function(matrix const&)> const &A, matrix const &B, double tol = 1e-6, std::size_t maxit = 10, std::function(matrix const&)> const &Am1 = std::function(matrix const&)>(), matrix const &X0 = matrix()) 146 | :project: castor 147 | 148 | 149 | 150 | See :ref:`label-linsolve`. 151 | 152 | .. _label-intersect: 153 | 154 | intersect 155 | --------- 156 | .. doxygenfunction:: intersect 157 | :project: castor 158 | 159 | See :ref:`label-argintersect`, :ref:`label-setdiff`, :ref:`label-unique`, :ref:`label-union2`. 160 | 161 | .. _label-kron: 162 | 163 | kron 164 | ---- 165 | .. doxygenfunction:: kron(R A, matrix const &B) 166 | :project: castor 167 | .. doxygenfunction:: kron(matrix const &A, S B) 168 | :project: castor 169 | .. doxygenfunction:: kron(matrix const &A, matrix const &B) 170 | :project: castor 171 | 172 | See :ref:`label-mtimes`. 173 | 174 | .. _label-max: 175 | 176 | max 177 | --- 178 | .. doxygenfunction:: max(matrix const &A) 179 | :project: castor 180 | .. doxygenfunction:: max(matrix const &A, int dim) 181 | :project: castor 182 | 183 | See :ref:`label-argmax`, :ref:`label-maximum`, :ref:`label-min`, :ref:`label-sort`. 184 | 185 | .. _label-min: 186 | 187 | min 188 | --- 189 | .. doxygenfunction:: min(matrix const &A) 190 | :project: castor 191 | .. doxygenfunction:: min(matrix const &A, int dim) 192 | :project: castor 193 | 194 | See :ref:`label-argmin`, :ref:`label-minimum`, :ref:`label-max`, :ref:`label-sort`. 195 | 196 | .. _label-maximum: 197 | 198 | maximum 199 | ------- 200 | .. doxygenfunction:: maximum(R A, matrix const &B) 201 | :project: castor 202 | .. doxygenfunction:: maximum(matrix const &A, S B) 203 | :project: castor 204 | .. doxygenfunction:: maximum(matrix const &A, matrix const &B) 205 | :project: castor 206 | 207 | See :ref:`label-minimum`, :ref:`label-max`, :ref:`label-min`, :ref:`label-sort`. 208 | 209 | .. _label-mean: 210 | 211 | mean 212 | ---- 213 | .. doxygenfunction:: mean(matrix const &A) 214 | :project: castor 215 | .. doxygenfunction:: mean(matrix const &A, int dim) 216 | :project: castor 217 | 218 | See :ref:`label-max`, :ref:`label-min`, :ref:`label-median`, :ref:`label-variance`, :ref:`label-stddev`. 219 | 220 | .. _label-median: 221 | 222 | median 223 | ------ 224 | .. doxygenfunction:: median(matrix const &A) 225 | :project: castor 226 | .. doxygenfunction:: median(matrix const &A, int dim) 227 | :project: castor 228 | 229 | See :ref:`label-max`, :ref:`label-min`, :ref:`label-variance`, :ref:`label-stddev`. 230 | 231 | .. _label-minimum: 232 | 233 | minimum 234 | ------- 235 | .. doxygenfunction:: minimum(R A, matrix const &B) 236 | :project: castor 237 | .. doxygenfunction:: minimum(matrix const &A, S B) 238 | :project: castor 239 | 240 | .. doxygenfunction:: minimum(matrix const &A, matrix const &B) 241 | :project: castor 242 | 243 | See :ref:`label-maximum`, :ref:`label-min`, :ref:`label-max` :ref:`label-sort`. 244 | 245 | .. _label-mtimes: 246 | 247 | mtimes 248 | ------ 249 | .. doxygenfunction:: mtimes(R A, matrix const &B) 250 | :project: castor 251 | .. doxygenfunction:: mtimes(matrix const &A, S B) 252 | :project: castor 253 | .. doxygenfunction:: mtimes(matrix const &A, matrix const &B) 254 | :project: castor 255 | 256 | See :ref:`label-tgemm-naive`, :ref:`label-kron`. 257 | 258 | .. _label-norm: 259 | 260 | norm 261 | ---- 262 | .. doxygenfunction:: norm(matrix const &A, std::string typ = "2") 263 | :project: castor 264 | .. doxygenfunction:: norm(matrix const &A, std::string typ, int dim) 265 | :project: castor 266 | 267 | See :ref:`label-max`, :ref:`label-sum`. 268 | 269 | .. _label-prod: 270 | 271 | prod 272 | ---- 273 | .. doxygenfunction:: prod(matrix const &A) 274 | :project: castor 275 | .. doxygenfunction:: prod(matrix const &A, int dim) 276 | :project: castor 277 | 278 | See :ref:`label-sum`, :ref:`label-diff`. 279 | 280 | .. _label-setdiff: 281 | 282 | setdiff 283 | ------- 284 | .. doxygenfunction:: setdiff 285 | :project: castor 286 | 287 | See :ref:`label-argsetdiff`, :ref:`label-intersect`, :ref:`label-unique`, :ref:`label-union2`. 288 | 289 | .. _label-sort: 290 | 291 | sort 292 | ---- 293 | .. doxygenfunction:: sort 294 | :project: castor 295 | 296 | See :ref:`label-argsort`, :ref:`label-min`, :ref:`label-max`. 297 | 298 | .. _label-stddev: 299 | 300 | stddev 301 | ------ 302 | .. doxygenfunction:: stddev(matrix const &A) 303 | :project: castor 304 | .. doxygenfunction:: stddev(matrix const &A, int dim) 305 | :project: castor 306 | 307 | See :ref:`label-max`, :ref:`label-min`, :ref:`label-mean`, :ref:`label-median`, :ref:`label-variance`. 308 | 309 | .. _label-sum: 310 | 311 | sum 312 | --- 313 | .. doxygenfunction:: sum(matrix const &A) 314 | :project: castor 315 | .. doxygenfunction:: sum(matrix const &A, int dim) 316 | :project: castor 317 | 318 | See :ref:`label-prod`, :ref:`label-diff`, :ref:`label-cumsum`. 319 | 320 | 321 | .. _label-tgemm-naive: 322 | 323 | tgemm 324 | ----- 325 | .. doxygenfunction:: tgemm(P alpha, matrix const &A, matrix const &B, S beta, matrix &C) 326 | :project: castor 327 | 328 | 329 | See :ref:`label-mtimes`, :ref:`label-tgemm-blas`. 330 | 331 | .. _label-union2: 332 | 333 | union2 334 | ------ 335 | .. doxygenfunction:: union2 336 | :project: castor 337 | 338 | See :ref:`label-intersect`, :ref:`label-setdiff`, :ref:`label-unique`. 339 | 340 | .. _label-unique: 341 | 342 | unique 343 | ------ 344 | .. doxygenfunction:: unique 345 | :project: castor 346 | 347 | See :ref:`label-argunique`, :ref:`label-intersect`, :ref:`label-setdiff`, :ref:`label-union2`. 348 | 349 | .. _label-variance: 350 | 351 | variance 352 | -------- 353 | .. doxygenfunction:: variance(matrix const &A) 354 | :project: castor 355 | .. doxygenfunction:: variance(matrix const &A, int dim) 356 | :project: castor 357 | 358 | See :ref:`label-max`, :ref:`label-min`, :ref:`label-median`, :ref:`label-mean`, :ref:`label-stddev`. 359 | -------------------------------------------------------------------------------- /demo/demo_graphics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | +========================================================================+ 3 | | (c) 2020 - PROPERTY OF ECOLE POLYTECHNIQUE - LGPL 3.0 | 4 | |________________________________________________________________________| 5 | | '&` | | 6 | | # | FILE : demo_graphics.cpp | 7 | | # | VERSION : 1.0.0 | 8 | | _#_ | AUTHOR(S) : Matthieu Aussal | 9 | | ( # ) | CREATION : 01.04.2020 | 10 | | / 0 \ | LAST MODIF : 31.10.2020 | 11 | | ( === ) | SYNOPSIS : Running test for VTK interface | 12 | | `---' | | 13 | +========================================================================+ 14 | */ 15 | 16 | #include "castor/matrix.hpp" 17 | #include "castor/smatrix.hpp" 18 | #include "castor/graphics.hpp" 19 | 20 | using namespace castor; 21 | 22 | int main (int argc, char* argv[]) 23 | { 24 | //=============================================================== 25 | std::cout << "+=====================+" << std::endl; 26 | std::cout << "| INITIALIZE |" << std::endl; 27 | std::cout << "+=====================+" << std::endl; 28 | 29 | // Documentation 30 | documentationFiles = 31 | { 32 | "/usr/local/include/castor/matrix.hpp", 33 | "/usr/local/include/castor/graphics.hpp" 34 | }; 35 | help("plot"); 36 | 37 | //=============================================================== 38 | std::cout << "+=====================+" << std::endl; 39 | std::cout << "| PLOT |" << std::endl; 40 | std::cout << "+=====================+" << std::endl; 41 | 42 | figure fig; 43 | matrix<> X = linspace(0,10,100); 44 | matrix<> Y = cat(1,cos(X),sin(X)); 45 | plot(fig,X,Y,{"k","r-"},{"cos(X)","sin(X)"}); 46 | X = linspace(-2,2,30); 47 | plot(fig,X,sqrt(X),{"bx-"}); 48 | plot(fig,X,X/2); 49 | plot(fig,{10},{1}); 50 | xlim(fig,{-4,10}); 51 | ylim(fig,{-2,2}); 52 | 53 | //=============================================================== 54 | std::cout << "+=====================+" << std::endl; 55 | std::cout << "| PLOT3 |" << std::endl; 56 | std::cout << "+=====================+" << std::endl; 57 | 58 | X = linspace(-1,1,10); 59 | Y = X; 60 | matrix<> Z = X; 61 | figure fig2; 62 | plot3(fig2,X,Y,Z,"-r"); 63 | plot3(fig2,X,zeros(size(Y)),zeros(size(Z)),"b"); 64 | 65 | //=============================================================== 66 | std::cout << "+=======================+" << std::endl; 67 | std::cout << "| IMAGESC |" << std::endl; 68 | std::cout << "+=======================+" << std::endl; 69 | 70 | matrix<> M = linspace(-1,1,100); 71 | M = reshape(M,5,20); 72 | figure fig3; 73 | imagesc(fig3,M); 74 | 75 | //=============================================================== 76 | std::cout << "+=======================+" << std::endl; 77 | std::cout << "| SPY |" << std::endl; 78 | std::cout << "+=======================+" << std::endl; 79 | 80 | smatrix<> Ms = speye(10,15); 81 | figure fig31; 82 | spy(fig31,Ms,"b","Ms"); 83 | 84 | //=============================================================== 85 | std::cout << "+=======================+" << std::endl; 86 | std::cout << "| MESH |" << std::endl; 87 | std::cout << "+=======================+" << std::endl; 88 | 89 | std::tie(X,Y) = meshgrid(linspace(-M_PI,M_PI,100)); 90 | Z = 2 * sin(X)/X * sin(Y)/Y; 91 | 92 | figure fig4; 93 | mesh(fig4,Z); 94 | 95 | figure fig5; 96 | caxis(fig5,{-1,1}); 97 | mesh(fig5,X,Y,Z); 98 | mesh(fig5,X,Y,-Z); 99 | 100 | //=============================================================== 101 | std::cout << "+=======================+" << std::endl; 102 | std::cout << "| VERMESH |" << std::endl; 103 | std::cout << "+=======================+" << std::endl; 104 | 105 | matrix elt = range(0,100); 106 | matrix<> vtx = -1+2*rand(numel(elt),3); 107 | figure fig6; 108 | vermesh(fig6,elt,vtx,eval(vtx(row(vtx),0))); 109 | 110 | //=============================================================== 111 | std::cout << "+=======================+" << std::endl; 112 | std::cout << "| EDGMESH |" << std::endl; 113 | std::cout << "+=======================+" << std::endl; 114 | 115 | elt = transpose(range(0,100)); 116 | elt = cat(2,elt,elt+1); 117 | elt(size(elt,1)-1,1) = 0; 118 | vtx = -1+2*rand(numel(elt),3); 119 | figure fig7; 120 | edgmesh(fig7,elt,vtx,eval(vtx(row(vtx),0))); 121 | 122 | //=============================================================== 123 | std::cout << "+=======================+" << std::endl; 124 | std::cout << "| TRIMESH |" << std::endl; 125 | std::cout << "+=======================+" << std::endl; 126 | 127 | // 2D grid with duplicate vertices 128 | std::tie(X,Y) = meshgrid(linspace(-1,1,10),linspace(-1,1,5)); 129 | X = vertcat(X,X); 130 | Y = vertcat(Y,Y); 131 | Z = zeros(size(X)); 132 | 133 | // Delaunay triangulation 134 | std::tie(elt,vtx) = tridelaunay(X,Y,Z); 135 | 136 | // Triangular mesh with vextex data 137 | figure fig8; 138 | trimesh(fig8,elt,vtx,eval(vtx(row(vtx),0))); 139 | 140 | //=============================================================== 141 | std::cout << "+=======================+" << std::endl; 142 | std::cout << "| TETMESH |" << std::endl; 143 | std::cout << "+=======================+" << std::endl; 144 | 145 | // 3D grid 146 | std::tie(X,Y) = meshgrid(linspace(-1,1,3)); 147 | X = vertcat(X,X); 148 | Y = vertcat(Y,Y); 149 | Z = vertcat(zeros(3),ones(3)); 150 | 151 | // Delaunay tetrahedrisation 152 | std::tie(elt,vtx) = tetdelaunay(X,Y,Z); 153 | 154 | // Tetrahedral mesh with vertex data 155 | figure fig9; 156 | tetmesh(fig9,elt,vtx,eval(vtx(row(vtx),0))); 157 | 158 | //=============================================================== 159 | std::cout << "+=======================+" << std::endl; 160 | std::cout << "| BOUNDARY MESH |" << std::endl; 161 | std::cout << "+=======================+" << std::endl; 162 | 163 | // Sphere grid 164 | std::tie(X,Y,Z) = sphere2(100); 165 | X = horzcat(0,reshape(X,1,numel(X))); 166 | Y = horzcat(0,reshape(Y,1,numel(Y))); 167 | Z = horzcat(0,reshape(Z,1,numel(Z))); 168 | 169 | // Delaunay tetrahedrisation 170 | std::tie(elt,vtx) = tetdelaunay(X,Y,Z); 171 | 172 | // Free boundary 173 | std::tie(elt,vtx) = tetboundary(elt,vtx); 174 | 175 | // Triangular mesh with vertex data 176 | figure fig10; 177 | trimesh(fig10,elt,vtx); 178 | 179 | //=============================================================== 180 | std::cout << "+=======================+" << std::endl; 181 | std::cout << "| TRIMESH I/O |" << std::endl; 182 | std::cout << "+=======================+" << std::endl; 183 | 184 | // Read .ply 185 | std::string path="./", name="testfile.ply"; 186 | triwrite(path,name,elt,vtx); 187 | std::tie(elt,vtx) = triread(path,name); 188 | 189 | // Read .vtk 190 | name="testfile.vtk"; 191 | triwrite(path,name,elt,vtx,rand(size(vtx,1),1)); 192 | std::tie(elt,vtx) = triread(path,name); 193 | 194 | // Display 195 | figure fig11; 196 | trimesh(fig11,elt,vtx); 197 | 198 | //=============================================================== 199 | std::cout << "+=======================+" << std::endl; 200 | std::cout << "| QUIVER |" << std::endl; 201 | std::cout << "+=======================+" << std::endl; 202 | 203 | matrix<> dir = vtx; 204 | figure fig12; 205 | trimesh(fig12,elt,vtx); 206 | quiver(fig12,vtx,dir); 207 | 208 | //=============================================================== 209 | std::cout << "+=======================+" << std::endl; 210 | std::cout << "| DRAWNOW |" << std::endl; 211 | std::cout << "+=======================+" << std::endl; 212 | 213 | drawnow(fig); 214 | 215 | //=============================================================== 216 | std::cout << "+=======================+" << std::endl; 217 | std::cout << "| IMAGE WRITE |" << std::endl; 218 | std::cout << "+=======================+" << std::endl; 219 | 220 | std::vector ext = {{""},{".png"},{".jpg"},{".ps"}, 221 | {".tiff"},{".bmp"},{".pnm"}}; 222 | for (int i=0; i source; 234 | vtkNew movie; 235 | movie->SetInputConnection(source->GetOutputPort()); 236 | movie->SetFileName("testfile.avi"); 237 | movie->SetQuality(1); // in [0,2] 238 | movie->SetRate(25); // frame per seconds 239 | 240 | // Recording frame by frame 241 | movie->Start(); 242 | for (int i = 0; i < 50; i++) 243 | { 244 | figure fig13; 245 | matrix<> X = linspace(0,10,100); 246 | matrix<> Y = cos(X+i/10.); 247 | plot(fig13,X,Y,{"r-x"}); 248 | source->SetInput(fig13.GetView()->GetRenderWindow()); 249 | source->SetInputBufferTypeToRGB(); 250 | source->ReadFrontBufferOff(); 251 | movie->Write(); 252 | } 253 | movie->End(); 254 | 255 | disp("done !"); 256 | return 0; 257 | } 258 | -------------------------------------------------------------------------------- /doc/source/eigenmode.rst: -------------------------------------------------------------------------------- 1 | Eigenmodes of Helmholtz 2 | ======================= 3 | 4 | *Shared by Antoine Rideau* 5 | 6 | On this page you will find how to show using **Castor** the eigenmodes of the wave equation on a rectangle with fixed edges. 7 | 8 | We start from the following D'Alembert equation on :math:`\Omega = \left [ 0, x_{0} \right ] \times \left [ 0, y_{0} \right ]` with Dirichlet boundary condition on :math:`\Gamma = \partial \Omega` 9 | 10 | .. math:: 11 | 12 | \left\{\begin{matrix} 13 | - \displaystyle \frac{1}{c} \frac{\partial^2 u }{\partial t^2}(\mathbf{x}) + \Delta u (\mathbf{x}) = 0 & , & \mathbf{x} \in \Omega \setminus \Gamma 14 | \\ 15 | u(\mathbf{x} , \cdot ) = 0 & , & \mathbf{x} \in \Gamma 16 | \end{matrix}\right. 17 | , 18 | 19 | considering 20 | 21 | .. math:: 22 | 23 | u (\mathbf{x},t) = V(\mathbf{x})e^{i \omega t} , 24 | 25 | gives the Helmholtz equation 26 | 27 | .. math:: 28 | 29 | \left\{\begin{matrix} 30 | k^{2}V(\mathbf{x}) + \Delta V(\mathbf{x}) = 0 & , & \mathbf{x} \in \Omega \setminus \Gamma 31 | \\ 32 | V(\mathbf{x}) = 0 & , & \mathbf{x} \in \Gamma 33 | \end{matrix}\right. 34 | , 35 | 36 | | with :math:`k = \displaystyle \frac{\omega}{c}` . 37 | | 38 | | The space domain ``L`` is discretized with ``dx`` steps which results in the meshgrid described by ``X`` and ``Y`` 39 | 40 | .. math:: 41 | 42 | \begin{matrix} x_{i} = i \delta x & \text{ for } i = \left [ \! \left [ 0, n_{x}-1 \right ] \! \right ]\\ y_{j} = j \delta x & \text{ for } j = \left [ \! \left [ 0, n_{y}-1 \right ] \! \right ] \end{matrix} 43 | 44 | .. code-block:: c++ 45 | 46 | // Parameters 47 | matrix<> L = {1, 2}; // Dimensions 48 | double dx = 0.05; // Space discretization 49 | 50 | // Discretization 51 | matrix<> X, Y; 52 | std::tie(X, Y) = meshgrid(colon(0, dx, L(0)), colon(0, dx, L(1))); 53 | 54 | See :ref:`label-meshgrid`. 55 | 56 | Laplacian 57 | --------- 58 | 59 | The Helmholtz equation can now be written in vector form 60 | 61 | .. math:: 62 | 63 | - K V(\mathbf{x}) = k^{2} V(\mathbf{x}) , 64 | 65 | where ``K`` stands for the matrix of the Laplacian operator. 66 | 67 | The Laplacian operator can be approximated as 68 | 69 | .. math:: 70 | 71 | \begin{matrix} 72 | \Delta_{\textbf{x}}u(x,y) & = & \displaystyle \frac{\partial^2 u}{\partial x^2}(x,y) + \frac{\partial^2 u}{\partial y^2}(x,y) 73 | \\ 74 | \Delta_{\textbf{x}}u_{i,j} & \approx & \displaystyle \frac{u_{i+1,j}+u_{i,j+1}-4u_{i,j}+u_{i-1,j}+u_{i,j-1}}{\delta_{\textbf{x}}^2} & . 75 | \end{matrix} 76 | 77 | 78 | 79 | This expression leads to this form for ``K`` 80 | 81 | .. math:: 82 | 83 | K = \frac{1}{\delta_{\textbf{x}}^2} \begin{pmatrix} 84 | -4 & 1 & 0 & \cdots & 0 & 1 & 0 & \cdots & 0\\ 85 | 1 & -4 & 1 & 0 & \cdots & 0 & 1 & \ddots & \vdots \\ 86 | 0 & 1 & \ddots & \ddots & \ddots & & \ddots & \ddots & 0\\ 87 | \vdots& \ddots & \ddots & -4 & 1 & 0 & & \ddots & 1\\ 88 | 0 & & 0 & 1 & -4 & 1 & 0 & & 0\\ 89 | 1& \ddots & & 0 & 1 & -4 & \ddots & \ddots & \vdots \\ 90 | 0 & \ddots & \ddots & & \ddots & \ddots & \ddots & 1 & 0 \\ 91 | \vdots& \ddots & 1 & 0 & \cdots & 0 & 1 & -4 & 1 \\ 92 | 0 & \cdots & 0 & 1 & 0 & \cdots & 0 & 1 & -4 93 | \end{pmatrix} 94 | . 95 | 96 | .. code-block:: c++ 97 | 98 | // Laplacian 99 | long nx = size(X, 2), ny = size(X, 1); 100 | matrix<> e = ones(nx * ny, 5); 101 | e(row(e), 2) = -4; 102 | matrix<> K = full(spdiags(1. / (dx * dx) * e, {-nx, -1, 0, 1, nx}, nx * ny, nx * ny)); 103 | 104 | See :ref:`label-spdiags` 105 | 106 | | Here, K is built as a sparse matrix using `spdiags` because it is easier to do so but I convert it into a dense matrix because **Castor** don't have a sparse solver yet. 107 | | 108 | | In order to take into account the homogeneous Dirichlet condition on the boundary, penalization is used on the index where the boundaries are : index ``i`` such as ``X(i)==0``, ``X(i)==L(0)``, ``Y(i)==0`` and ``Y(i)==L(1)`` . 109 | 110 | .. code-block:: c++ 111 | 112 | // Penalization on boundary (Homogeneous Dirichlet condition) 113 | matrix Ibnd; 114 | Ibnd = find((X == 0) || (X == L(0)) || (Y == 0) || (Y == L(1))); 115 | K(sub2ind(size(K), Ibnd, Ibnd)) = 1e6; 116 | 117 | See :ref:`label-find-smatrix`, :ref:`label-sub2ind`. 118 | 119 | Analytical solution 120 | ------------------- 121 | 122 | An eigenmodes is caracterize by 2 positive integers :math:`m` and :math:`n` . Thus the eigenvalues are 123 | 124 | .. math:: 125 | 126 | \lambda_{m,n} = c\pi \sqrt{\frac{m^2}{x_{0}}+\frac{n^2}{y_{0}}} 127 | 128 | and the corresponding eigenmode are 129 | 130 | .. math:: 131 | 132 | u_{m,n} = \sin \bigg(\frac{m\pi x}{x_{0}}\bigg) \sin \bigg(\frac{n\pi y}{y_{0}}\bigg) 133 | 134 | 135 | .. code-block:: c++ 136 | 137 | // Analytical 138 | auto Dth = zeros(nx, ny); 139 | for (int m = 0; m < nx; m++) 140 | { 141 | for (int n = 0; n < ny; n++) 142 | { 143 | Dth(m, n) = M_PI * sqrt(pow((m + 1) / L(0), 2) + pow((n + 1) / L(1), 2)); 144 | } 145 | } 146 | 147 | See :ref:`label-zeros` . 148 | 149 | Eigenmodes 150 | ----------- 151 | 152 | Once the Laplacian matrix have been built , eigenvalues are easily acquired in the ``1`` by ``nx*ny`` vector ``D`` and eigenvectors in the ``nx*ny`` by ``nx*ny`` matrix ``V`` using the ``eig`` function 153 | 154 | .. math:: 155 | 156 | - K V(\mathbf{x}) = D V(\mathbf{x}) 157 | 158 | .. code-block:: c++ 159 | 160 | // Numerical eigen values and vectors 161 | matrix> D, V; 162 | std::tie(D, V) = eig(-K, "right"); 163 | 164 | See :ref:`label-eig` . 165 | 166 | The eigenvalues considerated are these with an imaginary part null and a real part minimal. To do so eigenvalues and eigenvectors are sorted by ascending eigenvalues. 167 | 168 | .. code-block:: c++ 169 | 170 | // Sort 171 | matrix I; 172 | I = argsort(abs(real(D))); 173 | D = eval(D(I)); 174 | V = eval(V(row(V), I)); 175 | matrix Ith; 176 | Ith = argsort(Dth); 177 | Dth = eval(Dth(Ith)); 178 | 179 | See :ref:`label-argsort` , :ref:`label-row` . 180 | 181 | Then for each eigenmodes ``f`` , only the real part of the corresponding eigenvector is taken. 182 | 183 | .. code-block:: c++ 184 | 185 | // Visu 186 | std::vector
fig(5); 187 | for (int f = 0; f < fig.size(); f++) 188 | { 189 | matrix Z = reshape(real(eval(V(row(V), f))), size(X, 1), size(X, 2)); 190 | mesh(fig[f], X, Y, Z); 191 | } 192 | 193 | 194 | See :ref:`label-reshape` , :ref:`label-mesh` . 195 | 196 | Code 197 | ---- 198 | 199 | Here you have all the code at once : 200 | 201 | .. code-block:: c++ 202 | 203 | #include "castor/matrix.hpp" 204 | #include "castor/smatrix.hpp" 205 | #include "castor/linalg.hpp" 206 | #include "castor/graphics.hpp" 207 | 208 | using namespace castor; 209 | 210 | int main(int argc, char const *argv[]) 211 | { 212 | // Parameters 213 | matrix<> L = {1, 2}; // Dimensions 214 | double dx = 0.05; // Space discretization 215 | 216 | // Discretization 217 | matrix<> X, Y; 218 | std::tie(X, Y) = meshgrid(colon(0, dx, L(0)), colon(0, dx, L(1))); 219 | 220 | // Visu mesh 221 | figure fig1; 222 | mesh(fig1, X, Y, zeros(size(X))); 223 | 224 | // Laplacian 225 | long nx = size(X, 2), ny = size(X, 1); 226 | matrix<> e = ones(nx * ny, 5); 227 | e(row(e), 2) = -4; 228 | matrix<> K = full(spdiags(1. / (dx * dx) * e, {-nx, -1, 0, 1, nx}, nx * ny, nx * ny)); 229 | 230 | // Penalization on boundary (Homogeneous Dirichlet condition) 231 | matrix Ibnd; 232 | Ibnd = find((X == 0) || (X == L(0)) || (Y == 0) || (Y == L(1))); 233 | K(sub2ind(size(K), Ibnd, Ibnd)) = 1e6; 234 | 235 | // Analytical 236 | auto Dth = zeros(nx, ny); 237 | for (int m = 0; m < nx; m++) 238 | { 239 | for (int n = 0; n < ny; n++) 240 | { 241 | Dth(m, n) = M_PI * sqrt(pow((m + 1) / L(0), 2) + pow((n + 1) / L(1), 2)); 242 | } 243 | } 244 | 245 | // Numerical eigen values and vectors 246 | matrix> D, V; 247 | std::tie(D, V) = eig(-K, "right"); 248 | 249 | // Sort 250 | matrix I; 251 | I = argsort(abs(real(D))); 252 | D = eval(D(I)); 253 | V = eval(V(row(V), I)); 254 | matrix Ith; 255 | Ith = argsort(Dth); 256 | Dth = eval(Dth(Ith)); 257 | 258 | // Visu 259 | std::vector
fig(5); 260 | for (int f = 0; f < fig.size(); f++) 261 | { 262 | matrix Z = reshape(real(eval(V(row(V), f))), size(X, 1), size(X, 2)); 263 | mesh(fig[f], X, Y, Z); 264 | } 265 | 266 | // Results 267 | std::cout << "-- Numerical eigenvalues --" << endl; 268 | disp(sqrt(real(eval(D(range(0, fig.size()))))), 1, fig.size()); 269 | std::cout << "-- Analytical eigenvalues --" << endl; 270 | disp(eval(Dth(range(0, fig.size()))), 1, fig.size()); 271 | std::cout << "-- Relative errors --" << endl; 272 | auto errRelative = abs((sqrt(real(eval(D(range(0, fig.size()))))) - eval(Dth(range(0, fig.size())))) / eval(Dth(range(0, fig.size())))) * 100; 273 | disp(errRelative, 1, fig.size()); 274 | 275 | drawnow(fig1); 276 | 277 | return 0; 278 | } 279 | 280 | 281 | With this code you should get these outputs : 282 | 283 | .. code-block:: text 284 | 285 | -- Numerical eigenvalues -- 286 | Matrix 1x5 of type 'd' (40 B): 287 | 3.50946 4.43845 5.65288 6.45167 7.00046 288 | -- Analytical eigenvalues -- 289 | Matrix 1x5 of type 'd' (40 B): 290 | 3.51241 4.44288 5.66359 6.47656 7.02481 291 | -- Relative errors -- 292 | Matrix 1x5 of type 'd' (40 B): 293 | 0.08379 0.09980 0.18906 0.38427 0.34671 294 | 295 | 296 | 297 | .. figure:: img/results5eigenmodes.png 298 | :width: 1200 299 | :align: center 300 | :figclass: align-center 301 | 302 | From up left corner to bottom right corner : the meshgrid and the five first eigenmodes. 303 | 304 | 305 | 306 | 307 | References 308 | ---------- 309 | 310 | http://ramanujan.math.trinity.edu/rdaileda/teach/s14/m3357/lectures/lecture_3_4_slides.pdf 311 | 312 | http://www.cmap.polytechnique.fr/~jingrebeccali/frenchvietnammaster2_files/2017/LectureNotes/pde3d_mit.pdf --------------------------------------------------------------------------------