#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; indTest 1) { double *Dk = malloc(L * sizeof(double)); double *trDk = malloc(L * sizeof(double)); double * dummyprod = malloc(L * L * sizeof(double)); double *dummyprod2 = malloc(L * N * sizeof(double)); double *dummysub = malloc(L * N * sizeof(double)); int ind; /* beta=beta-Q(:,k)*(D(:,k)'*beta)/nork; */ extractCol(D, k, k, Dk, 1, 1, L, N_D, 1); transpose(trDk, Dk, L, 1); prodMatrices(dummyprod, Qk, L, 1, Dk, 1, L); prodMatrices(dummyprod2, dummyprod, L, L, beta, L, N); subMatrices(dummysub, beta, L, N, dummyprod2, L, N); for (ind=0; ind < L * N; ++ind) { *(beta + ind) = *(dummysub + ind) / *nork; } free(Dk); free(trDk); free(dummyprod2); free(dummysub); } /* beta(:,k)=Q(:,k)/nork; % k-th biorthogonal function */ for (ind = 0; ind < L; ++ind) { *(beta + k * L + ind) = *(Q + k * L + ind) / *nork; } /* orthogonalization of Q(:,k+1:n) wrt Q(:,k) */ for (p = 0; p < N - (k + 1); ++p) { /* orthogonalization of Q(:,p) wrt Q(:,k) */ double *Qp = malloc(L * sizeof(double)); double *dummyprod; double *dummyprod2 = malloc(L * sizeof(double)); double *dummysub = malloc(L * sizeof(double)); int ind; /* Q(:,p)=Q(:,p)-(Q(:,k)'*Q(:,p))*Q(:,k); */ /* Q(:,k)=Q(:,k)-(Q(:,p)'*Q(:,k))*Q(:,p); */ extractCol(Q, p, p, Qp, 1, 1, L, N_D, 1); prodMatrices(dummyprod, trQk, 1, L, Qp, L, 1); prodMatrices(dummyprod2, Qk, L, 1, dummyprod, 1, 1); subMatrices(dummysub, Qp, L, 1, dummyprod2, L, 1); for (ind=0; ind < L; ++ind) { *(Q + p * L + ind) = *(dummysub + ind); } free(Qp); free(dummyprod2); free(dummysub); } assignPr(new_Q, Q, L * N_D); assignPr(new_beta, beta, L * N); /* Copyright (C) 2006 Miroslav ANDRLE and Laura REBOLLO-NEIRA This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ } /* **************************************************************************************************** */ /* Gateway routine */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *D, *Q, *beta; int k, L, N, N_D; double *new_Q, *new_beta; if (nrhs > 4) mexErrMsgTxt("Too many input arguments."); else if (nlhs > 2) mexErrMsgTxt("Too many output arguments."); D=mxGetPr(prhs[0]); Q=mxGetPr(prhs[1]); beta=mxGetPr(prhs[2]); k=mxGetScalar(prhs[3]); /* [L,N]=size(beta); */ N_D=mxGetN(prhs[0]); L=mxGetM(prhs[2]); N=mxGetN(prhs[2]); plhs[0]=mxCreateDoubleMatrix(L, N_D, mxREAL); plhs[1]=mxCreateDoubleMatrix(L, N, mxREAL); new_Q=mxGetPr(plhs[0]); new_beta=mxGetPr(plhs[1]); /* [Q,beta]=biodictins(D,Q,beta,k); */ biodictins(new_Q, new_beta, D, Q, beta, k, L, N, N_D); }