Ejemplo n.º 1
0
/** 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;
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
//-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;
}