void mlr_get_real_symmetric_eigensystem( double matrix[2][2], // Input double *peigenvalue_1, // Output: dominant eigenvalue double *peigenvalue_2, // Output: less-dominant eigenvalue double eigenvector_1[2], // Output: corresponding to dominant eigenvalue double eigenvector_2[2]) // Output: corresponding to less-dominant eigenvalue { double L[2][2] = { { matrix[0][0], matrix[0][1] }, { matrix[1][0], matrix[1][1] } }; double V[2][2] = { { 1.0, 0.0 }, { 0.0, 1.0 }, }; double P[2][2], PT_A[2][2]; int n = 2; int found = 0; for (int iter = 0; iter < JACOBI_MAXITER; iter++) { double sum = 0.0; for (int i = 1; i < n; i++) for (int j = 0; j < i; j++) sum += fabs(L[i][j]); if (fabs(sum*sum) < JACOBI_TOLERANCE) { found = 1; break; } for (int p = 0; p < n; p++) { for (int q = p+1; q < n; q++) { double numer = L[p][p] - L[q][q]; double denom = L[p][q] + L[q][p]; if (fabs(denom) < JACOBI_TOLERANCE) continue; double theta = numer / denom; int sign_theta = (theta < 0) ? -1 : 1; double t = sign_theta / (fabs(theta) + sqrt(theta*theta + 1)); double c = 1.0 / sqrt(t*t + 1); double s = t * c; for (int pi = 0; pi < n; pi++) for (int pj = 0; pj < n; pj++) P[pi][pj] = (pi == pj) ? 1.0 : 0.0; P[p][p] = c; P[p][q] = -s; P[q][p] = s; P[q][q] = c; // L = P.transpose() * L * P // V = V * P matmul2t(PT_A, P, L); matmul2(L, PT_A, P); matmul2(V, V, P); } } } if (!found) { fprintf(stderr, "Jacobi eigensolver: max iterations (%d) exceeded. Non-symmetric input?\n", JACOBI_MAXITER); exit(1); } double eigenvalue_1 = L[0][0]; double eigenvalue_2 = L[1][1]; double abs1 = fabs(eigenvalue_1); double abs2 = fabs(eigenvalue_2); if (abs1 > abs2) { *peigenvalue_1 = eigenvalue_1; *peigenvalue_2 = eigenvalue_2; eigenvector_1[0] = V[0][0]; // Column 0 of V eigenvector_1[1] = V[1][0]; eigenvector_2[0] = V[0][1]; // Column 1 of V eigenvector_2[1] = V[1][1]; } else { *peigenvalue_1 = eigenvalue_2; *peigenvalue_2 = eigenvalue_1; eigenvector_1[0] = V[0][1]; eigenvector_1[1] = V[1][1]; eigenvector_2[0] = V[0][0]; eigenvector_2[1] = V[1][0]; } }
/*--------------------------------------------------------------------------*/ SCICOS_BLOCKS_IMPEXP void matmul2_m(scicos_block *block,int flag) { if (flag==1){ int i = 0; int ut=GetInType(block,1); int mu=GetOutPortRows(block,1); int nu=GetOutPortCols(block,1); switch (ut) { case SCSREAL_N :{ double *u1=GetRealInPortPtrs(block,1); double *u2=GetRealInPortPtrs(block,2); double *y1=GetRealOutPortPtrs(block,1); matmul2(y1,u1,u2,mu,nu); break;} case SCSINT32_N :{ long *u1=Getint32InPortPtrs(block,1); long *u2=Getint32InPortPtrs(block,2); long *y1=Getint32OutPortPtrs(block,1); matmul2(y1,u1,u2,mu,nu); break;} case SCSINT16_N :{ short *u1=Getint16InPortPtrs(block,1); short *u2=Getint16InPortPtrs(block,2); short *y1=Getint16OutPortPtrs(block,1); matmul2(y1,u1,u2,mu,nu); break;} case SCSINT8_N :{ char *u1=Getint8InPortPtrs(block,1); char *u2=Getint8InPortPtrs(block,2); char *y1=Getint8OutPortPtrs(block,1); matmul2(y1,u1,u2,mu,nu); break;} case SCSUINT32_N :{ unsigned long *u1=Getuint32InPortPtrs(block,1); unsigned long *u2=Getuint32InPortPtrs(block,2); unsigned long *y1=Getuint32OutPortPtrs(block,1); matmul2(y1,u1,u2,mu,nu); break;} case SCSUINT16_N :{ unsigned short *u1=Getuint16InPortPtrs(block,1); unsigned short *u2=Getuint16InPortPtrs(block,2); unsigned short *y1=Getuint16OutPortPtrs(block,1); matmul2(y1,u1,u2,mu,nu); break;} case SCSUINT8_N :{ unsigned char *u1=Getuint8InPortPtrs(block,1); unsigned char *u2=Getuint8InPortPtrs(block,2); unsigned char *y1=Getuint8OutPortPtrs(block,1); matmul2(y1,u1,u2,mu,nu); break;} case SCSCOMPLEX_N :{ double *u1r=GetRealInPortPtrs(block,1); double *u2r=GetRealInPortPtrs(block,2); double *y1r=GetRealOutPortPtrs(block,1); double *u1i=GetImagInPortPtrs(block,1); double *u2i=GetImagInPortPtrs(block,2); double *y1i=GetImagOutPortPtrs(block,1); for (i=0;i<mu*nu;i++) {y1r[i]=(u1r[i]*u2r[i])-(u1i[i]*u2i[i]); y1i[i]=(u1r[i]*u2i[i])+(u1i[i]*u2r[i]);} break;} default :{ set_block_error(-4); return;} } } }
void AvA(int n, double A[], double v[], double u[]) { double tmp[n] __attribute__ ((aligned (16))); matmul3(n, A, v, tmp); matmul2(n, tmp, A, u); }