# EmbeddedLapack
![](https://raw.githubusercontent.com/DanielMartensson/EmbeddedAlgebra/master/C-symbol.png) ![](https://raw.githubusercontent.com/DanielMartensson/EmbeddedAlgebra/master/CPU-symbol.png)
![](https://raw.githubusercontent.com/DanielMartensson/EmbeddedAlgebra/master/Matrix-symbol.png)
## Introduction
This is a C-library for linear algebra which are ment to be used for embedded systems such as AVR, PIC, ARM etc. The library is
easy built and follows as much as it can the MATLAB/Octave "standard", how to compute and solve matrices.
This C-library using Lapack subroutines from Lapack version 3.2.1 and I have change this Lapack library so it don't require a specific CPU/computer or asking for a operative system. I want this library to have 100% portability.
* Easy to use in the editor
* Basic easy code to read if needed
* Follows MATLAB commands as much as it can
* Can be used with a compiler as low as C99 standard, default is C11
* Simple use for most common matrix algebra
* Using minimal but necessary Lapack subroutines as possible due to the small amout of flash memory it will be loaded into.
If you looking for a even smaller library, but do the same job (except for imaginary eigenvectors), then CControl will be a good solution for you. CControl is more applied and contains lots of examples such as system identification, path finding, linear algebra, filtering, control engineering, optimization etc. CControl does not use LAPACK. So CControl fits even smaller microcontrollers. Please fork and star so more people can see CControl.
https://github.com/DanielMartensson/CControl
## Status of the project
I'm updating this project when I found bugs or when I will add something new. Else, this project works.
## Tested on without any compile errors
* Windows 7 MinGW 64 bit
* Ubuntu Linux GCC 64 bit
* Raspberry Pi B+/Zero W GCC-ARM 32 bit
* STM32 GCC-ARM-Atollic 32 bit
## Installation for testing and buildning your matrix algebra
Step 1: Download EmbeddedLapack folder
Step 2: Open EmbeddedLapack and go to Debug folder
Step 3:
Write this to compile
```
make clean
make
```
## Installation to an embedded target
Step 1: Download EmbeddedLapack folder
Step 2: Move the folders "Lapack" and "LinearAlgebra" from the folder EmbeddedLapack -> src, to the same folder as your main.c file is located.
Step 3: Link "-lm" like this.
![](https://raw.githubusercontent.com/DanielMartensson/EmbeddedLapack/master/Markering_006.png)
Step 4: Paste in "#include "LinearAlgebra/declareFunctions.h"" in top of your main.c file
![](https://raw.githubusercontent.com/DanielMartensson/EmbeddedLapack/master/Markering_008.png)
Done! Now you can compile.
## Functions
```
void tran(double* A, int row, int column);
void print(double* A, int row, int column);
void linsolve(double* A, double* X, double* B, int row, int column_b);
void svd(double* A, double* U, double* S, double* V, int row, int column);
void diag(double* A, double* B, int row_b, int column_b);
void qr(double* A, double* Q, double* R, int row, int column);
void triu(double* A, double* B, int shift, int row, int column);
void eye(double* A, int row, int column);
void mul(double* A, double* B, bool elementWise, double* C, int row_a, int column_a, int column_b);
void scale(double* A, double scalar, int row, int column);
void sub(double* A, double* B, double* C, int row_a, int column_a, int column_b);
void lu(double* A, double* L, double* U, double* P, int row, int column);
void tril(double* A, double* B, int shift, int row, int column);
void inv(double* A, int row);
void chol(double* A, double* L, int row);
double det(double *A, int row);
void toeplitz(double* A, double* B, int length);
void hankel(double* A, double* H, int length, int step);
void cut(double* A, int row, int column, double* B, int start_row, int stop_row, int start_column, int stop_column);
void diagpower(double* A, double p, int row, int column);
void eabs(double* A, int row, int column);
void add(double* A, double* B, double* C, int row_a, int column_a, int column_b);
void copy(double* A, double* B, int row, int column);
void cofact(double* A, double* CO, int row, int column);
void mdiag(double* A, double* B, int row, int column);
double dot(double* A, double* B, int row);
void horzcat(double* A, double* B, double* C, int row_a, int column_a, int column_b);
void maxvector(double* A, int row, double* val, int* index);
void minvector(double* A, int row, double* val, int* index);
double norm(double* A, int row, char* P);
void ones(double* A, int row, int column);
void pinv(double* A, int row, int column);
void power(double* A, int row, int column, double value);
void repmat(double* A, int row, int column, int horz, int vert, double* B);
void sqrte(double* A, int row, int column);
void sumrows(double* A, double* B, int row, int column);
void vec(double* A, double* B, int row, int column);
void vertcat(double* A, double* B, double* C, int row_a, int column_a, int row_b);
void zeros(double* A, int row, int column);
int rank(double* A, int row);
void eig(double* A, double* Ereal, double* Eimag, double* Vreal_left, double* Vimag_left, double* Vreal_right, double* Vimag_right, int row);
void mpower(double* A, int row, int n);
void insert(double* A, double* B, int row_a, int column_a, int column_b, int startRow_b, int startColumn_b);
void move(double* A, int row, int column, int down, int right);
void quadprog(double* H, double* g, double* A, double* ulb_vec, double* uub_vec, double* ylb_vec, double* yub_vec, int* nWSR, double* u, int columnH, int rowA);
void linprog(double* c, double* A, double* b, double* x, int row_a, int column_a, uint8_t max_or_min, int iteration_limit);
```
## Compiler and microprocessor
When you compile this, you need to take respect on this.
```
#include <math.h> // Need be linked with "-lm" when compiling this code
```
Also you need to link the folder "Include" located inside EmbeddedLapack -> src -> Lapack.
## Troubleshooting
If you declare a matrix or a vector and you use that with this library, but you getting garbage values back. Try to sett all values of the matrix or vector to zeros by using:
```
zeros(A, row, column);
```
Most of my functions have this algorithm included in the beginning of the functions.
## Examples and how to use
Here is some examples how to use
## QR-factorization
```
#include <time.h>
#include "LinearAlgebra/declareFunctions.h"
int main() {
clock_t start, end;
float cpu_time_used;
start = clock();
// A matrix with size 6 x 4
double A[6*4] = {0.674878, 0.151285, 0.875139, 0.150518,
0.828102, 0.150747, 0.934674, 0.474325,
0.476510, 0.914686, 0.740681, 0.060455,
0.792594, 0.471488, 0.529343, 0.743405,
0.084739, 0.475160, 0.419307, 0.628999,
0.674878, 0.151285, 0.875139, 0.150518};
double Q[6*6];
double R[6*4];
// Solve
qr(A, Q, R, 6, 4);
// Print
print(A, 6,4);
print(Q, 6,6);
print(R, 6,4);
end = clock();
cpu_time_used = ((float) (end - start)) / CLOCKS_PER_SEC;
printf("\nTotal speed was %f,", cpu_time_used);
return 0;
}
```
## Singular Value Decomposition
```
#include <time.h>
#include "LinearAlgebra/declareFunctions.h"
#define row 17
#define column 15
int main( )
{
clock_t start, end;
float cpu_time_used;
start = clock();
double A[row*column] = {
0.84245, 0.23405 , 0.69751 , 0.27905 , 0.18851 , 0.61018 , 0.62182 , 0.71839 , 0.79161 ,0.56156 , 0.83395 , 0.092388 , 0.8511 , 0.44826 , 0.82158,
0.84614 , 0.15947 , 0.096336 , 0.80793 , 0.35114 , 0.42583 , 0.2134 , 0.75324 , 0.31391 , 0.22892 , 0.94773 , 0.81204 , 0.62554 , 0.28367 , 0.26637,
0.26509 , 0.91429 , 0.14222 , 0.28321 , 0.11607 , 0.41188 , 0.10071 , 0.18224 , 0.75723 , 0.89125 , 0.62494 , 0.83016 , 0.46448 , 0.73119 , 0.10982,
0.45197 , 0.44562 , 0.27909 , 0.76019 , 0.014571 , 0.42705 , 0