/** Compute the cosine of a function. \param f function \param tol maximum error \param order maximum degree polynomial to use */ Piecewise<SBasis> cos( SBasis const &f, double tol, int order){ double alpha = (f.at0()+f.at1())/2.; SBasis x = f-alpha; double d = x.tailError(0),err=1; //estimate cos(x)-sum_0^order (-1)^k x^2k/2k! by the first neglicted term for (int i=1; i<=2*order; i++) err*=d/i; if (err<tol){ SBasis xk=Linear(1), c=Linear(1), s=Linear(0); for (int k=1; k<=2*order; k+=2){ xk*=x/k; //take also truncature errors into account... err+=xk.tailError(order); xk.truncate(order); s+=xk; xk*=-x/(k+1); //take also truncature errors into account... err+=xk.tailError(order); xk.truncate(order); c+=xk; } if (err<tol){ return Piecewise<SBasis>(std::cos(alpha)*c-std::sin(alpha)*s); } } Piecewise<SBasis> c0,c1; c0 = cos(compose(f,Linear(0.,.5)),tol,order); c1 = cos(compose(f,Linear(.5,1.)),tol,order); c0.setDomain(Interval(0.,.5)); c1.setDomain(Interval(.5,1.)); c0.concat(c1); return c0; }
void subdiv_sbasis(SBasis const & s, std::vector<double> & roots, double left, double right) { Interval bs = bounds_fast(s); if(bs.min() > 0 || bs.max() < 0) return; // no roots here if(s.tailError(1) < 1e-7) { double t = s[0][0] / (s[0][0] - s[0][1]); roots.push_back(left*(1-t) + t*right); return; } double middle = (left + right)/2; subdiv_sbasis(compose(s, Linear(0, 0.5)), roots, left, middle); subdiv_sbasis(compose(s, Linear(0.5, 1.)), roots, middle, right); }
//-Sqrt---------------------------------------------------------- static Piecewise<SBasis> sqrt_internal(SBasis const &f, double tol, int order){ SBasis sqrtf; if(f.isZero() || order == 0){ return Piecewise<SBasis>(sqrtf); } if (f.at0()<-tol*tol && f.at1()<-tol*tol){ return sqrt_internal(-f,tol,order); }else if (f.at0()>tol*tol && f.at1()>tol*tol){ sqrtf.resize(order+1, Linear(0,0)); sqrtf[0] = Linear(std::sqrt(f[0][0]), std::sqrt(f[0][1])); SBasis r = f - multiply(sqrtf, sqrtf); // remainder for(unsigned i = 1; int(i) <= order && i<r.size(); i++) { Linear ci(r[i][0]/(2*sqrtf[0][0]), r[i][1]/(2*sqrtf[0][1])); SBasis cisi = shift(ci, i); r -= multiply(shift((sqrtf*2 + cisi), i), SBasis(ci)); r.truncate(order+1); sqrtf[i] = ci; if(r.tailError(i) == 0) // if exact break; } }else{ sqrtf = Linear(std::sqrt(fabs(f.at0())), std::sqrt(fabs(f.at1()))); } double err = (f - multiply(sqrtf, sqrtf)).tailError(0); if (err<tol){ return Piecewise<SBasis>(sqrtf); } Piecewise<SBasis> sqrtf0,sqrtf1; sqrtf0 = sqrt_internal(compose(f,Linear(0.,.5)),tol,order); sqrtf1 = sqrt_internal(compose(f,Linear(.5,1.)),tol,order); sqrtf0.setDomain(Interval(0.,.5)); sqrtf1.setDomain(Interval(.5,1.)); sqrtf0.concat(sqrtf1); return sqrtf0; }