00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _BERNSTEINTETRAHEDRALPOLY_H
00034 #define _BERNSTEINTETRAHEDRALPOLY_H
00035
00036
00037 #include "Array.h"
00038 #include "errormacros.h"
00039 #include <vector>
00040 #include <iostream>
00041
00042
00043 namespace Go {
00046
00047
00048
00049 class BernsteinPoly;
00050
00051
00067 class BernsteinTetrahedralPoly {
00068 public:
00070 BernsteinTetrahedralPoly() : deg_(-1) { }
00074 BernsteinTetrahedralPoly(int deg, const std::vector<double>& coefs)
00075 : deg_(deg), coefs_(coefs) { }
00081 template <typename ForwardIterator>
00082 BernsteinTetrahedralPoly(int deg,
00083 ForwardIterator begin, ForwardIterator end)
00084 : deg_(deg), coefs_(begin, end) { }
00087 explicit BernsteinTetrahedralPoly(double coef)
00088 : deg_(0), coefs_(1, coef) { }
00089
00092 int degree() const
00093 { return deg_; }
00094
00096 const double& operator[] (int num) const
00097 { return coefs_[num]; }
00099 double& operator[] (int num)
00100 { return coefs_[num]; }
00101
00107 template <typename T>
00108 T operator() (const Array<T, 4>& u) const
00109 {
00110
00111
00112
00113 ASSERT(deg_ >= 0);
00114
00115 int sz = coefs_.size();
00116 std::vector<T> tmp(sz);
00117 for (int i = 0; i < sz; ++i)
00118 tmp[i] = T(coefs_[i]);
00119
00120 for (int r = 1; r <= deg_; ++r) {
00121 int m = -1;
00122 for (int i = 0; i <= deg_-r; ++i) {
00123 int k = (i+1) * (i+2) / 2;
00124 for (int j = 0; j <= i; ++j) {
00125 for (int l = 0; l <= j; ++l) {
00126 m++;
00127 tmp[m] = u[0] * tmp[m]
00128 + u[1] * tmp[m + k]
00129 + u[2] * tmp[m + 1 + j + k]
00130 + u[3] * tmp[m + 2 + j + k];
00131 }
00132 }
00133 }
00134 }
00135
00136 return tmp[0];
00137 }
00138
00143 double norm() const;
00147 void normalize();
00148
00155 void deriv(int der, const Vector4D& d,
00156 BernsteinTetrahedralPoly& btp) const;
00157
00167 template <typename T>
00168 T blossom(const std::vector<Array<T, 4> >& uvec) const
00169 {
00170
00171
00172 ASSERT(deg_ >= 0);
00173
00174 int sz = coefs_.size();
00175 std::vector<T> tmp(sz);
00176 for (int i = 0; i < sz; ++i)
00177 tmp[i] = T(coefs_[i]);
00178
00179 for (int r = 1; r <= deg_; ++r) {
00180 const T& u = uvec[r-1][0];
00181 const T& v = uvec[r-1][1];
00182 const T& w = uvec[r-1][2];
00183 const T& x = uvec[r-1][3];
00184 int m = -1;
00185 for (int i = 0; i <= deg_-r; ++i) {
00186 int k = (i+1) * (i+2) / 2;
00187 for (int j = 0; j <= i; ++j) {
00188 for (int l = 0; l <= j; ++l) {
00189 m++;
00190 tmp[m] = u * tmp[m]
00191 + v * tmp[m + k]
00192 + w * tmp[m + 1 + j + k]
00193 + x * tmp[m + 2 + j + k];
00194 }
00195 }
00196 }
00197 }
00198
00199 return tmp[0];
00200 }
00201
00211 BernsteinPoly pickLine(const Array<double, 4>& a,
00212 const Array<double, 4>& b) const;
00213
00215 BernsteinTetrahedralPoly&
00216 operator*= (const BernsteinTetrahedralPoly& poly);
00218 BernsteinTetrahedralPoly& operator*= (double c);
00219
00221 BernsteinTetrahedralPoly&
00222 operator+= (const BernsteinTetrahedralPoly& poly);
00224 BernsteinTetrahedralPoly& operator+= (double c);
00225
00227 BernsteinTetrahedralPoly&
00228 operator-= (const BernsteinTetrahedralPoly& poly);
00230 BernsteinTetrahedralPoly& operator-= (double c);
00231
00233 BernsteinTetrahedralPoly& operator/= (double c);
00234
00236 void read(std::istream& is);
00238 void write(std::ostream& os) const;
00239
00240 private:
00241 int deg_;
00242 std::vector<double> coefs_;
00243 };
00244
00245
00247 inline BernsteinTetrahedralPoly
00248 operator* (const BernsteinTetrahedralPoly& p1,
00249 const BernsteinTetrahedralPoly& p2)
00250 {
00251 BernsteinTetrahedralPoly tmp = p1;
00252 tmp *= p2;
00253 return tmp;
00254 }
00255
00256
00258 inline BernsteinTetrahedralPoly
00259 operator* (const BernsteinTetrahedralPoly& p, double c)
00260 {
00261 BernsteinTetrahedralPoly tmp = p;
00262 tmp *= c;
00263 return tmp;
00264 }
00265
00266
00268 inline BernsteinTetrahedralPoly
00269 operator* (double c, const BernsteinTetrahedralPoly& p)
00270 {
00271 BernsteinTetrahedralPoly tmp = p;
00272 tmp *= c;
00273 return tmp;
00274 }
00275
00276
00278 inline BernsteinTetrahedralPoly
00279 operator+ (const BernsteinTetrahedralPoly& p1,
00280 const BernsteinTetrahedralPoly& p2)
00281 {
00282 BernsteinTetrahedralPoly tmp = p1;
00283 tmp += p2;
00284 return tmp;
00285 }
00286
00287
00289 inline BernsteinTetrahedralPoly
00290 operator+ (double c, const BernsteinTetrahedralPoly& p)
00291 {
00292 BernsteinTetrahedralPoly tmp = p;
00293 tmp += c;
00294 return tmp;
00295 }
00296
00297
00299 inline BernsteinTetrahedralPoly
00300 operator+ (const BernsteinTetrahedralPoly& p, double c)
00301 {
00302 BernsteinTetrahedralPoly tmp = p;
00303 tmp += c;
00304 return tmp;
00305 }
00306
00307
00309 inline BernsteinTetrahedralPoly
00310 operator- (const BernsteinTetrahedralPoly& p1,
00311 const BernsteinTetrahedralPoly& p2)
00312 {
00313 BernsteinTetrahedralPoly tmp = p1;
00314 tmp -= p2;
00315 return tmp;
00316 }
00317
00318
00320 inline BernsteinTetrahedralPoly
00321 operator- (double c, const BernsteinTetrahedralPoly& p)
00322 {
00323 BernsteinTetrahedralPoly tmp(c);
00324 tmp -= p;
00325 return tmp;
00326 }
00327
00328
00330 inline BernsteinTetrahedralPoly
00331 operator- (const BernsteinTetrahedralPoly& p, double c)
00332 {
00333 BernsteinTetrahedralPoly tmp = p;
00334 tmp -= c;
00335 return tmp;
00336 }
00337
00338
00340 inline BernsteinTetrahedralPoly
00341 operator/ (const BernsteinTetrahedralPoly& p, double c)
00342 {
00343 BernsteinTetrahedralPoly tmp = p;
00344 tmp /= c;
00345 return tmp;
00346 }
00347
00348
00350 inline std::istream& operator >> (std::istream& is,
00351 Go::BernsteinTetrahedralPoly& p)
00352 {
00353 p.read(is);
00354 return is;
00355 }
00356
00357
00359 inline std::ostream& operator << (std::ostream& os,
00360 const Go::BernsteinTetrahedralPoly& p)
00361 {
00362 p.write(os);
00363 return os;
00364 }
00365
00366
00368 }
00369
00370
00371 #endif // _BERNSTEINTETRAHEDRALPOLY_H
00372
00373