// neighs is a matrix with ntakens rows. The n-th row has the neighbours of the // n-th Takens' vector. n is also present as neighbour. The n-th position of the // nneighs vector has the number of neighs of the n-th takens' vector. // verticalHistogram: vector with ntakens elements void getVerticalHistogram(int* neighs, int* nneighs, int* ntakens, int *vmin, int* verticalHistogram){ int i, j, count, lne; for (i = 0; i < (*ntakens); i++){ verticalHistogram[i] = 0; } // find vertical lines in every column/row for (i = 0; i < (*ntakens); i++){ // count number of neighbours + itself lne = nneighs[i]; j=1; while (j < lne){ count=1; // while there is a vertical line, update the length (count) while( (j < lne) && (MAT_ELEM(neighs,i,j,*ntakens) == (MAT_ELEM(neighs,i,(j-1),*ntakens)+1) ) ){ j++; count++; } // update the histogram if the current length > vmin if (count >= (*vmin)){ verticalHistogram[count-1]++; } j++; } } }
// compute the diagonal histogram and the recurrenceHistogram void getDiagonalHistogramRecurrenceHistogram(int* neighs, int* nneighs, int* ntakens, int *lmin, int* diagonalHistogram,int* recurrenceHistogram){ int i,j, currentNeigh, lastPosition; for (i=0;i < (*ntakens) ;i++){ diagonalHistogram[i]=0; recurrenceHistogram[i]=0; } // Treat the first row separately: It will be easier if we find diagonals that // "originate" at the first row separately for (j=0;j < nneighs[0]; j++){ currentNeigh = MAT_ELEM(neighs,0,j,*ntakens); // update recurrenceHistogram: the recurrence histogram takes into accoutn // the distance between neigbours. In this case:currentNeigh-0, and we store //it in tre previous position (position 0 stores distance 1) recurrenceHistogram[currentNeigh-1]++; // update diagonal histogram updateLengthHistogram(0,currentNeigh,neighs,nneighs, *ntakens,diagonalHistogram,*lmin); } // find diagonals that "originate" at other rows lastPosition = *ntakens-*lmin; for (i=1;i < lastPosition; i++){ for (j=0;j < nneighs[i]; j++){ currentNeigh = MAT_ELEM(neighs,i,j,*ntakens); //check if we have already took into acount the pair i,j if (currentNeigh <= i) continue; // update recurrenceHistogram recurrenceHistogram[currentNeigh-i-1]++; //check if this diagonal has its origin in any row before if (isContainedInNeighbourhood(currentNeigh-1,i-1,neighs,*ntakens,nneighs[i-1]) == 1){ continue; } else{ //update the diagonalHistogram and the recurrenceHistogram updateLengthHistogram(i,currentNeigh,neighs,nneighs, *ntakens,diagonalHistogram,*lmin); } } } //complete the recurrence vector if needed if (lastPosition < (*ntakens)){ for (i=lastPosition;i < (*ntakens); i++){ for (j=0;j < nneighs[i]; j++){ currentNeigh = MAT_ELEM(neighs,i,j,*ntakens); if (currentNeigh <= i) continue; // update recurrenceHistogram recurrenceHistogram[currentNeigh-i-1]++; } } } for (i=0;i < (*ntakens) ;i++){ diagonalHistogram[i]=2*diagonalHistogram[i]; recurrenceHistogram[i]=2*recurrenceHistogram[i]; } diagonalHistogram[*ntakens-1] = 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)); } }
/* Compute alphas ---------------------------------------------------------- */ double matrix_fitness(double *p, void *prm) { TiltPairAligner *aligner = (TiltPairAligner *) prm; Euler_angles2matrix(-p[1], p[3], p[2], aligner->pair_E); double retval = 0; for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) { double error = fabs( MAT_ELEM(aligner->pair_E,i, j) - MAT_ELEM(aligner->Put, i, j)); retval += error * error; } return retval; }
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); }
/* ------------------------------------------------------------------------- */ NaiveBayes::NaiveBayes( const std::vector< MultidimArray<double> > &features, const Matrix1D<double> &priorProbs, int discreteLevels) { K = features.size(); Nfeatures=XSIZE(features[0]); __priorProbsLog10.initZeros(K); FOR_ALL_ELEMENTS_IN_MATRIX1D(__priorProbsLog10) VEC_ELEM(__priorProbsLog10,i)=log10(VEC_ELEM(priorProbs,i)); // Create a dummy leaf for features that cannot classify std::vector < MultidimArray<double> > aux(K); dummyLeaf=new LeafNode(aux,0); // Build a leafnode for each feature and assign a weight __weights.initZeros(Nfeatures); for (int f=0; f<Nfeatures; f++) { for (int k=0; k<K; k++) features[k].getCol(f, aux[k]); LeafNode *leaf=new LeafNode(aux,discreteLevels); if (leaf->__discreteLevels>0) { __leafs.push_back(leaf); DIRECT_A1D_ELEM(__weights,f)=__leafs[f]->computeWeight(); } else { __leafs.push_back(dummyLeaf); DIRECT_A1D_ELEM(__weights,f)=0; delete leaf; } #ifdef DEBUG_WEIGHTS if(debugging == true) { std::cout << "Node " << f << std::endl; std::cout << *(__leafs[f]) << std::endl; //char c; //std::cin >> c; } #endif } double norm=__weights.computeMax(); if (norm>0) __weights *= 1.0/norm; // Set default cost matrix __cost.resizeNoCopy(K,K); __cost.initConstant(1); for (int i=0; i<K; i++) MAT_ELEM(__cost,i,i)=0; }
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; } }
int isContainedInNeighbourhood(int possibleNeigh, int i,int* neighs,int ntakens,int nneighs){ int iter; int found = 0; for (iter = 0; iter < nneighs; iter++ ){ if (possibleNeigh == MAT_ELEM(neighs,i,iter,ntakens)){ found = 1; break; } } return found; }
void KernelPCA::reduceDimensionality() { // Compute Gram matrix Matrix2D<double> D2; computeDistance(*X, D2, distance, false); computeSimilarityMatrix(D2,sigma); // Normalize it Matrix1D<double> mean_i; D2.rowSum(mean_i); mean_i/=MAT_XSIZE(D2); double mean=mean_i.computeMean(); FOR_ALL_ELEMENTS_IN_MATRIX2D(D2) MAT_ELEM(D2,i,j)+=mean-VEC_ELEM(mean_i,i)-VEC_ELEM(mean_i,j); // Compute the largest eigenvalues Matrix1D<double> lambda; firstEigs(D2,outputDim,lambda,Y); // Readjust variances FOR_ALL_ELEMENTS_IN_MATRIX1D(lambda) VEC_ELEM(lambda,i)=sqrt(VEC_ELEM(lambda,i)); FOR_ALL_ELEMENTS_IN_MATRIX2D(Y) MAT_ELEM(Y,i,j)*=VEC_ELEM(lambda,j); }
void mapOntoTilt() { p_map.resize(p_unt.size()); for (int u = 0; u < p_map.size()/2; u++) { double xu = (double)p_unt[2*u]; double yu = (double)p_unt[2*u+1]; p_map[2*u] = ROUND(MAT_ELEM(Pass, 0, 0) * xu + MAT_ELEM(Pass, 0, 1) * yu + MAT_ELEM(Pass, 0, 2)); p_map[2*u+1] = ROUND(MAT_ELEM(Pass, 1, 0) * xu + MAT_ELEM(Pass, 1, 1) * yu + MAT_ELEM(Pass, 1, 2)); } }
/* 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; }
void TiltPairAligner::addCoordinatePair(int _muX, int _muY, int _mtX, int _mtY) { coordU.push_back(_muX); coordU.push_back(_muY); coordT.push_back(_mtX); coordT.push_back(_mtY); Nu++; // Number of particles #ifdef _DEBUG std::cout << "Adding point U(" << U.X << "," << U.Y << ") T(" << T.X << "," << T.Y << ")\n"; std::cout << "A at input" << Au << "B at input" << Bt; #endif // Adjust untilted dependent matrix MAT_ELEM(Au,0, 0) += _muX * _muX; MAT_ELEM(Au,0, 1) += _muX * _muY; MAT_ELEM(Au,0, 2) += _muX; MAT_ELEM(Au,1, 0) = MAT_ELEM(Au,0, 1); MAT_ELEM(Au,1, 1) += _muY * _muY; MAT_ELEM(Au,1, 2) += _muY; MAT_ELEM(Au,2, 0) = MAT_ELEM(Au,0, 2); MAT_ELEM(Au,2, 1) = MAT_ELEM(Au,1, 2); MAT_ELEM(Au,2, 2) = Nu; // Adjust tilted dependent matrix MAT_ELEM(Bt,0, 0) += _mtX * _muX; MAT_ELEM(Bt,0, 1) += _mtY * _muX; MAT_ELEM(Bt,0, 2) = MAT_ELEM(Au,0, 2); MAT_ELEM(Bt,1, 0) += _mtX * _muY; MAT_ELEM(Bt,1, 1) += _mtY * _muY; MAT_ELEM(Bt,1, 2) = MAT_ELEM(Au,1, 2); MAT_ELEM(Bt,2, 0) += _mtX; MAT_ELEM(Bt,2, 1) += _mtY; MAT_ELEM(Bt,2, 2) = MAT_ELEM(Au,2, 2); #ifdef _DEBUG std::cout << "A at output" << Au << "B at output" << Bt; #endif }
double optimiseTransformationMatrix(bool do_optimise_nr_pairs) { std::vector<int> best_pairs_t2u, best_map; double score, best_score, best_dist=9999.; if (do_optimise_nr_pairs) best_score = 0.; else best_score = -999999.; int nn = XMIPP_MAX(1., (rotF-rot0)/rotStep); nn *= XMIPP_MAX(1., (tiltF-tilt0)/tiltStep); nn *= XMIPP_MAX(1., (xF-x0)/xStep); nn *= XMIPP_MAX(1., (yF-y0)/yStep); int n = 0; init_progress_bar(nn); for (double rot = rot0; rot <= rotF; rot+= rotStep) { for (double tilt = tilt0; tilt <= tiltF; tilt+= tiltStep) { // Assume tilt-axis lies in-plane... double psi = -rot; // Rotate all points correspondingly Euler_angles2matrix(rot, tilt, psi, Pass); //std::cerr << " Pass= " << Pass << std::endl; // Zero-translations for now (these are added in the x-y loops below) MAT_ELEM(Pass, 0, 2) = MAT_ELEM(Pass, 1, 2) = 0.; mapOntoTilt(); for (int x = x0; x <= xF; x += xStep) { for (int y = y0; y <= yF; y += yStep, n++) { if (do_optimise_nr_pairs) score = getNumberOfPairs(x, y); else score = -getAverageDistance(x, y); // negative because smaller distance is better! bool is_best = false; if (do_optimise_nr_pairs && score==best_score) { double dist = getAverageDistance(x, y); if (dist < best_dist) { best_dist = dist; is_best = true; } } if (score > best_score || is_best) { best_score = score; best_pairs_t2u = pairs_t2u; best_rot = rot; best_tilt = tilt; best_x = x; best_y = y; } if (n%1000==0) progress_bar(n); } } } } progress_bar(nn); // Update pairs with the best_pairs if (do_optimise_nr_pairs) pairs_t2u = best_pairs_t2u; // Update the Passing matrix and the mapping Euler_angles2matrix(best_rot, best_tilt, -best_rot, Pass); // Zero-translations for now (these are added in the x-y loops below) MAT_ELEM(Pass, 0, 2) = MAT_ELEM(Pass, 1, 2) = 0.; mapOntoTilt(); return best_score; }
void FourierProjector::project(double rot, double tilt, double psi) { double freqy, freqx; std::complex< double > f; Euler_angles2matrix(rot,tilt,psi,E); projectionFourier.initZeros(); double shift=-FIRST_XMIPP_INDEX(volumeSize); double xxshift = -2 * PI * shift / volumeSize; double maxFreq2=maxFrequency*maxFrequency; double volumePaddedSize=XSIZE(VfourierRealCoefs); for (size_t i=0; i<YSIZE(projectionFourier); ++i) { FFT_IDX2DIGFREQ(i,volumeSize,freqy); double freqy2=freqy*freqy; double phasey=(double)(i) * xxshift; double freqYvol_X=MAT_ELEM(E,1,0)*freqy; double freqYvol_Y=MAT_ELEM(E,1,1)*freqy; double freqYvol_Z=MAT_ELEM(E,1,2)*freqy; for (size_t j=0; j<XSIZE(projectionFourier); ++j) { // The frequency of pairs (i,j) in 2D FFT_IDX2DIGFREQ(j,volumeSize,freqx); // Do not consider pixels with high frequency if ((freqy2+freqx*freqx)>maxFreq2) continue; // Compute corresponding frequency in the volume double freqvol_X=freqYvol_X+MAT_ELEM(E,0,0)*freqx; double freqvol_Y=freqYvol_Y+MAT_ELEM(E,0,1)*freqx; double freqvol_Z=freqYvol_Z+MAT_ELEM(E,0,2)*freqx; double c,d; if (BSplineDeg==0) { // 0 order interpolation // Compute corresponding index in the volume int kVolume=(int)round(freqvol_Z*volumePaddedSize); int iVolume=(int)round(freqvol_Y*volumePaddedSize); int jVolume=(int)round(freqvol_X*volumePaddedSize); c = A3D_ELEM(VfourierRealCoefs,kVolume,iVolume,jVolume); d = A3D_ELEM(VfourierImagCoefs,kVolume,iVolume,jVolume); } else if (BSplineDeg==1) { // B-spline linear interpolation double kVolume=freqvol_Z*volumePaddedSize; double iVolume=freqvol_Y*volumePaddedSize; double jVolume=freqvol_X*volumePaddedSize; c=VfourierRealCoefs.interpolatedElement3D(jVolume,iVolume,kVolume); d=VfourierImagCoefs.interpolatedElement3D(jVolume,iVolume,kVolume); } else { // B-spline cubic interpolation double kVolume=freqvol_Z*volumePaddedSize; double iVolume=freqvol_Y*volumePaddedSize; double jVolume=freqvol_X*volumePaddedSize; c=VfourierRealCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume); d=VfourierImagCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume); } // Phase shift to move the origin of the image to the corner double dotp = (double)(j) * xxshift + phasey; double a,b; sincos(dotp,&b,&a); // Multiply Fourier coefficient in volume times phase shift double ac = a * c; double bd = b * d; double ab_cd = (a + b) * (c + d); // And store the multiplication double *ptrI_ij=(double *)&DIRECT_A2D_ELEM(projectionFourier,i,j); *ptrI_ij = ac - bd; *(ptrI_ij+1) = ab_cd - ac - bd; } } //VfourierRealCoefs.clear(); //VfourierImagCoefs.clear(); transformer2D.inverseFourierTransform(); }
void run() { MD.read(fn_star); // Check for rlnImageName label if (!MD.containsLabel(EMDL_IMAGE_NAME)) REPORT_ERROR("ERROR: Input STAR file does not contain the rlnImageName label"); if (do_split_per_micrograph && !MD.containsLabel(EMDL_MICROGRAPH_NAME)) REPORT_ERROR("ERROR: Input STAR file does not contain the rlnMicrographName label"); Image<DOUBLE> in; FileName fn_img, fn_mic; std::vector<FileName> fn_mics; std::vector<int> mics_ndims; // First get number of images and their size int ndim=0; bool is_first=true; int xdim, ydim, zdim; FOR_ALL_OBJECTS_IN_METADATA_TABLE(MD) { if (is_first) { MD.getValue(EMDL_IMAGE_NAME, fn_img); in.read(fn_img); xdim=XSIZE(in()); ydim=YSIZE(in()); zdim=ZSIZE(in()); is_first=false; } if (do_split_per_micrograph) { MD.getValue(EMDL_MICROGRAPH_NAME, fn_mic); bool have_found = false; for (int m = 0; m < fn_mics.size(); m++) { if (fn_mic == fn_mics[m]) { have_found = true; mics_ndims[m]++; break; } } if (!have_found) { fn_mics.push_back(fn_mic); mics_ndims.push_back(1); } } ndim++; } // If not splitting, just fill fn_mics and mics_ndim with one entry (to re-use loop below) if (!do_split_per_micrograph) { fn_mics.push_back(""); mics_ndims.push_back(ndim); } // Loop over all micrographs for (int m = 0; m < fn_mics.size(); m++) { ndim = mics_ndims[m]; fn_mic = fn_mics[m]; // Resize the output image std::cout << "Resizing the output stack to "<< ndim<<" images of size: "<<xdim<<"x"<<ydim<<"x"<<zdim << std::endl; DOUBLE Gb = ndim*zdim*ydim*xdim*8./1024./1024./1024.; std::cout << "This will require " << Gb << "Gb of memory...."<< std::endl; Image<DOUBLE> out(xdim, ydim, zdim, ndim); int n = 0; init_progress_bar(ndim); FOR_ALL_OBJECTS_IN_METADATA_TABLE(MD) { FileName fn_mymic; if (do_split_per_micrograph) MD.getValue(EMDL_MICROGRAPH_NAME, fn_mymic); else fn_mymic=""; if (fn_mymic == fn_mic) { MD.getValue(EMDL_IMAGE_NAME, fn_img); in.read(fn_img); if (do_apply_trans) { DOUBLE xoff = 0.; DOUBLE yoff = 0.; DOUBLE psi = 0.; MD.getValue(EMDL_ORIENT_ORIGIN_X, xoff); MD.getValue(EMDL_ORIENT_ORIGIN_Y, yoff); MD.getValue(EMDL_ORIENT_PSI, psi); // Apply the actual transformation Matrix2D<DOUBLE> A; rotation2DMatrix(psi, A); MAT_ELEM(A,0, 2) = xoff; MAT_ELEM(A,1, 2) = yoff; selfApplyGeometry(in(), A, IS_NOT_INV, DONT_WRAP); } out().setImage(n, in()); n++; if (n%100==0) progress_bar(n); } } progress_bar(ndim); FileName fn_out; if (do_split_per_micrograph) { // Remove any extensions from micrograph names.... fn_out = fn_root + "_" + fn_mic.withoutExtension() + fn_ext; } else fn_out = fn_root + fn_ext; out.write(fn_out); std::cout << "Written out: " << fn_out << std::endl; } std::cout << "Done!" <<std::endl; }
/** Image inplace subtraction, equivalent to -= operator */ PyObject * Image_applyTransforMatScipion(PyObject *obj, PyObject *args, PyObject *kwargs) { PyObject * list = NULL; PyObject * item = NULL; ImageObject *self = (ImageObject*) obj; ImageBase * img; PyObject *only_apply_shifts = Py_False; PyObject *wrap = (WRAP ? Py_True : Py_False); img = self->image->image; bool boolOnly_apply_shifts = false; bool boolWrap = WRAP; try { PyArg_ParseTuple(args, "O|OO", &list, &only_apply_shifts, &wrap); if (PyList_Check(list)) { if (PyBool_Check(only_apply_shifts)) boolOnly_apply_shifts = (only_apply_shifts == Py_True); else PyErr_SetString(PyExc_TypeError, "ImageGeneric::applyGeo: Expecting boolean value"); if (PyBool_Check(wrap)) boolWrap = (wrap == Py_True); else PyErr_SetString(PyExc_TypeError, "ImageGeneric::applyGeo: Expecting boolean value"); size_t size = PyList_Size(list); Matrix2D<double> A,B; A.initIdentity(4); for (size_t i = 0; i < size; ++i) { item = PyList_GetItem(list, i); MAT_ELEM(A,i/4,i%4 ) = PyFloat_AsDouble(item); } double scale, shiftX, shiftY, shiftZ, rot,tilt, psi; bool flip; transformationMatrix2Parameters3D(A, flip, scale, shiftX, shiftY, shiftZ, rot,tilt, psi); double _rot; if (tilt==0.) _rot=rot + psi; else _rot=psi; img->setEulerAngles(0,0.,_rot); img->setShifts(shiftX,shiftY); img->setScale(scale); img->setFlip(flip); img->selfApplyGeometry(LINEAR, boolWrap, boolOnly_apply_shifts);//wrap, onlyShifts Py_RETURN_NONE; } else { PyErr_SetString(PyExc_TypeError, "ImageGeneric::applyTransforMatScipion: Expecting a list"); } } catch (XmippError &xe) { PyErr_SetString(PyXmippError, xe.msg.c_str()); } return NULL; }//operator +=
// Outliers =============================================================== void ProgClassifyCL2DCore::computeStableCores() { if (verbose && node->rank==0) std::cerr << "Computing stable cores ...\n"; MetaData thisClass, anotherClass, commonImages, thisClassCore; MDRow row; size_t first, last; Matrix2D<unsigned char> coocurrence; Matrix1D<unsigned char> maximalCoocurrence; int Nblocks=blocks.size(); taskDistributor->reset(); std::vector<size_t> commonIdx; std::map<String,size_t> thisClassOrder; String fnImg; while (taskDistributor->getTasks(first, last)) for (size_t idx=first; idx<=last; ++idx) { // Read block CL2DBlock &thisBlock=blocks[idx]; if (thisBlock.level<=tolerance) continue; if (!existsBlockInMetaDataFile(thisBlock.fnLevelCore, thisBlock.block)) continue; thisClass.read(thisBlock.block+"@"+thisBlock.fnLevelCore); thisClassCore.clear(); // Add MDL_ORDER if (thisClass.size()>0) { size_t order=0; thisClassOrder.clear(); FOR_ALL_OBJECTS_IN_METADATA(thisClass) { thisClass.getValue(MDL_IMAGE,fnImg,__iter.objId); thisClassOrder[fnImg]=order++; } // Calculate coocurrence within all blocks whose level is inferior to this size_t NthisClass=thisClass.size(); if (NthisClass>0) { try { coocurrence.initZeros(NthisClass,NthisClass); } catch (XmippError e) { std::cerr << e << std::endl; std::cerr << "There is a memory allocation error. Most likely there are too many images in this class (" << NthisClass << " images). Consider increasing the number of initial and final classes\n"; REPORT_ERROR(ERR_MEM_NOTENOUGH,"While computing stable class"); } for (int n=0; n<Nblocks; n++) { CL2DBlock &anotherBlock=blocks[n]; if (anotherBlock.level>=thisBlock.level) break; if (!existsBlockInMetaDataFile(anotherBlock.fnLevelCore, anotherBlock.block)) continue; anotherClass.read(anotherBlock.block+"@"+anotherBlock.fnLevelCore); anotherClass.intersection(thisClass,MDL_IMAGE); commonImages.join1(anotherClass, thisClass, MDL_IMAGE,LEFT); commonIdx.resize(commonImages.size()); size_t idx=0; FOR_ALL_OBJECTS_IN_METADATA(commonImages) { commonImages.getValue(MDL_IMAGE,fnImg,__iter.objId); commonIdx[idx++]=thisClassOrder[fnImg]; } size_t Ncommon=commonIdx.size(); for (size_t i=0; i<Ncommon; i++) { size_t idx_i=commonIdx[i]; for (size_t j=i+1; j<Ncommon; j++) { size_t idx_j=commonIdx[j]; MAT_ELEM(coocurrence,idx_i,idx_j)+=1; } } } } // Take only those elements whose coocurrence is maximal maximalCoocurrence.initZeros(NthisClass); int aimedCoocurrence=thisBlock.level-tolerance; FOR_ALL_ELEMENTS_IN_MATRIX2D(coocurrence) if (MAT_ELEM(coocurrence,i,j)==aimedCoocurrence) VEC_ELEM(maximalCoocurrence,i)=VEC_ELEM(maximalCoocurrence,j)=1; // Now compute core FOR_ALL_OBJECTS_IN_METADATA(thisClass) { thisClass.getValue(MDL_IMAGE,fnImg,__iter.objId); size_t idx=thisClassOrder[fnImg]; if (VEC_ELEM(maximalCoocurrence,idx)) { thisClass.getRow(row,__iter.objId); thisClassCore.addRow(row); } } } thisClassCore.write(thisBlock.fnLevel.insertBeforeExtension((String)"_stable_core_"+thisBlock.block),MD_APPEND); }
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 FourierProjector::project(double rot, double tilt, double psi, const MultidimArray<double> *ctf) { double freqy, freqx; std::complex< double > f; Euler_angles2matrix(rot,tilt,psi,E); projectionFourier.initZeros(); double maxFreq2=maxFrequency*maxFrequency; int Xdim=(int)XSIZE(VfourierRealCoefs); int Ydim=(int)YSIZE(VfourierRealCoefs); int Zdim=(int)ZSIZE(VfourierRealCoefs); for (size_t i=0; i<YSIZE(projectionFourier); ++i) { FFT_IDX2DIGFREQ(i,volumeSize,freqy); double freqy2=freqy*freqy; double freqYvol_X=MAT_ELEM(E,1,0)*freqy; double freqYvol_Y=MAT_ELEM(E,1,1)*freqy; double freqYvol_Z=MAT_ELEM(E,1,2)*freqy; for (size_t j=0; j<XSIZE(projectionFourier); ++j) { // The frequency of pairs (i,j) in 2D FFT_IDX2DIGFREQ(j,volumeSize,freqx); // Do not consider pixels with high frequency if ((freqy2+freqx*freqx)>maxFreq2) continue; // Compute corresponding frequency in the volume double freqvol_X=freqYvol_X+MAT_ELEM(E,0,0)*freqx; double freqvol_Y=freqYvol_Y+MAT_ELEM(E,0,1)*freqx; double freqvol_Z=freqYvol_Z+MAT_ELEM(E,0,2)*freqx; double c,d; if (BSplineDeg==0) { // 0 order interpolation // Compute corresponding index in the volume int kVolume=(int)round(freqvol_Z*volumePaddedSize); int iVolume=(int)round(freqvol_Y*volumePaddedSize); int jVolume=(int)round(freqvol_X*volumePaddedSize); c = A3D_ELEM(VfourierRealCoefs,kVolume,iVolume,jVolume); d = A3D_ELEM(VfourierImagCoefs,kVolume,iVolume,jVolume); } else if (BSplineDeg==1) { // B-spline linear interpolation double kVolume=freqvol_Z*volumePaddedSize; double iVolume=freqvol_Y*volumePaddedSize; double jVolume=freqvol_X*volumePaddedSize; c=VfourierRealCoefs.interpolatedElement3D(jVolume,iVolume,kVolume); d=VfourierImagCoefs.interpolatedElement3D(jVolume,iVolume,kVolume); } else { // B-spline cubic interpolation double kVolume=freqvol_Z*volumePaddedSize; double iVolume=freqvol_Y*volumePaddedSize; double jVolume=freqvol_X*volumePaddedSize; // Commented for speed-up, the corresponding code is below // c=VfourierRealCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume); // d=VfourierImagCoefs.interpolatedElementBSpline3D(jVolume,iVolume,kVolume); // The code below is a replicate for speed reasons of interpolatedElementBSpline3D double z=kVolume; double y=iVolume; double x=jVolume; // Logical to physical z -= STARTINGZ(VfourierRealCoefs); y -= STARTINGY(VfourierRealCoefs); x -= STARTINGX(VfourierRealCoefs); int l1 = (int)ceil(x - 2); int l2 = l1 + 3; int m1 = (int)ceil(y - 2); int m2 = m1 + 3; int n1 = (int)ceil(z - 2); int n2 = n1 + 3; c = d = 0.0; double aux; for (int nn = n1; nn <= n2; nn++) { int equivalent_nn=nn; if (nn<0) equivalent_nn=-nn-1; else if (nn>=Zdim) equivalent_nn=2*Zdim-nn-1; double yxsumRe = 0.0, yxsumIm = 0.0; for (int m = m1; m <= m2; m++) { int equivalent_m=m; if (m<0) equivalent_m=-m-1; else if (m>=Ydim) equivalent_m=2*Ydim-m-1; double xsumRe = 0.0, xsumIm = 0.0; for (int l = l1; l <= l2; l++) { double xminusl = x - (double) l; int equivalent_l=l; if (l<0) equivalent_l=-l-1; else if (l>=Xdim) equivalent_l=2*Xdim-l-1; double CoeffRe = (double) DIRECT_A3D_ELEM(VfourierRealCoefs,equivalent_nn,equivalent_m,equivalent_l); double CoeffIm = (double) DIRECT_A3D_ELEM(VfourierImagCoefs,equivalent_nn,equivalent_m,equivalent_l); BSPLINE03(aux,xminusl); xsumRe += CoeffRe * aux; xsumIm += CoeffIm * aux; } double yminusm = y - (double) m; BSPLINE03(aux,yminusm); yxsumRe += xsumRe * aux; yxsumIm += xsumIm * aux; } double zminusn = z - (double) nn; BSPLINE03(aux,zminusn); c += yxsumRe * aux; d += yxsumIm * aux; } } // Phase shift to move the origin of the image to the corner double a=DIRECT_A2D_ELEM(phaseShiftImgA,i,j); double b=DIRECT_A2D_ELEM(phaseShiftImgB,i,j); if (ctf!=NULL) { double ctfij=DIRECT_A2D_ELEM(*ctf,i,j); a*=ctfij; b*=ctfij; } // Multiply Fourier coefficient in volume times phase shift double ac = a * c; double bd = b * d; double ab_cd = (a + b) * (c + d); // And store the multiplication double *ptrI_ij=(double *)&DIRECT_A2D_ELEM(projectionFourier,i,j); *ptrI_ij = ac - bd; *(ptrI_ij+1) = ab_cd - ac - bd; } } transformer2D.inverseFourierTransform(); }
// ###################################################################### //img : input image in RGB space //K : number of groups create by kmean //dist: distance weight when doing the segment, higher weight will make // each region group by its neighbor pixel // ###################################################################### Image<PixRGB<byte> > getKMeans(Image<PixRGB<byte> > img,int K,float dist) { //convert iNVT image to cvImage IplImage *cvImg = img2ipl(img); int h = img.getHeight(); int w = img.getWidth(); LINFO("Image Width %d Height %d cv W %d,H %d",w,h,cvImg->width,cvImg->height); CvMat *sample = cvCreateMat(w*h, 1, CV_32FC(5)); //CvMat *sample = cvCreateMat(w*h, 1, CV_32FC(3)); CvMat *cluster = cvCreateMat(w*h, 1, CV_32SC1); for(int y = 0; y < h; y++) { for(int x = 0; x < w; x++) { int idx= y*w+x; int idxpix= y*w*3+x*3; MAT_ELEM(sample,idx,0,0,x*dist); MAT_ELEM(sample,idx,0,1,y*dist); MAT_ELEM(sample,idx,0,2, *(cvImg->imageData + idxpix + 0)); MAT_ELEM(sample,idx,0,3, *(cvImg->imageData + idxpix + 1)); MAT_ELEM(sample,idx,0,4, *(cvImg->imageData + idxpix + 2)); } } //Doing cvKmean cvKMeans2(sample, K, cluster, cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, TT_KMEANS_ITERATIONS, TT_KMEANS_PRECISION)) ; IplImage *dst = cvCreateImage(cvGetSize(cvImg),8,3); cvZero(dst); std::vector<std::vector<Point2D<int> > > groups; groups.resize(K); // Put Pixel Color to each labeled bin for(int y = 0; y < h; y++) { for(int x = 0; x < w; x++) { int idx = cluster->data.i[y*w+x]; groups[idx].push_back(Point2D<int>(x,y)); } } // Given a int label map, we will create a average color map Image<PixRGB<byte> > output(img.getDims(), ZEROS); //Compute avg color for each region for(size_t grpIdx=0; grpIdx < groups.size(); grpIdx++) { //Compute Average Color PixRGB<long> avgColor(0,0,0); for(size_t pntIdx=0; pntIdx<groups[grpIdx].size(); pntIdx++) avgColor += img.getVal(groups[grpIdx][pntIdx]); if(groups[grpIdx].size() != 0) avgColor /= groups[grpIdx].size(); //Asign avg color to region pixels for(size_t pntIdx=0; pntIdx<groups[grpIdx].size(); pntIdx++) output.setVal(groups[grpIdx][pntIdx],avgColor); } cvReleaseMat(&sample); cvReleaseMat(&cluster); cvReleaseImage(&cvImg); return output; }
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); }
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 ProgVolumePCA::run() { show(); produce_side_info(); const MultidimArray<int> &imask=mask.imask; size_t Nvoxels=imask.sum(); MultidimArray<float> v; v.initZeros(Nvoxels); // Add all volumes to the analyzer FileName fnVol; FOR_ALL_OBJECTS_IN_METADATA(mdVols) { mdVols.getValue(MDL_IMAGE,fnVol,__iter.objId); V.read(fnVol); // Construct vector const MultidimArray<double> &mV=V(); size_t idx=0; FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(mV) { if (DIRECT_MULTIDIM_ELEM(imask,n)) DIRECT_MULTIDIM_ELEM(v,idx++)=DIRECT_MULTIDIM_ELEM(mV,n); } analyzer.addVector(v); } // Construct PCA basis analyzer.subtractAvg(); analyzer.learnPCABasis(NPCA,100); // Project onto the PCA basis Matrix2D<double> proj; analyzer.projectOnPCABasis(proj); std::vector<double> dimredProj; dimredProj.resize(NPCA); int i=0; FOR_ALL_OBJECTS_IN_METADATA(mdVols) { memcpy(&dimredProj[0],&MAT_ELEM(proj,i,0),NPCA*sizeof(double)); mdVols.setValue(MDL_DIMRED,dimredProj,__iter.objId); i++; } if (fnVolsOut!="") mdVols.write(fnVolsOut); else mdVols.write(fnVols); // Save the basis const MultidimArray<double> &mV=V(); for (int i=NPCA-1; i>=0; --i) { V().initZeros(); size_t idx=0; const MultidimArray<double> &mPCA=analyzer.PCAbasis[i]; FOR_ALL_DIRECT_ELEMENTS_IN_MULTIDIMARRAY(mV) { if (DIRECT_MULTIDIM_ELEM(imask,n)) DIRECT_MULTIDIM_ELEM(mV,n)=DIRECT_MULTIDIM_ELEM(mPCA,idx++); } if (fnBasis!="") V.write(fnBasis,i+1,true,WRITE_OVERWRITE); } // Generate the PCA volumes if (listOfPercentiles.size()>0 && fnOutStack!="" && fnAvgVol!="") { Image<double> Vavg; if (fnAvgVol!="") Vavg.read(fnAvgVol); else Vavg().initZeros(V()); Matrix1D<double> p; proj.toVector(p); Matrix1D<double> psorted=p.sort(); Image<double> Vpca; Vpca()=Vavg(); createEmptyFile(fnOutStack,(int)XSIZE(Vavg()),(int)YSIZE(Vavg()),(int)ZSIZE(Vavg()),listOfPercentiles.size()); std::cout << "listOfPercentiles.size()=" << listOfPercentiles.size() << std::endl; for (size_t i=0; i<listOfPercentiles.size(); i++) { int idx=(int)round(textToFloat(listOfPercentiles[i].c_str())/100.0*VEC_XSIZE(p)); std::cout << "Percentile " << listOfPercentiles[i] << " -> idx=" << idx << " p(idx)=" << psorted(idx) << std::endl; Vpca()+=psorted(idx)*V(); Vpca.write(fnOutStack,i+1,true,WRITE_REPLACE); } } }