void LinearQuadtreeExpansion::L2P(__uint32 source, __uint32 point, float& fx, float& fy)
{	
	const double* source_coeff = m_localExp + source*(m_numCoeff << 1);
	const double q = (double)m_tree.pointSize(point);
	const double x = (double)m_tree.pointX(point);
	const double y = (double)m_tree.pointY(point);
	const double centerX = (double)m_tree.nodeX(source);
	const double centerY = (double)m_tree.nodeY(source);
	ComplexDouble ak;
	ComplexDouble res;
	ComplexDouble delta(ComplexDouble(x,y) - ComplexDouble(centerX, centerY));
	ComplexDouble delta_k(1);
	for (__uint32 k=1; k<m_numCoeff; k++)
	{
		ak.load(source_coeff+(k<<1));
		res += ak*delta_k*(double)k;
		delta_k *= delta;		
	};
	res = res.conj();
	double resTemp[2];
	res.store_unaligned(resTemp);

	fx -= ((float)resTemp[0]);
	fy -= ((float)resTemp[1]);
};
void LinearQuadtreeExpansion::M2M(__uint32 source, __uint32 receiver)
{
	double* receiv_coeff = m_multiExp + receiver*(m_numCoeff<<1);
	double* source_coeff = m_multiExp + source*(m_numCoeff<<1);

	const double center_x_source   = (double)m_tree.nodeX(source);
	const double center_y_source   = (double)m_tree.nodeY(source);
	const double center_x_receiver = (double)m_tree.nodeX(receiver);
	const double center_y_receiver = (double)m_tree.nodeY(receiver);

	ComplexDouble delta(ComplexDouble(center_x_source, center_y_source) - ComplexDouble(center_x_receiver, center_y_receiver));

	ComplexDouble a(source_coeff);
	ComplexDouble b(receiv_coeff);
	b += a;
	b.store(receiv_coeff);
	for (__uint32 l=1;l<m_numCoeff;l++)
	{
		b.load(receiv_coeff+(l<<1));
		ComplexDouble delta_k(1.0,0.0);
		for (__uint32 k=0;k<l;k++)
		{
			a.load(source_coeff+((l-k)<<1));
			b += a*delta_k*binCoef.value(l-1, k);
			delta_k *= delta;
		};
		a.load(source_coeff);
		b -= a*delta_k*(1/(double)l); 
		b.store(receiv_coeff+(l<<1));
	};
};
Exemplo n.º 3
0
ComplexDouble QMFunction::integrate() const {
    double int_r = 0.0;
    double int_i = 0.0;
    if (hasReal()) int_r = real().integrate();
    if (hasImag()) int_i = imag().integrate();
    return ComplexDouble(int_r, int_i);
}
void LinearQuadtreeExpansion::P2M(__uint32 point, __uint32 receiver)
{
	double* receiv_coeff = m_multiExp + receiver*(m_numCoeff<<1);
	const double q = (double)m_tree.pointSize(point);
	const double x = (double)m_tree.pointX(point);
	const double y = (double)m_tree.pointY(point);
	const double centerX = (double)m_tree.nodeX(receiver);
	const double centerY = (double)m_tree.nodeY(receiver);
	// a0 += q_i
	receiv_coeff[0] += q;
	// a_1..m
	ComplexDouble ak;
	// p - z0
	ComplexDouble delta(ComplexDouble(x, y) - ComplexDouble(centerX, centerY));
	// (p - z0)^k
	ComplexDouble delta_k(delta);
	for (__uint32 k=1; k<m_numCoeff; k++)
	{
		ak.load(receiv_coeff+(k<<1));
		ak -= delta_k*(q/(double)k);
		ak.store(receiv_coeff+(k<<1));
		delta_k *= delta;
	};
};
Exemplo n.º 5
0
void Extract_FCs_FixedWindowLength::set_corrections( std::vector<StationBase> &station )
{
    // auxiliary variables
    size_t npts2;
    double pi2n, t, g, freq, period, w, RE, IM;
    ComplexDouble temp;
    bool auxID;

    npts2 = floor(this->windowLength/2);
    pi2n = 2*PI/(this->windowLength/2);

    for( int istn = 0; istn < station.size(); istn++ ) {
        for( int its = 0; its < station[istn].ts.size(); its++ ) {

            // fill in dr with sampling periods for all decimation levels
            //cout << station[istn].ts[its].maxDecimationLevel << endl;
            std::vector<double> dr( station[istn].ts[its].maxDecimationLevel );
            for( int i = 0;  i < dr.size(); i++ )
                dr[i] = pow( this->factorOfEachDecimationLevel, i )/station[istn].ts[its].samplingFrequency;

            // correct for first difference if appropriate
            // correct unist of fc's
            for( int ich = 0; ich < station[istn].ts[its].ch.size(); ich++ ) {
                station[istn].ts[its].ch[ich].correction = new matCUDA::Array<ComplexDouble>( station[istn].ts[its].maxDecimationLevel, npts2 );
                for( int id = 0; id < station[istn].ts[its].maxDecimationLevel; id++ ) {
                    t = sqrt(dr[id]);
                    for( int i = 0; i < npts2; i++ )
                        station[istn].ts[its].ch[ich].correction[0]( id, i ) = station[istn].ts[its].ch[ich].countConversion*t;
                }
            }

            //// checkouts
            //if( station[istn].ts[its].mtu.mtuTsBand == phoenixTsBand_t(5) ) {
            //	for( int ich = 0; ich < station[istn].ts[its].ch.size(); ich++ ) {
            //		cout << station[istn].ts[its].ch[ich].name << endl;
            //		cout << station[istn].ts[its].ch[ich].correction[0]( 0, 0) << endl;
            //		//for( int i = 0; i < station[istn].ts[its].ch[ich].correction[0].getDim(1) - 1; i++ ) {
            //		//	cout << station[istn].ts[its].ch[ich].correction[0]( 0, i) << endl;
            //		//}
            //		//cout << endl;
            //	}
            //}

            //// corrections for low pass decimation filters
            //// corrects for effect of low pass filters on all decimation levels
            //this->fcDistribution[0].print();
            //for( int ich = 0; ich < station[istn].ts[its].ch.size(); ich++ ) {
            //	for( int id = 1; id < station[istn].ts[its].maxDecimationLevel; id++ ) {
            //		for( int jd = id; jd < station[istn].ts[its].maxDecimationLevel; jd++ ) {
            //			pi2n = 2*PI*dr[id - 1]/dr[jd]/this->windowLength;
            //			for( int i = 0; i < npts2; i++ ) {
            //				g = this->fcDistribution[0]( id, 1 );
            //				for( int j = 1; j < this->fcDistribution[0].getDim(1); j++ ) {
            //					t = pi2n*i*( j - 1 );
            //					g += 2*this->fcDistribution[0]( id, j )*cos( t );
            //				}
            //				station[istn].ts[its].ch[ich].correction[0]( id, i ) = station[istn].ts[its].ch[ich].correction[0]( id, i )/g;
            //			}
            //		}
            //	}
            //}

            //// checkouts
            //if( station[istn].ts[its].mtu.mtuTsBand == phoenixTsBand_t(5) ) {
            //	for( int ich = 0; ich < station[istn].ts[its].ch.size(); ich++ ) {
            //		cout << station[istn].ts[its].ch[ich].name << endl;
            //		cout << station[istn].ts[its].ch[ich].correction[0]( 0, 0) << endl;
            //		//for( int i = 0; i < station[istn].ts[its].ch[ich].correction[0].getDim(1) - 1; i++ ) {
            //		//	cout << station[istn].ts[its].ch[ich].correction[0]( 0, i) << endl;
            //		//}
            //		//cout << endl;
            //	}
            //}

            // corrections for analogue instrument filters/system response
            for( int ich = 0; ich < station[istn].ts[its].ch.size(); ich++ ) {
                for( int id = 0; id < station[istn].ts[its].maxDecimationLevel; id++ ) {
                    for( int i = 0; i < npts2; i++ ) {
                        freq = (i + 1)/dr[id]/this->windowLength;
                        period = 1/freq;
                        temp = ComplexDouble( 0, 0 );
                        for( int j = 0; j < station[istn].ts[its].ch[ich].systemResponseFreqs[0].getDim(0) - 1; j++ ) {
                            if( freq > station[istn].ts[its].ch[ich].systemResponseFreqs[0]( j + 1 ) && freq <= station[istn].ts[its].ch[ich].systemResponseFreqs[0]( j ) ) {

                                w = (station[istn].ts[its].ch[ich].systemResponseFreqs[0]( j ) - freq)/(station[istn].ts[its].ch[ich].systemResponseFreqs[0]( j ) - station[istn].ts[its].ch[ich].systemResponseFreqs[0]( j + 1 ));
                                RE = station[istn].ts[its].ch[ich].systemResponse[0]( j + 1, 1 ).real()*w + station[istn].ts[its].ch[ich].systemResponse[0]( j, 1 ).real()*( 1 - w );
                                IM = station[istn].ts[its].ch[ich].systemResponse[0]( j + 1, 1 ).imag()*w + station[istn].ts[its].ch[ich].systemResponse[0]( j, 1 ).imag()*( 1 - w );

                                auxID = true;
                                break;
                            }
                        }
                        if(auxID) {
                            temp = ComplexDouble( RE, IM )*station[istn].ts[its].ch[ich].gain;
                            station[istn].ts[its].ch[ich].correction[0]( id, i ) = station[istn].ts[its].ch[ich].correction[0]( id, i )/temp;
                            auxID = false;
                        }
                        else
                            station[istn].ts[its].ch[ich].correction[0]( id, i ) = 0;
                    }
                }
            }
        }
    }

    //// checkouts
    //if( ts.mtu.mtuTsBand == phoenixTsBand_t(5) ) {
    //	for( int ich = 0; ich < ts.ch.size(); ich++ ) {
    //		//for( int i = 0; i < station[istn].ts[its].ch[ich].correction[0].getDim(1) - 1; i++ )
    //			cout << station[istn].ts[its].ch[ich].correction[0](0,1279) << " ";
    //	}
    //		cout << endl;
    //}
}
void LinearQuadtreeExpansion::M2L(__uint32 source, __uint32 receiver)
{
	double* receiv_coeff = m_localExp + receiver*(m_numCoeff<<1);
	double* source_coeff = m_multiExp + source*(m_numCoeff<<1);

	const float center_x_source   = (float)m_tree.nodeX(source);
	const float center_y_source   = (float)m_tree.nodeY(source);
	const float center_x_receiver = (float)m_tree.nodeX(receiver);
	const float center_y_receiver = (float)m_tree.nodeY(receiver);

	ComplexDouble center_receiver(center_x_receiver, center_y_receiver);
	ComplexDouble center_source(center_x_source, center_y_source);
	ComplexDouble delta0(center_source - center_receiver);

	ComplexDouble delta1 = -delta0;
	ComplexDouble delta1_l(delta1);
	ComplexDouble a;
	ComplexDouble a0(source_coeff);
	ComplexDouble b;
	ComplexDouble sum;
	for (__uint32 l=1;l<m_numCoeff;l++)
	{
		b.load(receiv_coeff+(l<<1));
		sum = a0*(-1/(double)l);
		ComplexDouble delta0_k(delta0);
		for (__uint32 k=1;k<m_numCoeff;k++)
		{
			a.load(source_coeff+(k<<1));
			sum += (a*binCoef.value(l+k-1, k-1)) / delta0_k;
			delta0_k *= delta0;
		};
		
		b += sum/delta1_l;
		b.store(receiv_coeff+(l<<1));
		delta1_l *= delta1;
	};

	// b0
	b.load(receiv_coeff);
	//std::complex<double> sdelta(m_center[(receiver<<1)] - m_center[(source<<1)],  m_center[(receiver<<1)+1] - m_center[(source<<1) +1]);//, m_x[receiver] - m_x[source], m_y[receiver] - m_y[source]);
	/*std::complex<double> sdelta(center_x_receiver - center_x_source,  
								center_y_receiver - center_y_source);//, m_x[receiver] - m_x[source], m_y[receiver] - m_y[source]);
	
	if ((sdelta.real() <=0) && (sdelta.imag() == 0)) //no cont. compl. log fct exists !!!
		sdelta = log(sdelta + 0.00000001);
	else
		sdelta = log(sdelta);
	
	*/
	double r = delta1.length();//= sqrt(sdelta.real()*sdelta.real()+sdelta.imag()*sdelta.imag());
	double phi = atan((center_x_receiver - center_x_source)/(center_y_receiver - center_y_source));
	// sum = a0*log(z1 - z0)
	b += a0*ComplexDouble(log(r), phi);
	// (z1 - z0)^1
	//b += a0*ComplexDouble(sdelta.real(), sdelta.imag());
	delta1_l = delta1;
	for (__uint32 k=1;k<m_numCoeff;k++)
	{
		a.load(source_coeff+(k<<1));
		b += a/delta1_l;
		//(z1 - z0)^k
		delta1_l *= delta1;
	};
	b.store(receiv_coeff);
};