/* Set cost matrix --------------------------------------------------------- */ void NaiveBayes::setCostMatrix(const Matrix2D<double> &cost) { size_t iK=(size_t) K; if (MAT_XSIZE(cost)!=iK || MAT_YSIZE(cost)!=iK) REPORT_ERROR(ERR_MULTIDIM_SIZE,"Cost matrix does not have the apropriate size"); __cost=cost; }
// Compute subgroup ======================================================== bool found_not_tried(const Matrix2D<int> &tried, int &i, int &j, int true_symNo) { i = j = 0; int n = 0; while (n != MAT_YSIZE(tried)) { if (tried(i, j) == 0 && !(i >= true_symNo && j >= true_symNo)) return true; if (i != n) { // Move downwards i++; } else { // Move leftwards j--; if (j == -1) { n++; j = n; i = 0; } } } return false; }
// Add matrix ============================================================== void SymList::add_matrices(const Matrix2D<DOUBLE> &L, const Matrix2D<DOUBLE> &R, int chain_length) { if (MAT_XSIZE(L) != 4 || MAT_YSIZE(L) != 4 || MAT_XSIZE(R) != 4 || MAT_YSIZE(R) != 4) REPORT_ERROR( "SymList::add_matrix: Transformation matrix is not 4x4"); if (TrueSymsNo() == SymsNo()) { __L.resize(MAT_YSIZE(__L) + 4, 4); __R.resize(MAT_YSIZE(__R) + 4, 4); __chain_length.resize(__chain_length.size() + 1); } set_matrices(true_symNo, L, R); __chain_length(__chain_length.size() - 1) = chain_length; true_symNo++; }
//#define DEBUG void ProgSSNR::run() { show(); produceSideInfo(); Matrix2D<double> output; if (!radial_avg) { if (!generate_VSSNR) estimateSSNR(1, output); else estimateSSNR(2, output); if (fn_out == "") fn_out=fn_S.insertBeforeExtension("_SSNR").removeLastExtension().addExtension("xmd"); } else { radialAverage(output); if (fn_out == "") fn_out=fn_VSSNR.insertBeforeExtension("_radial_avg").removeLastExtension().addExtension("xmd"); } #ifdef DEBUG output.write(fn_out); #endif MetaData MD; for (size_t i=1; i<MAT_YSIZE(output); ++i) { size_t id=MD.addObject(); MD.setValue(MDL_RESOLUTION_FREQ,output(i,1),id); MD.setValue(MDL_RESOLUTION_SSNR,output(i,2),id); MD.setValue(MDL_RESOLUTION_FREQREAL,1.0/output(i,1),id); } MD.write(fn_out); }
void LaplacianEigenmap::reduceDimensionality() { Matrix2D<double> G,L,D; Matrix1D<double> mappedX; //Construct neighborhood graph computeDistanceToNeighbours(*X,numberOfNeighbours,G,distance,false); //Compute Gaussian kernel(heat kernel based weights) computeSimilarityMatrix(G,sigma,true,true); //Compute Laplacian computeGraphLaplacian(G,L); //Construct diagonal weight matrix D.initZeros(MAT_YSIZE(G),MAT_YSIZE(G)); FOR_ALL_ELEMENTS_IN_MATRIX2D(G) MAT_ELEM(D,i,i)+=MAT_ELEM(G,i,j); //Construct eigenmaps generalizedEigs(L,D,mappedX,Y); keepColumns(Y,1,(int)outputDim); }
void HessianLLE::buildYiHessianEstimator(const Matrix2D<double> &V, Matrix2D<double> &Yi, size_t no_dim, size_t dp) { size_t ct = 0; Yi.resizeNoCopy(MAT_YSIZE(V),dp); for(size_t mm=0; mm<no_dim; mm++) { size_t length = no_dim-mm; size_t indle=mm; for(size_t nn=0; nn<length; nn++) { size_t column = ct+nn; for(size_t element = 0; element<MAT_YSIZE(V); element++) MAT_ELEM(Yi, element, column) = MAT_ELEM(V, element, mm)*MAT_ELEM(V, element, indle); ++indle; } ct += length; } }
//#define DEBUG_EULER void Euler_matrix2angles(const Matrix2D<DOUBLE> &A, DOUBLE &alpha, DOUBLE &beta, DOUBLE &gamma) { DOUBLE abs_sb, sign_sb; if (MAT_XSIZE(A) != 3 || MAT_YSIZE(A) != 3) REPORT_ERROR("Euler_matrix2angles: The Euler matrix is not 3x3"); abs_sb = sqrt(A(0, 2) * A(0, 2) + A(1, 2) * A(1, 2)); if (abs_sb > 16 * FLT_EPSILON) { gamma = atan2(A(1, 2), -A(0, 2)); alpha = atan2(A(2, 1), A(2, 0)); if (ABS(sin(gamma)) < FLT_EPSILON) sign_sb = SGN(-A(0, 2) / cos(gamma)); // if (sin(alpha)<FLT_EPSILON) sign_sb=SGN(-A(0,2)/cos(gamma)); // else sign_sb=(sin(alpha)>0) ? SGN(A(2,1)):-SGN(A(2,1)); else sign_sb = (sin(gamma) > 0) ? SGN(A(1, 2)) : -SGN(A(1, 2)); beta = atan2(sign_sb * abs_sb, A(2, 2)); } else { if (SGN(A(2, 2)) > 0) { // Let's consider the matrix as a rotation around Z alpha = 0; beta = 0; gamma = atan2(-A(1, 0), A(0, 0)); } else { alpha = 0; beta = PI; gamma = atan2(A(1, 0), -A(0, 0)); } } gamma = RAD2DEG(gamma); beta = RAD2DEG(beta); alpha = RAD2DEG(alpha); #ifdef DEBUG_EULER std::cout << "abs_sb " << abs_sb << std::endl; std::cout << "A(1,2) " << A(1, 2) << " A(0,2) " << A(0, 2) << " gamma " << gamma << std::endl; std::cout << "A(2,1) " << A(2, 1) << " A(2,0) " << A(2, 0) << " alpha " << alpha << std::endl; std::cout << "sign sb " << sign_sb << " A(2,2) " << A(2, 2) << " beta " << beta << std::endl; #endif }
//#define DEBUG void SymList::compute_subgroup() { Matrix2D<DOUBLE> I(4, 4); I.initIdentity(); Matrix2D<DOUBLE> L1(4, 4), R1(4, 4), L2(4, 4), R2(4, 4), newL(4, 4), newR(4, 4); Matrix2D<int> tried(true_symNo, true_symNo); int i, j; int new_chain_length; while (found_not_tried(tried, i, j, true_symNo)) { tried(i, j) = 1; get_matrices(i, L1, R1); get_matrices(j, L2, R2); newL = L1 * L2; newR = R1 * R2; new_chain_length = __chain_length(i) + __chain_length(j); Matrix2D<DOUBLE> newR3 = newR; newR3.resize(3,3); if (newL.isIdentity() && newR3.isIdentity()) continue; // Try to find it in current ones bool found; found = false; for (int l = 0; l < SymsNo(); l++) { get_matrices(l, L1, R1); if (newL.equal(L1) && newR.equal(R1)) { found = true; break; } } if (!found) { //#define DEBUG #ifdef DEBUG std::cout << "Matrix size " << tried.Xdim() << " " << "trying " << i << " " << j << " " << "chain length=" << new_chain_length << std::endl; std::cout << "Result R Sh\n" << newR; #endif #undef DEBUG newR.setSmallValuesToZero(); newL.setSmallValuesToZero(); add_matrices(newL, newR, new_chain_length); tried.resize(MAT_YSIZE(tried) + 1, MAT_XSIZE(tried) + 1); } } }
void HessianLLE::completeYt(const Matrix2D<double> &V, const Matrix2D<double> &Yi, Matrix2D<double> &Yt_complete) { size_t Xdim = 1+MAT_XSIZE(V)+MAT_XSIZE(Yi); size_t Ydim = MAT_YSIZE(Yi); Yt_complete.resizeNoCopy(Ydim, Xdim); for (size_t i=0; i<Ydim; ++i) { MAT_ELEM(Yt_complete,i,0)=1.; memcpy(&MAT_ELEM(Yt_complete,i,1), &MAT_ELEM(V,i,0), MAT_XSIZE(V)*sizeof(double)); memcpy(&MAT_ELEM(Yt_complete,i,MAT_XSIZE(V)+1),&MAT_ELEM(Yi,i,0),MAT_XSIZE(Yi)*sizeof(double)); } }
/* Euler angles --> matrix ------------------------------------------------- */ void Euler_angles2matrix(DOUBLE alpha, DOUBLE beta, DOUBLE gamma, Matrix2D<DOUBLE> &A, bool homogeneous) { DOUBLE ca, sa, cb, sb, cg, sg; DOUBLE cc, cs, sc, ss; if (homogeneous) { A.initZeros(4, 4); MAT_ELEM(A, 3, 3) = 1; } else if (MAT_XSIZE(A) != 3 || MAT_YSIZE(A) != 3) A.resize(3, 3); alpha = DEG2RAD(alpha); beta = DEG2RAD(beta); gamma = DEG2RAD(gamma); ca = cos(alpha); cb = cos(beta); cg = cos(gamma); sa = sin(alpha); sb = sin(beta); sg = sin(gamma); cc = cb * ca; cs = cb * sa; sc = sb * ca; ss = sb * sa; A(0, 0) = cg * cc - sg * sa; A(0, 1) = cg * cs + sg * ca; A(0, 2) = -cg * sb; A(1, 0) = -sg * cc - cg * sa; A(1, 1) = -sg * cs + cg * ca; A(1, 2) = sg * sb; A(2, 0) = sc; A(2, 1) = ss; A(2, 2) = cb; }
/** Last part of function applyT */ void MpiProgImageRotationalPCA::allReduceApplyT(Matrix2D<double> &Wnode_0) { MPI_Allreduce(MPI_IN_PLACE, MATRIX2D_ARRAY(Wnode_0), MAT_XSIZE(Wnode_0)*MAT_YSIZE(Wnode_0), MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD); }
void MpiProgImageRotationalPCA::comunicateMatrix(Matrix2D<double> &W) { MPI_Bcast(&MAT_ELEM(W,0,0),MAT_XSIZE(W)*MAT_YSIZE(W),MPI_DOUBLE,0,MPI_COMM_WORLD); }
void ProbabilisticPCA::reduceDimensionality() { size_t N=MAT_YSIZE(*X); // N= number of rows of X size_t D=MAT_XSIZE(*X); // D= number of columns of X bool converged=false; size_t iter=0; double sigma2=rnd_unif()*2; double Q=MAXDOUBLE, oldQ; Matrix2D<double> S, W, inW, invM, Ez, WtX, Wp1, Wp2, invWp2, WinvM, WinvMWt, WtSDIW, invCS; // Compute variance and row energy subtractColumnMeans(*X); matrixOperation_AtA(*X,S); S/=(double)N; Matrix1D<double> normX; X->rowEnergySum(normX); W.initRandom(D,outputDim,0,2,RND_UNIFORM); matrixOperation_AtA(W,inW); MultidimArray <double> Ezz(N,outputDim,outputDim); while (!converged && iter<=Niters) { ++iter; // Perform E-step // Ez=(W^t*W)^-1*W^t*X^t for (size_t i=0; i<outputDim; ++i) MAT_ELEM(inW,i,i)+=sigma2; inW.inv(invM); matrixOperation_AtBt(W,*X,WtX); matrixOperation_AB(invM,WtX,Ez); for (size_t k=0; k<N; ++k) FOR_ALL_ELEMENTS_IN_MATRIX2D(invM) DIRECT_A3D_ELEM(Ezz,k,i,j)=MAT_ELEM(invM,i,j)*sigma2+MAT_ELEM(Ez,i,k)*MAT_ELEM(Ez,j,k); // Perform M-step (maximize mapping W) Wp1.initZeros(D,outputDim); Wp2.initZeros(outputDim,outputDim); for (size_t k=0; k<N; ++k) { FOR_ALL_ELEMENTS_IN_MATRIX2D(Wp1) MAT_ELEM(Wp1,i,j)+=MAT_ELEM(*X,k,i)*MAT_ELEM(Ez,j,k); FOR_ALL_ELEMENTS_IN_MATRIX2D(Wp2) MAT_ELEM(Wp2,i,j)+=DIRECT_A3D_ELEM(Ezz,k,i,j); } Wp2.inv(invWp2); matrixOperation_AB(Wp1,invWp2,W); matrixOperation_AtA(W,inW); // Update sigma2 double sigma2_new=0; for (size_t k=0; k<N; ++k){ double EzWtX=0; FOR_ALL_ELEMENTS_IN_MATRIX2D(W) EzWtX+=MAT_ELEM(*X,k,i)*MAT_ELEM(W,i,j)*MAT_ELEM(Ez,j,k); double t=0; for (size_t i = 0; i < outputDim; ++i) { double aux=0.; for (size_t kk = 0; kk < outputDim; ++kk) aux += DIRECT_A3D_ELEM(Ezz,k,i,kk) * MAT_ELEM(inW, kk, i); t+=aux; } sigma2_new += VEC_ELEM(normX,k) - 2 * EzWtX + t; } sigma2_new/=(double) N * (double) D; //Compute likelihood of new model oldQ = Q; if (iter > 1) { matrixOperation_AB(W,invM,WinvM); matrixOperation_ABt(WinvM,W,WinvMWt); matrixOperation_IminusA(WinvMWt); WinvMWt*=1/sigma2_new; matrixOperation_AtA(W,WtSDIW); WtSDIW*=1/sigma2_new; matrixOperation_IplusA(WtSDIW); double detC = pow(sigma2_new,D)* WtSDIW.det(); matrixOperation_AB(WinvMWt,S,invCS); Q = (N*(-0.5)) * (D * log (2*PI) + log(detC) + invCS.trace()); } // Stop condition to detect convergence // Must not apply to the first iteration, because then it will end inmediately if (iter>2 && abs(oldQ-Q) < 0.001) converged=true; sigma2=sigma2_new; } //mapping.M = (inW \ W')'; matrixOperation_ABt(W,inW.inv(),A); matrixOperation_AB(*X,A,Y); if (fnMapping!="") A.write(fnMapping); }
void HessianLLE::reduceDimensionality() { Matrix2D<int> neighboursMatrix; Matrix2D<double> distanceNeighboursMatrix; kNearestNeighbours(*X, kNeighbours, neighboursMatrix, distanceNeighboursMatrix); size_t sizeY = MAT_YSIZE(*X); size_t dp = outputDim * (outputDim+1)/2; Matrix2D<double> weightMatrix, thisX, U, V, Vpr, Yi, Yi_complete, Yt, R, Pii; Matrix1D<double> D, vector; weightMatrix.initZeros(dp*sizeY,sizeY); for(size_t index=0; index<MAT_YSIZE(*X);++index) { extractNearestNeighbours(*X, neighboursMatrix, index, thisX); subtractColumnMeans(thisX); thisX = thisX.transpose(); svdcmp(thisX, U, D, Vpr); // thisX = U * D * Vpr^t // Copy the first columns of Vpr onto V V.resizeNoCopy(MAT_YSIZE(Vpr),outputDim); for (size_t y=0; y<MAT_YSIZE(V); ++y) memcpy(&MAT_ELEM(V,y,0),&MAT_ELEM(Vpr,y,0),outputDim*sizeof(double)); //Basically, the above is applying PCA to the neighborhood of Xi. //The PCA mapping that is found (and that is contained in V) is an //approximation for the tangent space at Xi. //Build Hessian estimator buildYiHessianEstimator(V,Yi,outputDim,dp); completeYt(V, Yi, Yt); orthogonalizeColumnsGramSchmidt(Yt); //Get the transpose of the last columns size_t indexExtra = outputDim+1; size_t Ydim = MAT_XSIZE(Yt)-indexExtra; Pii.resizeNoCopy(Ydim,MAT_YSIZE(Yt)); FOR_ALL_ELEMENTS_IN_MATRIX2D(Pii) MAT_ELEM(Pii,i,j) = MAT_ELEM(Yt,j,indexExtra+i); //Double check weights sum to 1 for (size_t j=0; j<dp; j++) { Pii.getRow(j,vector); double sum = vector.sum(); if(sum > 0.0001) vector*=1.0/sum; //Fill weight matrix for(int k = 0; k<kNeighbours; k++){ size_t neighbourElem = MAT_ELEM(neighboursMatrix,index,k); MAT_ELEM(weightMatrix,index*dp+j,neighbourElem) = VEC_ELEM(vector,k); } } } Matrix2D<double> G; matrixOperation_AtA(weightMatrix,G); Matrix1D<double> v; eigsBetween(G,1,outputDim,v,Y); Y*=sqrt(sizeY); }