示例#1
0
文件: mlrmath.c 项目: johnkerl/miller
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];
	}
}
示例#2
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;} 
		} 
	}

}
示例#3
0
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);
}