vec cheb(int n, const vec &x) { it_assert_debug(x.size() > 0, "cheb(): empty vector"); vec out(x.size()); for (int i = 0; i < x.size(); ++i) { out(i) = cheb(n, x(i)); } return out; }
/**------------------------------------------------- * Make a quadrature given a Polynomial. * @param P :: A polynomial to use to make the quadrature. */ void MakeQuadrature::makeQuadrature(const Polynomial& P) { auto& r = P.getRoots(); auto& w = P.getWeights(); const size_t n = r.size(); auto quad = new Quadrature; quad->setRowCount( int(n) ); quad->addDoubleColumn("r", API::NumericColumn::X); auto& rc = quad->getDoubleData("r"); rc = r; quad->addDoubleColumn("w", API::NumericColumn::Y); auto& wc = quad->getDoubleData("w"); wc = w; FunctionDomain1DView domain( r ); FunctionValues values( domain ); std::vector<double> wgt; std::vector<double> wgtDeriv; P.weightFunction()->function( domain, values ); values.copyToStdVector( wgt ); P.weightDerivative()->function( domain, values ); values.copyToStdVector( wgtDeriv ); quad->addDoubleColumn("weight", API::NumericColumn::Y); auto& wgtc = quad->getDoubleData("weight"); wgtc = wgt; quad->addDoubleColumn("deriv", API::NumericColumn::Y); auto& derc = quad->getDoubleData("deriv"); derc = wgtDeriv; Quadrature::FuncVector fvec( n ); Quadrature::FuncVector dvec( n ); for(size_t i = 0; i < n; ++i) { std::string colInd = boost::lexical_cast<std::string>( i ); quad->addDoubleColumn("f"+colInd, API::NumericColumn::Y); fvec[i] = &quad->getDoubleData("f"+colInd); quad->addDoubleColumn("d"+colInd, API::NumericColumn::Y); dvec[i] = &quad->getDoubleData("d"+colInd); } P.calcPolyValues( fvec, dvec ); quad->init(); setClassProperty( "Quadrature", API::TableWorkspace_ptr( quad ) ); { const double startX = get("StartX"); const double endX = get("EndX"); ChebfunWorkspace_sptr cheb( new ChebfunWorkspace(chebfun( 100, startX, endX )) ); cheb->fun().fit( P ); setClassProperty("ChebWorkspace", cheb); } }
mat cheb(int n, const mat &x) { it_assert_debug((x.rows() > 0) && (x.cols() > 0), "cheb(): empty matrix"); mat out(x.rows(), x.cols()); for (int i = 0; i < x.rows(); ++i) { for (int j = 0; j < x.cols(); ++j) { out(i, j) = cheb(n, x(i, j)); } } return out; }
void setup (int N, const Parameter ¶m, Array<double, 1> &WR, Array<double,2> &ev, Array<double,2> &evInv) { int Nm1 = N; int i; Array<double, 1> x; Array<double, 2> D; Array<double, 1> r; Array<double, 2> Dsec; Array<double, 1> XX; Array<double, 1> YY; Array<double, 2> A(N,N); Array<double, 2> B(N,N); Array<int, 1> IPIV(Nm1); char BALANC[1]; char JOBVL[1]; char JOBVR[1]; char SENSE[1]; int LDA; int LDVL; int LDVR; int NRHS; int LDB; int INFO; //resize output arrays WR.resize(N); ev.resize(N, N); evInv.resize(N, N); // parameters for DGEEVX Array<double, 1> WI(Nm1); // WR(Nm1), // The real and imaginary part of the eig.values Array<double, 2> VL(N, N); Array<double, 2> VR(Nm1,Nm1); //VR(Nm1,Nm1); // The left and rigth eigenvectors int ILO, IHI; // Info on the balanced output matrix Array<double, 1> SCALE(Nm1); // Scaling factors applied for balancing double ABNRM; // 1-Norm of the balanced matrix Array<double, 1> RCONDE(Nm1); // the reciprocal cond. numb of the respective eig.val Array<double, 1> RCONDV(Nm1); // the reciprocal cond. numb of the respective eig.vec int LWORK = (N+1)*(N+7); // Depending on SENSE Array<double, 1> WORK(LWORK); Array<int, 1> IWORK(2*(N+1)-2); // Compute the Chebyshev differensiation matrix and D*D // cheb(N, x, D); cheb(N, x, D); Dsec.resize(D.shape()); MatrixMatrixMultiply(D, D, Dsec); // Compute the 1. and 2. derivatives of the transformations XYmat(N, param, XX, YY, r); // Set up the full timepropagation matrix A // dy/dt = - i A y Range range(1, N); //Dsec and D have range 0, N+1. //We don't want the edge points in A A = XX(tensor::i) * Dsec(range, range) + YY(tensor::i) * D(range, range); //Transpose A for (int i=0; i<A.extent(0); i++) { for (int j=0; j<i; j++) { double t = A(i,j); A(i,j) = A(j, i); A(j,i) = t; } } // Add radialpart of non-time dependent potential here /* 2D radial for (int i=0; i<A.extent(0); i++) { A(i, i) += 0.25 / (r(i)*r(i)); } */ // Compute eigen decomposition BALANC[0] ='B'; JOBVL[0] ='V'; JOBVR[0] ='V'; SENSE[0] ='B'; LDA = Nm1; LDVL = Nm1; LDVR = Nm1; FORTRAN_NAME(dgeevx)(BALANC, JOBVL, JOBVR, SENSE, &Nm1, A.data(), &LDA, WR.data(), WI.data(), VL.data(), &LDVL, VR.data(), &LDVR, &ILO, &IHI, SCALE.data(), &ABNRM, RCONDE.data(), RCONDV.data(), WORK.data(), &LWORK, IWORK.data(), &INFO); // Compute the inverse of the eigen vector matrix NRHS = Nm1; evInv = VR ;// VL; LDB = LDA; B = 0.0; for (i=0; i<Nm1; i++) B(i,i) = 1.0; FORTRAN_NAME(dgesv)(&Nm1, &NRHS, evInv.data(), &LDA, IPIV.data(), B.data(), &LDB, &INFO); ev = VR(tensor::j, tensor::i); //Transpose evInv = B(tensor::j, tensor::i); //Transpose //cout << "Eigenvectors (right): " << ev << endl; //cout << "Eigenvectors (inv): " << evInv << endl; //printf(" Done inverse, INFO = %d \n", INFO); } // done
/*----------------------------------------------------------------------------*/ bool DEreader::GetPlanetPoz(double jdate, int index, bool geleo, double poz[]) { if (jdate != dJD) { bool r = read(jdate); if (!r){ qDebug() << "GetPlanetPoz"; return false; } dJD = jdate; } double tc[16]; double tcp[16]; for (int i = 0; i < 16; i++) { tc[i] = 0; tcp[i] = 0; } double d = buf[0]; double c = d - deHeader.raz[index]; int n1 = -3 * deHeader.pow[index]; do { c += deHeader.raz[index]; d += deHeader.raz[index]; n1 += 3*deHeader.pow[index]; } while (jdate < c || jdate > d); cheb(false, c, d, jdate, deHeader.pow[index], tc, tcp); coor(false, index, n1, tc, tcp, poz); if (index == 2 || index == 9) { int idx = index == 2 ? 9 : 2; n1 = 0; d = buf[0]; c = d - deHeader.raz[idx]; n1 = -3*deHeader.pow[idx]; do { c += deHeader.raz[idx]; d += deHeader.raz[idx]; n1 += 3*deHeader.pow[idx]; } while (jdate < c || jdate > d); cheb(false, c, d, jdate, deHeader.pow[idx], tc, tcp); double x[6]; coor(false, idx, n1, tc, tcp, x); if (index == 2) for (int k = 0; k < 6; k++) poz[k] = poz[k] - x[k] / (deHeader.EarthDivMoon + 1); // земля else if (index == 9) { for (int k = 0; k < 6; k++) x[k] = x[k] - poz[k] / (deHeader.EarthDivMoon + 1); // земля for (int k = 0; k < 6; k++) poz[k] += x[k]; // луна } } if (geleo) { n1 = 0; d = buf[0]; c = d - deHeader.raz[10]; n1 = -3*deHeader.pow[10]; do { c += deHeader.raz[10]; d += deHeader.raz[10]; n1 += 3*deHeader.pow[10]; } while (jdate < c || jdate > d); cheb(false, c, d, jdate, deHeader.pow[10], tc, tcp); double x[6]; coor(false, 10, n1, tc, tcp, x); for (int k = 0; k < 6; k++) poz[k] = (poz[k] - x[k]) / deConst.AE; } else for (int k = 0; k < 6; k++) poz[k] /= deConst.AE; return true; // qDebug() << poz[0]; // qDebug() << poz[1]; // qDebug() << poz[2]; }