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)); }; };
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; }; };
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); };