// pivot on element _r, _c void MATRIX(_pivot)(T * _X, unsigned int _XR, unsigned int _XC, unsigned int _r, unsigned int _c) { T v = matrix_access(_X,_XR,_XC,_r,_c); if (v==0) { fprintf(stderr, "warning: matrix_pivot(), pivoting on zero\n"); return; } unsigned int r,c; // pivot using back-substitution T g; // multiplier for (r=0; r<_XR; r++) { // skip over pivot row if (r == _r) continue; // compute multiplier g = matrix_access(_X,_XR,_XC,r,_c) / v; // back-substitution for (c=0; c<_XC; c++) { matrix_access(_X,_XR,_XC,r,c) = g*matrix_access(_X,_XR,_XC,_r,c) - matrix_access(_X,_XR,_XC, r,c); } } }
void MATRIX(_swaprows)(T * _X, unsigned int _XR, unsigned int _XC, unsigned int _r1, unsigned int _r2) { if (_r1 == _r2) return; unsigned int c; T v_tmp; for (c=0; c<_XC; c++) { v_tmp = matrix_access(_X,_XR,_XC,_r1,c); matrix_access(_X,_XR,_XC,_r1,c) = matrix_access(_X,_XR,_XC,_r2,c); matrix_access(_X,_XR,_XC,_r2,c) = v_tmp; } }
void MATRIX(_inv)(T * _X, unsigned int _XR, unsigned int _XC) { // ensure lengths are valid if (_XR != _XC ) { fprintf(stderr, "error: matrix_inv(), invalid dimensions\n"); exit(1); } // X: // x11 x12 ... x1n // x21 x22 ... x2n // ... // xn1 xn2 ... xnn // allocate temporary memory T x[2*_XR*_XC]; unsigned int xr = _XR; unsigned int xc = _XC*2; // x: // x11 x12 ... x1n 1 0 ... 0 // x21 x22 ... x2n 0 1 ... 0 // ... // xn1 xn2 ... xnn 0 0 ... 1 unsigned int r,c; for (r=0; r<_XR; r++) { // copy matrix elements for (c=0; c<_XC; c++) matrix_access(x,xr,xc,r,c) = matrix_access(_X,_XR,_XC,r,c); // append identity matrix for (c=0; c<_XC; c++) matrix_access(x,xr,xc,r,_XC+c) = (r==c) ? 1 : 0; } // perform Gauss-Jordan elimination on x // x: // 1 0 ... 0 y11 y12 ... y1n // 0 1 ... 0 y21 y22 ... y2n // ... // 0 0 ... 1 yn1 yn2 ... ynn MATRIX(_gjelim)(x,xr,xc); // copy result from right half of x for (r=0; r<_XR; r++) { for (c=0; c<_XC; c++) matrix_access(_X,_XR,_XC,r,c) = matrix_access(x,xr,xc,r,_XC+c); } }
int main() { matrix_construction(); matrix_access(); test_cblas_dgemm(); test_basic_alloc(); test_asum(); test_axpy(); test_copy(); test_dot(); test_sdot(); test_dotc(); test_dotu(); test_nrm2(); test_rot(); test_rotg(); test_scal(); test_swap(); test_iamax(); test_iamin(); test_dcabs1(); test_gemv(); test_gemm(); test_vmul(); test_vml(); test_std_vector_vml(); test_gemm_boost(); return 0; }
// Gauss-Jordan elmination void MATRIX(_gjelim)(T * _X, unsigned int _XR, unsigned int _XC) { unsigned int r, c; // choose pivot rows based on maximum element along column float v; float v_max=0.; unsigned int r_opt=0; unsigned int r_hat; for (r=0; r<_XR; r++) { // check values along this column and find the maximum for (r_hat=r; r_hat<_XR; r_hat++) { v = T_ABS( matrix_access(_X,_XR,_XC,r_hat,r) ); // swap rows if necessary if (v > v_max || r_hat==r) { r_opt = r_hat; v_max = v; } } // if the maximum is zero, matrix is singular if (v_max == 0.0f) { fprintf(stderr,"warning: matrix_gjelim(), matrix singular to machine precision\n"); } // if row does not match column (e.g. maximum value does not // lie on the diagonal) swap the rows if (r != r_opt) { MATRIX(_swaprows)(_X,_XR,_XC,r,r_opt); } // pivot on the diagonal element MATRIX(_pivot)(_X,_XR,_XC,r,r); } // scale by diagonal T g; for (r=0; r<_XR; r++) { g = 1 / matrix_access(_X,_XR,_XC,r,r); for (c=0; c<_XC; c++) matrix_access(_X,_XR,_XC,r,c) *= g; } }
// // test Cholesky decomposition // void autotest_matrixcf_chol() { float tol = 1e-3f; // error tolerance // lower triangular matrix with positive values on diagonal float complex L[16]= { 1.01, 0, 0, 0, -1.42 + _Complex_I*0.25, 0.50, 0, 0, 0.32 - _Complex_I*1.23, 2.01 + _Complex_I*0.78, 0.30, 0, -1.02 + _Complex_I*1.02, -0.32 - _Complex_I*0.03, -1.65 + _Complex_I*2.01, 1.07}; float complex A[16]; // A = L * L^T float complex Lp[16]; // output Cholesky decomposition unsigned int i; // compute A matrixcf_mul_transpose(L,4,4,A); // force A to be positive definite for (i=0; i<4; i++) matrix_access(A,4,4,i,i) = creal(matrix_access(A,4,4,i,i)); // run decomposition matrixcf_chol(A,4,Lp); if (liquid_autotest_verbose) { printf("L :\n"); matrixcf_print(L,4,4); printf("A :\n"); matrixcf_print(A,4,4); printf("Lp:\n"); matrixcf_print(Lp,4,4); } for (i=0; i<16; i++) { CONTEND_DELTA( crealf(L[i]), crealf(Lp[i]), tol ); CONTEND_DELTA( cimagf(L[i]), cimagf(Lp[i]), tol ); } }
int main() { unsigned int num_iterations=8; #if 0 unsigned int n=4; float A[16] = { 1,2,3,4, 5,5,7,8, 6,4,8,7, 1,0,3,1}; #else unsigned int n=3; float A[9] = { 1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 1.0f, 1.0f, 1.0f, 2.0f}; #endif float eig[n]; float A0[n*n]; float Q[n*n], R[n*n]; memmove(A0, A, n*n*sizeof(float)); printf("\n"); printf("testing Q/R decomposition [Gram-Schmidt]\n"); matrixf_qrdecomp_gramschmidt(A,n,n,Q,R); //matrixf_print(Q,n,n); //matrixf_print(R,n,n); unsigned int k; for (k=0; k<num_iterations; k++) { // compute Q/R decomposition matrixf_qrdecomp_gramschmidt(A0,n,n,Q,R); // compute A1 = R*Q matrixf_mul(R,n,n, Q,n,n, A0,n,n); matrixf_print(A0,n,n); } // extract eigen values unsigned int i; for (i=0; i<n; i++) eig[i] = matrix_access(A0,n,n,i,i); for (i=0; i<n; i++) printf("eig[%3u] = %12.8f\n", i, eig[i]); printf("done.\n"); return 0; }
// multiply two matrices modulo 2 void matrix2_mul(unsigned char * _x, unsigned int _mx, unsigned int _nx, unsigned char * _y, unsigned int _my, unsigned int _ny, unsigned char * _z, unsigned int _mz, unsigned int _nz) { // ensure lengths are valid if (_mz != _mx || _nz != _ny || _nx != _my ) { fprintf(stderr,"error: matrix2_mul(), invalid dimensions\n"); exit(1); } unsigned int r, c, i; for (r=0; r<_mz; r++) { for (c=0; c<_nz; c++) { unsigned int sum = 0; for (i=0; i<_nx; i++) { sum += matrix_access(_x,_mx,_nx,r,i) * matrix_access(_y,_my,_ny,i,c); } matrix_access(_z,_mz,_nz,r,c) = sum % 2; } } }
void printMatrix(float *Matrix, unsigned int lines, unsigned int cols, char *mname) { char name[100]; sprintf(name, "test_%s.txt", mname); FILE *fp = fopen(name, "w"); assert(fp); for (unsigned int j = 0; j < cols; j++) { for (unsigned int i = 0; i < lines; i++) { fprintf(fp, "%.5f", matrix_access(Matrix, lines, cols, i, j)*255); } fprintf(fp, "\n"); } fclose(fp); }
void POLY(_fit)(T * _x, T * _y, unsigned int _n, T * _p, unsigned int _k) { // ... T X[_n*_k]; unsigned int r,c; T v; for (r=0; r<_n; r++) { v = 1; for (c=0; c<_k; c++) { matrix_access(X,_n,_k,r,c) = v; v *= _x[r]; } } // compute transpose of X T Xt[_k*_n]; memmove(Xt,X,_k*_n*sizeof(T)); MATRIX(_trans)(Xt,_n,_k); // compute [X']*y T Xty[_k]; MATRIX(_mul)(Xt, _k, _n, _y, _n, 1, Xty,_k, 1); // compute [X']*X T X2[_k*_k]; MATRIX(_mul)(Xt, _k, _n, X, _n, _k, X2, _k, _k); // compute inv([X']*X) T G[_k*_k]; memmove(G,X2,_k*_k*sizeof(T)); MATRIX(_inv)(G,_k,_k); // compute coefficients MATRIX(_mul)(G, _k, _k, Xty,_k, 1, _p, _k, 1); }
int main() { float x[6] = { 1, 2, 3, 4, 5, 6 }; float y[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; float z[6]; // compute z = x * y printf("z = x * y :\n"); matrixf_mul(x,2,3,y,3,3,z,2,3); matrixf_print(z,2,3); /* // compute z = y * x' matrixf_transpose(x); printf("x' : \n"); matrixf_print(x); matrixf_transpose(z); matrixf_multiply(y,x,z); printf("z = y * x' :\n"); matrixf_print(z); matrixf_destroy(x); matrixf_destroy(y); matrixf_destroy(z); */ float s[16] = { 1,2,3,4, 5,5,7,8, 6,4,8,7, 1,0,3,1 }; float s_inv[16]; memmove(s_inv,s,16*sizeof(float)); matrixf_inv(s_inv,4,4); float i4[16]; matrixf_mul(s,4,4,s_inv,4,4,i4,4,4); printf("\ns:\n"); matrixf_print(s,4,4); printf("\ninv(s):\n"); matrixf_print(s_inv,4,4); printf("\ns*inv(s):\n"); matrixf_print(i4,4,4); printf("\n"); float det = matrixf_det(s,4,4); printf("det(s) = %12.8f\n", det); #if 0 // pivot test (matrix inversion) float t[32] = { 1,2,3,4, 1,0,0,0, 5,5,7,8, 0,1,0,0, 6,4,8,7, 0,0,1,0, 1,0,3,1, 0,0,0,1 }; unsigned int i; for (i=0; i<4; i++) { matrixf_pivot(t,4,8,i,i); matrixf_print(t,4,8); } unsigned int j; for (i=0; i<4; i++) { float v = matrix_access(t,4,8,i,i); for (j=0; j<8; j++) matrix_access(t,4,8,i,j) /= v; } matrixf_print(t,4,8); #endif printf("\n"); printf("testing L/U decomposition [Crout's method]\n"); float L[16], U[16], P[16]; matrixf_ludecomp_crout(s,4,4,L,U,P); matrixf_print(L,4,4); matrixf_print(U,4,4); printf("\n"); printf("testing L/U decomposition [Doolittle's method]\n"); matrixf_ludecomp_doolittle(s,4,4,L,U,P); matrixf_print(L,4,4); matrixf_print(U,4,4); printf("\n\n"); float X[16] = { 0.84382, -2.38304, 1.43061, -1.66604, 3.99475, 0.88066, 4.69373, 0.44563, 7.28072, -2.06608, 0.67074, 9.80657, 6.07741, -3.93099, 1.22826, -0.42142 }; float Y[16]; printf("\nX:\n"); matrixf_print(X,4,4); // swaprows memmove(Y,X,16*sizeof(float)); matrixf_swaprows(Y,4,4,0,2); printf("\nmatrixf_swaprows(X,4,4,0,2):\n"); matrixf_print(Y,4,4); // pivot test memmove(Y,X,16*sizeof(float)); matrixf_pivot(Y,4,4,1,2); printf("\nmatrixf_pivot(X,4,4,1,2):\n"); matrixf_print(Y,4,4); // inverse test memmove(Y,X,16*sizeof(float)); matrixf_inv(Y,4,4); printf("\nmatrixf_inv(X,4,4):\n"); matrixf_print(Y,4,4); // determinant test float D = matrixf_det(X,4,4); printf("\nmatrixf_det(X,4) = %12.8f\n", D); // L/U decomp (Crout's method) matrixf_ludecomp_crout(X,4,4,L,U,P); printf("\nmatrixf_ludecomp_crout(X,4,4,L,U,P)\n"); printf("L:\n"); matrixf_print(L,4,4); printf("U:\n"); matrixf_print(U,4,4); // L/U decomp (Doolittle's method) matrixf_ludecomp_doolittle(X,4,4,L,U,P); printf("\nmatrixf_ludecomp_doolittle(X,4,4,L,U,P)\n"); printf("L:\n"); matrixf_print(L,4,4); printf("U:\n"); matrixf_print(U,4,4); printf("\n"); printf("testing Q/R decomposition [Gram-Schmidt]\n"); float Q[16], R[16]; matrixf_qrdecomp_gramschmidt(X,4,4,Q,R); matrixf_print(Q,4,4); matrixf_print(R,4,4); /* float b[4] = { 0.91489, 0.71789, 1.06553, -0.81707}; */ float Xb[20] = { 0.84382, -2.38304, 1.43061, -1.66604, 0.91489, 3.99475, 0.88066, 4.69373, 0.44563, 0.71789, 7.28072, -2.06608, 0.67074, 9.80657, 1.06553, 6.07741, -3.93099, 1.22826, -0.42142, -0.81707 }; printf("\n[X b] =\n"); matrixf_print(Xb,4,5); matrixf_gjelim(Xb,4,5); printf("\nmatrixf_gjelim(Xb,4,5)\n"); matrixf_print(Xb,4,5); // compute a*a' float a[20] = { -0.24655, -1.78843, 0.39477, 0.43735, -1.08998, -0.42751, 0.62496, 1.43802, 0.19814, 0.78155, -0.35658, -0.81875, -1.09984, 1.87006, -0.94191, 0.39553, -2.02036, 1.17393, 1.54591, 1.29663 }; printf("\na =\n"); matrixf_print(a,4,5); printf("\n\n"); printf("computing a*a'\n"); float aaT[16]; matrixf_mul_transpose(a,4,5,aaT); matrixf_print(aaT,4,4); printf("\n\n"); printf("computing a'*a\n"); float aTa[25]; matrixf_transpose_mul(a,4,5,aTa); matrixf_print(aTa,5,5); printf("\n"); printf("testing Gram-Schmidt\n"); float Xgs[12] = { 1., 2., 1., 0., 2., 0., 2., 3., 1., 1., 1., 0. }; float Ugs[12]; float Ugs_test[12] = { sqrtf(6.)/6., sqrtf(2.)/6., 2./3., 0., 2.*sqrtf(2.)/3.,-1./3., sqrtf(6.)/3., 0., 0., sqrtf(6.)/6., -sqrtf(2.)/6., -2./3. }; matrixf_gramschmidt(Xgs,4,3,Ugs); printf("X:\n"); matrixf_print(Xgs,4,3); printf("normalized X:\n"); matrixf_print(Ugs,4,3); printf("expected:\n"); matrixf_print(Ugs_test,4,3); // // test Cholesky decomposition // printf("\n"); printf("testing Cholesky decomposition\n"); // generate input matrix float complex Lp[9] = { 1.0, 0.0, 0.0, -3.1 + 0.2*_Complex_I, 0.3, 0.0, 1.7 + 0.5*_Complex_I, -0.6 - 0.3*_Complex_I, 2.9 }; float complex Ap[9]; matrixcf_mul_transpose(Lp, 3, 3, Ap); float complex Lc[9]; matrixcf_chol(Ap, 3, Lc); printf("Lp:\n"); matrixcf_print(Lp, 3, 3); printf("Ap:\n"); matrixcf_print(Ap, 3, 3); printf("Lc:\n"); matrixcf_print(Lc, 3, 3); printf("done.\n"); return 0; }
// compute Hessian void qnsearch_compute_Hessian(qnsearch _q) { unsigned int i, j; unsigned int n = _q->num_parameters; float f00, f01, f10, f11; float f0, f1, f2; float m0, m1; float delta = 1e-2f; // reset v_prime memmove(_q->v_prime, _q->v, (_q->num_parameters)*sizeof(float)); for (i=0; i<_q->num_parameters; i++) { //for (j=0; j<_q->num_parameters; j++) { for (j=0; j<=i; j++) { if (i==j) { _q->v_prime[i] = _q->v[i] - delta; f0 = _q->get_utility(_q->userdata, _q->v_prime, _q->num_parameters); _q->v_prime[i] = _q->v[i]; f1 = _q->get_utility(_q->userdata, _q->v_prime, _q->num_parameters); _q->v_prime[i] = _q->v[i] + delta; f2 = _q->get_utility(_q->userdata, _q->v_prime, _q->num_parameters); m0 = (f1 - f0) / delta; m1 = (f2 - f1) / delta; matrix_access(_q->H, n, n, i, j) = (m1 - m0) / delta; } else { // 0 0 _q->v_prime[i] = _q->v[i] - delta; _q->v_prime[j] = _q->v[j] - delta; f00 = _q->get_utility(_q->userdata, _q->v_prime, _q->num_parameters); // 0 1 _q->v_prime[i] = _q->v[i] - delta; _q->v_prime[j] = _q->v[j] + delta; f01 = _q->get_utility(_q->userdata, _q->v_prime, _q->num_parameters); // 1 0 _q->v_prime[i] = _q->v[i] + delta; _q->v_prime[j] = _q->v[j] - delta; f10 = _q->get_utility(_q->userdata, _q->v_prime, _q->num_parameters); // 1 1 _q->v_prime[i] = _q->v[i] + delta; _q->v_prime[j] = _q->v[j] + delta; f11 = _q->get_utility(_q->userdata, _q->v_prime, _q->num_parameters); // compute second partial derivative m0 = (f01 - f00) / (2.0f*delta); m1 = (f11 - f10) / (2.0f*delta); matrix_access(_q->H, n, n, i, j) = (m1 - m0) / (2.0f*delta); matrix_access(_q->H, n, n, j, i) = (m1 - m0) / (2.0f*delta); } } } //matrixf_print(_q->H, n, n); //exit(1); }
int main() { // options unsigned int n = 8; unsigned int i; // allocate memory for arrays float A[n*n]; float b[n]; float x[n]; float x_hat[n]; // generate symmetric positive-definite matrix by first generating // lower triangular matrix L and computing A = L*L' float L[n*n]; unsigned int j; for (i=0; i<n; i++) { for (j=0; j<n; j++) { #if 0 // sparse matrix if (j > i) matrix_access(L,n,n,i,j) = 0.0; else if (j == i) matrix_access(L,n,n,i,j) = randnf(); else if ((rand()%4)==0) matrix_access(L,n,n,i,j) = randnf(); else matrix_access(L,n,n,i,j) = 0.0; #else // full matrix matrix_access(L,n,n,i,j) = (j < i) ? 0.0 : randnf(); #endif } } matrixf_mul_transpose(L, n, n, A); // generate random solution for (i=0; i<n; i++) x[i] = randnf(); // compute b matrixf_mul(A, n, n, x, n, 1, b, n, 1); // solve symmetric positive-definite system of equations matrixf_cgsolve(A, n, b, x_hat, NULL); //matrixf_linsolve(A, n, b, x_hat, NULL); // print results printf("A:\n"); matrixf_print(A, n, n); printf("b:\n"); matrixf_print(b, n, 1); printf("x (original):\n"); matrixf_print(x, n, 1); printf("x (estimate):\n"); matrixf_print(x_hat, n, 1); // compute error norm float e = 0.0; for (i=0; i<n; i++) e += (x[i] - x_hat[i])*(x[i] - x_hat[i]); e = sqrt(e); printf("error norm: %12.4e\n", e); printf("done.\n"); return 0; }
bool PdfTransfer::NDPdfTransfer(float *input, float *palette, float **rotations) { clock_t start, end; FILE *fp = fopen("time.txt", "w"); unsigned long int var_time = 0; float *finalPic = new float[_projections * _inputSize]; for (unsigned int i = 0; i < _iterations; ++i) { start = clock(); float * ptrRotation = rotations[i]; assert(ptrRotation); float *inputRotation = new float[_projections * _inputSize]; float *paletteRotation = new float[_projections * _paletteSize]; _matrixModule->matrix_multiply(ptrRotation, _projections, NUM_CHANNELS, input, NUM_CHANNELS, _inputSize, inputRotation, _projections, _inputSize); #ifdef DEBUG if (!i) { printMatrix(ptrRotation, _projections, NUM_CHANNELS, "ptrRotation", _height, _width); printMatrix(input, NUM_CHANNELS, _inputSize, "input", _height, _width); printMatrix(inputRotation, _projections, _inputSize, "inputRotation", _height, _width); } #endif _matrixModule->matrix_multiply(ptrRotation, _projections, NUM_CHANNELS, palette, NUM_CHANNELS, _paletteSize, paletteRotation, _projections, _paletteSize); #ifdef DEBUG if (!i) { printMatrix(palette, NUM_CHANNELS, _paletteSize, "palette", _height, _width); printMatrix(paletteRotation, _projections, _paletteSize, "paletteRotation", _height, _width); } #endif Histogram ** histogramsInput = new Histogram*[_projections]; Histogram ** histogramsPalette = new Histogram*[_projections]; //Step1: Creation of Histograms CreateHistograms(inputRotation, _inputSize, paletteRotation, _paletteSize, _projections, histogramsInput, histogramsPalette); #ifdef DEBUG printHistogr(histogramsInput, i); #endif std::vector<float> *inter = new std::vector<float>[_projections]; for (unsigned int j = 0; j < _projections; ++j) { std::vector<float> ptr = SinglePdfTransfer(histogramsInput[j], histogramsPalette[j]); std::vector<float> newPtr(ptr.begin() + 1, ptr.end() - 1); float scale = bin_count / (histogramsInput[j]->GetOverallMax() - histogramsInput[j]->GetOverallMin()); //populate X points before interpolation std::vector<float> X(newPtr.size()); for (unsigned int k = 0; k < X.size(); ++k) { X[k] = (float) k; } std::vector<float> Xq(_inputSize); unsigned int itr = 0; for (unsigned k = j * _inputSize; k < (j + 1) * _inputSize; ++k, ++itr) { Xq[itr] = inputRotation[k]; Xq[itr] = (Xq[itr] - histogramsInput[j]->GetOverallMin()) * scale; } inter[j] = linearInterpolation(X, newPtr, Xq); for (unsigned int k = 0; k < inter[j].size(); ++k) { inter[j][k] = inter[j][k] / scale + histogramsInput[j]->GetOverallMin(); inter[j][k] -= matrix_access(inputRotation, _projections, _inputSize, j, k); matrix_access(finalPic, _projections, _inputSize, j, k) = inter[j][k]; } } #ifdef DEBUG char filename2[10]; sprintf(filename2, "finalPic%d", i); printMatrix(finalPic, _projections, _inputSize, filename2, _height, _width); #endif //resolve linear system of ptrRotation*x = inter _matrixModule->matrix_inverse(ptrRotation, _projections, NUM_CHANNELS); float *aux = new float[ _projections * _inputSize ]; _matrixModule->matrix_multiply(ptrRotation, _projections, NUM_CHANNELS, finalPic, _projections, _inputSize, aux, _projections, _inputSize); _matrixModule->matrix_add(input, aux, input, _projections, _inputSize); #ifdef DEBUG //if(!i) //{ char filename[10]; sprintf(filename, "iter%d", i); printMatrix(input, _projections, _inputSize, filename, _height, _width); //} #endif end = clock(); var_time = (end - start) / (CLOCKS_PER_SEC); fprintf(fp, "It took %lu seconds to complete %d iteration\n", var_time, i); //freeing memory delete [] inputRotation; delete [] paletteRotation; } //freeing heap delete [] finalPic; //used for logging time fclose(fp); return true; }
void PdfTransfer::CreateHistograms(float *input, unsigned int iSize, float *palette, unsigned int pSize, unsigned int projections, Histogram **orig, Histogram **target) { static int var = 0; assert(orig); assert(target); for (unsigned int i = 0; i < projections; ++i) { float minimum, maximum; minimum = maximum = matrix_access(input, projections, iSize, i, 0); //finding minumum and maximum per line for input matrix for (unsigned int j = 0; j < iSize; ++j) { if (matrix_access(input, projections, iSize, i, j) < minimum) { minimum = matrix_access(input, projections, iSize, i, j); } if (matrix_access(input, projections, iSize, i, j) > maximum) { maximum = matrix_access(input, projections, iSize, i, j); } } //finding minumum and maximum per line for palette matrix for (unsigned int j = 0; j < pSize; ++j) { if (matrix_access(palette, projections, pSize, i, j) < minimum) { minimum = matrix_access(palette, projections, pSize, i, j); } if (matrix_access(palette, projections, pSize, i, j) > maximum) { maximum = matrix_access(palette, projections, pSize, i, j); } } float step = (maximum - minimum) / (float) bin_count; orig[i] = new Histogram[ bin_count + 1]; for (unsigned int j = 0; j < iSize; ++j) { float element = matrix_access(input, projections, iSize, i, j); float dblPos = (element - minimum) / step; //int pos = static_cast<int>(floor(dblPos)); int pos = static_cast<int> (round(dblPos)); assert(pos < bin_count + 1); assert(pos >= 0); orig[i][pos].incrementCounter(); orig[i][pos].SetInferiorLimit(minimum + pos * step); orig[i][pos].SetSuperiorLimit(minimum + (pos + 1) * step); orig[i]->incrementGlobalCounter(); orig[i]->SetOverallMax(maximum); orig[i]->SetOverallMin(minimum); } target[i] = new Histogram[ bin_count + 1]; for (unsigned int j = 0; j < pSize; ++j) { float dblPos = (matrix_access(palette, projections, pSize, i, j) - minimum) / step; //int pos = static_cast<int>(floor(dblPos)); int pos = static_cast<int> (round(dblPos)); assert(pos < bin_count + 1); assert(pos >= 0); target[i][pos].incrementCounter(); target[i][pos].SetInferiorLimit(minimum + pos * step); target[i][pos].SetSuperiorLimit(minimum + (pos + 1) * step); target[i]->incrementGlobalCounter(); target[i]->SetOverallMax(maximum); target[i]->SetOverallMin(minimum); } #ifdef DEBUG if (!var) { FILE *fp = NULL; char name[100]; char name2[100]; sprintf(name, "histo_orig%d.txt", i); sprintf(name2, "histo_palette%d.txt", i); fp = fopen(name, "w"); for (unsigned int j = 0; j < 301; ++j) { fprintf(fp, "%d\n", orig[i][j].getCounter()); } fclose(fp); fp = fopen(name2, "w"); for (unsigned int j = 0; j < 301; ++j) { fprintf(fp, "%d\n", target[i][j].getCounter()); } fclose(fp); } #endif } var++; }
// update BFGS estimate of Hessian matrix inverse // _n : dimension // _dx : step size (previous), [size: _n x 1] // _y : gradient difference // _H0 : Hessian matrix inverse estimate (previous), [size: _n x _n] // _H1 : Hessian matrix inverse estimate [size: _n x _n] void bfgs_update(unsigned int _n, float * _dx, float * _y, float * _H0, float * _H1) { #if DEBUG_BFGS // print inputs printf("********************\n"); print_vector(" dx ", _dx, _n); print_vector(" y ", _y, _n); printf("H0 = \n"); matrixf_print(_H0,_n,_n); #endif // //float In[_n*_n]; // I(_n) [_n x _n] float ydxT[_n*_n]; // _y * _dx' [_n x _n] float yTdx; // _y' * _dx [1 x 1] float q[_n*_n]; // I(_n) - (_y*_dx' / _y'_dx) [_n x _n] float dxdxT[_n*_n]; // _dx * _dx' [_n x _n] float tmp[_n*_n]; // temporary array [_n x _n] // compute _y * _dx' matrixf_mul(_y, _n, 1, _dx, 1, _n, ydxT, _n, _n); #if DEBUG_BFGS printf("y*dx' = \n"); matrixf_print(ydxT,_n,_n); #endif // compute _y' * _dx' matrixf_mul(_y, 1, _n, _dx, _n, 1, &yTdx, 1, 1); // compute _n x _n identity matrix // compute q unsigned int i; unsigned int j; for (i=0; i<_n; i++) { for (j=0; j<_n; j++) { matrix_access(q,_n,_n,i,j) = (i==j ? 1.0f : 0.0f) - matrix_access(ydxT,_n,_n,i,j)/yTdx; } } #if DEBUG_BFGS printf("q = \n"); matrixf_print(q,_n,_n); #endif // compute _dx*_dx' matrixf_mul(_dx, _n, 1, _dx, 1, _n, dxdxT, _n, _n); #if DEBUG_BFGS printf("dx*dx' = \n"); matrixf_print(dxdxT,_n,_n); #endif // compute _H0 * q, store in tmp matrixf_mul(_H0, _n, _n, q, _n, _n, tmp, _n, _n); // compute q' (transpose) matrixf_trans(q, _n, _n); // compute q' * _H0 * _q, store in _H1 matrixf_mul(q, _n, _n, tmp, _n, _n, _H1, _n, _n); // add dxdxT / yTdx to _H1 for (i=0; i<_n; i++) { for (j=0; j<_n; j++) { matrix_access(_H1,_n,_n,i,j) += matrix_access(dxdxT,_n,_n,i,j) / yTdx; } } #if DEBUG_BFGS printf("H1 = \n"); matrixf_print(_H1,_n,_n); #endif }
// Orthnormalization using the Gram-Schmidt algorithm void MATRIX(_gramschmidt)(T * _x, unsigned int _rx, unsigned int _cx, T * _v) { // validate input if (_rx == 0 || _cx == 0) { fprintf(stderr,"error: matrix_gramschmidt(), input matrix cannot have zero-length dimensions\n"); exit(1); } unsigned int i; unsigned int j; unsigned int k; // copy _x to _u memmove(_v, _x, _rx * _cx * sizeof(T)); unsigned int n = _rx; // dimensionality of each vector T proj_ij[n]; for (j=0; j<_cx; j++) { for (i=0; i<j; i++) { // v_j <- v_j - proj(v_i, v_j) #if DEBUG_MATRIX_GRAMSCHMIDT printf("computing proj(v_%u, v_%u)\n", i, j); #endif // compute proj(v_i, v_j) T vij = 0.; // dotprod(v_i, v_j) T vii = 0.; // dotprod(v_i, v_i) T ti; T tj; for (k=0; k<n; k++) { ti = matrix_access(_v, _rx, _cx, k, i); tj = matrix_access(_v, _rx, _cx, k, j); T prodij = ti * conj(tj); vij += prodij; T prodii = ti * conj(ti); vii += prodii; } // TODO : vii should be 1.0 from normalization step below T g = vij / vii; // complete projection for (k=0; k<n; k++) proj_ij[k] = matrix_access(_v, _rx, _cx, k, i) * g; // subtract projection from v_j for (k=0; k<n; k++) matrix_access(_v, _rx, _cx, k, j) -= proj_ij[k]; } // normalize v_j T vjj = 0.; // dotprod(v_j, v_j) T tj = 0.; for (k=0; k<n; k++) { tj = matrix_access(_v, _rx, _cx, k, j); T prodjj = tj * conj(tj); vjj += prodjj; } // TODO : check magnitude of vjj T g = 1. / sqrt( creal(vjj) ); for (k=0; k<n; k++) matrix_access(_v, _rx, _cx, k, j) *= g; #if DEBUG_MATRIX_GRAMSCHMIDT MATRIX(_print)(_v, _rx, _cx); #endif } }
// Q/R decomposition using the Gram-Schmidt algorithm void MATRIX(_qrdecomp_gramschmidt)(T * _x, unsigned int _rx, unsigned int _cx, T * _Q, T * _R) { // validate input if (_rx != _cx) { fprintf(stderr,"error: matrix_qrdecomp_gramschmidt(), input matrix not square\n"); exit(-1); } unsigned int n = _rx; unsigned int i; unsigned int j; unsigned int k; // generate and initialize matrices T e[n*n]; // normalized... for (i=0; i<n*n; i++) e[i] = 0.0f; for (k=0; k<n; k++) { // e(i,k) <- _x(i,k) for (i=0; i<n; i++) matrix_access(e,n,n,i,k) = matrix_access(_x,n,n,i,k); // subtract... for (i=0; i<k; i++) { // compute dot product _x(:,k) * e(:,i) T g = 0; for (j=0; j<n; j++) { T prod = matrix_access(_x,n,n,j,k) * conj( matrix_access(e,n,n,j,i) ); g += prod; } //printf(" i=%2u, g = %12.4e\n", i, crealf(g)); for (j=0; j<n; j++) matrix_access(e,n,n,j,k) -= matrix_access(e,n,n,j,i) * g; } // compute e_k = e_k / |e_k| float ek = 0.0f; T ak; for (i=0; i<n; i++) { ak = matrix_access(e,n,n,i,k); ek += fabsf( ak*conjf(ak) ); } ek = sqrtf(ek); // normalize e for (i=0; i<n; i++) matrix_access(e,n,n,i,k) /= ek; } // move Q memmove(_Q, e, n*n*sizeof(T)); // compute R // j : row // k : column for (j=0; j<n; j++) { for (k=0; k<n; k++) { if (k < j) { matrix_access(_R,n,n,j,k) = 0.0f; } else { // compute dot product between and Q(:,j) and _x(:,k) T g = 0; for (i=0; i<n; i++) { T prod = conj( matrix_access(_Q,n,n,i,j) ) * matrix_access(_x,n,n,i,k); g += prod; } matrix_access(_R,n,n,j,k) = g; } } } }