diff options
Diffstat (limited to 'include/2geom/orphan-code/linearN.h')
-rw-r--r-- | include/2geom/orphan-code/linearN.h | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/include/2geom/orphan-code/linearN.h b/include/2geom/orphan-code/linearN.h new file mode 100644 index 0000000..bb27c30 --- /dev/null +++ b/include/2geom/orphan-code/linearN.h @@ -0,0 +1,363 @@ +/**
+ * @file
+ * @brief LinearN fragment function class
+ *//*
+ * Authors:
+ * JF Barraud <jf.barraud@gmail.com>
+ * Nathan Hurst <njh@mail.csse.monash.edu.au>
+ * Michael Sloan <mgsloan@gmail.com>
+ *
+ * Copyright (C) 2006-2007 authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ */
+
+#ifndef SEEN_LINEARN_H
+#define SEEN_LINEARN_H
+#include <2geom/interval.h>
+#include <2geom/math-utils.h>
+#include <2geom/linear.h> //for conversion purpose ( + lerp() )
+
+#include <iostream>
+
+namespace Geom{
+
+//TODO: define this only once!! (see linear.h)
+inline double lerpppp(double t, double a, double b) { return a*(1-t) + b*t; }
+
+template<unsigned n>
+class SBasisN;
+
+template<unsigned n>
+class LinearN{
+public:
+ double a[1<<n];// 1<<n is 2^n
+ LinearN() {
+ for (unsigned i=0; i < (1<<n); i++){
+ a[i] = 0.;
+ }
+ }
+ LinearN(double aa[]) {
+ for (unsigned i=0; i < (1<<n); i++){
+ a[i] = aa[i];
+ }
+ }
+ LinearN(double c) {
+ for (unsigned i=0; i<(1<<n); i++){
+ a[i] = c;
+ }
+ }
+ LinearN(LinearN<n-1> const &aa, LinearN<n-1> const &b, unsigned var=0) {
+// for (unsigned i=0; i<(1<<n-1); i++){
+// a[i] = aa[i];
+// a[i+(1<<(n-1))] = b[i];
+// }
+ unsigned mask = (1<<var)-1;
+ for (unsigned i=0; i < (1<<(n-1)); i++){
+ unsigned low_i = i & mask, high_i = i & ~mask;
+ unsigned idx0 = (high_i<<1)|low_i;
+ unsigned idx1 = (high_i<<1)|(1<<var)|low_i;
+ a[idx0] = aa[i];
+ a[idx1] = b[i];
+ }
+
+ }
+ double operator[](const int i) const {
+ assert( i >= 0 );
+ assert( i < (1<<n) );
+ return a[i];
+ }
+ double& operator[](const int i) {
+ assert(i >= 0);
+ assert(i < (1<<n) );
+ return a[i];
+ }
+
+ //IMPL: FragmentConcept
+ typedef double output_type;
+ unsigned input_dim() const {return n;}
+ inline bool isZero() const {
+ for (unsigned i=0; i < (1<<n); i++){
+ if (a[i] != 0) return false;
+ }
+ return true; }
+ inline bool isConstant() const {
+ for (unsigned i=1; i < (1<<n); i++){
+ if (a[i] != a[0]) return false;
+ }
+ return true; }
+ inline bool isConstant(unsigned var) const {
+ unsigned mask = (1<<var)-1;
+ for (unsigned i=0; i < (1<<(n-1)); i++){
+ unsigned low_i = i & mask, high_i = i & ~mask;
+ unsigned idx0 = (high_i<<1)|low_i;
+ unsigned idx1 = (high_i<<1)|(1<<var)|low_i;
+ if (a[idx0] != a[idx1]) return false;
+ }
+ return true;
+ }
+ inline bool isFinite() const {
+ for (unsigned i=0; i < (1<<n); i++){
+ if ( !std::isfinite(a[i]) ) return false;
+ }
+ return true; }
+ //value if k-th variable is set to 0.
+ inline LinearN<n-1> at0(unsigned k=0) const {
+ LinearN<n-1> res;
+ unsigned mask = (1<<k)-1;
+ for (unsigned i=0; i < (1<<(n-1)); i++){
+ unsigned low_i = i & mask, high_i = i & ~mask;
+ unsigned idx = (high_i<<1)|low_i;
+ res[i] = a[idx];
+ }
+ return res;
+ }
+ //value if k-th variable is set to 1.
+ inline LinearN<n-1> at1(unsigned k=0) const {
+ LinearN<n-1> res;
+ for (unsigned i=0; i < (1<<(n-1)); i++){
+ unsigned mask = (1<<k)-1;
+ unsigned low_i = i & mask, high_i = i & ~mask;
+ unsigned idx = (high_i<<1)|(1<<k)|low_i;
+ res[i] = a[idx];
+ }
+ return res;
+ }
+ inline double atCorner(unsigned k) const {
+ assert( k < (1<<n) );
+ return a[k];
+ }
+ inline double atCorner(double t[]) const {
+ unsigned k=0;
+ for(unsigned i=0; i<n; i++){
+ if (t[i] == 1.) k = k | (1<<i);
+ else assert( t[i] == 0. );
+ }
+ return atCorner(k);
+ }
+ inline LinearN<n-1> partialEval(double t, unsigned var=0 ) const {
+ LinearN<n-1> res;
+ res = at0(var)*(1-t) + at1(var)*t;
+ return res;
+ }
+
+ //fixed and flags are used for recursion.
+ inline double valueAt(double t[], unsigned fixed=0, unsigned flags=0 ) const {
+ if (fixed == n) {
+ return a[flags];
+ }else{
+ double a0 = valueAt(t, fixed+1, flags);
+ double a1 = valueAt(t, fixed+1, flags|(1<<fixed));
+ return lerpppp( t[fixed], a0, a1 );
+ }
+ }
+ inline double operator()(double t[]) const { return valueAt(t); }
+
+ //defined in sbasisN.h
+ inline SBasisN<n> toSBasisN() const;
+
+ inline OptInterval bounds_exact() const {
+ double min=a[0], max=a[0];
+ for (unsigned i=1; i < (1<<n); i++){
+ if (a[i] < min) min = a[i];
+ if (a[i] > max) max = a[i];
+ }
+ return Interval(min, max);
+ }
+ inline OptInterval bounds_fast() const { return bounds_exact(); }
+ //inline OptInterval bounds_local(double u, double v) const { return Interval(valueAt(u), valueAt(v)); }
+};
+
+//LinearN<0> are doubles. Specialize them out.
+template<>
+class LinearN<0>{
+public:
+ double d;
+ LinearN () {}
+ LinearN(double d) :d(d) {}
+ operator double() const { return d; }
+ double operator[](const int i) const {assert (i==0); return d;}
+ double& operator[](const int i) {assert (i==0); return d;}
+ typedef double output_type;
+ unsigned input_dim() const {return 0;}
+ inline bool isZero() const { return d==0; }
+ inline bool isConstant() const { return true; }
+ inline bool isFinite() const { return std::isfinite(d); }
+};
+
+//LinearN<1> are usual Linear. Allow conversion.
+Linear toLinear(LinearN<1> f){
+ return Linear(f[0],f[1]);
+}
+
+
+
+//inline Linear reverse(Linear const &a) { return Linear(a[1], a[0]); }
+
+//IMPL: AddableConcept
+template<unsigned n>
+inline LinearN<n> operator+(LinearN<n> const & a, LinearN<n> const & b) {
+ LinearN<n> res;
+ for (unsigned i=0; i < (1<<n); i++){
+ res[i] = a[i] + b[i];
+ }
+ return res;
+}
+template<unsigned n>
+inline LinearN<n> operator-(LinearN<n> const & a, LinearN<n> const & b) {
+ LinearN<n> res;
+ for (unsigned i=0; i < (1<<n); i++){
+ res[i] = a[i] - b[i];
+ }
+ return res;
+}
+template<unsigned n>
+inline LinearN<n>& operator+=(LinearN<n> & a, LinearN<n> const & b) {
+ for (unsigned i=0; i < (1<<n); i++){
+ a[i] += b[i];
+ }
+ return a;
+}
+template<unsigned n>
+inline LinearN<n>& operator-=(LinearN<n> & a, LinearN<n> const & b) {
+ for (unsigned i=0; i < (1<<n); i++){
+ a[i] -= b[i];
+ }
+ return a;
+}
+//IMPL: OffsetableConcept
+template<unsigned n>
+inline LinearN<n> operator+(LinearN<n> const & a, double b) {
+ LinearN<n> res;
+ for (unsigned i=0; i < (1<<n); i++){
+ res[i] = a[i] + b;
+ }
+ return res;
+}
+template<unsigned n>
+inline LinearN<n> operator-(LinearN<n> const & a, double b) {
+ LinearN<n> res;
+ for (unsigned i=0; i < (1<<n); i++){
+ res[i] = a[i] - b;
+ }
+ return res;
+}
+template<unsigned n>
+inline LinearN<n>& operator+=(LinearN<n> & a, double b) {
+ for (unsigned i=0; i < (1<<n); i++){
+ a[i] += b;
+ }
+ return a;
+}
+template<unsigned n>
+inline LinearN<n>& operator-=(LinearN<n> & a, double b) {
+ for (unsigned i=0; i < (1<<n); i++){
+ a[i] -= b;
+ }
+ return a;
+}
+//IMPL: boost::EqualityComparableConcept
+template<unsigned n>
+inline bool operator==(LinearN<n> const & a, LinearN<n> const & b) {
+ for (unsigned i=0; i < (1<<n); i++){
+ if (a[i] != b[i]) return false;
+ }
+ return true;
+}
+template<unsigned n>
+inline bool operator!=(LinearN<n> const & a, LinearN<n> const & b) {
+ return !(a==b);
+}
+//IMPL: ScalableConcept
+template<unsigned n>
+inline LinearN<n> operator-(LinearN<n> const &a) {
+ LinearN<n> res;
+ for (unsigned i=0; i < (1<<n); i++){
+ res[i] = -a[i];
+ }
+ return res;
+}
+template<unsigned n>
+inline LinearN<n> operator*(LinearN<n> const & a, double b) {
+ LinearN<n> res;
+ for (unsigned i=0; i < (1<<n); i++){
+ res[i] = a[i] * b;
+ }
+ return res;
+}
+template<unsigned n>
+inline LinearN<n> operator/(LinearN<n> const & a, double b) {
+ LinearN<n> res;
+ for (unsigned i=0; i < (1<<n); i++){
+ res[i] = a[i] / b;
+ }
+ return res;
+}
+template<unsigned n>
+inline LinearN<n> operator*=(LinearN<n> & a, double b) {
+ for (unsigned i=0; i < (1<<n); i++){
+ a[i] *= b;
+ }
+ return a;
+}
+template<unsigned n>
+inline LinearN<n> operator/=(LinearN<n> & a, double b) {
+ for (unsigned i=0; i < (1<<n); i++){
+ a[i] /= b;
+ }
+ return a;
+}
+
+template<unsigned n>
+void setToVariable(LinearN<n> &x, unsigned k){;
+ x = LinearN<n>(0.);
+ unsigned mask = 1<<k;
+ for (unsigned i=0; i < (1<<n); i++){
+ if ( i & mask ) x[i] = 1;
+ }
+}
+
+template<unsigned n>
+inline std::ostream &operator<< (std::ostream &out_file, const LinearN<n> &bo) {
+ out_file << "{";
+ for (unsigned i=0; i < (1<<n); i++){
+ out_file << bo[i]<<(i == (1<<n)-1 ? "}" : ",");
+ }
+ return out_file;
+}
+
+
+}
+#endif //SEEN_LINEAR_H
+
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
|