[PD-cvs] externals/iem/iemmatrix/src mtx_inverse.c,1.3,1.4
IOhannes m zmölnig
zmoelnig at users.sourceforge.net
Wed May 11 16:07:21 CEST 2005
Update of /cvsroot/pure-data/externals/iem/iemmatrix/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24854
Modified Files:
mtx_inverse.c
Log Message:
for non-square matrices, we now calculate automatically the (correct) pseudoinverse
Index: mtx_inverse.c
===================================================================
RCS file: /cvsroot/pure-data/externals/iem/iemmatrix/src/mtx_inverse.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** mtx_inverse.c 11 May 2005 13:05:29 -0000 1.3
--- mtx_inverse.c 11 May 2005 14:07:18 -0000 1.4
***************
*** 18,22 ****
! t_matrixfloat* mtx_doInvert(t_matrixfloat*input, int rowcol){
/*
* row==col==rowclo
--- 18,22 ----
! t_matrixfloat* mtx_doInvert(t_matrixfloat*input, int rowcol, int*error){
/*
* row==col==rowclo
***************
*** 31,38 ****
int col=rowcol, row=rowcol, row2=row*col;
t_matrixfloat *original=input;
! // 1a reserve space for the inverted matrix
! t_matrixfloat *inverted = (t_matrixfloat *)getbytes(sizeof(t_matrixfloat)*row2);
! // 1b make an eye-shaped float-buf for B
i=row2;
b1=inverted;
--- 31,43 ----
int col=rowcol, row=rowcol, row2=row*col;
t_matrixfloat *original=input;
+ t_matrixfloat *inverted = 0;
! if(input==0)return 0;
!
! /* 1a reserve space for the inverted matrix */
! inverted=(t_matrixfloat *)getbytes(sizeof(t_matrixfloat)*row2);
! if(inverted==0)return 0;
!
! /* 1b make an eye-shaped float-buf for B */
i=row2;
b1=inverted;
***************
*** 42,48 ****
while(i--)b1[i*(row+1)]=1;
! // 2. do the Gauss-Jordan
for (k=0;k<row;k++) {
! // 2. adjust current row
t_matrixfloat diagel = original[k*(col+1)];
t_matrixfloat i_diagel = diagel?1./diagel:0;
--- 47,53 ----
while(i--)b1[i*(row+1)]=1;
! /* 2. do the Gauss-Jordan */
for (k=0;k<row;k++) {
! /* adjust current row */
t_matrixfloat diagel = original[k*(col+1)];
t_matrixfloat i_diagel = diagel?1./diagel:0;
***************
*** 57,62 ****
*b2++*=i_diagel;
}
- /* eliminate the k-th element in each row by adding the weighted normalized row */
a2=original+k*row;
b2=inverted+k*row;
--- 62,67 ----
*b2++*=i_diagel;
}
+ /* eliminate the k-th element in each row by adding the weighted normalized row */
a2=original+k*row;
b2=inverted+k*row;
***************
*** 73,78 ****
}
}
-
if (ok)post("mtx_inverse: couldn't really invert the matrix !!! %d error%c", ok, (ok-1)?'s':0);
return inverted;
--- 78,83 ----
}
}
if (ok)post("mtx_inverse: couldn't really invert the matrix !!! %d error%c", ok, (ok-1)?'s':0);
+ if(error!=0)*error=ok;
return inverted;
***************
*** 92,123 ****
}
! // 1 extract values of A to float-buf
! original=matrix2float(argv);
!
! // reserve memory for outputting afterwards
adjustsize(x, col, row);
! if (row!=col){
! // we'll have to do the pseudo-inverse:
! // P=A'*inv(A*A');
! t_matrixfloat*transposed=mtx_doTranspose(original, row, col);
! t_matrixfloat*invertee =mtx_doMultiply(row, original, col, transposed, row);
! inverted=mtx_doMultiply(col, transposed, row, mtx_doInvert(invertee, row), row);
! freebytes(transposed, sizeof(t_matrixfloat)*col*row);
! freebytes(invertee , sizeof(t_matrixfloat)*row*row);
!
} else {
! inverted=mtx_doInvert(original, row);
}
! // 3. output the matrix
! // 3a convert the floatbuf to an atombuf;
float2matrix(x->atombuffer, inverted);
! // 3b destroy the buffers
freebytes(original, sizeof(t_matrixfloat)*row*col);
- freebytes(inverted, sizeof(t_matrixfloat)*row*row);
! // 3c output the atombuf;
matrix_bang(x);
}
--- 97,137 ----
}
! /* reserve memory for outputting afterwards */
adjustsize(x, col, row);
! /* 1. extract values of A to float-buf */
! original=matrix2float(argv);
! if (row==col){
! /* fine, the matrix is square */
! inverted=mtx_doInvert(original, row, 0);
} else {
! /* we'll have to do the pseudo-inverse:
! * P=A'*inv(A*A') if row<col
! * P=inv(A'*A)*A' if col<row
! */
! t_matrixfloat*transposed, *invertee;
! int inverteeCol=0;
! transposed=mtx_doTranspose(original, row, col);
! if(row>col){
! inverteeCol=col;
! invertee =mtx_doMultiply(col, transposed, row, original, col);
! inverted =mtx_doMultiply(col, mtx_doInvert(invertee, col, 0), col, transposed, row);
! } else {
! inverteeCol=row;
! invertee =mtx_doMultiply(row, original, col, transposed, row);
! inverted =mtx_doMultiply(col, transposed, row, mtx_doInvert(invertee, row, 0), row);
! }
! freebytes(transposed, sizeof(t_matrixfloat)*col*row);
! freebytes(invertee , sizeof(t_matrixfloat)*inverteeCol*inverteeCol);
}
! /* 3. output the matrix */
! /* 3a convert the floatbuf to an atombuf; */
float2matrix(x->atombuffer, inverted);
! /* 3b destroy the buffers */
freebytes(original, sizeof(t_matrixfloat)*row*col);
! /* 3c output the atombuf; */
matrix_bang(x);
}
More information about the Pd-cvs
mailing list