sbasis.h revision 07bda0b13ae048815f53f21ad1edbe3cc1b7e4e8
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński * \brief Defines S-power basis function class
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * Nathan Hurst <njh@mail.csse.monash.edu.au>
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * Michael Sloan <mgsloan@gmail.com>
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * Copyright (C) 2006-2007 authors
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * This library is free software; you can redistribute it and/or
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * modify it either under the terms of the GNU Lesser General Public
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * License version 2.1 as published by the Free Software Foundation
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * (the "LGPL") or, at your option, under the terms of the Mozilla
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * Public License Version 1.1 (the "MPL"). If you do not alter this
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * notice, a recipient may use your version of this file under either
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * the MPL or the LGPL.
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * You should have received a copy of the LGPL along with this library
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * in the file COPYING-LGPL-2.1; if not, write to the Free Software
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * You should have received a copy of the MPL along with this library
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * in the file COPYING-MPL-1.1
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * The contents of this file are subject to the Mozilla Public License
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * Version 1.1 (the "License"); you may not use this file except in
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * compliance with the License. You may obtain a copy of the License at
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński * OF ANY KIND, either express or implied. See the LGPL or the MPL for
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński * the specific language governing rights and limitations.
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen//#define USE_SBASISN 1
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen/*** An empty SBasis is identically 0. */
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen* \brief S-power basis function class
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen* An empty SBasis is identically 0. */
29684a16b6c92bee28a94fdc2607bcc143950fa8johanengelen void push_back(Linear const&l) { d.push_back(l); }
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen // As part of our migration away from SBasis isa vector we provide this minimal set of vector interface methods.
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen return d[i];
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen Linear& operator[](unsigned i) { return d.at(i); }
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński Linear const* begin() const { return (Linear const*)&*d.begin();}
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński Linear const* end() const { return (Linear const*)&*d.end();}
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen Linear* begin() { return (Linear*)&*d.begin();}
e4369b05aaa20df73a37f4d319ce456865cc74f3Krzysztof Kosiński Linear const &back() const {return d.back();}
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen void resize(unsigned n, Linear const& l) { d.resize(n, l);}
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen void insert(Linear* before, const Linear* src_begin, const Linear* src_end) { d.insert(std::vector<Linear>::iterator(before), src_begin, src_end);}
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen //void insert(Linear* aa, Linear* bb, Linear* cc} { d.insert(aa, bb, cc);}
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen //void insert(Linear* before, int& n, Linear const &l) { d.insert(std::vector<Linear>::iterator(before), n, l);}
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen bool operator==(SBasis const&B) const { return d == B.d;}
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen bool operator!=(SBasis const&B) const { return d != B.d;}
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński explicit SBasis(size_t n, Linear const&l) : d(n, l) {}
e4369b05aaa20df73a37f4d319ce456865cc74f3Krzysztof Kosiński //IMPL: FragmentConcept
e4369b05aaa20df73a37f4d319ce456865cc74f3Krzysztof Kosiński inline bool isZero() const {
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński if(empty()) return true;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński for(unsigned i = 0; i < size(); i++) {
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński inline bool isConstant() const {
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński if (empty()) return true;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński if(!(*this)[0].isConstant()) return false;
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński inline double at0() const {
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński if(empty()) return 0; else return (*this)[0][0];
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński inline double at1() const{
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński if(empty()) return 0; else return (*this)[0][1];
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen int degreesOfFreedom() const { return size()*2;}
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen double valueAt(double t) const {
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen double s = t*(1-t);
e6bdf746e2d9e775704a475a29cc1bb167ec271cjohanengelen for(unsigned k = size(); k > 0; k--) {
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen //double valueAndDerivative(double t, double &der) const {
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen double operator()(double t) const {
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen std::vector<double> valueAndDerivatives(double t, unsigned n) const;
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen SBasis toSBasis() const { return SBasis(*this); }
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen// compute f(g)
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen//MUTATOR PRISON
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen //remove extra zeros
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński while(!empty() && 0 == back()[0] && 0 == back()[1])
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen void truncate(unsigned k) { if(k < size()) resize(k); }
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński//TODO: figure out how to stick this in linear, while not adding an sbasis dep
981b809bc6ed10a21e89444d9447e5475801874fjohanengeleninline SBasis Linear::toSBasis() const { return SBasis(*this); }
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen//implemented in sbasis-roots.cpp
981b809bc6ed10a21e89444d9447e5475801874fjohanengelenOptInterval bounds_fast(SBasis const &a, int order = 0);
981b809bc6ed10a21e89444d9447e5475801874fjohanengelenOptInterval bounds_local(SBasis const &a, const OptInterval &t, int order = 0);
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński/** Returns a function which reverses the domain of a.
981b809bc6ed10a21e89444d9447e5475801874fjohanengelen \param a sbasis function
40742313779ee5e43be93a9191f1c86412cf183bKrzysztof Kosiński \relates SBasis
63267518b4ce196caab66ef8cbdcfc0921206b3djohanengelenuseful for reversing a parameteric curve.
63267518b4ce196caab66ef8cbdcfc0921206b3djohanengelen for(unsigned k = 0; k < a.size(); k++)
for(unsigned i = 0; i < p.size(); i++) {
result[i] = -p[i];
return result;
result[0] += b;
return result;
result[0] -= b;
return result;
if(a.isZero())
if(a.isZero())
SBasis c;
// This performs a multiply and accumulate operation in about the same time as multiply. return a*b + c
return multiply(a, b);
a = multiply(a, b);
unsigned val=0;
val++;
return val;
inline SBasis portion(const SBasis &t, double from, double to) { return compose(t, Linear(from, to)); }
inline SBasis portion(const SBasis &t, Interval ivl) { return compose(t, Linear(ivl.min(), ivl.max())); }
inline SBasis
return out_file;
for(unsigned i = 0; i < p.size(); i++) {
return out_file;
// These are deprecated, use sbasis-math.h versions if possible
double level,