74 #define MAXITERATION 50
79 #define TESTSMALL(x, y) ((fabs(y)+(x)) == fabs(y))
88 static void PerformJacobiRotation(
int ip,
int iq,
REAL g,
int n,
123 REAL threshold = 0.0,
124 offDiagonalSum = 0.0,
128 diagonal = (
REAL *)malloc(matrixSize*
sizeof(
REAL));
129 ta_pq = (
REAL *)malloc(matrixSize*
sizeof(
REAL));
131 if((diagonal ==
NULL) || (ta_pq ==
NULL))
133 if(diagonal !=
NULL) free(diagonal);
134 if(ta_pq !=
NULL) free(ta_pq);
139 for(row=0; row<matrixSize; row++)
141 for(column=0; column<matrixSize; column++)
142 eigenVectors[row][column]=0.0;
143 eigenVectors[row][row]=1.0;
150 for(row=0; row<matrixSize; row++)
152 diagonal[row] = matrix[row][row];
153 eigenValues[row] = matrix[row][row];
161 offDiagonalSum = 0.0;
162 for(row=0; row<matrixSize-1; row++)
164 for(column=row+1; column<matrixSize; column++)
166 offDiagonalSum += fabs(matrix[row][column]);
173 if(offDiagonalSum == 0.0)
185 threshold = 0.2 * offDiagonalSum / (matrixSize*matrixSize);
192 for(row=0; row<matrixSize-1; row++)
194 for(column=row+1; column<matrixSize; column++)
196 REAL offDiagonal = 100.0 * fabs(matrix[row][column]);
202 TESTSMALL(offDiagonal, eigenValues[row]) &&
203 TESTSMALL(offDiagonal, eigenValues[column]))
205 matrix[row][column]=0.0;
207 else if(fabs(matrix[row][column]) > threshold)
209 PerformJacobiRotation(row, column, offDiagonal, matrixSize,
210 matrix, eigenVectors, eigenValues,
222 for(row=0; row<matrixSize; row++)
224 diagonal[row] += ta_pq[row];
225 eigenValues[row] = diagonal[row];
256 static void PerformJacobiRotation(
int row,
int column,
REAL offDiagonal,
261 REAL deltaEigenValue = eigenValues[column] - eigenValues[row];
270 if(
TESTSMALL(offDiagonal, deltaEigenValue))
272 t = (matrix[row][column]) / deltaEigenValue;
277 theta = 0.5 * deltaEigenValue / matrix[row][column];
279 t = 1.0 / (fabs(theta) + sqrt(1.0+theta*theta));
280 if(theta < 0.0) t = -t;
283 tTimesElement = t * matrix[row][column];
285 ta_pq[row] -= tTimesElement;
286 ta_pq[column] += tTimesElement;
287 eigenValues[row] -= tTimesElement;
288 eigenValues[column] += tTimesElement;
289 matrix[row][column] = 0.0;
291 oneOverSqrtTSq = 1.0 / sqrt(1 + (t*t));
292 tOverSqrtTSq = t * oneOverSqrtTSq;
293 tau = tOverSqrtTSq / (1.0 + oneOverSqrtTSq);
298 REAL temp1 = matrix[j][row];
299 REAL temp2 = matrix[j][column];
300 matrix[j][row] = temp1 - tOverSqrtTSq*(temp2 + temp1*tau);
301 matrix[j][column] = temp2 + tOverSqrtTSq*(temp1 - temp2*tau);
305 for(j=row+1; j<column; j++)
307 REAL temp1 = matrix[row][j];
308 REAL temp2 = matrix[j][column];
309 matrix[row][j] = temp1 - tOverSqrtTSq*(temp2 + temp1*tau);
310 matrix[j][column] = temp2 + tOverSqrtTSq*(temp1 - temp2*tau);
314 for(j=column+1; j<matrixSize; j++)
316 REAL temp1 = matrix[row][j];
317 REAL temp2 = matrix[column][j];
318 matrix[row][j] = temp1 - tOverSqrtTSq*(temp2 + temp1*tau);
319 matrix[column][j] = temp2 + tOverSqrtTSq*(temp1 - temp2*tau);
323 for(j=0; j<matrixSize; j++)
325 REAL temp1 = eigenVectors[j][row];
326 REAL temp2 = eigenVectors[j][column];
327 eigenVectors[j][row] = temp1 - tOverSqrtTSq*(temp2 + temp1*tau);
328 eigenVectors[j][column] = temp2 + tOverSqrtTSq*(temp1 - temp2*tau);
Include file for 2D/3D array functions.
int blEigen(REAL **matrix, REAL **eigenVectors, REAL *eigenValues, int matrixSize)
Type definitions for maths.