Changeset 389 for cpp/frams/model/similarity/SVD/matrix_tools.cpp
- Timestamp:
- 05/24/15 21:03:46 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
cpp/frams/model/similarity/SVD/matrix_tools.cpp
r370 r389 15 15 double *Create(int nSize) 16 16 { 17 double *matrix = (double *) malloc(nSize * sizeof(double));18 19 20 21 22 23 24 17 double *matrix = (double *)malloc(nSize * sizeof(double)); 18 19 for (int i = 0; i < nSize; i++) 20 { 21 matrix[i] = 0; 22 } 23 24 return matrix; 25 25 } 26 26 27 27 double *Multiply(double *&a, double *&b, int nrow, int ncol, double ncol2, double *&toDel, int delSize) 28 28 { 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 29 double *c = Create(nrow * ncol2); 30 int i = 0, j = 0, k = 0; 31 32 for (i = 0; i < nrow; i++) 33 { 34 for (j = 0; j < ncol2; j++) 35 { 36 for (k = 0; k < ncol; k++) 37 c[i * nrow + j] += a[i * nrow + k] * b[k * ncol + j]; 38 } 39 } 40 41 if (delSize != 0) 42 free(toDel); 43 return c; 44 44 } 45 45 46 46 double *Power(double *&array, int nrow, int ncol, double pow, double *&toDel, int delSize) 47 47 { 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 48 double *m_Power = Create(nrow * ncol); 49 if (pow == 2) 50 { 51 for (int i = 0; i < nrow; i++) 52 { 53 for (int j = 0; j < ncol; j++) 54 { 55 m_Power[i * nrow + j] = array[i * nrow + j] * array[i * nrow + j]; 56 } 57 58 } 59 } 60 else 61 { 62 for (int i = 0; i < nrow; i++) 63 { 64 for (int j = 0; j < ncol; j++) 65 { 66 m_Power[i * nrow + j] = sqrt(array[i * nrow + j]); 67 } 68 69 } 70 } 71 72 if (delSize != 0) 73 free(toDel); 74 75 return m_Power; 76 76 } 77 77 78 78 void Print(double *&mat, int nelems) 79 79 { 80 81 82 80 for (int i = 0; i < nelems; i++) 81 printf("%6.2f ", mat[i]); 82 printf("\n"); 83 83 84 84 } … … 86 86 double *Transpose(double *&A, int arow, int acol) 87 87 { 88 89 90 91 92 93 94 95 96 88 double *result = Create(acol * arow); 89 90 for (int i = 0; i < acol; i++) 91 for (int j = 0; j < arow; j++) 92 { 93 result[i * arow + j] = A[j * acol + i]; 94 } 95 96 return result; 97 97 98 98 } 99 99 100 100 /** Computes the SVD of the nSize x nSize distance matrix 101 @param vdEigenvalues [OUT] Vector of doubles. On return holds the eigenvalues of the 102 decomposed distance matrix (or rather, to be strict, of the matrix of scalar products 103 104 105 106 107 108 101 @param vdEigenvalues [OUT] Vector of doubles. On return holds the eigenvalues of the 102 decomposed distance matrix (or rather, to be strict, of the matrix of scalar products 103 created from the matrix of distances). The vector is assumed to be empty before the function call and 104 all variance percentages are pushed at the end of it. 105 @param nSize size of the matrix of distances. 106 @param pDistances [IN] matrix of distances between parts. 107 @param Coordinates [OUT] array of three dimensional coordinates obtained from SVD of pDistances matrix. 108 */ 109 109 void MatrixTools::SVD(std::vector<double> &vdEigenvalues, int nSize, double *pDistances, Pt3D *&Coordinates) 110 110 { 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 Z[i * nSize + j] = 1.0 / ((double)nSize) * Ones[i * nSize + j];150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 size_t astep = nSize * sizeof(double);184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 Coordinates[ i].x = dCoordinates[i * nSize];210 Coordinates[ i ].y = dCoordinates[i * nSize + 1];211 212 Coordinates[ i ].z = dCoordinates[i * nSize + 2];213 214 Coordinates[ i].z = 0;215 216 217 218 219 220 221 222 223 224 225 226 } 111 // compute squares of elements of this array 112 // compute the matrix B that is the parameter of SVD 113 double *B = Create(nSize * nSize); 114 { 115 // use additional scope to delete temporary matrices 116 double *Ones, *Eye, *Z, *D; 117 118 D = Create(nSize * nSize); 119 D = Power(pDistances, nSize, nSize, 2.0, D, nSize); 120 121 Ones = Create(nSize * nSize); 122 for (int i = 0; i < nSize; i++) 123 for (int j = 0; j < nSize; j++) 124 { 125 Ones[i * nSize + j] = 1; 126 } 127 128 Eye = Create(nSize * nSize); 129 for (int i = 0; i < nSize; i++) 130 { 131 for (int j = 0; j < nSize; j++) 132 { 133 if (i == j) 134 { 135 Eye[i * nSize + j] = 1; 136 } 137 else 138 { 139 Eye[i * nSize + j] = 0; 140 } 141 } 142 } 143 144 Z = Create(nSize * nSize); 145 for (int i = 0; i < nSize; i++) 146 { 147 for (int j = 0; j < nSize; j++) 148 { 149 Z[i * nSize + j] = 1.0 / ((double)nSize) * Ones[i * nSize + j]; 150 } 151 } 152 153 for (int i = 0; i < nSize; i++) 154 { 155 for (int j = 0; j < nSize; j++) 156 { 157 Z[i * nSize + j] = Eye[i * nSize + j] - Z[i * nSize + j]; 158 } 159 } 160 161 for (int i = 0; i < nSize; i++) 162 { 163 for (int j = 0; j < nSize; j++) 164 { 165 B[i * nSize + j] = Z[i * nSize + j] * -0.5; 166 } 167 } 168 169 B = Multiply(B, D, nSize, nSize, nSize, B, nSize); 170 B = Multiply(B, Z, nSize, nSize, nSize, B, nSize); 171 172 free(Ones); 173 free(Eye); 174 free(Z); 175 free(D); 176 } 177 178 double *Eigenvalues = Create(nSize); 179 double *S = Create(nSize * nSize); 180 181 // call SVD function 182 double *Vt = Create(nSize * nSize); 183 size_t astep = nSize * sizeof(double); 184 Lapack::JacobiSVD(B, astep, Eigenvalues, Vt, astep, nSize, nSize, nSize); 185 186 double *W = Transpose(Vt, nSize, nSize); 187 188 free(B); 189 free(Vt); 190 191 for (int i = 0; i < nSize; i++) 192 for (int j = 0; j < nSize; j++) 193 { 194 if (i == j) 195 S[i * nSize + j] = Eigenvalues[i]; 196 else 197 S[i * nSize + j] = 0; 198 } 199 200 // compute coordinates of points 201 double *sqS, *dCoordinates; 202 sqS = Power(S, nSize, nSize, 0.5, S, nSize); 203 dCoordinates = Multiply(W, sqS, nSize, nSize, nSize, W, nSize); 204 free(sqS); 205 206 for (int i = 0; i < nSize; i++) 207 { 208 // set coordinate from the SVD solution 209 Coordinates[i].x = dCoordinates[i * nSize]; 210 Coordinates[i].y = dCoordinates[i * nSize + 1]; 211 if (nSize > 2) 212 Coordinates[i].z = dCoordinates[i * nSize + 2]; 213 else 214 Coordinates[i].z = 0; 215 } 216 217 // store the eigenvalues in the output vector 218 for (int i = 0; i < nSize; i++) 219 { 220 double dElement = Eigenvalues[i]; 221 vdEigenvalues.push_back(dElement); 222 } 223 224 free(Eigenvalues); 225 free(dCoordinates); 226 }
Note: See TracChangeset
for help on using the changeset viewer.