int main(void) { printf("10 + 2 = %.2f\n", vsum(0, 10, 2)); printf("57 + 300000L = %.2f\n", vsum(1, 57, 300000L)); printf("98 + 2L + 3.14 = %.2f\n", vsum(2, 98, 2L, 3.14)); return(0); }
// -------------------------------------------------------------------------- // // void ScalarDistributionData::init(const std::vector<int> & sampleset, const Library & library) { // Get the number of elements in the sample set. nsample_ = static_cast<int>(sampleset.size()); // Loop through the sample set and extract the scalar value. for (size_t i = 0; i < sampleset.size(); ++i) { const int index = sampleset[i]; const double value = library.get_scalar_at(index, pos_); // Calculate which bin this value belongs to. const int bin = get_bin(value); // Increment the distribution at this bin. distribution_[bin] += 1.0; } // Normalize the distribution to 1. const double norm = vsum(distribution_); distribution_ = distribution_ / norm; // Calculate chi2. chi2_ = calculate_chi2(distribution_); }
void linie_3d(int c,vecp v1p,vecp v2p){ int i; vec v1,v2; static int handle, initialized=0, maxnum=2000, aktnum=-1; static Gobject *linien,*linientmp; veq(v1,v1p);veq(v2,v2p); if (!initialized) { handle=getview3dhandle(); linien=malloc(maxnum*sizeof(Gobject)); for (i=0;i<maxnum;i++) il(i) initialized=1; } if (newframe(handle)) aktnum=-1; if (++aktnum>=maxnum){ linientmp=malloc(2*maxnum*sizeof(Gobject)); for (i=0;i<maxnum;i++)linientmp[i]=linien[i]; free(linien); linien=linientmp; for (i=maxnum;i<maxnum*2;i++) il(i) maxnum*=2; } linien[aktnum].van=c; veq(linien[aktnum].tva[0],mc2wc(v1)); veq(linien[aktnum].tva[1],mc2wc(v2)); veq(linien[aktnum].poswc,sm(0.5,vsum(linien[aktnum].tva[0], linien[aktnum].tva[1]))); insertGobject(&(linien[aktnum])); }
int main(){ int a[5] = {1,2,3,4,5}; int sum; sum = vsum(a, 5); printf("%d", sum); return 0; }
void mesh(Mesh* mymesh){ register int i; vecp v; matp m; int *ip,calculatedisplaykoordinates=1; i=mymesh->mode; if ((!mymesh->normalsinitialized) &&((i==MESHONESIDED)||(i==SQUAREMESHONESIDED))) { calcnormals(&mymesh->Garray[0],1); mymesh->normalsinitialized=1; /*calculatedisplaykoordinates=0*/ } ip=mymesh->transf2dc; meq(mymesh->mc2wcmn,getmc2wcmn()); meq(mymesh->mc2wcm,getmc2wcm()); veq(mymesh->mc2wcv,getmc2wcv()); m=mymesh->mc2wcm; v=mymesh->mc2wcv; for (i=0;i<mymesh->xdim*mymesh->ydim;i++){ veq(mymesh->tva[i],vsum(matvecmul(m,mymesh->va[i]),v)); *(ip++)=0; } if (calculatedisplaykoordinates) for (i=0;i<mymesh->xdim*mymesh->ydim;i++) wc2dc(&mymesh->points[i].x,&mymesh->points[i].y,mymesh->tva[i]); meq(mymesh->mc2wcmn,getmc2wcmn()); for (i=0;i<(mymesh->xdim-1)*(mymesh->ydim-1);i++)insertGobject(&mymesh->Garray[i]); }
/* Subroutine to compute the Mean of vector */ double vmean(vector *X) { double sum=0, result; sum = vsum(X); result = sum/(X->l); return result; }
std::unique_ptr<Image> leastSquarePatch(const std::unique_ptr<Image>& image) { // process grayscale patches only if (image->getChannelNum() > 1) return std::unique_ptr<Image>(); auto data_ptr = image->getValues(0); const auto w = image->getWidth(); const auto h = image->getHeight(); // least square fit to linear plane for light compensation float xsum_orig = 0; float ysum_orig = 0; float csum_orig = 0; for (size_t j = 0; j < h; j++) { for (size_t i = 0; i < w; i++) { xsum_orig += (i * data_ptr[j*w + i]); ysum_orig += (j * data_ptr[j*w + i]); csum_orig += (data_ptr[j*w + i]); } } Eigen::Vector3d vsum(xsum_orig, ysum_orig, csum_orig); float x2sum = 0, y2sum = 0, xysum = 0, xsum = 0, ysum = 0; float csum = w*h; for (size_t j = 0; j < h; j++) { for (size_t i = 0; i < w; i++) { x2sum += (i*i); y2sum += (j*j); xysum += (i*j); xsum += i; ysum += j; } } Eigen::Matrix3d msum; msum << x2sum, xysum, xsum, xysum, y2sum, ysum, xsum, ysum, csum; auto vcoeff = msum.inverse() * vsum; auto newImage = std::make_unique<Image>(w, h, 1); for (size_t j = 0; j < h; j++) { for (size_t i = 0; i < w; i++) { (newImage->getValues(0))[j*w + i] = data_ptr[j*w + i] - i*vcoeff[0] - j*vcoeff[1] - vcoeff[2]; } } return newImage; }
// -------------------------------------------------------------------------- // // void ScalarDistributionData::weighted_analysis(const Library & library, const std::vector<BasisContainer> & weights_table, const std::string & basename) const { // Setup distributions. std::vector<double> distribution(distribution_.size(), 0.0); std::vector<double> weighted_distribution(distribution_.size(), 0.0); // Loop through the library set and extract the scalar value. for (size_t i = 0; i < weights_table.size(); ++i) { const int index = weights_table[i].index; const double weight = weights_table[i].weight; const double value = library.get_scalar_at(index, pos_); // Calculate which bin this value belongs to. const int bin = get_bin(value); // Increment the distribution at this bin. distribution[bin] += 1.0; weighted_distribution[bin] += 1.0 * weight; } // Normalize the distributions to 1. const double norm = vsum(distribution); distribution = distribution / norm; weighted_distribution = weighted_distribution / norm; // Print scale unweighted and weighted to file. std::string filename = basename + "." + "Distribution-" + name_; std::ofstream outfile(filename.c_str()); // Check that the file is ok. if (outfile.bad()) { open_file_error(filename, LOCATION); } outfile << " SCALE DISTRIBUTION WEIGHTED REFERENCE" << std::endl; // Loop over bins. for (size_t i = 0; i < distribution.size(); ++i) { // Pull out the values. const double scale = scale_[i]; const double target = target_[i]; const double value = distribution[i]; const double weighted_value = weighted_distribution[i]; char line[300]; sprintf(line, "%20.10f %20.10f %20.10f %20.10f\n", scale, value, weighted_value, target); outfile << std::string(line); } outfile.close(); }
// -------------------------------------------------------------------------- // // void Test_Mathutils::testSumVectorElementsDouble() { std::vector<double> vec(4); vec[0] = 1.1; vec[1] = 2.2; vec[2] = 3.3; vec[3] = -7.7; const double sum = vsum(vec); CPPUNIT_ASSERT_DOUBLES_EQUAL(sum, -1.1, EPS); }
// -------------------------------------------------------------------------- // // void Test_Mathutils::testSumVectorElementsInt() { std::vector<int> vec(4); vec[0] = 4; vec[1] = 2; vec[2] = 3; vec[3] = -7; const int sum = vsum(vec); CPPUNIT_ASSERT_EQUAL(sum, 2); }
t_vector get_cone_normale(t_vector p, t_icone *cone) { double m; t_vector res; m = pow(vlen(vsub(p, cone->vertex)), 2) / vscalar_multiple(vsub(p, cone->vertex), cone->vector); res = vsum(cone->vertex, vk_multiple(cone->vector, m)); res = vnormalize(vsub(p, res)); return (res); }
void contour3d(Contour* c){ int i,j,*k; vecp v; matp m; if (c->initialized==0){ c->tva=malloc((c->vaakt+1)*sizeof(vec)); c->na=malloc((c->polakt+1)*sizeof(vec)); c->sp=malloc((c->polakt+1)*sizeof(vec)); c->points=malloc((c->polakt+1)*sizeof(DPoint)); c->Garray=malloc((c->polakt+1)*sizeof(Gobject)); for (i=0;i<=c->polakt;i++) { c->Garray[i].na=c->na; c->Garray[i].tva=c->tva; c->Garray[i].poswc=(vecp) &c->sp[i]; /* compiler distinguishes between vec* and vecp */ c->Garray[i].points=c->points; c->Garray[i].polygons=&c->pol[i*6]; c->Garray[i].drawstruct=drawtrianglelight; j=c->pol[i*6]; veq(c->na[i],vnorm(vp(vdiff(c->va[j+4],c->va[j+3]),vdiff(c->va[j+5],c->va[j+3])))); } c->initialized=1; } /* Transformation, die jedes Mal durchlaufen wird. */ meq(c->mc2wcmn,getmc2wcmn()); meq(c->mc2wcm,getmc2wcm()); veq(c->mc2wcv,getmc2wcv()); m=c->mc2wcm; v=c->mc2wcv; for (i=0;i<=c->vaakt;i++) { veq(c->tva[i],vsum(matvecmul(m,c->va[i]),v)); wc2dc(&c->points[i].x,&c->points[i].y,c->tva[i]); } for (i=0;i<=c->polakt;i++){ /* Schwerpunkt in Weltkoordinaten */ k=&c->pol[i*6+3]; veq(c->sp[i],sm(0.33333, vsum(vsum(c->tva[*k],c->tva[*(k+1)]),c->tva[*(k+2)]))); insertGobject(&c->Garray[i]); } }
// -------------------------------------------------------------------------- // // void ScalarDistributionData::read_reference(const std::string & path) { // Open the file. std::ifstream infile(path.c_str()); check_eof(infile, path, LOCATION); // Read the number of bins. infile >> nbins_; check_eof(infile, path, LOCATION); // Throw an error if the number of bins is too small. if (nbins_ <= 1) { std::string msg = "Number of bins as read from the file \"" + path + "\" is too small.\n"; error(msg, LOCATION); } // Resize member data according to the number of bins. target_.resize(nbins_, 0.0); scale_.resize(nbins_, 0.0); factor_.resize(nbins_, 0.0); distribution_.resize(nbins_, 0.0); distribution_new_.resize(nbins_, 0.0); // Read all data. for (int i = 0; i < nbins_; ++i) { // Read the three columns, scale, target distrubution and local sigma. infile >> scale_[i]; check_eof(infile, path, LOCATION); infile >> target_[i]; check_eof(infile, path, LOCATION); infile >> factor_[i]; check_eof(infile, path, LOCATION); } // Close the file after reading. infile.close(); // Normalize the target to 1. const double norm = vsum(target_); target_ = target_ / norm; // Calculate the bin related data. const double halfbinsize = (scale_[1] - scale_[0]) / 2; lowest_ = scale_[0] - halfbinsize; highest_ = scale_[nbins_-1] - halfbinsize; one_over_binsize_ = 1.0 / (2.0 * halfbinsize); }
// -------------------------------------------------------------------------- // // void Test_ScalarDistributionData::testConstruction() { // Make sure we can default construct without crashing. CPPUNIT_ASSERT_NO_THROW( ScalarDistributionData sdd ); // Construct with the normal constructor. const std::string scalar_name("VP-Volume"); const std::string ref_path("./testfiles/vvol_ref.data"); const double sigma = 0.093; const int pos = 2; ScalarDistributionData sdd(scalar_name, ref_path, sigma, pos); // Check the member data. const double eps = 1.0e-12; CPPUNIT_ASSERT_EQUAL( sdd.name_, scalar_name ); CPPUNIT_ASSERT_EQUAL( sdd.pos_, pos ); CPPUNIT_ASSERT_EQUAL( sdd.nbins_, 125 ); CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.sigma_, sigma, eps ); CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.one_over_sigma2_, 1.0/(sigma*sigma), eps ); CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.lowest_, 25.45, eps ); CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.highest_, 37.85, eps ); CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.one_over_binsize_, 10.0, eps ); // Check dimensions. CPPUNIT_ASSERT_EQUAL( static_cast<int>(sdd.target_.size()), sdd.nbins_ ); CPPUNIT_ASSERT_EQUAL( static_cast<int>(sdd.scale_.size()), sdd.nbins_ ); CPPUNIT_ASSERT_EQUAL( static_cast<int>(sdd.factor_.size()), sdd.nbins_ ); CPPUNIT_ASSERT_EQUAL( static_cast<int>(sdd.distribution_.size()), sdd.nbins_ ); CPPUNIT_ASSERT_EQUAL( static_cast<int>(sdd.distribution_new_.size()), sdd.nbins_ ); // Check hardcoded reference values. CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.target_[0], 0.00887034393507342, eps ); CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.target_[8], 0.00151451299040374, eps ); CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.target_[19], 0.00237382469428914, eps ); CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.target_[99], 0.00178721705381046, eps ); // CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.scale_[0], 25.5, eps ); CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.scale_[8], 26.3, eps ); CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.scale_[19], 27.4, eps ); CPPUNIT_ASSERT_DOUBLES_EQUAL( sdd.scale_[99], 35.4, eps ); // Check the target norm. CPPUNIT_ASSERT_DOUBLES_EQUAL( vsum(sdd.target_), 1.0, eps ); // Test the edges of the binning routine in a realistic case. CPPUNIT_ASSERT_EQUAL(sdd.get_bin(25.0), 0); CPPUNIT_ASSERT_EQUAL(sdd.get_bin(31.83), 63); CPPUNIT_ASSERT_EQUAL(sdd.get_bin(37.87),124); }
double c_ctr::doc_inference(const c_document* doc, const gsl_vector* theta_v, const gsl_matrix* log_beta, gsl_matrix* phi, gsl_vector* gamma, gsl_matrix* word_ss, bool update_word_ss) { double pseudo_count = 1.0; double likelihood = 0; gsl_vector* log_theta_v = gsl_vector_alloc(theta_v->size); gsl_vector_memcpy(log_theta_v, theta_v); vct_log(log_theta_v); int n, k, w; double x; for (n = 0; n < doc->m_length; n ++) { w = doc->m_words[n]; for (k = 0; k < m_num_factors; k ++) mset(phi, n, k, vget(theta_v, k) * mget(m_beta, k, w)); gsl_vector_view row = gsl_matrix_row(phi, n); vnormalize(&row.vector); for (k = 0; k < m_num_factors; k ++) { x = mget(phi, n, k); if (x > 0) likelihood += x*(vget(log_theta_v, k) + mget(log_beta, k, w) - log(x)); } } if (pseudo_count > 0) { likelihood += pseudo_count * vsum(log_theta_v); } gsl_vector_set_all(gamma, pseudo_count); // smoothing with small pseudo counts for (n = 0; n < doc->m_length; n ++) { for (k = 0; k < m_num_factors; k ++) { x = doc->m_counts[n] * mget(phi, n, k); vinc(gamma, k, x); if (update_word_ss) minc(word_ss, k, doc->m_words[n], x); } } gsl_vector_free(log_theta_v); return likelihood; }
// -------------------------------------------------------------------------- // // double ScalarDistributionData::calculate_chi2(const std::vector<double> & distribution) const { // Subtract the target from the scalar distribution. std::vector<double> tmp_distribution = distribution - target_; // Square the difference. vsquare(tmp_distribution); // Multiply with the elementwize factors. tmp_distribution = tmp_distribution * factor_; // Sum. double chi2 = vsum(tmp_distribution); // Divide by sigma2. chi2 *= one_over_sigma2_; // All done. return chi2; }
void run2(float ** output_collapsed, float ** kernel_collapsed, float ** img){ int ct = 0; for(int r=0;r<nrow_output;r++){ for(int c=0;c<ncol_output;c++){ for(int ir=r;ir<r+nrow_kernel;ir++){ for(int ic=c;ic<c+ncol_kernel;ic++){ materialize[ct++] = img[ir][ic]; } } } } for(int i_epoch=0;i_epoch<NRUN;i_epoch++){ float sum[nrow_kernel*ncol_kernel]; float sum1 = 0.0; float * output_flatten = &output_collapsed[0][0]; for(int m=0;m<nfeaturemap;m++){ int ct = m; const float * const buf_kernel2 = &buf_kernel[nrow_kernel*ncol_kernel*m]; const float * mat = &materialize[0]; for(int i=0;i<size_of_stream;i+=nrow_kernel*ncol_kernel){ MultiSSE(sum, mat, buf_kernel2, nrow_kernel*ncol_kernel); output_flatten[ct] = vsum(sum, nrow_kernel*ncol_kernel); ct = ct + nfeaturemap; mat += nrow_kernel*ncol_kernel; } } /** //for(int j=0;j<nrow_kernel*nrow_kernel;j++){ // sum[j] = mat[j] * buf_kernel2[j]; //} */ } }
void text_3d(int c,vecp v1p,vecp v2p,char *str,char *ref,double size){ int i; vec v1,v2,vnull={0.,0.,0.}; static int handle, initialized=0, maxnum=2000, aktnum=-1; static Gobject *texte,*textetmp; veq(v1,v1p); if (v2p!=NULL) veq(v2,v2p); if (!initialized) { handle=getview3dhandle(); texte=malloc(maxnum*sizeof(Gobject)); for (i=0;i<maxnum;i++) it(i) initialized=1; } if (newframe(handle)) aktnum=-1; if (++aktnum>=maxnum){ textetmp=malloc(2*maxnum*sizeof(Gobject)); for (i=0;i<maxnum;i++)textetmp[i]=texte[i]; free(texte); texte=textetmp; for (i=maxnum;i<maxnum*2;i++) it(i) maxnum*=2; } texte[aktnum].type=TEXTOBJECT; texte[aktnum].van=c; texte[aktnum].size=size; texte[aktnum].polygons=malloc(strlen(str)*sizeof(char)+1); sprintf((char *) texte[aktnum].polygons,"%s",str); texte[aktnum].transfv=(int *) ref; /* typecast to reuse pointer */ veq(texte[aktnum].poswc,mc2wc(v1)); if (v2p==NULL) veq(texte[aktnum].tva[0],vnull); else veq(texte[aktnum].tva[0],mc2wc(vsum(v2,v1))); insertGobject(&(texte[aktnum])); }
void flaeche_3d(int c,vecp rp, vecp v1p,vecp v2p,int n1, int n2){ int i,j; vec r,r2,v1,v2; veq(r,mc2wc(rp)); veq(v1,sm(1.0/n1,vdiff(mc2wc(vsum(rp,v1p)),r))); veq(v2,sm(1.0/n2,vdiff(mc2wc(vsum(rp,v2p)),r))); /* veq(v1,mc2wcnorm(v1p))); veq(v2,sm(1.0/n2,mc2wcnorm(v2p)));*/ veq(r2,vsum(r,sm(0.5,vsum(v1,v2)))); for (i=0;i<n1;i++) for (j=0;j<n2;j++) einfache_flaeche_wc_3d(c, vsum(r2,vsum(sm(1.0*i,v1),sm(1.0*j,v2))), vsum(r,vsum(sm(1.0*i,v1),sm(1.0*j,v2))), vsum(r,vsum(sm(1.0*(i+1),v1),sm(1.0*j,v2))), vsum(r,vsum(sm(1.0*(i+1),v1),sm(1.0*(j+1),v2))), vsum(r,vsum(sm(1.0*i,v1),sm(1.0*(j+1),v2)))); }
//===================================================================// //START assembly of DVE resultant vector //===================================================================// //assembles remaining parts of resultant vector that are due to the //velocities at each surface element that are the results of the //free stream and the vorticity in the wake. The component of that velocity //that is normal to the surface DVE form the non-zero values of the //resultant vector. They are part of the kinematic condition, i.e., no //flow through the elementary-wing surface at the control point void DVE_Resultant(const GENERAL info,const PANEL *panelPtr,\ const DVE *surfacePtr,DVE **wakePtr,const int timestep,\ double *R) { int element; //loop counter over surface DVE's int panel,m,i; //loops over panels, chord lines, span wise elements int imax; //max. no. of spanwise elements that are not at edge int n2=2*info.noelement;//2*number of elements double w_wake[3]; //velocity induced by wake in control point double w_extern[3]; //free stream and wake induced velocities in ith DVE element=0; // initializing element index counter for(panel=0;panel<info.nopanel;panel++) //loop over panels { imax = panelPtr[panel].n-1; //loop over chordwise lift. lines for(m=0;m<info.m;m++) { //checking if left edge is a free tip if(panelPtr[panel].BC1==110) { //kinematic condition is not being satisfied at the tips, but //gamma'= 0, see boundary conditions R[element] = 0; R[element+info.noelement] = 0; R[element+n2] = 0; //increase DVE index element ++; } else { //compute the velocity induced at suface DVE by wake and free stream if(timestep<0) { w_extern[0]=surfacePtr[element].u[0]; w_extern[1]=surfacePtr[element].u[1]; w_extern[2]=surfacePtr[element].u[2]; } else { Wake_DVE_Vel_Induction\ (info,surfacePtr[element].xo,wakePtr,timestep,w_wake); //Subroutine in induced_velocity //add wake induced vel. and free stream vsum(w_wake,surfacePtr[element].u,w_extern); } //upper two-thirds are zero R[element] = 0; R[element+info.noelement] = 0; //computing the external velocity normal component R[element+n2] = 4*Pi*dot(w_extern,surfacePtr[element].normal); //increase DVE index element ++; }//done with left side edge for(i=1;i<imax;i++) //loop over spanwise elements-1 { //compute the velocity of ith suface DVE control point that //is induced by wake with if(timestep<0) { w_extern[0]=surfacePtr[element].u[0]; w_extern[1]=surfacePtr[element].u[1]; w_extern[2]=surfacePtr[element].u[2]; } else { Wake_DVE_Vel_Induction\ (info,surfacePtr[element].xo,wakePtr,timestep,w_wake); //Subroutine in induced_velocity //add wake induced vel. and free stream vsum(w_wake,surfacePtr[element].u,w_extern); } //upper two-thirds are zero R[element] = 0; R[element+info.noelement] = 0; //computing the external velocity normal component R[element+n2] = 4*Pi*dot(w_extern,surfacePtr[element].normal); //increase DVE index to next one element ++; }//done with loop over spanwise elements -1 if(panelPtr[panel].n > 1) //panel has more than one spanwise element //checking if right edge is a free tip if(panelPtr[panel].BC2==110) { //kinematic condition is not being satisfied at the tips, but //gamma'= 0, see boundary conditions R[element] = 0; R[element+info.noelement] = 0; R[element+n2] = 0; //increase DVE index element ++; } else { //compute the velocity ind. at suface DVE by wake and free stream if(timestep<0) { w_extern[0]=surfacePtr[element].u[0]; w_extern[1]=surfacePtr[element].u[1]; w_extern[2]=surfacePtr[element].u[2]; } else { Wake_DVE_Vel_Induction\ (info,surfacePtr[element].xo,wakePtr,timestep,w_wake); //Subroutine in induced_velocity //add wake induced vel. and free stream vsum(w_wake,surfacePtr[element].u,w_extern); } //upper two-thirds are zero R[element] = 0; R[element+info.noelement]= 0; //computing the external velocity normal component R[element+n2] = 4*Pi*dot(w_extern,surfacePtr[element].normal); //used to be dot(w_extern,surfacePtr[i].normal), //don't know why,but sometimes doesnt work with i. //G.B. 2-11-06 //increase DVE index element ++; }//done with right side edge }//done loop over m, next chord location }//done panel, next panel //########################################## //#control output of R //FILE *fp; //# //fp = fopen("output\\test.txt", "a"); //# //fprintf(fp,"R:"); //# //for(i=0;i<info.Dsize;i++) //# // fprintf(fp,"%lf ",R[i]); //# //fprintf(fp,"\n"); //# //fclose (fp); //# //########################################################################### }
/******************************************************************* Subroutine to do the Sub-Level PCA-PPM matrix *pcadata_re: the pointer to the new matrix containing the real part of data projected onto the space defined by the PCA matrix *pcadata_re: the pointer to the new matrix containing the imaginary part of data projected onto the space defined by the PCA matrix *pcavec_re: the pointer to a matrix containing the real part of eigenvector matrix *pcavec_im: the pointer to a matrix containing the imaginary part of eigenvector vector *pcaval_re: the pointer to a vector containing the real part of eigenvalues vector *pcaval_im: the pointer to a vector containing the imaginary part of eigenvalues vector *Zjk: the pointer to a vector containing the Zjk values matrix *subpcappmvec_re: the pointer to a matrix containing the real part of sorted eigenvectors by sub kurtosis rank matrix *subpcappmvec_re: the pointer to a matrix containing the imaginary part of sorted eigenvectors by sub kurtosis rank return value: '1' - successfully exit '0' - exit with waring/error *******************************************************************/ int veSubPCAPPM(matrix *pcadata_re, matrix *pcadata_im, matrix *pcavec_re, matrix *pcavec_im, vector *pcaval_re, vector *pcaval_im, vector *Zjk, matrix *subpcappmvec_re, matrix *subpcappmvec_im) { int m, n; int i, j, u=0, v=0; vector X1n, Xm1; matrix mZjk; matrix M1; matrix data_pow2; matrix data_pow4; vector V1; vector V2; vector V4; vector kurt; int* kurt_id; double sumZjk; double cen_data; bool allreal = true; m=pcadata_re->m; n=pcadata_im->n; vnew(&X1n, n); vnew(&Xm1, m); mnew(&mZjk, m, n); mnew(&M1, m, n); mnew(&data_pow2, m, n); mnew(&data_pow4, m, n); vnew(&V1, n); vnew(&V2, n); vnew(&V4, n); vnew(&kurt, n); kurt_id = new int[n]; vector V1_im; vector Xm1_im; matrix M1_im; double cen_data_im; matrix data_pow2_im; matrix data_pow4_im; vector V2_im; vector V4_im; vector kurt_im; vnew(&Xm1_im, m); mnew(&M1_im, m, n); mnew(&data_pow2_im, m, n); mnew(&data_pow4_im, m, n); vnew(&V1_im, n); vnew(&V2_im, n); vnew(&V4_im, n); vnew(&kurt_im, n); // whether complex eigenvalue exists for (i=0; i<n; i++) { if (*(pcaval_im->pr+i) != 0) { allreal = false; break; } } // center the data set its means // data_proj = data_proj - ones(n,1)*(sum(Zjk*ones(1,p).*(data_proj))./sum(Zjk)); vones(&X1n); vones(&Xm1); vvMul(Zjk, &X1n, &mZjk); sumZjk = vsum(Zjk); if (allreal==true) { kurtmodel(&mZjk, sumZjk, pcadata_re, &V1); vvMul(&Xm1, &V1, &M1); for (i=0; i<m*n; i++) { cen_data = *(pcadata_re->pr + i) - *(M1.pr + i); //*(data->pr + i) = cen_data; *(data_pow2.pr+i) = pow(cen_data, 2); *(data_pow4.pr+i) = pow(cen_data, 4); } // calculate kurtosis : kurt(y) = E{y^4}-3(E{y^2})^2 //kurt = sum(Zjk*ones(1,p).*(data_proj.^4))./sum(Zjk)... //- 3*(sum(Zjk*ones(1,p).*(data_proj.^2))./sum(Zjk)).^2; %Not normalized Kurtosis kurtmodel(&mZjk, sumZjk, &data_pow2, &V2); kurtmodel(&mZjk, sumZjk, &data_pow4, &V4); for (j=0; j<n; j++) { *(kurt.pr+j) = *(V4.pr+j) - 3*(pow(*(V2.pr+j), 2)); } } else { ckurtmodel(&mZjk, sumZjk, pcadata_re, pcadata_im, &V1, &V1_im); cvvMul(&Xm1, &Xm1_im, &V1, &V1_im, &M1, &M1_im); for (i=0; i<m*n; i++) { cen_data = *(pcadata_re->pr + i) - *(M1.pr + i); cen_data_im = *(pcadata_im->pr + i) - *(M1_im.pr + i); //*(data->pr + i) = cen_data; *(data_pow2.pr+i) = pow(cen_data, 2) - pow(cen_data_im, 2); *(data_pow2_im.pr+i) = 2 * cen_data * cen_data_im; *(data_pow4.pr+i) = pow(*(data_pow2.pr+i), 2) - pow(*(data_pow2_im.pr+i), 2); *(data_pow4_im.pr+i) = 2 * (*(data_pow2.pr+i)) * (*(data_pow2_im.pr+i)); } // calculate kurtosis : kurt(y) = E{y^4}-3(E{y^2})^2 //kurt = sum(Zjk*ones(1,p).*(data_proj.^4))./sum(Zjk)... //- 3*(sum(Zjk*ones(1,p).*(data_proj.^2))./sum(Zjk)).^2; %Not normalized Kurtosis ckurtmodel(&mZjk, sumZjk, &data_pow2, &data_pow2_im, &V2, &V2_im); ckurtmodel(&mZjk, sumZjk, &data_pow4, &data_pow4_im, &V4, &V4_im); for (j=0; j<n; j++) { *(kurt.pr+j) = *(V4.pr+j) - 3*(pow(*(V2.pr+j), 2) - pow(*(V2_im.pr+j), 2)); *(kurt_im.pr+j) = *(V4_im.pr+j) - 3 * 2 * (*(V2.pr+j)) * (*(V2_im.pr+j)); } } // sort kurt value in ascending order and reorder the pca_vec int realeig_num; int *realeig_id; int *compeig_id; vector realkurt; int *real_order; realeig_num = n; for (i=0; i<n; i++) { if (*(pcaval_im->pr+i) != 0) { realeig_num--; } } vnew(&realkurt, realeig_num); realeig_id = new int[realeig_num]; compeig_id = new int[n-realeig_num]; real_order = new int[realeig_num]; for (i=0; i<n; i++) { if (*(pcaval_im->pr+i) == 0) { realeig_id[u] = i; *(realkurt.pr+u) = *(kurt.pr+i); u++; } else { compeig_id[v] = i; v++; } } sort(&realkurt, real_order, 'a'); int *tmp; tmp = new int[realeig_num]; for (i=0; i<realeig_num; i++) { tmp[i] = realeig_id[i]; } for (i=0; i<realeig_num; i++) { realeig_id[i] = tmp[real_order[i]]; } delete []tmp; vector kurt0; vector kurt0_im; vnew(&kurt0, kurt.l); vcopy(&kurt, &kurt0); vnew(&kurt0_im, kurt.l); vcopy(&kurt_im, &kurt0_im); for (i=0; i<realeig_num; i++) { kurt_id[i] = realeig_id[i]; *(kurt.pr+i) = *(realkurt.pr+i); *(kurt_im.pr+i) = 0; } for (i=0; i<n-realeig_num; i++) { kurt_id[i+realeig_num] = compeig_id[i]; *(kurt.pr+i+realeig_num) = *(kurt0.pr + compeig_id[i]); *(kurt_im.pr+i+realeig_num) = *(kurt0_im.pr + compeig_id[i]); } //printf(" the real part of kurt value is : \n"); //vprint(&kurt); //printf(" the imaginary part of kurt value is : \n"); //vprint(&kurt_im); //printf(" the kurt id is : \n"); //for (i=0; i<n; i++) { // printf("%d\t", kurt_id[i]); //} sortcols(kurt_id, pcavec_re, subpcappmvec_re); sortcols(kurt_id, pcavec_im, subpcappmvec_im); vdelete(&X1n); vdelete(&Xm1); mdelete(&mZjk); mdelete(&M1); mdelete(&data_pow2); mdelete(&data_pow4); vdelete(&V1); vdelete(&V2); vdelete(&V4); vdelete(&kurt); vdelete(&kurt0); delete []kurt_id; vdelete(&realkurt); delete []realeig_id; delete []compeig_id; delete []real_order; vdelete(&Xm1_im); mdelete(&M1_im); mdelete(&data_pow2_im); mdelete(&data_pow4_im); vdelete(&V1_im); vdelete(&V2_im); vdelete(&V4_im); vdelete(&kurt_im); vdelete(&kurt0_im); return 1; }
/******************************************************************* Subroutine to compute the inverse matrix and determinant matrix *cov: the pointer to the covariance matrix matrix *inv_cov: the pointer to the inverse covariance matrix matrix *cov_mat: the pointer to the approximate covariance matrix when singular. If unsingular, it equals to cov double *det_cov: the pointer to determinant return value: '1' - successfully exit '0' - exit with waring/error *******************************************************************/ int veCov(matrix *cov, matrix *inv_cov, matrix *cov_mat, double *det_cov) { int i, j; matrix eigvec_re; matrix eigvec_im; vector eigval_re; vector eigval_im; int *eig_order; int eig_info; int num_v; // the number of eigenvalue int rank_c; double sum_v; double factor = 0.02; double ass_value; double min_real; mnew(&eigvec_re, cov->m, cov->n); mnew(&eigvec_im, cov->m, cov->n); vnew(&eigval_re, cov->n); vnew(&eigval_im, cov->n); eig_order = new int[cov->n]; // the eigenvector and eigenvalue of covariance matrix eig_info = eig(cov, &eigvec_re, &eigvec_im, &eigval_re, &eigval_im); //vprint(&eigval_re); //vprint(&eigval_im); if (!eig_info) { printf(" The eigenvalue computation failed! \n"); return 0; //.... } // the rank of covariance matrix num_v = cov->n; /*rank_c = num_v; for (i=0; i<num_v; i++) { if ((fabs(*(eigval_re.pr+i)) < ZEROTHRESH) && (fabs(*(eigval_im.pr+i)) < ZEROTHRESH)) { rank_c--; } } printf("rank = %d", rank_c);*/ rank_c = rank(cov, TOLERANCE); // compute the inverse and determinate if (rank_c == num_v) { // nonsingular inv(cov, inv_cov); mcopy(cov, cov_mat); *det_cov = det(cov); } else { // singular min_real = pow(10, (((double)-250) / ((double) cov->m))); /*for (i=0; i<num_v; i++) { if ((*(eigval_re.pr+i) < ZEROTHRESH) || (*(eigval_im.pr+i) != 0)) { *(eigval_re.pr+i) = 0; // ???? keep the real part of complex or not *(eigval_im.pr+i) = 0; } } sort(&eigval_re, eig_order, 'd'); */ for (i=0; i<num_v; i++) { // when negtive real eigenvalue, change to absolute value // to ensure all the real eigenvalues are positive if ((eigval_re.pr[i] < 0) && (eigval_im.pr[i] == 0)) { eigval_re.pr[i] *= -1; // the i-th column of eigenvector should also be changed the sign for (j=0; j<(eigvec_re.m); j++) { eigvec_re.pr[j*(eigvec_re.n)+i] *= -1; } } } //vprint(&eigval_re); //vprint(&eigval_im); // sort real eigenvalues descendingly, put complex ones at the end sorteig(&eigval_re, &eigval_im, eig_order); for (i=rank_c; i<num_v; i++) { *(eigval_re.pr+i) = 0; *(eigval_im.pr+i) = 0; } //vprint(&eigval_re); //vprint(&eigval_im); sum_v = vsum(&eigval_re); ass_value = factor * sum_v / (num_v - rank_c); if (ass_value < (0.5 * (*(eigval_re.pr+rank_c)) * (1 - factor))) { if (ass_value > min_real) { for (i=rank_c; i<num_v; i++) { *(eigval_re.pr+i) = ass_value; } for (i=0; i<rank_c; i++) { *(eigval_re.pr+i) *= 1 - factor; } } else { for (i=rank_c; i<num_v; i++) { *(eigval_re.pr+i) = min_real; } } } else { ass_value = 0.5 * (*(eigval_re.pr+rank_c)) * (1 - factor); if (ass_value > min_real) { for (i=rank_c; i<num_v; i++) { *(eigval_re.pr+i) = ass_value; } for (i=0; i<rank_c; i++) { *(eigval_re.pr+i) = *(eigval_re.pr+i) - ass_value * (num_v - rank_c) * (*(eigval_re.pr+i)) / sum_v; } } else { for (i=rank_c; i<num_v; i++) { *(eigval_re.pr+i) = min_real; } } } //vprint(&eigval_re); //vprint(&eigval_im); matrix eigvec_re_sorted; matrix eigvec_re_sorted_t; mnew(&eigvec_re_sorted, num_v, num_v); mnew(&eigvec_re_sorted_t, num_v, num_v); sortcols(eig_order, &eigvec_re, &eigvec_re_sorted); transpose(&eigvec_re_sorted, &eigvec_re_sorted_t); matrix inv_eig_vl_s; mnew(&inv_eig_vl_s, num_v, num_v); for (i=1; i<num_v; i++) { *(inv_eig_vl_s.pr + i*num_v + i) = 1 / (*(eigval_re.pr+i)); } matrix tmp; mnew(&tmp, num_v, num_v); mmMul(&eigvec_re_sorted, &inv_eig_vl_s, &tmp); mmMul(&tmp, &eigvec_re_sorted_t, inv_cov); matrix diag_eigval; mnew(&diag_eigval, num_v, num_v); for (i=0; i<num_v; i++) { *(diag_eigval.pr + i*num_v + i) = *(eigval_re.pr+i); } mmMul(&eigvec_re_sorted, &diag_eigval, &tmp); mmMul(&tmp, &eigvec_re_sorted_t, cov_mat); *det_cov = 1; for (i=0; i<num_v; i++) { *det_cov = (*det_cov) * (*(eigval_re.pr+i)); } mdelete(&inv_eig_vl_s); mdelete(&eigvec_re_sorted); mdelete(&eigvec_re_sorted_t); mdelete(&tmp); mdelete(&diag_eigval); } #ifdef _DEBUG printf("rank = %d \n", rank_c); printf("\n det_cov = %e \n", *det_cov); printf("inv_cov = \n"); mprint(inv_cov); printf("cov_mat = \n"); mprint(cov_mat); #endif mdelete(&eigvec_re); mdelete(&eigvec_im); vdelete(&eigval_re); vdelete(&eigval_im); delete []eig_order; return 1; }
vector<GaussianDistribution> EMGaussianClustering(vector<Feature>& points, int K, int maxIter, float tolerance) { if (K >= points.size()) { vector<GaussianDistribution> dist(points.size()); for (int i = 0; i < points.size(); ++i) { dist[i].mu = points[i]; vector<Feature> f(1, points[i]); dist[i].sgm = Covariance::computeCovariance(f); } return dist; } int N = points[0].length(); Feature zero(N); //initialize the Gaussian distributions from K-means vector<Feature> centers = KmeansClustering(points, K, tolerance); //use K-means for initialization K = centers.size(); Feature zero2(K); vector<int> labels(points.size()); for (int i = 0; i < points.size(); ++i) { labels[i] = selectKmeansCluster(points[i], centers); } vector<GaussianDistribution> dist(centers.size()); for (int i = 0; i < centers.size(); ++i) { vector<Feature> x; for (int j = 0; j < labels.size(); ++j) { if (labels[j] == i) { x.push_back(points[j]); } } dist[i] = GaussianDistribution(x); } int iter = 0; while (true) { iter++; if (iter >= maxIter) { //printf("EMGaussian: Maximum iteration reached before convergence.\n"); break; } //E-step: compute the weights vector<Feature> w(points.size(), zero2); for (int i = 0; i < points.size(); ++i) { float sum = 0; for (int j = 0; j < K; ++j) { float pval = dist[j].eval(points[i]); w[i].vals[j] = pval; sum += pval; } for (int j = 0; j < K; ++j) { w[i].vals[j] /= sum; } } //M-step: //Compute the means vector<GaussianDistribution> dist2(K); vector<float> vsum(K); for (int i = 0; i < K; ++i) { Feature m = zero; float sum = 0; for (int j = 0; j < points.size(); ++j) { for (int k = 0; k < m.length(); ++k) { m.vals[k] += w[j].vals[i] * points[j].vals[k]; } sum += w[j].vals[i]; } for (int k = 0; k < m.length(); ++k) { m.vals[k] /= sum; } dist2[i].mu = m; vsum[i] = sum; } //Compute the covariances for (int i = 0; i < K; ++i) { techsoft::matrix<float> cov(N, N, 0.0f); techsoft::matrix<float> m = Feature::toColumnVector(dist2[i].mu); float sum = 0; for (int j = 0; j < points.size(); ++j) { techsoft::matrix<float> df(N, 1); for (int k = 0; k < N; ++k) { df(k,0) = points[j].vals[k] - m(k, 0); } cov = cov + w[j].vals[i] * (df * (~df)); } cov /= vsum[i]; dist2[i].sgm = Covariance(K); dist2[i].sgm.mat = cov; dist2[i].sgm.imat = !cov; } dist = dist2; } return dist; }