//******************************************************************* // ilEuclidNorm // normalizes vectors of dim=n in mxn input matrix with the // Euclidean norm //******************************************************************* void ilEuclidNorm(pMat const& src, pMat dst) { int m = src->rows; int n = src->cols; int type = src->type; pMat ones = CreateMat(n, 1, type); pMat res1 = CreateMat(m, n, type); pMat norm = CreateMat(m, 1, type); SetValue(ones, cvScalar(1.0)); //*** compute the norm Multiply(src, src, res1); MatrixMultiply(res1, ones, norm); PowerMatrix(norm, norm, .5); //*** normalize columns of src #if 0 //*** matrix version pMat normmat = CreateMat(m, n, CV_32FC1); pMat onesrow = CreateMat(1, n, CV_32FC1); SetValue(onesrow, cvScalar(1.0)); MatrixMultiply(norm, onesrow, normmat); Divide(src, normmat, dst); #endif #if 1 // *** column version CvMat colmat1 = cvMat(0, 0, 0, 0); CvMat colmat2 = cvMat(0, 0, 0, 0); for (int i = 0; i<n; ++i) { cvGetCol(src.get(), &colmat1, i); cvGetCol(dst.get(), &colmat2, i); Divide(dummyGuard(&colmat1), norm, dummyGuard(&colmat2)); } #endif }
//************************************************************** // ilMatTestFun // performs tests of matrix functions: // ilEuclidDist, ilEuclidNorm, ilMinAtDim //*************************************************************** void ilMatFunTest() { #if 0 //*** testing ilEuclidNorm (comparison with matlab) std::string matfnamein = "C:/temp/matdata3.xml"; std::string matfnameout = "C:/temp/matdata4.xml"; pFileStorage fsr = OpenFileStorage(matfnamein, RWM_Read); pMat mat1 = ReadMatrixFromFile(fsr, "matrix1"); //*** normalize pMat mat2 = CreateMat(mat1->rows, mat1->cols, mat1->type); ilEuclidNorm(mat1, mat2); //*** Save result in xml pFileStorage fsw = OpenFileStorage(matfnameout, RWM_Write); WriteMatrixToFile(fsw, "matrix2", mat2); /* % Matlab test code m1=rand(10,5); xmlsavematrices('C:/temp/matdata3.xml',{m1},{'matrix1'}); %%% run ilMatFunTest(); [matval,matname]=xmlreadmatrices('c:/temp/matdata4.xml'); enorm=euclidnorm(m1); err=mean(abs(enorm(:)-matval{1}(:))) */ #endif #if 0 //*** testing ilEuclidDist (comparison with matlab) std::string matfnamein = "C:/temp/matdata1.xml"; std::string matfnameout = "C:/temp/matdata2.xml"; // we don't own the matrices below -- file storage does pFileStorage fsr = OpenFileStorage(matfnamein, RWM_Read); pMat mat1 = ReadMatrixFromFile(fsr, "matrix1"); pMat mat2 = ReadMatrixFromFile(fsr, "matrix2"); //*** compute Euclidean distance pMat mat3 = CreateMat(mat1->rows, mat2->rows, mat1->type); ilEuclidDist(mat1, mat2, mat3); //*** Save result in xml pFileStorage fsw = OpenFileStorage(matfnameout, RWM_Write); WriteMatrixToFile(fsw, "matrix3", mat3); // cvReleaseMat(&mat1); // TODO do we have to? // cvReleaseMat(&mat2); // TODO do we have to? /* % Matlab test code m1=rand(10,5); m2=rand(20,5); xmlsavematrices('C:/temp/matdata1.xml',{m1,m2},{'matrix1','matrix2'}); %%% run ilMatFunTest(); [matval,matname]=xmlreadmatrices('c:/temp/matdata2.xml'); edist=eucliddist(m1,m2); err=mean(abs(edist(:)-matval{1}(:))) */ #endif }
int InvertMat(MatHandler mat, MatHandler *ans){ matrix_t *m, *alg; double det = 0.0; int k = DetMat(mat, &det); if (k != M_OK || !det) return M_ERR; /* Найдем матрицу алгебраических дополнений */ m = (matrix_t *)mat; if (!m) return M_ERR_PTRISNULL; alg = (matrix_t *)CreateMat(m->cols, m->rows, NULL); if (!alg) return M_ERR_ALLOC; for (int i = 0; i < m->cols; ++i){ for (int j = 0; j < m->rows; ++j){ MatHandler t = NULL; if (CreateMinorMat(mat, i, j, &t) != M_OK) return M_ERR; double res = 0.0; if (DetMat(t, &res) != M_OK) return M_ERR; if ((i + j) % 2) alg->data[idx(i, m->cols, j)] = -res; else alg->data[idx(i, m->cols, j)] = res; } } matrix_t *talg = NULL; if (TransposeMat((MatHandler)alg, &talg) != M_OK) return M_ERR; if (NumberMulMat((MatHandler)talg, 1/det, ans) != M_OK) return M_ERR; return M_OK; }
//! Computes the 3D Hessian matrix for a pixel. CvMat* hessian3D(int r, int c, ResponseLayer *t, ResponseLayer *m, ResponseLayer *b) { CvMat* H; double v, dxx, dyy, dss, dxy, dxs, dys; v = getResponse(r, c, t, m); dxx = getResponse(r, c + 1, t, m) + getResponse(r, c - 1, t, m) - 2 * v; dyy = getResponse(r + 1, c, t, m) + getResponse(r - 1, c, t, m) - 2 * v; dss = get_Response(r, c, t) + getResponse(r, c, t, b) - 2 * v; dxy = ( getResponse(r + 1, c + 1, t, m) - getResponse(r + 1, c - 1, t, m) - getResponse(r - 1, c + 1, t, m) + getResponse(r - 1, c - 1, t, m) ) / 4.0; dxs = ( get_Response(r, c + 1, t) - get_Response(r, c - 1, t) - getResponse(r, c + 1, t, b) + getResponse(r, c - 1, t, b) ) / 4.0; dys = ( get_Response(r + 1, c, t) - get_Response(r - 1, c, t) - getResponse(r + 1, c, t, b) + getResponse(r - 1, c, t, b) ) / 4.0; H = CreateMat( 3, 3, CV_64FC1 ); cvmSet( H, 0, 0, dxx ); cvmSet( H, 0, 1, dxy ); cvmSet( H, 0, 2, dxs ); cvmSet( H, 1, 0, dxy ); cvmSet( H, 1, 1, dyy ); cvmSet( H, 1, 2, dys ); cvmSet( H, 2, 0, dxs ); cvmSet( H, 2, 1, dys ); cvmSet( H, 2, 2, dss ); return H; }
//! Performs one step of extremum interpolation. void interpolateStep(int r, int c, ResponseLayer *t, ResponseLayer *m, ResponseLayer *b, double* xi, double* xr, double* xc ) //void interpolateStep() { CvMat* dD, * H, * H_inv, X; double x[3] = { 0 }; dD = deriv3D( r, c, t, m, b ); H = hessian3D( r, c, t, m, b ); H_inv = CreateMat( 3, 3, CV_64FC1 ); cvInvert( H, H_inv, CV_SVD ); // incomplete check after invert() => CreateSVD() //cvInitMatHeader( &X, 3, 1, CV_64FC1, x, CV_AUTOSTEP ); InitMatHeader( &X, 3, 1, CV_64FC1, x, CV_AUTOSTEP ); //check cvGEMM( H_inv, dD, -1, NULL, 0, &X, 0 ); //incomplete free(&dD); free(&H); free(&H_inv); //cvReleaseMat( &dD ); //cvReleaseMat( &H ); //cvReleaseMat( &H_inv ); *xi = x[2]; *xr = x[1]; *xc = x[0]; }
int main (int argc, char* argv[]) { int size = 10, bound = 5, rate = 5; char* OUTPATH = "data_input"; int b_print = 0; //switch for the print int option; int temp,i,j; int ** A; FILE *op; while ((option = getopt(argc, argv, "s:b:r:po:")) != -1) switch(option){ case 's': size = strtol(optarg, NULL, 10); break; case 'b': bound = strtol(optarg, NULL, 10);break; case 'r': rate = strtol(optarg, NULL, 10); case 'p': b_print = 1; break; case 'o': OUTPATH = optarg; break; case '?': printf("Unexpected Options. \n"); return -1; } A = CreateMat(size); srand(time(NULL)); for (i = 0; i < size; ++i){ for (j = i; j < size; ++j){ if (rand() % 100 <= rate) A[i][j] = INF * bound; else A[i][j] = rand() % bound + 1; A[j][i] = A[i][j]; } } for (i = 0; i < size; ++i){ A[i][i] = 0; } if ((op = fopen(OUTPATH,"w")) == NULL){ printf("Cant open a file!/n"); return -2; } fprintf(op,"%d\n\n", size); for (i = 0; i < size; ++i) { for (j = 0; j < size; ++j){ fprintf(op,"%d\t", A[i][j]); } fprintf(op,"\n"); } fclose(op); if (b_print){ printf("The matrix size is %d\n", size); printf("=====================================\n"); printf("Matrix A is \n"); PrintMat(A, size); } DestroyMat(A, size); return 0; }
int TransposeMat(MatHandler mat, MatHandler *ans){ matrix_t *m, *a; m = (matrix_t *)mat; a = (matrix_t *)(*ans) = CreateMat(m->rows, m->cols, NULL); if (!a) return M_ERR_ALLOC; for (int i = 0; i < m->cols; ++i){ for (int j = 0; j < m->rows; ++j){ a->data[idx(j, m->rows, i)] = m->data[idx(i, m->cols, j)]; } } return M_OK; }
void CFkModel::InitModel() { mat = CreateMat(); new_mat = CreateMat(); s_mat = CreateMat(); new_s_mat = CreateMat(); f_mat = CreateMat(); new_f_mat = CreateMat(); }
//! Computes the partial derivatives in x, y, and scale of a pixel. CvMat* deriv3D(int r, int c, ResponseLayer *t, ResponseLayer *m, ResponseLayer *b) { CvMat* dI; double dx, dy, ds; dx = (getResponse(r, c + 1, t, m) - getResponse(r, c - 1, t, m)) / 2.0; dy = (getResponse(r + 1, c, t, m) - getResponse(r - 1, c, t, m)) / 2.0; ds = (get_Response(r, c, t) - getResponse(r, c, t, b)) / 2.0; dI = CreateMat( 3, 1, CV_64FC1 ); cvmSet( dI, 0, 0, dx ); cvmSet( dI, 1, 0, dy ); cvmSet( dI, 2, 0, ds ); return dI; }
int NumberMulMat(MatHandler mat, double k, MatHandler *ans){ matrix_t *m1, *a; m1 = (matrix_t *)mat; if (!m1) return M_ERR_PTRISNULL; a = (matrix_t *)(*ans) = (matrix_t *)CreateMat(m1->cols, m1->rows, NULL); if (!a) return M_ERR_ALLOC; for (int i = 0; i < a->cols; ++i){ for (int j = 0; j < a->rows; ++j){ int t = idx(i, a->cols, j); a->data[t] = m1->data[t] * k; } } return M_OK; }
int AddMat(MatHandler mat1, MatHandler mat2, MatHandler *ans){ matrix_t *m1, *m2, *a; m1 = (matrix_t *)mat1; m2 = (matrix_t *)mat2; if (!m1 || !m2) return M_ERR_PTRISNULL; if (m1->cols != m2->cols || m1->rows != m2->rows) return M_ERR_COLSROWS; a = (matrix_t *)(*ans) = (matrix_t *)CreateMat(m1->cols, m1->rows, NULL); if (!a) return M_ERR_ALLOC; for (int i = 0; i < a->cols; ++i){ for (int j = 0; j < a->rows; ++j){ int t = idx(i, a->cols, j); a->data[t] = m1->data[t] + m2->data[t]; } } return M_OK; }
int MatrixMulMatrix(MatHandler mat1, MatHandler mat2, MatHandler *ans){ matrix_t *m1, *m2, *a; m1 = (matrix_t *)mat1; m2 = (matrix_t *)mat2; if (m1->cols != m2->rows) return M_ERR_COLSROWS; a = (matrix_t *)(*ans) = CreateMat(m2->cols, m1->rows, NULL); if (!a) return M_ERR_ALLOC; for (int i = 0; i < a->cols; ++i){ for (int j = 0; j < a->rows; ++j){ for (int k = 0; k < m1->cols; ++k){ a->data[idx(i, a->cols, j)] += m1->data[idx(k, m1->cols, j)] * m2->data[idx(i, m2->cols, k)]; } } } return M_OK; }
int Lab3LoadInput(double ***A, int *size){ /* Allocate memory and load the input data for Lab 3. The returned matrix is the augmented size by (size+1) matrix [A|b] ----- Input: int ***A pointer to the augmented matrix [A|b] int *size pointer to the rows of the augmented matrix [A|b]. (Number of columns will be 1 more) Note: original files should be the output of the datagen.c with name "data_input" in the same folder ----- Output: Generated matrix will be passed back to the array *A, along with the matrix size in *size ----- Example: An integer array pointer and a integer should be defined before calling this function: int **A; int size; call this function as Lab3LoadInput(&A, &size); */ FILE* ip; int i,j; if ((ip = fopen("data_input","r")) == NULL){ printf("error opening the input data.\n"); return 1; } fscanf(ip, "%d\n\n", size); (*A) = CreateMat(*size, (*size) + 1); for (i = 0; i < *size; ++i){ for(j = 0; j < *size; ++j) fscanf(ip, "%lf\t", &(*A)[i][j]); fscanf(ip, "\n"); } fscanf(ip, "\n"); for (i = 0; i < *size; ++i) fscanf(ip, "%lf\n", &(*A)[i][(*size - 1) + 1]); fclose(ip); return 0; }
int CreateMinorMat(MatHandler mat, int icol, int jrow, MatHandler *ans){ /* Создает минор только n-1-ого порядка*/ matrix_t *a, *m = (matrix_t *)mat; assert(m->cols > 1 && m->rows > 1); a = (matrix_t *)(*ans) = (matrix_t *)CreateMat(m->cols - 1, m->rows - 1, NULL); if (!a) return M_ERR_ALLOC; a->cols = m->cols - 1; a->rows = m->rows - 1; int id = 0; for (int i = 0; i < m->cols; ++i){ if (i == icol) continue; for (int j = 0; j < m->rows; ++j){ if (j == jrow) continue; int r = idx(i, m->cols, j); a->data[id] = m->data[r]; ++id; } } return M_OK; }
int DetMat(MatHandler mat, double *ans){ matrix_t *m = (matrix_t *)mat; if (m->cols != m->rows) return M_ERR_COLSROWS; if (m->cols == 1){ *ans = m->data[0]; return M_OK; } if (m->cols == 2){ *ans = m->data[0] * m->data[3] - m->data[1] * m->data[2]; return M_OK; } matrix_t *t = (matrix_t *)CreateMat(m->cols - 1, m->rows - 1, NULL); /* Разложение по первой строке */ int id = 0; for (int i = 0; i < m->cols; ++i){ /* Бежит по всем определителям, дополнительным минорам */ id = 0; for (int j = 0; j < m->cols; ++j){ /* Бежит по всем столбцам */ if (j == i) continue; for (int k = 1; k < m->rows; ++k){ t->data[id] = m->data[idx(j, m->cols, k)]; ++id; } } //ShowMatrix(t); printf("\n"); double res = 0; int r = DetMat(t, &res); if (r == M_OK){ if (i % 2) *ans -= m->data[idx(i, m->cols, 0)] * res; else *ans += m->data[idx(i, m->cols, 0)] * res; } else return r; } DestroyMat(t); return M_OK; }
int main (int argc, char* argv[]){ int i, j, option; int size = 100; int b_print = 0; int range = 100; double **A, **T, **S; double *b; double temp; char* OUTPATH = "data_input"; FILE* fp; srand(time(NULL)); while ((option = getopt(argc, argv, "s:b:po:")) != -1) switch(option){ case 's': size = strtol(optarg, NULL, 10); break; case 'b': range = strtol(optarg, NULL, 10);break; case 'p': b_print = 1; break; case 'o': OUTPATH = optarg; break; case '?': printf("Unexpected Options. \n"); return -1; } /*Generate the data*/ A = CreateMat(size, size); T = CreateMat(size, size); S = CreateMat(size, size); b = malloc(size * sizeof(double)); for (i = 0; i < size; ++i) for (j = 0; j < size; ++j){ A[i][j] = 0; T[i][j] = 0; } MatGen(size, T, (double)range); GenPerm(size, A); MatMul(size, T, A, S); for (i = 0; i < size; ++i){ temp = (double)(rand() % (int)(range * DECIMAL)) / DECIMAL; if (rand() % 2) temp *= -1; b[i] = temp; } /*Output the data*/ if ((fp = fopen(OUTPATH,"w")) == NULL){ printf("Fail to open a file to save the data. \n"); return -2; } fprintf(fp, "%d\n\n", size); for (i = 0; i < size; ++i){ for (j = 0; j < size; ++j) fprintf(fp, "%lf\t", S[i][j]); fprintf(fp, "\n"); } fprintf(fp, "\n"); for (i = 0; i < size; ++i) fprintf(fp, "%lf\n", b[i]); fclose(fp); /*Print the result if neccesary*/ if (b_print){ printf("The problem size is %d.\n", size); printf("============\n The A is \n============\n"); PrintMat(S, size, size); printf("============\n The b is \n============\n"); PrintVec(b, size); } DestroyMat(A, size); DestroyMat(T, size); DestroyMat(S, size); free(b); return 0; }
//************************************************************************ // ilEuclidDist // Computes Euclidean distance between sets of points in src1 and src2. // src1 is m1*n array; src2 is m2*n array where m1 and m2 are // the number of points in each set and n is the dimensionality // of the Euclidean space. The result dst is an m1*m2 matrix // with distances between all pairs of points. // If m1=m2=1 Euclidean distance between two vectors is computed. //************************************************************************ void ilEuclidDist(pMat const& src1, pMat const& src2, pMat dst) { int m1 = src1->rows; int m2 = src2->rows; int n = src1->cols; int type=src1->type; #if 0 //*** matrix version pMat ones_nm2 = CreateMat(n, m2, type); pMat ones_m1n = CreateMat(m1, n, type); pMat src1sq = CreateMat(m1, n, type); pMat src2sq = CreateMat(m2, n, type); pMat res1 = CreateMat(m1, m2, type); pMat res2 = CreateMat(m1, m2, type); Multiply(src1, src1, src1sq); Multiply(src2, src2, src2sq); SetValue(ones_nm2, cvScalar(1.0)); SetValue(ones_m1n, cvScalar(1.0)); //*** Euclidean distance with matrix multiplications MatrixMultiply(src1sq, ones_nm2, res1); GEMM(ones_m1n, src2sq, 1.0, res1, 1, res2, CV_GEMM_B_T); GEMM(src1, src2, -2.0, res2, 1, dst, CV_GEMM_B_T); PowerMatrix(dst, dst, .5); #endif #if 1 //*** element-wise version pMat src1sq = CreateMat(m1, n, type); pMat src2sq = CreateMat(m2, n, type); Multiply(src1, src1, src1sq); Multiply(src2, src2, src2sq); float *ptrsrc1sq, *ptrsrc2sq, *ptrdst; ptrsrc1sq = Ptr2D<float>(src1sq); ptrsrc2sq = Ptr2D<float>(src2sq); ptrdst = Ptr2D<float>(dst); int indsrc1sq, indsrc2sq, inddst=0; float v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, vdst; for(int i = 0; i<m1; ++i) { indsrc1sq = i * n; v0 = ptrsrc1sq[indsrc1sq + 0]; v1 = ptrsrc1sq[indsrc1sq + 1]; v2 = ptrsrc1sq[indsrc1sq + 2]; v3 = ptrsrc1sq[indsrc1sq + 3]; v4 = ptrsrc1sq[indsrc1sq + 4]; v5 = ptrsrc1sq[indsrc1sq + 5]; v6 = ptrsrc1sq[indsrc1sq + 6]; v7 = ptrsrc1sq[indsrc1sq + 7]; v8 = ptrsrc1sq[indsrc1sq + 8]; v9 = ptrsrc1sq[indsrc1sq + 9]; for (int j=0; j<m2; ++j) { inddst = i * m2 + j; indsrc2sq = j * n; vdst = (v0-ptrsrc2sq[indsrc2sq]) * (v0-ptrsrc2sq[indsrc2sq]); vdst += (v1-ptrsrc2sq[indsrc2sq+1]) * (v1-ptrsrc2sq[indsrc2sq+1]); vdst += (v2-ptrsrc2sq[indsrc2sq+2]) * (v2-ptrsrc2sq[indsrc2sq+2]); vdst += (v3-ptrsrc2sq[indsrc2sq+3]) * (v3-ptrsrc2sq[indsrc2sq+3]); vdst += (v4-ptrsrc2sq[indsrc2sq+4]) * (v4-ptrsrc2sq[indsrc2sq+4]); vdst += (v5-ptrsrc2sq[indsrc2sq+5]) * (v5-ptrsrc2sq[indsrc2sq+5]); vdst += (v6-ptrsrc2sq[indsrc2sq+6]) * (v6-ptrsrc2sq[indsrc2sq+6]); vdst += (v7-ptrsrc2sq[indsrc2sq+7]) * (v7-ptrsrc2sq[indsrc2sq+7]); vdst += (v8-ptrsrc2sq[indsrc2sq+8]) * (v8-ptrsrc2sq[indsrc2sq+8]); vdst += (v9-ptrsrc2sq[indsrc2sq+9]) * (v9-ptrsrc2sq[indsrc2sq+9]); ptrdst[inddst] = vdst; } } #endif }
BENCHMARK(UMatBenchmarks, CreateMat, num_samples, num_iterations) { CreateMat(); }