sbasis.h revision e6bdf746e2d9e775704a475a29cc1bb167ec271c
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * sbasis.h - S-power basis function class
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * Nathan Hurst <njh@mail.csse.monash.edu.au>
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * Michael Sloan <mgsloan@gmail.com>
2eefc362ae6a0a94b84ee5bc9e7844ef45c3642cAlex Valavanis * Copyright (C) 2006-2007 authors
2eefc362ae6a0a94b84ee5bc9e7844ef45c3642cAlex Valavanis * This library is free software; you can redistribute it and/or
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * modify it either under the terms of the GNU Lesser General Public
2eefc362ae6a0a94b84ee5bc9e7844ef45c3642cAlex Valavanis * License version 2.1 as published by the Free Software Foundation
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * (the "LGPL") or, at your option, under the terms of the Mozilla
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * Public License Version 1.1 (the "MPL"). If you do not alter this
2eefc362ae6a0a94b84ee5bc9e7844ef45c3642cAlex Valavanis * notice, a recipient may use your version of this file under either
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * the MPL or the LGPL.
2eefc362ae6a0a94b84ee5bc9e7844ef45c3642cAlex Valavanis * You should have received a copy of the LGPL along with this library
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * in the file COPYING-LGPL-2.1; if not, write to the Free Software
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * You should have received a copy of the MPL along with this library
2eefc362ae6a0a94b84ee5bc9e7844ef45c3642cAlex Valavanis * in the file COPYING-MPL-1.1
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * The contents of this file are subject to the Mozilla Public License
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * Version 1.1 (the "License"); you may not use this file except in
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * compliance with the License. You may obtain a copy of the License at
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * OF ANY KIND, either express or implied. See the LGPL or the MPL for
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b * the specific language governing rights and limitations.
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b/*** An empty SBasis is identically 0. */
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b //IMPL: FragmentConcept
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b typedef double output_type;
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b inline bool isZero() const {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b if(empty()) return true;
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b for(unsigned i = 0; i < size(); i++) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b return true;
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b bool isFinite() const;
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b inline double at0() const {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b inline double at1() const{
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b double valueAt(double t) const {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b double s = t*(1-t);
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b//TODO: rewrite as horner
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b for(unsigned k = 0; k < size(); k++) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b double valueAndDerivative(double t, double &der) const {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b double s = t*(1-t);
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b//TODO: rewrite as horner
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b for(unsigned k = 0; k < size(); k++) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b // p0 and p1 at this point form a linear approximation at t
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex Valavanis double operator()(double t) const {
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex Valavanis std::vector<double> valueAndDerivatives(double /*t*/, unsigned /*n*/) const {
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex Valavanis SBasis toSBasis() const { return SBasis(*this); }
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex Valavanis// compute f(g)
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex Valavanis//MUTATOR PRISON
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex Valavanis Linear& operator[](unsigned i) { return this->at(i); }
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex Valavanis //remove extra zeros
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b while(!empty() && 0 == back()[0] && 0 == back()[1])
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b void truncate(unsigned k) { if(k < size()) resize(k); }
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b//TODO: figure out how to stick this in linear, while not adding an sbasis dep
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline SBasis Linear::toSBasis() const { return SBasis(*this); }
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b//implemented in sbasis-roots.cpp
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_bInterval bounds_fast(SBasis const &a, int order = 0);
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex ValavanisInterval bounds_local(SBasis const &a, const Interval &t, int order = 0);
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex Valavanis for(unsigned k = 0; k < a.size(); k++)
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b//IMPL: ScalableConcept
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b for(unsigned i = 0; i < p.size(); i++) {
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex Valavanisinline SBasis operator*(double k, SBasis const &a) { return a*k; }
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex Valavanisinline SBasis operator/(SBasis const &a, double k) { return a*(1./k); }
f6d8c168c2d1b1e168545b090dfbb22a3f4923a3Alex Valavanisinline SBasis& operator/=(SBasis& a, double b) { return (a*=(1./b)); }
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b//IMPL: AddableConcept
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b//TODO: remove?
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline SBasis operator+(const SBasis & a, Linear const & b) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b if(b.isZero()) return a;
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b if(a.isZero()) return b;
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline SBasis operator-(const SBasis & a, Linear const & b) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b if(b.isZero()) return a;
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline SBasis& operator+=(SBasis& a, const Linear& b) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline SBasis& operator-=(SBasis& a, const Linear& b) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b//IMPL: OffsetableConcept
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline SBasis operator+(const SBasis & a, double b) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline SBasis operator-(const SBasis & a, double b) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline SBasis truncate(SBasis const &a, unsigned terms) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b c.insert(c.begin(), a.begin(), a.begin() + std::min(terms, (unsigned)a.size()));
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b// return a kth order approx to 1/a)
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_bSBasis divide(SBasis const &a, SBasis const &b, int k);
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline SBasis operator*(SBasis const & a, SBasis const & b) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b return multiply(a, b);
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline SBasis& operator*=(SBasis& a, SBasis const & b) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b//valuation: degree of the first non zero coefficient.
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline unsigned
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b unsigned val=0;
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_bSBasis compose(SBasis const &a, SBasis const &b, unsigned k);
d19de0ff8b0793e74e98429ded50868ce7e9f75cAlex Valavanis//compose_inverse(f,g)=compose(f,inverse(g)), but is numerically more stable in some good cases...
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b//TODO: requires g(0)=0 & g(1)=1 atm. generalization should be obvious.
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_bSBasis compose_inverse(SBasis const &f, SBasis const &g, unsigned order=2, double tol=1e-3);
d19de0ff8b0793e74e98429ded50868ce7e9f75cAlex Valavanisinline SBasis portion(const SBasis &t, double from, double to) { return compose(t, Linear(from, to)); }
d19de0ff8b0793e74e98429ded50868ce7e9f75cAlex Valavanis// compute f(g)
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline std::ostream &operator<< (std::ostream &out_file, const Linear &bo) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_binline std::ostream &operator<< (std::ostream &out_file, const SBasis & p) {
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b for(unsigned i = 0; i < p.size(); i++) {
d19de0ff8b0793e74e98429ded50868ce7e9f75cAlex Valavanisstd::vector<std::vector<double> > multi_roots(SBasis const &f,
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b double a=0,
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b double b=1);
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b Local Variables:
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b c-file-style:"stroustrup"
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b indent-tabs-mode:nil
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b fill-column:99
a0df1b8dd5b14367c583ce2f72a2ca6bf1cde799gustav_b// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :