#include #include #include "mex.h" /* boompf.c */ /* Computational subroutines */ /* removeCol * Remove column i of the m*n matrix mat; the columns at the right of column i are shifted to the left * mat: pointer to the original matrix * new_mat: pointer to the matrix mat with column i removed and columns at the right of column i shifted to the left * m: number of lines of mat * n: number of columns of mat * i: index of the column to be removed */ void removeCol(double *new_mat, double *mat, int m, int n, int i) { int ind, ind2; --i; for(ind = 0; ind < i; ++ind) { for (ind2 = 0; ind2 < m; ++ind2) { *(new_mat + ind * m + ind2) = *(mat + ind * m + ind2); } } for(ind = i; ind < n - 1; ++ind) { for (ind2 = 0; ind2 < m; ++ind2) { *(new_mat + ind * m + ind2) = *(mat + (ind + 1) * m + ind2); } } } /* prodMatrices * Product of matrices: result = mat1*mat2 * result: pointer to the matrix of the product * mat1: pointer to the first matrix * m1: number of lines of mat1 * n1: number of columns of mat1 * mat2: pointer to the second matrix * m2: number of lines of mat2 * n2: number of columns of mat2 */ void prodMatrices(double *result, double *mat1, int m1, int n1, double *mat2, int m2, int n2) { int ind, ind2, ind3; if (n1 != m2) { printf("Multiplication (%d*%d)*(%d*%d) impossible\n",m1, n1, m2, n2); return; } for (ind=0; ind N - 1) { printf("%s: Required index %d is out of range (%d atoms)\n", name, j + 1, N); return; } ++j; /* b=beta(:,j)/norm(beta(:,j)) */ extractCol(beta, j, j, betaj, 1, 1, L, N, 1); normVec(betaj, L, normbetaj); for (ind = 0; ind < L; ++ind) { *(b + ind) = *(betaj + ind) / *normbetaj; } /* beta(:,j)=[] */ removeCol(beta_temp, beta, L, N, j); /* beta=beta-b*(b'*beta) */ transpose(trb, b, L, 1); prodMatrices(dummyprod, b, L, 1, trb, 1, L); prodMatrices(dummyprod2, dummyprod, L, L, beta_temp, L, N - 1); subMatrices(beta_temp, beta_temp, L, N - 1, dummyprod2, L, N - 1); free(trb); free(dummyprod); free(dummyprod2); free(dummySub); /* R=psin(:,1:kb)'*D(:,1:kb); */ extractCol(D, 1, N, D_temp, 1, N, L, N, N); extractCol(psin, 1, N, dummypsin, 1, N, L, N, N); transpose(trdummypsin, dummypsin, L, N); prodMatrices(R, trdummypsin, N, L, D_temp, L, N); free(D_temp); free(dummypsin); free(trdummypsin); /* dummy=R(:,j); */ extractCol(R, j, j, dummy, 1, 1, N, N, 1); /* R(:,j)=[]; */ removeCol(R_temp, R, N, N, j); /* R(:,kb)=dummy; */ extractCol(dummy, 1, 1, R_temp, N, N, N, 1, N); for (ind = j; ind < N; ++ind) { double *R_temp2 = malloc(2 * sizeof(double)); mxArray *array_ptr; mxArray *input_array[1], *output_array[2]; int num_in=1; int num_out=2; double *G = malloc(4 * sizeof(double)); double *R_temp3 = malloc(2 * sizeof(double)); double *R_temp4 = malloc(2 * (N - ind) * sizeof(double)); double *dummyprod = malloc(2 * (N - ind) * sizeof(double)); double *psinp = malloc(L * 2 * sizeof(double)); double *trG = malloc(4 * sizeof(double)); double *dummyprod2 = malloc(L * 2 * sizeof(double)); int p[2]; p[0] = ind; p[1] = ind + 1; //printf("p[0]=%d\t p[1]=%d\n", p[0], p[1]); injectEl(R_temp, ind, ind, p[0], p[1], R_temp2, 1, 1, 1, 2, N, N, 2, 1); //printf("R_temp[%d][%d]=%f\t R_temp[%d][%d]=%f\n", p[0]-1, ind-1, *(R_temp+(ind-1)*N+p[0]-1), p[1]-1, ind-1, *(R_temp+(ind-1)*N+p[1]-1)); //printf("R_temp2[0][0]=%f\t R_temp2[1][0]=%f\n", *R_temp2, *(R_temp2+1)); /* [G,R(p,i)]=planerot(R(p,i)); %find appropriate Givens rotation */ array_ptr = mxCreateDoubleMatrix(2, 1, mxREAL); memcpy(mxGetPr(array_ptr), R_temp2, 2*sizeof(double)); input_array[0]=array_ptr; mexCallMATLAB(num_out, output_array, num_in, input_array, "planerot"); G=mxGetPr(output_array[0]); //printf("G[0][0]=%f\t G[1][0]=%f\t G[0][1]=%f\t G[1][1]=%f\n", *G, *(G+1), *(G+2), *(G+3)); R_temp3=mxGetPr(output_array[1]); //printf("R_temp3[0][0]=%f\t R_temp3[1][0]=%f\n", *R_temp3, *(R_temp3+1)); free(array_ptr); free(input_array); free(output_array); injectEl(R_temp3, 1, 1, 1, 2, R_temp, ind, ind, p[0], p[1], 2, 1, N, N); //printf("R_temp[%d][%d]=%f\t R_temp[%d][%d]=%f\n", p[0]-1, ind-1, *(R_temp+(ind-1)*N+p[0]-1), p[1]-1, ind-1, *(R_temp+(ind-1)*N+p[1]-1)); /* R(p,i+1:kb)=G*R(p,i+1:kb); %apply Givens rotation to R(p,i+1:k) */ injectEl(R_temp, ind + 1, N, p[0], p[1], R_temp4, 1, N - ind, 1, 2, N, N, 2, N - ind); //for (indTest=0; indTestN) { printf("%s: You want to reduce %d atoms into %d atoms!\n",name, N, No); return; } /* C=f*beta; */ prodMatrices(C, f, 1, L, beta, L, N); /* c=C; */ assignPr(c, C, N); /* SQRT NOT COMPUTED SINCE delta=1*/ /* nor1=norm(f'-D(:,1:N)*C')*sqrt(delta); nor2=nor1; */ transpose(trC, C, 1, N); extractCol(D, 1, N, dummyD, 1, N, L, N, N); prodMatrices(dummyprod, dummyD, L, N, trC, N, 1); transpose(trf, f, 1, L); subMatrices(dummySub, trf, L, 1, dummyprod, L, 1); normVec(dummySub, L, nor1); nor2=nor1; free(trC); free(dummyD); free(dummyprod); free(trf); free(dummySub); if ((*nor1>tol) && (No==0)) { printf("\n%s: Approximation is too coarse, I cannot satisfy the tolerance condition\n",name); } else { int ind, s = N; double *trnew_c, *dummyD, *dummyprod, *trf, *dummySub; for (ind=0; indtol); break; end */ /* TO BE FINISHED PROPERLY RETURN */ transpose(trC, C, 1, s); extractCol(D, 1, s, dummyD, 1, s, L, N, s); prodMatrices(dummyprod2, dummyD, L, s, trC, s, 1); transpose(trf, f, 1, L); subMatrices(dummySub, trf, L, 1, dummyprod2, L, 1); normVec(dummySub, L, norSub); free(trC); free(dummyD); free(dummyprod2); free(trf); free(dummySub); if ((tol != 0) && *norSub>tol) { assignPr(new_D, D, L * N_D); assignPr(new_Q, Q, L * N_D); assignPr(new_beta, beta, L * N); assignPr(new_Di, Di, N_D); assignPr(new_c, c, N); goto stopCond; } /* [D,Q,beta]=biodictdel(D,Q,beta,p); */ /* TO BE FINISHED PROPERLY ALLOCATION OF POINTERS */ biodictdel(new_D, new_Q, new_beta, D, Q, beta, p, L, N_D, N); /* dummy=Di(p); Di(p)=[]; Di(N)=dummy; C(p)=[]; c=C; */ extractCol(Di, p + 1, p + 1, dummy, 1, 1, 1, N_D, 1); removeCol(Di_temp, Di, 1, N_D, p + 1); injectEl(dummy, 1, 1, 1, 1, Di_temp, N, N, 1, 1, 1, 1, 1, N_D); free(dummy); memcpy(new_Di, Di_temp, (N_D - 1) * sizeof(double)); removeCol(C, C, 1, s, p+1); assignPr(new_c, C, N); s = L - (ind + 1); } stopCond: /* nor2=norm(f'-D(:,1:s)*c')*sqrt(delta); */ trnew_c = malloc(s * sizeof(double)); transpose(trnew_c, new_c, 1, s); dummyD = malloc((L * s) * sizeof(double)); extractCol(new_D, 1, s, dummyD, 1, s, L, N, s); dummyprod = malloc(L * sizeof(double)); prodMatrices(dummyprod, dummyD, L, s, trnew_c, s, 1); trf = malloc(L * sizeof(double)); transpose(trf, f, 1, L); dummySub = malloc(L * sizeof(double)); subMatrices(dummySub, trf, L, 1, dummyprod, L, 1); normVec(dummySub, L, nor2); } printf("%s reduces the space of %d functions into a space of %d functions\n", name, N, s); printf("Previous norm ||f-f_approx|| was %f, new norm is %f\n", *nor1, *nor2); if (No != 0) { printf("You have required %d atoms in decomposition\n", No); } else { printf("Required precision was tol = %f\n", tol); } /* printf("%s ran for %f seconds\n", name, toc); */ return; } /* **************************************************************************************************** */ /* Gateway routine */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *f, *D, *Di, *Q, *beta; double tol; int No, L, N, N_D, delta=1; double *new_D, *new_Di, *new_Q, *new_beta, *c; if (nrhs > 7) mexErrMsgTxt("Too many input arguments."); else if (nlhs > 5) mexErrMsgTxt("Too many output arguments."); f=mxGetPr(prhs[0]); D=mxGetPr(prhs[1]); Di=mxGetPr(prhs[2]); Q=mxGetPr(prhs[3]); beta=mxGetPr(prhs[4]); /* [L,N]=size(beta); */ N_D=mxGetN(prhs[1]); L=mxGetM(prhs[4]); N=mxGetN(prhs[4]); /* if nargin==5; tol=1.0e-2;end; if nargin==6; No=0;end; */ if (nrhs > 6) { tol=mxGetScalar(prhs[5]); No=(int)mxGetScalar(prhs[6]); } else if (nrhs > 5) { tol=mxGetScalar(prhs[5]); No=0; } else { tol=1.0e-2; No=0; } plhs[0]=mxCreateDoubleMatrix(L, N_D, mxREAL); plhs[1]=mxCreateDoubleMatrix(1, N_D, mxREAL); plhs[2]=mxCreateDoubleMatrix(L, N_D, mxREAL); plhs[3]=mxCreateDoubleMatrix(L, N, mxREAL); plhs[4]=mxCreateDoubleMatrix(1, N, mxREAL); new_D=mxGetPr(plhs[0]); new_Di=mxGetPr(plhs[1]); new_Q=mxGetPr(plhs[2]); new_beta=mxGetPr(plhs[3]); c=mxGetPr(plhs[4]); boompf(new_D, new_Di, new_Q, new_beta, c, f, D, Di, Q, beta, tol, No, L, N, N_D); }