Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document basic Matrices #1733

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test_tutorials.yml
Expand Up @@ -9,7 +9,7 @@ jobs:
- uses: actions/checkout@v2
- name: Run tutorials
run: |
export NB_PYTHON_PREFIX=$CONDA_PREFIX
export NB_PYTHON_PREFIX=$our_install_dir
source bin/install_travis.sh
./binder/postBuild
python bin/test_tutorials.py
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -173,3 +173,4 @@ symengine/symengine_config_cling.h
gen_docs/
/docs/Doxygen/tags/
*.ipynb
.auctex-auto/
1 change: 0 additions & 1 deletion binder/environment.yml
Expand Up @@ -12,4 +12,3 @@ dependencies:
- libflint
- jupytext
- papermill
- symengine
4 changes: 1 addition & 3 deletions binder/postBuild
@@ -1,10 +1,8 @@
set -e
mkdir build
cd build
export LDFLAGS="-Wl,-rpath,${NB_PYTHON_PREFIX}/lib -L${NB_PYTHON_PREFIX}/lib"
cmake -DWITH_COTIRE=no -DBUILD_SHARED_LIBS=yes -DWITH_MPC=yes -DWITH_ARB=yes -DINTEGER_CLASS=flint -DWITH_LLVM=yes -DCMAKE_PREFIX_PATH=${NB_PYTHON_PREFIX} -DCMAKE_INSTALL_PREFIX=${NB_PYTHON_PREFIX} -DBUILD_TESTS=off -DBUILD_BENCHMARKS=off -DCMAKE_INSTALL_LIBDIR=lib ..
cmake -DWITH_COTIRE=no -DBUILD_SHARED_LIBS=yes -DWITH_MPC=yes -DWITH_ARB=yes -DINTEGER_CLASS=flint -DWITH_LLVM=yes -DBUILD_TESTS=off -DBUILD_BENCHMARKS=off ..
make -j4
make install
sudo make install
cd ..
rm -rf build
163 changes: 158 additions & 5 deletions docs/mystMD/Matrices.myst.md
Expand Up @@ -14,25 +14,178 @@ kernelspec:

# Matrices

```{code-cell}
#include <chrono>
#include <xcpp/xdisplay.hpp>
```{note}
As of now there is no pretty printer implemented for matrices ([issue](https://github.com/symengine/symengine/issues/1701))
```


The following header files will be necessary for this section.

```{code-cell}
#include <symengine/parser.h>
#include <symengine/matrix.h>
#include <symengine/add.h>
#include <symengine/pow.h>
#include <symengine/symengine_exception.h>
#include <symengine/visitor.h>
#include <symengine/printers/strprinter.h>
```

## Base Elements

We will need a set of basic elements to cover a reasonable set of operations. Namely we would like:

- Two Matrices (A,B)
- A Vector (X)

```{code-cell}
SymEngine::vec_basic elems{SymEngine::integer(1),
SymEngine::vec_basic elemsA{SymEngine::integer(1),
SymEngine::integer(0),
SymEngine::integer(-1),
SymEngine::integer(-2)};
SymEngine::DenseMatrix A = SymEngine::DenseMatrix(2, 2, elems);
SymEngine::DenseMatrix A = SymEngine::DenseMatrix(2, 2, elemsA);
```

```{code-cell}
A.__str__()
```

```{code-cell}
SymEngine::vec_basic elemsB{SymEngine::integer(5),
SymEngine::integer(2),
SymEngine::integer(-7),
SymEngine::integer(-3)};
SymEngine::DenseMatrix B = SymEngine::DenseMatrix(2, 2, elemsB);
B.__str__()
```

Note that the real utility of working with SymEngine is the ability to include free symbols as first class members of the matrix.

+++

## Basic Operations

The key thing to remember that as a `C++` library, we need to pre-allocated variable sizes and types. Furthermore, the unary operators are **not** overloaded, so we will call functions for each of the standard operations. The general form of each of these is:

**operation**(_term1_,_term2_,**output**)

+++

### Matrix-Matrix

#### Addition
The addition of two dense matrices is carried out as expected.

\begin{align*}
\mathbf{A}+\mathbf{B} & = \begin{bmatrix}
a_{11} & a_{12} & \cdots & a_{1n} \\
a_{21} & a_{22} & \cdots & a_{2n} \\
\vdots & \vdots & \ddots & \vdots \\
a_{m1} & a_{m2} & \cdots & a_{mn} \\
\end{bmatrix} +

\begin{bmatrix}
b_{11} & b_{12} & \cdots & b_{1n} \\
b_{21} & b_{22} & \cdots & b_{2n} \\
\vdots & \vdots & \ddots & \vdots \\
b_{m1} & b_{m2} & \cdots & b_{mn} \\
\end{bmatrix} \\
& = \begin{bmatrix}
a_{11} + b_{11} & a_{12} + b_{12} & \cdots & a_{1n} + b_{1n} \\
a_{21} + b_{21} & a_{22} + b_{22} & \cdots & a_{2n} + b_{2n} \\
\vdots & \vdots & \ddots & \vdots \\
a_{m1} + b_{m1} & a_{m2} + b_{m2} & \cdots & a_{mn} + b_{mn} \\
\end{bmatrix} \\
\end{align*}

```{code-cell}
SymEngine::DenseMatrix C = SymEngine::DenseMatrix(2, 2);
add_dense_dense(A, B, C);
C.__str__()
```

#### Multiplication

+++

### Matrix-Scalar
#### Addition

## Gaussian Elimination

One of the main use-cases for any library with matrices is the ability to perform Gaussian elimination. We will consider an example from the literature {cite}`nakosFractionfreeAlgorithmsLinear1997`.

```{code-cell}
// Fraction-Free Algorithms for Linear and Polynomial Equations, George C
// Nakos,
// Peter R Turner et. al.
SymEngine::DenseMatrix A = SymEngine::DenseMatrix(4, 4, {SymEngine::integer(1), SymEngine::integer(2), SymEngine::integer(3), SymEngine::integer(4),
SymEngine::integer(2), SymEngine::integer(2), SymEngine::integer(3), SymEngine::integer(4),
SymEngine::integer(3), SymEngine::integer(3), SymEngine::integer(3), SymEngine::integer(4),
SymEngine::integer(9), SymEngine::integer(8), SymEngine::integer(7), SymEngine::integer(6)});
SymEngine::DenseMatrix B = SymEngine::DenseMatrix(4, 4);
fraction_free_gaussian_elimination(A, B);
B.__str__()
```

## Hadamard Product

```{warning}
This will be part of the next release
```


This is essentially the element wise multiplication of two matrices, so for two matrices of the same dimension we have $(A \circ B)_{ij} = (A \odot B)_{ij} = (A)_{ij} (B)_{ij}$.

$$
\begin{bmatrix}
a_{11} & a_{12} & a_{13}\\
a_{21} & a_{22} & a_{23}\\
a_{31} & a_{32} & a_{33}
\end{bmatrix} \circ \begin{bmatrix}
b_{11} & b_{12} & b_{13}\\
b_{21} & b_{22} & b_{23}\\
b_{31} & b_{32} & b_{33}
\end{bmatrix} = \begin{bmatrix}
a_{11}\, b_{11} & a_{12}\, b_{12} & a_{13}\, b_{13}\\
a_{21}\, b_{21} & a_{22}\, b_{22} & a_{23}\, b_{23}\\
a_{31}\, b_{31} & a_{32}\, b_{32} & a_{33}\, b_{33}
\end{bmatrix}
$$

For `SymEngine` this has been implemented recently as the `element_mul_matrix` function.

```{code-cell}
SymEngine::DenseMatrix D = SymEngine::DenseMatrix(2, 2);
B.elementwise_mul_matrix(A, D);
D.__str__()
```

# NumPY Convenience Functions
A set of functions are provided to allow for `numpy`-esque generation of matrices.
- `eye` for generating a 2-D matrix with ones on the diagonal and zeros elsewhere
- `diag` for generating diagonal matrices
- `ones` for generating a dense matrix of ones
- `zeros` for generating a dense matrix of zeros

+++

## Identity Matrices and Offsets
The `eye` function is used to create 2D matrices with ones on the diagonal and zeros elsewhere; with an optional parameter to offset the position of the ones.

```{code-cell}
SymEngine::DenseMatrix npA = SymEngine::DenseMatrix(3, 3);
SymEngine::eye(npA);
npA.__str__()
```

```{code-cell}
SymEngine::eye(npA,1);
npA.__str__()
```

## Diagonal Matrix Helpers
The `diag` function

```{bibliography} references.bib
```
1 change: 1 addition & 0 deletions docs/mystMD/index.md
Expand Up @@ -4,4 +4,5 @@ This part of the documentation deals with the use of basic C++ structures.
```{toctree}
:maxdepth: 2
Expressions <firststeps.myst.md>
Matrices <Matrices.myst.md>
```
13 changes: 13 additions & 0 deletions docs/mystMD/references.bib
@@ -0,0 +1,13 @@
@article{nakosFractionfreeAlgorithmsLinear1997,
title = {Fraction-Free Algorithms for Linear and Polynomial Equations},
author = {Nakos, George C. and Turner, Peter R. and Williams, Robert M.},
year = {1997},
month = sep,
volume = {31},
pages = {11--19},
issn = {0163-5824},
doi = {10.1145/271130.271133},
abstract = {This paper extends the ideas behind Bareiss's fraction-free Gauss elimination algorithm in a number of directions. First, in the realm of linear algebra, algorithms are presented for fraction-free LU "factorization" of a matrix and for fraction-free algorithms for both forward and back substitution. These algorithms are valid not just for integer computation but also for any matrix system where the entries are taken from a unique factorization domain such as a polynomial ring. The second part of the paper introduces the application of the fraction-free formulation to resultant algorithms for solving systems of polynomial equations. In particular, the use of fraction-free polynomial arithmetic and triangularization algorithms in computing the Dixon resultant of a polynomial system is discussed.},
journal = {ACM SIGSAM Bulletin},
number = {3}
}