Ejemplo n.º 1
0
    //*************************************************TERM 3*************************************************
    dcomplex Zetafunc::term3full(const double q2){
        double resultre=0.,resultim=0.;
#pragma omp parallel
        {
            double tmp,r,theta,phi,wdprod,ghatwnorm;
            dcomplex result(0.,0.),tmpcomp1,tmpcomp2,tmpcomp3;
            threevec<double> wvec,ghatw,wpar,wperp;
            
            Zetafuncint integrand2;
#pragma omp parallel for reduction(+:resultre) reduction(+:resultim)
            for(int z=-MAXRUN; z<=MAXRUN; z++){
                for(int y=-MAXRUN; y<=MAXRUN; y++){
                    for(int x=-MAXRUN; x<=MAXRUN; x++){
                        if( (x==0) && (y==0) && (z==0) ) continue; //exclude zero!
                        wvec(static_cast<double>(x),static_cast<double>(y),static_cast<double>(z));
                        
                        //compute scalar product and orthogonal projection:
                        if(!is_zeroboost){
                            orthogonal_projection(wvec,boost,wpar,wperp);
                            ghatw=gamma*wpar+wperp;
                        }
                        else{
                            ghatw=wvec;
                        }
                        ghatwnorm=ghatw.norm();
                        
                        //solve the integral:
                        integrand2.set(q2,ghatwnorm,l);
                        Midpnt<TFunctor> int2(integrand2,0.,lambda);
                        tmp=qromo(int2);
                        if(l!=0) tmp*=::std::pow(ghatwnorm,static_cast<double>(l));
                        
                        //compute the complex parts:
                        ghatw.get_spherical_coordinates(r,theta,phi);
                        tmpcomp1=spherical_harmonicy(l,m,theta,phi);
                        //exip(-ipi w*d)-term
                        if(!is_zeroboost){
                            wdprod=wvec*boost;
                            tmpcomp2(cos(pimath*wdprod),-sin(pimath*wdprod));
                        }
                        else tmpcomp2(1.,0.);
                        tmpcomp3=tmpcomp1*tmpcomp2*tmp;
                        //result+=tmpcomp3;
                        resultre+=tmpcomp3.re();
                        resultim+=tmpcomp3.im();
                    }
                }
            }
        }
        dcomplex result(resultre,resultim);
        result*=gamma*::std::pow(pimath,static_cast<double>(1.5+l));
        
        return result;
    }
Ejemplo n.º 2
0
    inline
    int getri (MatrA& a, IVec& ipiv) {

#ifndef BOOST_NUMERIC_BINDINGS_POOR_MANS_TRAITS
      typedef typename traits::matrix_traits<MatrA>::value_type val_t; 
#else 
      typedef typename MatrA::value_type val_t; 
#endif 

      //TODO: compute optimal size of work array. Useful for small arrays?

      int const o = traits::matrix_size2 (a) < traits::matrix_size1 (a) ? traits::matrix_size2 (a) : traits::matrix_size1 (a);
	  traits::detail::array <val_t> wvec (o); 
	  
      return getri (a, ipiv, wvec);
    }
Ejemplo n.º 3
0
static void Diagonalizer_and_CrossCorrelationTable_qdiag (Diagonalizer me, CrossCorrelationTables thee, double *cweights, long maxNumberOfIterations, double delta) {
	try {
		CrossCorrelationTable c0 = (CrossCorrelationTable) thy item[1];
		double **w = my data;
		long dimension = c0 -> numberOfColumns;

		autoEigen eigen = Thing_new (Eigen);
		autoCrossCorrelationTables ccts = Data_copy (thee);
		autoNUMmatrix<double> pinv (1, dimension, 1, dimension);
		autoNUMmatrix<double> d (1, dimension, 1, dimension);
		autoNUMmatrix<double> p (1, dimension, 1, dimension);
		autoNUMmatrix<double> m1 (1, dimension, 1, dimension);
		autoNUMmatrix<double> wc (1, dimension, 1, dimension);
		autoNUMvector<double> wvec (1, dimension);
		autoNUMvector<double> wnew (1, dimension);
		autoNUMvector<double> mvec (1, dimension);

		for (long i = 1; i <= dimension; i++) // Transpose W
			for (long j = 1; j <= dimension; j++) {
				wc[i][j] = w[j][i];
			}

		// d = diag(diag(W'*C0*W));
		// W = W*d^(-1/2);

		NUMdmatrix_normalizeColumnVectors (wc.peek(), dimension, dimension, c0 -> data);

		// scale eigenvectors for sphering
		// [vb,db] = eig(C0);
		// P = db^(-1/2)*vb';

		Eigen_initFromSymmetricMatrix (eigen.peek(), c0 -> data, dimension);
		for (long i = 1; i <= dimension; i++) {
			if (eigen -> eigenvalues[i] < 0) {
				Melder_throw (U"Covariance matrix not positive definite, eigenvalue[", i, U"] is negative.");
			}
			double scalef = 1 / sqrt (eigen -> eigenvalues[i]);
			for (long j = 1; j <= dimension; j++) {
				p[dimension - i + 1][j] = scalef * eigen -> eigenvectors[i][j];
			}
		}

		// P*C[i]*P'

		for (long ic = 1; ic <= thy size; ic++) {
			CrossCorrelationTable cov1 = (CrossCorrelationTable) thy item[ic];
			CrossCorrelationTable cov2 = (CrossCorrelationTable) ccts -> item[ic];
			NUMdmatrices_multiply_VCVp (cov2 -> data, p.peek(), dimension, dimension, cov1 -> data, 1);
		}

		// W = P'\W == inv(P') * W

		NUMpseudoInverse (p.peek(), dimension, dimension, pinv.peek(), 0);

		NUMdmatrices_multiply_VpC (w, pinv.peek(), dimension, dimension, wc.peek(), dimension);

		// initialisation for order KN^3

		for (long ic = 2; ic <= thy size; ic++) {
			CrossCorrelationTable cov = (CrossCorrelationTable) ccts -> item[ic];
			// C * W
			NUMdmatrices_multiply_VC (m1.peek(), cov -> data, dimension, dimension, w, dimension);
			// D += scalef * M1*M1'
			NUMdmatrices_multiplyScaleAdd (d.peek(), m1.peek(), dimension, dimension, 2 * cweights[ic]);
		}

		long iter = 0;
		double delta_w;

		autoMelderProgress progress (U"Simultaneous diagonalization of many CrossCorrelationTables...");
		try {
			do {
				// the standard diagonality measure is rather expensive to calculate so we compare the norms of
				// differences of eigenvectors.

				delta_w = 0;
				for (long kol = 1; kol <= dimension; kol++) {
					for (long i = 1; i <= dimension; i++) {
						wvec[i] = w[i][kol];
					}

					update_one_column (ccts.peek(), d.peek(), cweights, wvec.peek(), -1, mvec.peek());

					Eigen_initFromSymmetricMatrix (eigen.peek(), d.peek(), dimension);

					// Eigenvalues already sorted; get eigenvector of smallest !

					for (long i = 1; i <= dimension; i++) {
						wnew[i] = eigen -> eigenvectors[dimension][i];
					}

					update_one_column (ccts.peek(), d.peek(), cweights, wnew.peek(), 1, mvec.peek());
					for (long i = 1; i <= dimension; i++) {
						w[i][kol] = wnew[i];
					}

					// compare norms of eigenvectors. We have to compare ||wvec +/- w_new|| because eigenvectors
					//  may change sign.

					double normp = 0, normm = 0;
					for (long j = 1; j <= dimension; j++) {
						double dm = wvec[j] - wnew[j], dp = wvec[j] + wnew[j];
						normp += dm * dm; normm += dp * dp;
					}

					normp = normp < normm ? normp : normm;
					normp = sqrt (normp);
					delta_w = normp > delta_w ? normp : delta_w;
				}
				iter++;

				Melder_progress ((double) iter / (double) (maxNumberOfIterations + 1), U"Iteration: ", iter, U", norm: ", delta_w);
			} while (delta_w > delta && iter < maxNumberOfIterations);
		} catch (MelderError) {
			Melder_clearError ();
		}

		// Revert the sphering W = P'*W;
		// Take transpose to make W*C[i]W' diagonal instead of W'*C[i]*W => (P'*W)'=W'*P

		NUMmatrix_copyElements (w, wc.peek(), 1, dimension, 1, dimension);
		NUMdmatrices_multiply_VpC (w, wc.peek(), dimension, dimension, p.peek(), dimension); // W = W'*P: final result

		// Calculate the "real" diagonality measure
	//	double dm = CrossCorrelationTables_and_Diagonalizer_getDiagonalityMeasure (thee, me, cweights, 1, thy size);

	} catch (MelderError) {
		Melder_throw (me, U" & ", thee, U": no joint diagonalization (qdiag).");
	}
}