danielmartensson / embeddedlapack Goto Github PK
View Code? Open in Web Editor NEWLinear algebra for embedded system with MATLAB style
License: MIT License
Linear algebra for embedded system with MATLAB style
License: MIT License
Hi,
I'm a master student from China. Recently I ported this libraty to RT-Thread, a burgeoning RTOS in China, so that this library can be used on STM32, RISC-V, i.mx, arm, x86, virtually all hardware platform supported by RT-Thread, as well as software simulator QEMU. And it works pretty well, though some examples require a little more RAM for MCUs.
(This video was recorded on STM32F103RCT6 with 256KB ROM and 48KB RAM)
Example | Memory |
---|---|
linsolve | 2 KB |
qr | 2 KB |
lu | 2 KB |
svd | 20 KB |
eig | 30 KB |
model predictive control | 20 KB |
state space | 800 KB |
I renamed my port to eLapack to be more precise. Is there any addtional license required for it?
Thanks a lot for your work on this project, it is really exhilarating to use Matlab/Octave-like API on microcontrollers.
Wu Han
ๅดๆ
Hello,
I'm new to LAPACK. I only know that it can speed up your code, but I'm not sure how it works.
For example, I look into your LinearAlgebra/dot.c and it seems like you're directly multiplying an element of both array together.
I cannot see how functions in Lapack/Scr/ are called even though they are included in LinearAlgebra/declareFunctions.h.
Could you explain to me how this library works? Does it do the operator overloading somewhere?
Best regards,
Is it possible to run this on VS2022?
EmbeddedLapack/EmbeddedLapack/src/LinearAlgebra/print.c
Lines 12 to 16 in d3fbc6f
I encountered a hard_fault,I thought it is caused by a array overflow in dgetrf.c.
When entering the dgetrf_
function, a pointer(stored in stack when compiled with -O0) is modified toa non-valid address therefore later write to that pointer cause hard_fault. Code will run smoothly if I introduce any level of optimization since the pointer would be stored in the register, so the overflow would not affect.
The caller:
// in EmbeddedLapack/src/Lapack/Src/dgetrf:124
double IPIV_d[(int) *n]; // this was added 2019 due to memory loss of ipiv when using LU.c file
dgetrf_(n, n, &a[a_offset], lda, &ipiv[1], info, IPIV_d);
if (*info == 0) {
Here pass in IPIV_d
is a *n
dim array
The callee:
// in EmbeddedLapack/src/Lapack/Src/dgetrf:215
// Add to IPIV_d due to memory loss from ipiv when using LU.c file.
for(int i = 1; i <= min(*m, *n); i++)
IPIV_d[i] = (double) ipiv[i];
Here *m == *n
so i
can be up to *n
and overflow(I thought)
Project setup:
Thanks for reading this, if I miss anything, sorry for any trouble caused by me, if possible plz let me know.
Hi,
I am trying to compile my application using gcc from the terminal in vscode. I keep getting undefined reference errors even with using the -lm flag
Using the src folder example and running
gcc -lm main.c
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function qpOASES_getSqrt': main.c:(.text+0x27f): undefined reference to
sqrt'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function Indexlist_isMember': main.c:(.text+0x31c): undefined reference to
Indexlist_getIndex'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function Bounds_setType': main.c:(.text+0x440): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x46c): undefined reference to MessageHandling_throwError' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
Bounds_setStatus':
main.c:(.text+0x4bf): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x4eb): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function Constraints_setType': main.c:(.text+0x77c): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x7a8): undefined reference to MessageHandling_throwError' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
Constraints_setStatus':
main.c:(.text+0x7fb): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x827): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function QProblemB_getBounds': main.c:(.text+0x9c3): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x9ef): undefined reference to MessageHandling_throwError' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblemB_setOptions':
main.c:(.text+0xd6b): undefined reference to OptionsCPY' /usr/bin/ld: main.c:(.text+0xd7d): undefined reference to
Options_ensureConsistency'
/usr/bin/ld: main.c:(.text+0xd95): undefined reference to QProblemB_setPrintLevel' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblemB_setH':
main.c:(.text+0xed0): undefined reference to DenseMatrixCON' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblemB_setG':
main.c:(.text+0xf11): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0xf3d): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: main.c:(.text+0xf54): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0xf80): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function QProblemB_setLB': main.c:(.text+0xfe5): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x1011): undefined reference to MessageHandling_throwError' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblemB_setLBn':
main.c:(.text+0x10c0): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x10ec): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: main.c:(.text+0x112d): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x1159): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function QProblemB_setUB': main.c:(.text+0x1192): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x11be): undefined reference to MessageHandling_throwError' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblemB_setUBn':
main.c:(.text+0x1261): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x128d): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: main.c:(.text+0x12ce): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x12fa): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function QProblemB_computeGivens': main.c:(.text+0x1405): undefined reference to
sqrt'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function QProblem_getBounds': main.c:(.text+0x1585): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x15b1): undefined reference to MessageHandling_throwError' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblem_setOptions':
main.c:(.text+0x192d): undefined reference to OptionsCPY' /usr/bin/ld: main.c:(.text+0x193f): undefined reference to
Options_ensureConsistency'
/usr/bin/ld: main.c:(.text+0x1957): undefined reference to QProblem_setPrintLevel' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblem_setH':
main.c:(.text+0x1a92): undefined reference to DenseMatrixCON' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblem_setG':
main.c:(.text+0x1ad3): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x1aff): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: main.c:(.text+0x1b16): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x1b42): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function QProblem_setLB': main.c:(.text+0x1ba7): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x1bd3): undefined reference to MessageHandling_throwError' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblem_setLBn':
main.c:(.text+0x1c82): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x1cae): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: main.c:(.text+0x1cef): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x1d1b): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function QProblem_setUB': main.c:(.text+0x1d54): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x1d80): undefined reference to MessageHandling_throwError' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblem_setUBn':
main.c:(.text+0x1e23): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x1e4f): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: main.c:(.text+0x1e90): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x1ebc): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function QProblem_getConstraints': main.c:(.text+0x1f53): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x1f7f): undefined reference to MessageHandling_throwError' /usr/bin/ld: main.c:(.text+0x1f9f): undefined reference to
ConstraintsCPY'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function QProblem_setA': main.c:(.text+0x20c9): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x20f5): undefined reference to MessageHandling_throwError' /usr/bin/ld: main.c:(.text+0x210f): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x213b): undefined reference to MessageHandling_throwError' /usr/bin/ld: main.c:(.text+0x218e): undefined reference to
DenseMatrixCON'
/usr/bin/ld: main.c:(.text+0x21da): undefined reference to DenseMatrix_times' /usr/bin/ld: main.c:(.text+0x229c): undefined reference to
DenseMatrix_getRowNorm'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function QProblem_setLBA': main.c:(.text+0x2328): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x2354): undefined reference to MessageHandling_throwError' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblem_setLBAn':
main.c:(.text+0x2411): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x243d): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: main.c:(.text+0x247d): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x24a9): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: /tmp/ccq6aT7Z.o: in function QProblem_setUBA': main.c:(.text+0x24f1): undefined reference to
qpOASES_getGlobalMessageHandler'
/usr/bin/ld: main.c:(.text+0x251d): undefined reference to MessageHandling_throwError' /usr/bin/ld: /tmp/ccq6aT7Z.o: in function
QProblem_setUBAn':
main.c:(.text+0x25ce): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x25fa): undefined reference to
MessageHandling_throwError'
/usr/bin/ld: main.c:(.text+0x263a): undefined reference to qpOASES_getGlobalMessageHandler' /usr/bin/ld: main.c:(.text+0x2666): undefined reference to
MessageHandling_throwError'
collect2: error: ld returned 1 exit status
this is the output.
Probably a bone head problem, but any help is appreciated!
Thanks,
Jon
Hello, I'm a master student and I'm trying to do linear algebra on STM32 with very limited RAM resources.
After walking around Github, I was brought here. It's really interesting to use Matlab style code on embedded devices, and it's also friendly for Matlab users. Thanks a lot for your work.
But I found some issues working with the example Solve A=QR. There is a discrepancy between results from Octave/Matlab and Embedded Lapack.
Here's my main.c file:
#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;
}
After compiling with Eclipse on Ubuntu 18, it prints out:
0.674877999999999978 0.151285000000000003 0.875139000000000000 0.150518000000000013
0.828102000000000005 0.150746999999999992 0.934674000000000005 0.474324999999999997
0.476509999999999989 0.914685999999999999 0.740681000000000034 0.060455000000000002
0.792594000000000021 0.471488000000000018 0.529343000000000008 0.743404999999999982
0.084738999999999995 0.475160000000000027 0.419306999999999985 0.628998999999999975
0.674877999999999978 0.151285000000000003 0.875139000000000000 0.150518000000000013
0.430363367488631909 -0.194014593066344582 0.323945401703134239 -0.148698048729633159 0.773585469161194750 -0.227287259922755835
0.528072874421852689 -0.277360065364141040 0.137757391146332453 0.191610586778221681 -0.164011596168225859 0.749412379122773364
0.303865955390467624 0.773024563663661679 0.049330325017480775 -0.520576407464857893 -0.040937527689586389 0.187054395774491289
0.505429756031882560 0.103108123446773947 -0.770067557220855514 0.285532138610407826 0.052095825655674069 -0.238039611582949229
0.054037265102165402 0.489479119419501785 0.419170765875818196 0.752685037352313957 0.026402643324590441 -0.120640663290151051
0.430363367488631965 -0.194014593066344609 0.323945401703134572 -0.148698048729633325 -0.607929899269971208 -0.529636870123429748
1.568158563165408914 0.751742792671696747 1.762103166518584008 0.808131642683462381
0.000000000000000000 0.887755694132771223 0.233565475697944780 0.241301981100816465
0.000000000000000000 0.000000000000000000 0.500422161463870863 -0.142970812509125689
0.000000000000000000 0.000000000000000000 0.000000000000000000 0.700354934376156257
0.000000000000000000 0.000000000000000000 0.000000000000000000 0.000000000000000000
0.000000000000000000 0.000000000000000000 0.000000000000000000 0.000000000000000000
While using octave, the QR decomposition for A is:
octave:1> A = [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]
A =
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
octave:2> [Q, R] = qr(A)
Q =
-0.430363 -0.194015 0.323945 0.148698 -0.562826 -0.577340
-0.528073 -0.277360 0.137757 -0.191611 0.739060 -0.205691
-0.303866 0.773025 0.049330 0.520576 0.184470 -0.051341
-0.505430 0.103108 -0.770068 -0.285532 -0.234751 0.065335
-0.054037 0.489479 0.419171 -0.752685 -0.118974 0.033112
-0.430363 -0.194015 0.323945 0.148698 -0.183642 0.785092
R =
-1.56816 -0.75174 -1.76210 -0.80813
0.00000 0.88776 0.23357 0.24130
0.00000 0.00000 0.50042 -0.14297
0.00000 0.00000 0.00000 -0.70035
0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000
The differences stay with negative signs.
To tell which one is the correct answer, I tried Q*Q' in octave and it gave me an identity matrix, thus I though octave gave me the correct answer.
octave:3> Q*Q'
ans =
1.0000e+00 -1.8986e-16 -2.2909e-16 -2.0480e-16 4.6334e-16 2.1534e-16
-1.8986e-16 1.0000e+00 1.9844e-16 2.0262e-16 -1.0305e-16 -2.0158e-16
-2.2909e-16 1.9844e-16 1.0000e+00 2.3685e-16 1.4035e-16 -7.8100e-17
-2.0480e-16 2.0262e-16 2.3685e-16 1.0000e+00 -5.4078e-16 -1.7920e-16
4.6334e-16 -1.0305e-16 1.4035e-16 -5.4078e-16 1.0000e+00 1.9398e-16
2.1534e-16 -2.0158e-16 -7.8100e-17 -1.7920e-16 1.9398e-16 1.0000e+00
octave:4> Q*R-A
ans =
1.1102e-16 2.2204e-16 1.1102e-16 1.6653e-16
-1.1102e-16 1.1102e-16 -1.1102e-16 -1.1102e-16
5.5511e-17 0.0000e+00 0.0000e+00 7.6328e-17
-1.1102e-16 5.5511e-17 -1.1102e-16 -1.1102e-16
0.0000e+00 0.0000e+00 1.1102e-16 0.0000e+00
0.0000e+00 8.3267e-17 0.0000e+00 -5.5511e-17
octave:5>
I think this should be an issue and I'm trying to find solutions.
Once again, thanks for your project that introduces Matlab to STM32.
Hello I followed the instructions rules of your setup, in the stmcube IDE and I receive the following error messenge:
Description Resource Path Location Type make: *** No rule to make target 'C:/Users/xxxxx/EmbeddedLapack-master/EmbeddedLapack/src/LinearAlgebra/add.c', needed by 'Core/Src/LinearAlgebra/add.o'. Stop. final C/C++ Problem
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.