Go Down

Topic: Octave/Matlab Vector Programming in Due (Read 11040 times) previous topic - next topic

randomvibe

#15
Feb 24, 2013, 08:58 am Last Edit: Feb 24, 2013, 09:00 am by randomvibe Reason: 1
I tried the snippet below as suggested by Arctic_Eddie in Arduino-IDE-1.5.2 without luck.  The compiler reports warnings about undefined references, and the function reports negative RAM sizes.  Any other proved methods for reporting RAM usage?  Thank you.


Code: [Select]
void setup() {
   
   int xxx;  

   Serial.begin(9600);    
   xxx = freeRam();
   Serial.println(xxx);
}

void loop() {
}

int freeRam() {
 extern int __heap_start, *__brkval;
 int v;
 return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}



Compiler Message:
Code: [Select]
sketch_feb23b.cpp.o: In function `freeRam()':
C:\Programs\arduino-1.5.2/sketch_feb23b.ino:21: warning: undefined reference to `__brkval'
C:\Programs\arduino-1.5.2/sketch_feb23b.ino:21: warning: undefined reference to `__heap_start'



Program Output:
Code: [Select]
-28



Suggestion for future IDE release... include tally of RAM usage to supplement "sketch size" report.  This added feature would be very useful for all users.  Thank you.

robtillaart


Those are AVR specific labels, so the won't work on a DUE

Quote
Any other proved methods for reporting RAM usage?

It is rather impossible to make a RAM (peak) usage estimation compile time.
Only the global declared vars can be counted "relative" easily.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

stimmer

#17
Feb 24, 2013, 01:35 pm Last Edit: Feb 24, 2013, 01:39 pm by stimmer Reason: 1
There was a thread here a short time ago about ram usage. I did post some code about an estimate of free RAM at runtime but it is not well tested. I'll try to find it.

update: here it is :)
http://arduino.cc/forum/index.php/topic,146589.0.html
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

josheeg

This is awsome and might work with the maple. I wonder if it would compile for fpga somehow like a xillinx.

I am interested in this and want to try to do linear discriminent analisis pattern matching.

The matrix inverse multiplication addition etc is needed for it.

I do not have a duo yet so i will try it in code blocks then on my leaflabs maple then the duo maby.

Has anyone tried this i like their documentation.

8)  XD  :smiley-mr-green:

josheeg

Pattern Matching in arduino c++
I don't have the Arduino Due yet but I did write  this code in c++ code blocks on the release compile the size is Output size is 531.00 KB on my windows 8 computer and want to try it in a due. I wonder if the arduino due will be able to hold it and any suggestions to make it fit if not?

It inverts and multiplies and divides a constant from a matrix...

Code: [Select]
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/LU>
using Eigen::MatrixXd;
using namespace std;
int main()
{
cout << "Hello Pattern matching Linear Discriminent Analisis!" << endl;
cout << "" << endl;
cout << "x data" << endl;

//data matrix x row col
MatrixXd x(4,2);
//cur
x(0,0) = 2.95;//g0
x(1,0) = 2.53;
x(2,0) = 3.57;
x(3,0) = 3.16;

//dia
x(0,1) = 6.63;//g0
x(1,1) = 7.79;
x(2,1) = 5.65;
x(3,1) = 5.47;

std::cout << x << std::endl;
cout << "End of x data" << endl;
cout << "" << endl;

cout << "x1 data" << endl;

MatrixXd x1(3,2);

x1(0,0) = 2.58;//g1
x1(1,0) = 2.16;
x1(2,0) = 3.27;

x1(0,1) = 4.46;//g1
x1(1,1) = 6.22;
x1(2,1) = 3.52;

std::cout << x1 << std::endl;
cout << "End of x1 data" << endl;
cout << "" << endl;

//group adv
cout << "x data adverage ui" << endl;

MatrixXd ui(1,2);//group/feature
ui(0,0)=(x(0,0) + x(1,0) + x(2,0) + x(3,0))/4;
ui(0,1)=(x(0,1) + x(1,1) + x(2,1) + x(3,1))/4;
std::cout << ui << std::endl;
cout << "" << endl;

cout << "x1 data adverage ui1" << endl;

MatrixXd ui1(1,2);//group/feature

ui1(0,0)=(x1(0,0) + x1(1,0) + x1(2,0))/3.0;
ui1(0,1)=(x1(0,1) + x1(1,1) + x1(2,1))/3.0;
std::cout << ui1 << std::endl;
cout << "" << endl;

cout << "x & x1 data adverage u" << endl;
MatrixXd u(1,2);//all group/feature
u(0,0)=(x(0,0) + x(1,0) + x(2,0) + x(3,0) + x1(0,0) + x1(1,0) + x1(2,0))/7.0;

u(0,1)=(x(0,1) + x(1,1) + x(2,1) + x(3,1) + x1(0,1) + x1(1,1) + x1(2,1))/7.0;

std::cout << u << std::endl;
cout << "" << endl;


cout << "mean corrected data xig - u" << endl;
MatrixXd ximinu(4,2);
//cur
ximinu(0,0) = x(0,0) - u(0,0);//f0
ximinu(1,0) = x(1,0) - u(0,0);
ximinu(2,0) = x(2,0) - u(0,0);
ximinu(3,0) = x(3,0) - u(0,0);
//dia
ximinu(0,1) = x(0,1) - u(0,1);//f1
ximinu(1,1) = x(1,1) - u(0,1);
ximinu(2,1) = x(2,1) - u(0,1);
ximinu(3,1) = x(3,1) - u(0,1);
std::cout << ximinu << std::endl;
cout << "" << endl;

cout << "mean corrected data xi1 - u" << endl;


MatrixXd ximinu1(3,2);
//cur
ximinu1(0,0) = x1(0,0) - u(0,0);
ximinu1(1,0) = x1(1,0) - u(0,0);
ximinu1(2,0) = x1(2,0) - u(0,0);
//dia
ximinu1(0,1) = x1(0,1) - u(0,1);//g1
ximinu1(1,1) = x1(1,1) - u(0,1);
ximinu1(2,1) = x1(2,1) - u(0,1);

std::cout << ximinu1 << std::endl;

cout << " " << endl;

cout << "Transpose matricies" << endl;
cout << "xi - u T" << endl;

MatrixXd ximinut(4,2);
ximinut= ximinu.transpose();
std::cout << ximinut<< std::endl;
cout << " " << endl;

cout << "xi1 - u T" << endl;
MatrixXd ximinu1t(3,2);
ximinu1t= ximinu1.transpose();
std::cout << ximinu1t << std::endl;
cout << " " << endl;

cout << "Covariance matrix of group ci" << endl;
MatrixXd ci(2,2);
ci = ( ximinut * ximinu ) /4.0;
std::cout << ci << std::endl;
cout << "" << endl;

cout << "Covariance matrix of group ci1" << endl;
MatrixXd ci1(2,2);
ci1 = ( ximinu1t * ximinu1 ) /3.0;
std::cout << ci1 << std::endl;
cout << "" << endl;

cout << "Pooled within group Covariance matrix c" << endl;
MatrixXd c(2,2);
c(0,0) = 4.0/7.0 * ci(0,0) + 3.0/7.0 * ci1(0,0);
c(1,0) = 4.0/7.0 * ci(1,0) + 3.0/7.0 * ci1(1,0);
c(0,1) = 4.0/7.0 * ci(0,1) + 3.0/7.0 * ci1(0,1);
c(1,1) = 4.0/7.0 * ci(1,1) + 3.0/7.0 * ci1(1,1);
std::cout << c << std::endl;
cout << "" << endl;

cout << "inverse of Pooled within group Covariance matrix cinverse" << endl;
MatrixXd cinverse(2,2);
cinverse=c.inverse();
std::cout << cinverse << std::endl;
cout << "" << endl;

cout << "Probability of a group" << endl;
cout << "x = 4/7 x1 = 3/7" << endl;

//create a vector of a probability...
cout << "" << endl;

//formula for calculatin likelyhood of data in a group...
//fi = uig cinverse xkt - 1/2uig cinverse uitg + ln probability

cout << "End of program!" << endl;

    return 0;
}

stimmer

Even without the Due you can download the IDE, follow the instructions to get Eigen working then try compiling your code and see what the code size is, that will give you an idea if it will work. The IDE will work without a board.

Although std::cout does work on the Due you might want to change those lines to use Serial.print as that uses a lot less flash.
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

josheeg

Thanks I downloaded Arduino 1.5 ...
I put the eigen subdirectory into arduino hardware sam libraries then the eigen.h file in there. That is in the adafruit post.

Now I am getting errors with namespace...
using namespace Eigen;    // Eigen related statement; simplifies syntax for declaration of matrices
The print out option of the matrix tipe I am not shure how that works.

I useualy use standard c and arduino c.

josheeg

I switched the board type to duo and it must look into the sam libraries folder so now the example compiles. I will try my code latter. Thank You.  :D  :smiley-mr-green:  XD

josheeg


Binary sketch size: 183,028 bytes (of a 524,288 byte maximum) - 34% used

So the LDA eample that has slightly different number results but did one calculation correctly i would have to try it with some of the sample data or octave or r example data to see if it continues to work.

Well I got the code to compile for a pc and compile for the arduino due. Now the pc I tested it will this run on the arduino due? Sorry about the mess.

Code: [Select]
//Josh W
//lda example reference http://people.revoledu.com/kardi/tutorial/LDA/Numerical%20Example.html
//reference http://eigen.tuxfamily.org/dox/TutorialMatrixArithmetic.html
// Example By: RandomVibe
// Eigen Doc: http://eigen.tuxfamily.org/dox/
// Quick Reference: http://eigen.tuxfamily.org/dox/QuickRefPage.html

#include <iostream>
#include <math.h>
#include <Eigen312.h>     // Calls main Eigen3.1.2 matrix class library
#include <Dense>
#include <LU>             // Calls inverse, determinant, LU decomp., etc.
using namespace Eigen;    // Eigen related statement; simplifies syntax for declaration of matrices
using Eigen::MatrixXd;
using namespace std;

void print_mtxf(const Eigen::MatrixXf& K);


void setup() {

    Serial.begin(9600);
   
    // DECLARE MATRICES
    //--------------------
  //data matrix x row col
MatrixXd x(4,2);
//cur
x(0,0) = 2.95;//g0
x(1,0) = 2.53;
x(2,0) = 3.57;
x(3,0) = 3.16;

//dia
x(0,1) = 6.63;//g0
x(1,1) = 7.79;
x(2,1) = 5.65;
x(3,1) = 5.47;

MatrixXd x1(3,2);

x1(0,0) = 2.58;//g1
x1(1,0) = 2.16;
x1(2,0) = 3.27;

x1(0,1) = 4.46;//g1
x1(1,1) = 6.22;
x1(2,1) = 3.52;

MatrixXd ui(1,2);//group/feature

ui(0,0)=(x(0,0) + x(1,0) + x(2,0) + x(3,0))/4.0;
ui(0,1)=(x(0,1) + x(1,1) + x(2,1) + x(3,1))/4.0;

//transpose ui to uit
MatrixXd uit(1,2);//group/feature
uit=ui.transpose();


MatrixXd ui1(1,2);//group/feature

ui1(0,0)=(x1(0,0) + x1(1,0) + x1(2,0))/3.0;
ui1(0,1)=(x1(0,1) + x1(1,1) + x1(2,1))/3.0;

MatrixXd ui1t(1,2);//group/feature
ui1t=ui1.transpose();

MatrixXd u(1,2);//all group/feature
u(0,0)=(x(0,0) + x(1,0) + x(2,0) + x(3,0) + x1(0,0) + x1(1,0) + x1(2,0))/7.0;

u(0,1)=(x(0,1) + x(1,1) + x(2,1) + x(3,1) + x1(0,1) + x1(1,1) + x1(2,1))/7.0;

MatrixXd ximinu(4,2);
//cur
ximinu(0,0) = x(0,0) - u(0,0);//f0
ximinu(1,0) = x(1,0) - u(0,0);
ximinu(2,0) = x(2,0) - u(0,0);
ximinu(3,0) = x(3,0) - u(0,0);
//dia
ximinu(0,1) = x(0,1) - u(0,1);//f1
ximinu(1,1) = x(1,1) - u(0,1);
ximinu(2,1) = x(2,1) - u(0,1);
ximinu(3,1) = x(3,1) - u(0,1);
std::cout << ximinu << std::endl;
cout << "" << endl;

MatrixXd ximinu1(3,2);
//cur
ximinu1(0,0) = x1(0,0) - u(0,0);
ximinu1(1,0) = x1(1,0) - u(0,0);
ximinu1(2,0) = x1(2,0) - u(0,0);
//dia
ximinu1(0,1) = x1(0,1) - u(0,1);//g1
ximinu1(1,1) = x1(1,1) - u(0,1);
ximinu1(2,1) = x1(2,1) - u(0,1);

MatrixXd ximinut(4,2);
ximinut= ximinu.transpose();

MatrixXd ximinu1t(3,2);
ximinu1t= ximinu1.transpose();

MatrixXd ci(2,2);
ci = ( ximinut * ximinu ) /4.0;

MatrixXd ci1(2,2);
ci1 = ( ximinu1t * ximinu1 ) /3.0;

MatrixXd c(2,2);
c(0,0) = 4.0/7.0 * ci(0,0) + 3.0/7.0 * ci1(0,0);
c(1,0) = 4.0/7.0 * ci(1,0) + 3.0/7.0 * ci1(1,0);
c(0,1) = 4.0/7.0 * ci(0,1) + 3.0/7.0 * ci1(0,1);
c(1,1) = 4.0/7.0 * ci(1,1) + 3.0/7.0 * ci1(1,1);

MatrixXd cinverse(2,2);
cinverse=c.inverse();

MatrixXd xk(1,2);//new data
xk(0,0) = 2.81;//f1
xk(0,1) = 5.46;

MatrixXd xkt(1,2);//new data
xkt=xk.transpose();

MatrixXd lnp1(1,1);//p1 4/7
lnp1(0,0) = 0.0;
lnp1(0,0)=log(4.0/7.0);

MatrixXd lnp2(1,1);//p1 3/7
lnp2(0,0) = 0.0;
lnp2(0,0)=log(4.0/7.0);

MatrixXd f1(1,1);//ui   * cinverse * xkt  -1.0/2.0 * ui  * cinverse * uit + lnp1
MatrixXd f2(1,1);//ui1  * cinverse * xkt -1.0/2.0 * ui1 * cinverse * ui1t + lnp2

f1 = ui   * cinverse * xkt  -1.0/2.0 * ui  * cinverse * uit + lnp1;
f2 = ui1  * cinverse * xkt -1.0/2.0 * ui1 * cinverse * ui1t + lnp2;

if (f1(0,0)>f2(0,0)) cout << "the data is in group 1" << endl;
if (f1(0,0)<f2(0,0)) cout << "the data is in group 2" << endl;
    // Print Result
    //----------------------------
     //print_mtxf(K);      // Print Matrix Result (passed by reference)
   
}




void loop() {
  // put your main code here, to run repeatedly:

}




// PRINT MATRIX (float type)
//-----------------------------
void print_mtxf(const Eigen::MatrixXf& X)
{
    int i, j, nrow, ncol;
   
    nrow = X.rows();
    ncol = X.cols();

    Serial.print("nrow: "); Serial.println(nrow);
    Serial.print("ncol: "); Serial.println(ncol);       
    Serial.println();
   
    for (i=0; i<nrow; i++)
    {
        for (j=0; j<ncol; j++)
        {
            Serial.print(X(i,j), 6);   // print 6 decimal places
            Serial.print(", ");
        }
        Serial.println();
    }
    Serial.println();
}

eecharlie

For those following this thread, you may be interested to know that the MatrixMath library has been patched to have the proper #includes for the latest Arduino library, and the source is again available in the Playground (the downloadable zip file recently disappeared).

It is indeed inadequate if you want the advanced functions and high-level language simplicity of Matlab/Octave, and horribly mismatched to the capabilities of the Due's ARM processor =)

But if you're rolling your own Kalman filter or system identification/adaptive control algorithm on a simpler Arduino, it should be useful.

randomvibe

#25
Apr 04, 2013, 03:13 am Last Edit: Apr 04, 2013, 03:17 am by randomvibe Reason: 1
The basic MatrixMath library is okay.  If you want the high-level simplicity of Matlab/Octave for intense linear algebra operations, the Eigen3 C++ library is almost just a simple yet much faster.

Several projects use it including Google, the European Space Agency, some mobile apps, etc.

I have actually tested Eigne3 on the Arduino Due, and it works.  Here's an excerpt from an Arduino sketch demonstrating Matlab/Octave-like programming, on the Due:

Code: [Select]

    // Kalman Gain Example
    // Matlab form:  K = Pp * H' * inv(H * Pp * H' + R)
    // On Arduino:
    X  = H * Pp * H.transpose() + R;   
    K  = Pp * H.transpose() * X.inverse();   



I detailed out instructions for obtaining and setting up Eigen3 for the Arduino Due IDE here:

http://arduino.cc/forum/index.php/topic,144446.msg1089371.html#msg1089371

robtillaart

Code: [Select]

// Kalman Gain Example
    // Matlab form:  K = Pp * H' * inv(H * Pp * H' + R)
    // On Arduino:
    X  = H * Pp * H.transpose() + R;   
    K  = Pp * H.transpose() * X.inverse();   


might be faster this way

Code: [Select]
// Kalman Gain Example
    // Matlab form:  K = Pp * H' * inv(H * Pp * H' + R)
    // On Arduino:
    T = Pp * H.transpose();
    X  = H * T + R;   
    K  = T * X.inverse();   
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

randomvibe

Eigen3.1.3 has been recently released.  Eigen is a C++ library enabling Matlab and Octave-like matrix programming, on the Due!

Step-by-step instructions (simplified) and example are posted in following link (full ready-to-use library attached there):

http://forum.arduino.cc/index.php?topic=144446.msg1089371#msg1089371

anqurarora

#28
Dec 18, 2013, 11:07 pm Last Edit: Dec 18, 2013, 11:45 pm by anqurarora Reason: 1
Hi,

I tried the same example and that works fine on due.
but, whem I tried to use it togehter wiht "DMP6050" which has "helper_3d_math" header file included.. then it gives me error "Quaternion unambigious" i dont know what is that...if anybody can help me that.

then also i troed to comment the line " using namespace Eigen " it complied partially and removed most of the errors. the only error i am getting with this is "  expected constructor, destructor, or type conversion before '<<' token".

I think there is  a conflict between the libaraies that i am using in my project. it will be really helpfull if someone can help me out.

Thank you.

randomvibe


I am not familiar with DMP6050, but after quickly reviewing your library, "helper_3d_mat.h", it appears to have a class called "Quaternion" that will certainly clash with Quaternion in the Eigen library.  Since the "helper_3d_mat.h" only has 276 lines, I recommend changing the name of the class in question, but you'll have to rename the instances in DMP6050.  Also, you have to leave the line "using namespace Eigen", otherwise you'll have to type "Eigen::" as a prefix to Eigen related commands.  See the following example:

http://forum.arduino.cc/index.php?topic=144446.msg1089371#msg1089371

Good luck.

Go Up