Code

added missing files in 2geom update.
authorjfbarraud <jfbarraud@users.sourceforge.net>
Mon, 9 Mar 2009 13:05:01 +0000 (13:05 +0000)
committerjfbarraud <jfbarraud@users.sourceforge.net>
Mon, 9 Mar 2009 13:05:01 +0000 (13:05 +0000)
src/2geom/chebyshev.cpp [new file with mode: 0644]
src/2geom/chebyshev.h [new file with mode: 0644]

diff --git a/src/2geom/chebyshev.cpp b/src/2geom/chebyshev.cpp
new file mode 100644 (file)
index 0000000..447c518
--- /dev/null
@@ -0,0 +1,126 @@
+#include <2geom/chebyshev.h>
+
+#include <2geom/sbasis.h>
+#include <2geom/sbasis-poly.h>
+
+#include <vector>
+using std::vector;
+
+#include <gsl/gsl_math.h>
+#include <gsl/gsl_chebyshev.h>
+
+namespace Geom{
+
+SBasis cheb(unsigned n) {
+    static std::vector<SBasis> basis;
+    if(basis.empty()) {
+        basis.push_back(Linear(1,1));
+        basis.push_back(Linear(0,1));
+    }
+    for(unsigned i = basis.size(); i <= n; i++) {
+        basis.push_back(Linear(0,2)*basis[i-1] - basis[i-2]);
+    }
+    
+    return basis[n];
+}
+
+SBasis cheb_series(unsigned n, double* cheb_coeff) {
+    SBasis r;
+    for(unsigned i = 0; i < n; i++) {
+        double cof = cheb_coeff[i];
+        //if(i == 0)
+        //cof /= 2;
+        r += cheb(i)*cof;
+    }
+    
+    return r;
+}
+
+SBasis clenshaw_series(unsigned m, double* cheb_coeff) {
+    /** b_n = a_n
+        b_n-1 = 2*x*b_n + a_n-1
+        b_n-k = 2*x*b_{n-k+1} + a_{n-k} - b_{n - k + 2}
+        b_0 = x*b_1 + a_0 - b_2
+    */
+    
+    double a = -1, b = 1;
+    SBasis d, dd;
+    SBasis y = (Linear(0, 2) - (a+b)) / (b-a);
+    SBasis y2 = 2*y;
+    for(int j = m - 1; j >= 1; j--) {
+        SBasis sv = d;
+        d = y2*d - dd + cheb_coeff[j];
+        dd = sv;
+    }
+    
+    return y*d - dd + 0.5*cheb_coeff[0];
+}
+
+SBasis chebyshev_approximant (double (*f)(double,void*), int order, Interval in, void* p) {
+    gsl_cheb_series *cs = gsl_cheb_alloc (order+2);
+
+    gsl_function F;
+
+    F.function = f;
+    F.params = p;
+
+    gsl_cheb_init (cs, &F, in[0], in[1]);
+    
+    SBasis r = compose(clenshaw_series(order, cs->c), Linear(-1,1));
+        
+    gsl_cheb_free (cs);
+    return r;
+}
+
+struct wrap {
+    double (*f)(double,void*);
+    void* pp;
+    double fa, fb;
+    Interval in;
+};
+
+double f_interp(double x, void* p) {
+    struct wrap *wr = (struct wrap *)p;
+    double z = (x - wr->in[0]) / (wr->in[1] - wr->in[0]);
+    return (wr->f)(x, wr->pp) - ((1 - z)*wr->fa + z*wr->fb);
+}
+
+SBasis chebyshev_approximant_interpolating (double (*f)(double,void*), 
+                                            int order, Interval in, void* p) {
+    double fa = f(in[0], p);
+    double fb = f(in[1], p);
+    struct wrap wr;
+    wr.fa = fa;
+    wr.fb = fb;
+    wr.in = in;
+    printf("%f %f\n", fa, fb);
+    wr.f = f;
+    wr.pp = p;
+    return compose(Linear(in[0], in[1]), Linear(fa, fb)) + chebyshev_approximant(f_interp, order, in, &wr) + Linear(fa, fb);
+}
+
+SBasis chebyshev(unsigned n) {
+    static std::vector<SBasis> basis;
+    if(basis.empty()) {
+        basis.push_back(Linear(1,1));
+        basis.push_back(Linear(0,1));
+    }
+    for(unsigned i = basis.size(); i <= n; i++) {
+        basis.push_back(Linear(0,2)*basis[i-1] - basis[i-2]);
+    }
+    
+    return basis[n];
+}
+
+};
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
diff --git a/src/2geom/chebyshev.h b/src/2geom/chebyshev.h
new file mode 100644 (file)
index 0000000..6de9e9c
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _CHEBYSHEV
+#define _CHEBYSHEV
+
+#include <2geom/sbasis.h>
+#include <2geom/interval.h>
+
+/*** Conversion between Chebyshev approximation and SBasis.
+ * 
+ */
+
+namespace Geom{
+
+SBasis chebyshev_approximant (double (*f)(double,void*), int order, Interval in, void* p=0);
+SBasis chebyshev_approximant_interpolating (double (*f)(double,void*), int order, Interval in, void* p=0);
+SBasis chebyshev(unsigned n);
+
+};
+
+/*
+  Local Variables:
+  mode:c++
+  c-file-style:"stroustrup"
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+  indent-tabs-mode:nil
+  fill-column:99
+  End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+
+#endif