NXC: Matrix algebra library

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
linusa
Posts: 228
Joined: 16 Oct 2010, 11:44
Location: Aachen, Germany
Contact:

Re: NXC: can't pass expression to ArrayInit

Post by linusa »

doc-helmut wrote:but for NXC
A[n][0] is != A[n]
That's not the point. The point is, you ALWAYS use A[][], even if you have to define A by "float A[n][1]". A scalar would be defined as "float S[1][1]". You would access this by using "float x = S[0][0];".

Everything is a matrix. Everything hast 2 dimensions. Everyhing is always A[][]. I hope we are both clear on that, if not, please tell me where you see a problem. In this version, you NEVER need A[] (since this would, as you correctly stated, not work).
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
linusa
Posts: 228
Joined: 16 Oct 2010, 11:44
Location: Aachen, Germany
Contact:

Re: NXC: can't pass expression to ArrayInit

Post by linusa »

doc-helmut wrote:well, Linusa, I don't need your code and your assay,
You might not need it, but others might as well enjoy it. I don't want people learning "bad code" or wrong ways of doing this. If you get the habit of doings a certain way without questioning yourself, that can get very dangerous, especially in coding. Accept criticism or ignore it if you wish. I was just showing a cool way of doings things.
doc-helmut wrote: because my matrix algebra works fine,
I never doubted that.
doc-helmut wrote: and it's again OT, because the topic is about passing expressions to ArrayInit (or any other function).
It's not OT at all, since the things I wrote are exactly resolving this problem once and for all! Apart from that, we're free to discuss problems here (it's a forum where you aren't the moderator), and other people but you answered to this topic, too.

The stuff I wrote is related to matrix algebra libraries in general, yes. So it might fit better in your other thread, but it's a close call. If you don't like my posts, don't read them. I advise you to put me as "foe" on your users lists, so my posts will be hidden from your thread-view and don't bother you ever again.
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
linusa
Posts: 228
Joined: 16 Oct 2010, 11:44
Location: Aachen, Germany
Contact:

Re: NXC: can't pass expression to ArrayInit

Post by linusa »

doc-helmut wrote: a scalar would be isomorph to S[1][0] (edit - ok, don't know, maybe also 1)
That might be true, but in this case, the whole TRICK is that it has to be defined as "float A[1][1]". So in total, you have 1 * 1 = 1 element in it. If you do it this way, it consistently works out.
doc-helmut wrote:...On the other hand, I don't want to expand all 1-dim arrays[n] to arrays[n][0] before I can use them and back to calculate array[n']
That is your free choice. I'm saying, if you did do that, if you in fact expaneded all your n-vectors to "float A[n][1]" or "float A[1][n]", it would solve this problem entirely, and this is the way the big linear algebra libraries or any other math software I know does it, and this is, by my understanding, the superior way.
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: Matrix algebra library

Post by HaWe »

well,
I opened this thread to publish my library to other people who might share and enjoy it.
I have no problems with my library, but some things are still on my to-do list.
My intention is to use both more-dimensional and 1-dimensional arrays (edit: and one day maybe even 3-dim arrays) to use with the matrix algebra (not only 2-dim functions).

If you want to show us your own matrix /Linear Algebra library for NXC, which does it in a different way, do it, and show us (in a different thread).
linusa
Posts: 228
Joined: 16 Oct 2010, 11:44
Location: Aachen, Germany
Contact:

Re: NXC: Matrix algebra library

Post by linusa »

doc-helmut wrote:well,
I opened this thread to publish my library to other people who might share and enjoy it.
Thanks, and I did. I also shared some (minor) piece of code with an idea.
doc-helmut wrote: I have no problems with my library, but some things are still on my to-do list.
Consider this just as a wish for the wish-list.
doc-helmut wrote: My intention is to use both more-dimensional and 1-dimensional arrays to use with the matrix algebra (not only 2-dim functions).
I respect that, and I won't push my suggestion (it wasn't even a suggestion, just a hint of how other successful projects do things). I think it's great that you share code. If other people want to improve your library or do a spin-off, they now have more insight.
RWTH - Mindstorms NXT Toolbox for MATLAB
state of the art in nxt remote control programming
http://www.mindstorms.rwth-aachen.de
MotorControl now also in Python, .net, and Mathematica
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: Matrix algebra library

Post by HaWe »

as I don't share your minor idea for having to transfer all 1-dim matrices to 2-dim matrices forth and back in order to be able to use them (as I already clarified several times), here are the latest additional 1-dim matrix functions. Now one can simply calculate by all matrices of any size from scalar, 1x1.. ..nx1.. ..2x2.. ..nx2.. ..2xm.. ..n x m :

2-dim Matrix x 2-dim Matrix,
2-dim Matrix x 1-dim Matrix,
1-dim MatrixT x 2-dim Matrix,
2-dim Matrix Rotation (Math, Geo),
1-dim Matrix Rotation (Math, Geo):
transposed 1-dim-1-column-n-row-matrix v[n] (which will generate a 1-dim-n-column-matrix V'[1][n] with V'[0][n]=n .

Code: Select all

#define ArrayInit2D(array, tmp, init_val, dimx, dimy) { \
  ArrayInit(tmp, init_val, dimy);  \
  ArrayInit(array, tmp, dimx);     \
  ArrayInit(tmp,0,0);              \
}

                                                      // [n , m] x [m , k]
void MatrixMatrixMult(float A[][], float B[][], float &C[][], int N, int M, int K){
  int i, j, s;
  float tmp[];
  ArrayInit2D(C,tmp, 0, N, K);
  for (i=0; i<N; ++i) {
    for (j=0; j<K; ++j) {
       C[i][j]=0;
       for (s=0; s<M; ++s) {
         C[i][j]=C[i][j] + A[i][s]*B[s][j];
      }
    }
  }
}


                                                // Matrix[n,m] x Vector[m]
void MatrixVectorMult(float A[][], float B[], float &C[], int N, int M){    
  int i, s;
  ArrayInit(C,0, M);
  for (i=0; i<M; ++i) {
     C[i]=0;
     for (s=0; s<N; ++s) {
       C[i]=C[i] + A[i][s]*B[s];
     }
  }
}

                                                 // Vector[n]^T x Matrix [n,m]
void VectorMatrixMult(float A[], float B[][], float &C[], int N, int M){    // K=1
  int j, s;
  ArrayInit(C,0, M);
  for (j=0; j<M; ++j) {
     C[j]=0;
     for (s=0; s<N; ++s) {
       C[j]=C[j] + A[s]*B[s][j];
     }
  }
}


void MatrixRotate2DMath(float A[][], float &C[][], float angleDeg) {
   float tmp[], x, B[][];

   ArrayInit2D(C, tmp, 0, 2, 2);

   x=cosd(angleDeg);
   ArrayInit2D(B, tmp, x, 2, 2);
   x=sind(angleDeg);
   B[0][1]=-x;
   B[1][0]= x;

   MatrixMatrixMult(B, A, C, 2, 2, 2);
}


void VectorRotate2DMath(float A[], float &C[], float angleDeg) {
   float tmp[], x, B[][];

   ArrayInit(C, 0, 2);

   x=cosd(angleDeg);
   ArrayInit2D(B, tmp, x, 2, 2);
   x=sind(angleDeg);
   B[0][1]=-x;
   B[1][0]= x;

   MatrixVectorMult(B, A, C, 2, 2);
}


void MatrixRotate2DGeo(float A[][], float &C[][], float angleDeg) {
   float tmp[], x, B[][];
   angleDeg*=-1;
   ArrayInit2D(C, tmp, 0, 2, 2);

   x=cosd(angleDeg);
   ArrayInit2D(B, tmp, x, 2, 2);
   x=sind(angleDeg);
   B[0][1]=-x;
   B[1][0]= x;

   MatrixMatrixMult(B, A, C, 2, 2, 2);
}


void VectorRotate2DGeo(float A[], float &C[], float angleDeg) {
   float tmp[], x, B[][];
   angleDeg*=-1;
   ArrayInit(C, 0, 2);

   x=cosd(angleDeg);
   ArrayInit2D(B, tmp, x, 2, 2);
   x=sind(angleDeg);
   B[0][1]=-x;
   B[1][0]= x;

   MatrixVectorMult(B, A, C, 2, 2);
}


void VectorTransp(float A[], float &C[][], int R) {
   int r;
   float tmp[];
   ArrayInit2D(C,tmp, 0, 2,R);
   for (r=0; r<R; r++) {
     C[0][r]=A[r];
   }
}



task main() {
  float A[2][2], B[2][2], C[][], x;
  float O[4][4], T[][], L[2], M[];


  A[0][0]=1;   A[0][1]=3;
  A[1][0]=2;   A[1][1]=4;
  NumOut(0,56,A[0][0]);  NumOut(30,56,A[0][1]);
  NumOut(0,48,A[1][0]);  NumOut(30,48,A[1][1]);
  
  B[0][0]=10;   B[0][1]=0;
  B[1][0]=20;   B[1][1]=0;

  L[0]=10;
  L[1]=20;
  
  TextOut(0,40,"B Matrix  L vect");
  NumOut(0,32,B[0][0]);  NumOut(30,32,B[0][1]);  NumOut(72,32,L[0]);
  NumOut(0,24,B[1][0]);  NumOut(30,24,B[1][1]);  NumOut(72,24,L[1]);
  

  MatrixMatrixMult(A,B,C, 2,2,2);
  MatrixVectorMult(A,L,M, 2,2);
  TextOut(0,16,"A*B         A*L");
  NumOut(0, 8,C[0][0]);  NumOut(30, 8,C[0][1]);  NumOut(72, 8,M[0]);
  NumOut(0, 0,C[1][0]);  NumOut(30, 0,C[1][1]);  NumOut(72, 0,M[1]);
  
  while (!ButtonPressed(BTNCENTER, false));
  while ( ButtonPressed(BTNCENTER, false));
  ClearScreen();

  B[0][0]=1;   B[0][1]=3;
  B[1][0]=2;   B[1][1]=4;
  NumOut(0,56,B[0][0]);  NumOut(30,56,B[0][1]);
  NumOut(0,48,B[1][0]);  NumOut(30,48,B[1][1]);

  A[0][0]=10;   A[0][1]=20;
  A[1][0]=0;    A[1][1]=0;

  L[0]=10;      L[1]=20;

  TextOut(0,40,"A Matrix  L vect");
  NumOut(0,32,A[0][0]);  NumOut(24,32,A[0][1]);  NumOut(56,32,L[0]);  NumOut(78,32,L[1]);
  NumOut(0,24,A[1][0]);  NumOut(24,24,A[1][1]);


  MatrixMatrixMult(A,B,C, 2,2,2);
  VectorMatrixMult(L,B,M, 2,2);
  TextOut(0,16,"A*B         L*B");
  NumOut(0, 8,C[0][0]);  NumOut(24, 8,C[0][1]);  NumOut(56, 8,M[0]);  NumOut(78, 8,M[1]);
  NumOut(0, 0,C[1][0]);  NumOut(24, 0,C[1][1]);
  
  while (!ButtonPressed(BTNCENTER, false));
  while ( ButtonPressed(BTNCENTER, false));
  ClearScreen();
  TextOut(0,56,"Rotat 30deg Math");
  
  A[0][0]=1;   A[0][1]=0;
  A[1][0]=1;   A[1][1]=0;


  L[0]=1;
  L[1]=1;

  TextOut(0,40,"A Matrix  L vect");
  NumOut(0,32,A[0][0]);  NumOut(36,32,A[0][1]);  NumOut(66,32,L[0]);
  NumOut(0,24,A[1][0]);  NumOut(36,24,A[1][1]);  NumOut(66,24,L[1]);
  

  
  MatrixRotate2DMath(A,C,30);
  VectorRotate2DMath(L,M,30);
  TextOut(0,16,"A 30deg   L 30deg");
  NumOut(0, 8,C[0][0]);  NumOut(36, 8,C[0][1]);  NumOut(66, 8,M[0]);
  NumOut(0, 0,C[1][0]);  NumOut(36, 0,C[1][1]);  NumOut(66, 0,M[1]);
  
  while (!ButtonPressed(BTNCENTER, false));
  while ( ButtonPressed(BTNCENTER, false));
  ClearScreen();
  TextOut(0,56,"Rotat 90deg Math");

  A[0][0]=1;   A[0][1]=0;
  A[1][0]=1;   A[1][1]=0;


  L[0]=1;
  L[1]=1;

  TextOut(0,40,"A Matrix  L vect");
  NumOut(0,32,A[0][0]);  NumOut(36,32,A[0][1]);  NumOut(66,32,L[0]);
  NumOut(0,24,A[1][0]);  NumOut(36,24,A[1][1]);  NumOut(66,24,L[1]);


  MatrixRotate2DMath(A,C,90);
  VectorRotate2DMath(L,M,90);
  TextOut(0,16,"A 90deg   L 90deg");
  NumOut(0, 8,C[0][0]);  NumOut(36, 8,C[0][1]);  NumOut(66, 8,M[0]);
  NumOut(0, 0,C[1][0]);  NumOut(36, 0,C[1][1]);  NumOut(66, 0,M[1]);


  while(1);

}

Last edited by HaWe on 19 Jul 2011, 21:45, edited 1 time in total.
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: Matrix algebra library

Post by afanofosc »

I still do not understand why you insist that a matrix should be represented differently in C code depending on the count of its rows or columns. If it is a matrix then it has 2 dimensions as I have previously stated, i.e., 1 for rows and 1 for columns. If it is a vector then it has 1 dimension. If it is a scalar then it has zero dimensions and is not an array. The number or rows and columns in a matrix should not change how you represent it in C code. Treat matrices as matrices. Treat vectors as vectors. Treat scalars as scalars. If you want to add a matrix to a matrix then have a function that takes 2 2d arrays as input and outputs the result as a 2-d array. If you want to multiply a matrix by a scalar than have a function that takes a matrix (2d array) and a scalar as input and outputs a matrix (2d array). The literature that describes calculating the determinant of a 1x1 matrix never (that I have seen) refers to this simplest form of matrix as a scalar or worse, as a vector (i.e,. 1d array). It refers a 1x1 matrix as a 1x1 matrix and says that the determinant is the value at row 0 and column 0 (or 1, depending on whether they start counting rows and columns at 0 or 1).

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: Matrix algebra library

Post by afanofosc »

FYI, I merged the accidentally OT posts from the expressions in ArrayInit topic to this topic. And deleted a couple that were "this is OT/no it isn't" kind of posts.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: NXC: Matrix algebra library

Post by HaWe »

(I meanwhile think it's a matter of understanding your or my english explanations by each other).

For me, a vector in R² is nothing but a 1-dim-matrix with n rows and only 1 column. I write this: A[n].

Further more, I don't understand why you insist that vectors have to be handled differently from matrices.
I may rotate a single 2x1 vector A[2] as well as a 2x2 matrix, even without a conversion of a 2x1 vector A[2] to a 2x2 matrix or to the notation B[2][1] before

The only problem is a problem of NXC itself:
trying to pass a float A[2] with A[0]=1, A[1]=-1 to a rotation function
MatrixRotation(float A[][]; float &C[][]; float angle)
is not possible!

so I had to write a new function sort of MatrixRotation1(float A[]; float &C[]; float angle) that does it well.
It would be a quite different thing if we had pointers, recursion, or even function overloading.

if you wish to try out the matrix rotation you will see that it works both for 1-dim matrices (you are calling vectors) and for 2-dim matrices as well by the same operations. I'm sure you will have no problem to observe this.

But if you or anyone don't want to use my library and likes to handle this in a different way - I have no problem if you will or won't, I did it my way, but I don't want to be pushed to do it differently because it would end in a restriction.

And please notice that I'm no mathematics teacher, just a mathematics user. I'm sure a mathematician can explain it to you (and me) much better than I can.

To my observation, the lib works.
(In medicine, we say: who heals is right)^^
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests