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 _BERNSTEINMULTI_H
00034 #define _BERNSTEINMULTI_H
00035
00036 #include "Array.h"
00037 #include <vector>
00038 #include <iostream>
00039
00040
00041 namespace Go {
00044
00045
00046
00047 class BernsteinPoly;
00048
00049
00067 class BernsteinMulti {
00068 public:
00070 BernsteinMulti() : degu_(-1), degv_(-1) { }
00075 BernsteinMulti(int m, int n,
00076 const std::vector<double>& coefs)
00077 : degu_(m), degv_(n), coefs_(coefs)
00078 {
00079 ALWAYS_ERROR_IF((degu_+1) * (degv_+1) != int(coefs_.size()),
00080 "Number of coefficients does not match degrees");
00081 }
00088 template <typename ForwardIterator>
00089 BernsteinMulti(int m, int n,
00090 ForwardIterator begin, ForwardIterator end)
00091 : degu_(m), degv_(n), coefs_(begin, end) { }
00094 explicit BernsteinMulti(double coef)
00095 : degu_(0), degv_(0), coefs_(std::vector<double>(1, coef)) { }
00096
00099 int degreeU() const
00100 { return degu_; }
00103 int degreeV() const
00104 { return degv_; }
00105
00107 const double& operator[] (int num) const
00108 { return coefs_[num]; }
00110 double& operator[] (int num)
00111 { return coefs_[num]; }
00113 std::vector<double>::iterator coefsBegin()
00114 { return coefs_.begin(); }
00116 std::vector<double>::const_iterator coefsBegin() const
00117 { return coefs_.begin(); }
00119 std::vector<double>::iterator coefsEnd()
00120 { return coefs_.end(); }
00122 std::vector<double>::const_iterator coefsEnd() const
00123 { return coefs_.end(); }
00124
00129 double operator() (double u, double v) const;
00134 double operator() (const Vector2D& pt) const
00135 { return (*this)(pt[0], pt[1]); }
00140 double operator() (const std::vector<double>& pt) const
00141 { return (*this)(pt[0], pt[1]); }
00142
00148 bool isZero(const double eps = 0.0) const;
00154 bool isStrictlyPositive(const double eps = 0.0) const;
00160 bool isStrictlyNegative(const double eps = 0.0) const;
00166 bool isNonNegative(const double eps = 0.0) const;
00167
00174 double norm() const;
00178 void normalize();
00179
00181 double mean() const;
00182
00191 BernsteinMulti deriv(int der1, int der2) const;
00194 BernsteinMulti detHess() const;
00198 BernsteinMulti traceHess() const;
00199
00214 double blossom(const std::vector<double>& uvec,
00215 const std::vector<double>& vvec) const;
00234 BernsteinMulti pickDomain(double u0, double u1,
00235 double v0, double v1) const;
00242 BernsteinPoly pickLine(Array<double,2> a,
00243 Array<double,2> b) const;
00244
00250 void degreeElevate(int du, int dv);
00251
00253 BernsteinMulti& operator*= (const BernsteinMulti& multi);
00255 BernsteinMulti& operator*= (double c);
00256
00258 BernsteinMulti& operator+= (const BernsteinMulti& multi);
00260 BernsteinMulti& operator+= (double c);
00261
00263 BernsteinMulti& operator-= (const BernsteinMulti& multi);
00265 BernsteinMulti& operator-= (double c);
00266
00268 BernsteinMulti& operator/= (double c);
00269
00273 BernsteinPoly bindU(double u) const;
00277 BernsteinPoly bindV(double v) const;
00278
00280 void read(std::istream& is);
00282 void write(std::ostream& os) const;
00283
00284 private:
00285
00286 int degu_, degv_;
00287
00288
00289
00290
00291 std::vector<double> coefs_;
00292 };
00293
00294
00296 inline BernsteinMulti operator* (const BernsteinMulti& m1,
00297 const BernsteinMulti& m2)
00298 {
00299 BernsteinMulti tmp = m1;
00300 tmp *= m2;
00301 return tmp;
00302 }
00303
00304
00306 inline BernsteinMulti operator* (const BernsteinMulti& m1,
00307 double c)
00308 {
00309 BernsteinMulti tmp = m1;
00310 tmp *= c;
00311 return tmp;
00312 }
00313
00314
00316 inline BernsteinMulti operator* (double c,
00317 const BernsteinMulti& m1)
00318 {
00319 BernsteinMulti tmp = m1;
00320 tmp *= c;
00321 return tmp;
00322 }
00323
00324
00326 inline BernsteinMulti operator+ (const BernsteinMulti& m1,
00327 const BernsteinMulti& m2)
00328 {
00329 BernsteinMulti tmp = m1;
00330 tmp += m2;
00331 return tmp;
00332 }
00333
00334
00336 inline BernsteinMulti operator+ (const BernsteinMulti& m,
00337 double c)
00338 {
00339 BernsteinMulti tmp = m;
00340 tmp += c;
00341 return tmp;
00342 }
00343
00344
00346 inline BernsteinMulti operator+ (double c,
00347 const BernsteinMulti& m)
00348 {
00349 BernsteinMulti tmp = m;
00350 tmp += c;
00351 return tmp;
00352 }
00353
00354
00356 inline BernsteinMulti operator- (const BernsteinMulti& m1,
00357 const BernsteinMulti& m2)
00358 {
00359 BernsteinMulti tmp = m1;
00360 tmp -= m2;
00361 return tmp;
00362 }
00363
00364
00366 inline BernsteinMulti operator- (const BernsteinMulti& m,
00367 double c)
00368 {
00369 BernsteinMulti tmp = m;
00370 tmp -= c;
00371 return tmp;
00372 }
00373
00374
00376 inline BernsteinMulti operator- (double c,
00377 const BernsteinMulti& m)
00378 {
00379 BernsteinMulti tmp(c);
00380 tmp -= m;
00381 return tmp;
00382 }
00383
00384
00386 inline BernsteinMulti operator/ (const BernsteinMulti& m,
00387 double c)
00388 {
00389 BernsteinMulti tmp = m;
00390 tmp /= c;
00391 return tmp;
00392 }
00393
00394
00396 }
00397
00398
00400 namespace std {
00403
00404
00405
00407 inline std::istream& operator >> (std::istream& is,
00408 Go::BernsteinMulti& m)
00409 {
00410 m.read(is);
00411 return is;
00412 }
00413
00414
00416 inline std::ostream& operator << (std::ostream& os,
00417 const Go::BernsteinMulti& m)
00418 {
00419 m.write(os);
00420 return os;
00421 }
00422
00423
00425 }
00426
00427
00428 #endif // _BERNSTEINMULTI_H
00429
00430