19#ifndef _GIMLI_POLYNOMIAL__H 
   20#define _GIMLI_POLYNOMIAL__H 
   24#include "modellingbase.h" 
   25#include "regionManager.h" 
   27#include "numericbase.h" 
   33template< 
class ValueType > 
class PolynomialElement {
 
   35    PolynomialElement(Index i, Index j, Index k, 
const ValueType & val)
 
   36    :   i_(i), j_(j), k_(k), val_(val){
 
   39    inline ValueType operator () (
const Pos & xyz)
 const {
 
   40        return val_ * powInt(xyz[0], i_) * powInt(xyz[1], j_) * powInt(xyz[2], k_);
 
 
   48template < 
class ValueType > 
bool operator < (
const PolynomialElement < ValueType > & a, 
 
   49                                              const PolynomialElement < ValueType > & b){
 
   50    return ((a.i_ < b.i_) && (a.j_ < b.j_) && (a.k_ < b.k_));
 
 
   53template < 
class ValueType > 
bool operator != (
const PolynomialElement < ValueType > & a, 
 
   54                                               const PolynomialElement < ValueType > & b){
 
   58template < 
class ValueType > 
bool operator == (
const PolynomialElement < ValueType > & a, 
 
   59                                               const PolynomialElement < ValueType > & b){
 
   60    return ((a.i_ == b.i_) && (a.j_ == b.j_) && (a.k_ == b.k_) && (a.val_ == b.val_));
 
   98                       const Vector < ValueType > & ay, 
 
   99                       const Vector < ValueType > & az){
 
 
  104    RMatrix & operator [] (Index k){ 
return mat_[k]; }
 
  107    const RMatrix & operator [] (Index k)
 const { 
return mat_[k]; }
 
  110    RMatrix & 
matR(Index k){ 
return mat_[k]; }
 
  113    ValueType operator () (
const Pos & xyz)
 const {
 
  116        for (
typename std::vector <PolynomialElement < ValueType > >::const_iterator it = elementList_.begin();
 
  117                it != elementList_.end(); it ++){
 
 
  124    Vector < ValueType > operator () (
const std::vector < Pos > & xyz)
 const {
 
  125        Vector < ValueType > ret(xyz.size(), 0.0);
 
  127        for (Index i = 0 ; i < ret.size(); i ++) ret [i] = (*
this)(xyz[i]);
 
 
  133    Index 
size()
 const { 
return mat_.size(); }
 
  140    PolynomialFunction < ValueType > 
derive(uint dim)
 const {
 
  145            for (Index k = 0; k < mat_.size(); k ++){ 
 
  146                for (Index j = 0; j < mat_[k].rows(); j ++){ 
 
  147                    for (Index i = 0; i < mat_[k][j].size() -1; i ++){ 
 
  148                        ret[k][i][j] = mat_[k][i + 1][j] * (i + 1.0);
 
  153            for (Index k = 0; k < mat_.size(); k ++){ 
 
  154                for (Index j = 0; j < mat_[k].rows() - 1; j ++){ 
 
  155                    for (Index i = 0; i < mat_[k][j].size(); i ++){ 
 
  156                        ret[k][i][j] = mat_[k][i][j + 1] * (j + 1.0);
 
  160        } 
else if (dim == 2){
 
  161            for (Index k = 0; k < mat_.size() -1 ; k ++){ 
 
  162                for (Index j = 0; j < mat_[k].rows(); j ++){ 
 
  163                    for (Index i = 0; i < mat_[k][j].size(); i ++){ 
 
  164                        ret[k][i][j] = mat_[k + 1][i][j] * (k + 1.0);
 
  169        ret.fillElementList();
 
 
  174    void fillElementList(){
 
  175        elementList_.clear();
 
  177        for (Index k = 0; k < mat_.size(); k ++){ 
 
  178            for (Index j = 0; j < mat_[k].rows(); j ++){ 
 
  179                for (Index i = 0; i < mat_[k][j].size(); i ++){ 
 
  180                    if (::fabs(mat_[k][i][j]) > TOLERANCE){
 
  188    const std::vector <PolynomialElement < ValueType > > & elements()
 const { 
return elementList_; }
 
  191        elementList_.clear();
 
  192        for (Index k = 0; k < mat_.size(); k ++){ mat_[k] *= 0.0; }
 
  203    PolynomialFunction <  ValueType > & 
fill(
const Vector < ValueType > & c){
 
  204        if (c.size() == powInt(mat_.size(), 3)) {
 
  205            for (Index k = 0; k < mat_.size(); k ++){ 
 
  206                for (Index j = 0; j < mat_[k].rows(); j ++){ 
 
  207                    for (Index i = 0; i < mat_[k][j].size(); i ++){ 
 
  208                        if (::fabs(c[k*(
size() * 
size())+ j * 
size() + i]) > TOLERANCE){
 
  222        } 
else if (c.size() == elementList_.size()){
 
  223            for (Index k = 0; k < mat_.size(); k ++){ 
 
  226            for (Index i = 0; i < c.size(); i ++){
 
  228                mat_[e.k_][e.i_][e.j_] = c[i];
 
  231            throwLengthError(WHERE_AM_I + 
" c size out of range " +
 
  232                                str(c.size()) + 
" needed " + str(powInt(mat_.size(), 3)) +
 
  233                                                    " or " + str(elementList_.size()));
 
  235        this->fillElementList();
 
 
  241        RVector c(powInt(mat_.size(), 3));
 
  243        for (Index k = 0; k < mat_.size(); k ++){ 
 
  244            for (Index j = 0; j < mat_[k].rows(); j ++){ 
 
  245                for (Index i = 0; i < mat_[k][j].size(); i ++){ 
 
 
  255    void init_(
const Vector < ValueType > & ax, 
 
  256               const Vector < ValueType > & ay, 
 
  257               const Vector < ValueType > & az){
 
  258        Index maxDim = max(max(ax.size(), ay.size()), az.size());
 
  260        for (Index k = 0; k < maxDim; k ++){
 
  261            mat_.push_back(RMatrix(maxDim, maxDim));
 
  265        for (Index i = 0; i < ax.size(); i ++) mat_[0][i][0] = ax[i];
 
  266        for (Index j = 0; j < ay.size(); j ++) mat_[0][0][j] = ay[j];
 
  267        for (Index k = 0; k < az.size(); k ++) mat_[k][0][0] = az[k];
 
  271    std::vector < Matrix < ValueType > > mat_;
 
  273    std::vector <PolynomialElement < ValueType > > elementList_;
 
 
  276template < 
class ValueType > 
bool operator == (
const PolynomialFunction < ValueType > & a, 
const PolynomialFunction < ValueType > & b){
 
  277    if (a.elements().size() == b.elements().size()){
 
  278        typename std::vector <PolynomialElement < ValueType > >::const_iterator ita = a.elements().begin();
 
  279        typename std::vector <PolynomialElement < ValueType > >::const_iterator itb = b.elements().begin();
 
  281        for (; ita != a.elements().end(); ita ++, itb ++){
 
  282            if (*ita != *itb) 
return false;
 
  291template < 
class ValueType > PolynomialFunction < ValueType >
 
  292operator - (
const PolynomialFunction < ValueType > & f){
 
  296    for (Index k = 0; k < f.size(); k ++){ 
 
  297        for (Index j = 0; j < f[k].rows(); j ++){ 
 
  298            for (Index i = 0; i < f[k][j].size(); i ++){ 
 
  299                h[k][i][j] = -f[k][i][j];
 
  307template < 
class ValueType > PolynomialFunction < ValueType >
 
  308operator * (
const ValueType & val, 
const PolynomialFunction < ValueType > & f){
 
  310    PolynomialFunction < ValueType > h(RVector(f.size()), 0.0);
 
  312    for (Index k = 0; k < f.size(); k ++){ 
 
  313        for (Index j = 0; j < f[k].rows(); j ++){ 
 
  314            for (Index i = 0; i < f[k][j].size(); i ++){ 
 
  315                h[k][i][j] = f[k][i][j] * val;
 
  323template < 
class ValueType > PolynomialFunction < ValueType >
 
  324operator * (
const PolynomialFunction < ValueType > & f, 
const ValueType & val){
 
  326    PolynomialFunction < ValueType > h(RVector(f.size()), 0.0);
 
  328    for (Index k = 0; k < f.size(); k ++){ 
 
  329        for (Index j = 0; j < f[k].rows(); j ++){ 
 
  330            for (Index i = 0; i < f[k][j].size(); i ++){ 
 
  331                h[k][i][j] = f[k][i][j] * val;
 
  339template < 
class ValueType > PolynomialFunction < ValueType >
 
  340operator + (
const ValueType & val, 
const PolynomialFunction < ValueType > & f){
 
  341    PolynomialFunction < ValueType > h(RVector(f.size(), 0.0));
 
  343    for (Index k = 0; k < f.size(); k ++){ 
 
  344        for (Index j = 0; j < f[k].rows(); j ++){ 
 
  345            for (Index i = 0; i < f[k][j].size(); i ++){ 
 
  346                h[k][i][j] = f[k][i][j];
 
  355template < 
class ValueType > PolynomialFunction < ValueType >
 
  356operator + (
const PolynomialFunction < ValueType > & f, 
const ValueType & val){
 
  357    PolynomialFunction < ValueType > h(RVector(f.size(), 0.0));
 
  359    for (Index k = 0; k < f.size(); k ++){ 
 
  360        for (Index j = 0; j < f[k].rows(); j ++){ 
 
  361            for (Index i = 0; i < f[k][j].size(); i ++){ 
 
  362                h[k][i][j] = f[k][i][j];
 
  371template < 
class ValueType > PolynomialFunction < ValueType >
 
  372operator + (
const PolynomialFunction < ValueType > & f, 
const PolynomialFunction < ValueType > & g){
 
  374    PolynomialFunction < ValueType > h(RVector(max(f.size(),g.size()), 0.0));
 
  376    for (Index k = 0; k < f.size(); k ++){ 
 
  377        for (Index j = 0; j < f[k].rows(); j ++){ 
 
  378            for (Index i = 0; i < f[k][j].size(); i ++){ 
 
  379                h[k][i][j] = f[k][i][j];
 
  383    for (Index k = 0; k < g.size(); k ++){ 
 
  384        for (Index j = 0; j < g[k].rows(); j ++){ 
 
  385            for (Index i = 0; i < g[k][j].size(); i ++){ 
 
  386                h[k][i][j] += g[k][i][j];
 
  394template < 
class ValueType > PolynomialFunction < ValueType >
 
  395operator - (
const PolynomialFunction < ValueType > & f, 
const PolynomialFunction < ValueType > & g){
 
  397    PolynomialFunction < ValueType > h(RVector(max(f.size(),g.size()), 0.0));
 
  399    for (Index k = 0; k < f.size(); k ++){ 
 
  400        for (Index j = 0; j < f[k].rows(); j ++){ 
 
  401            for (Index i = 0; i < f[k][j].size(); i ++){ 
 
  402                h[k][i][j] = f[k][i][j];
 
  406    for (Index k = 0; k < g.size(); k ++){ 
 
  407        for (Index j = 0; j < g[k].rows(); j ++){ 
 
  408            for (Index i = 0; i < g[k][j].size(); i ++){ 
 
  409                h[k][i][j] -= g[k][i][j];
 
  418template < 
class ValueType > PolynomialFunction < ValueType >
 
  419operator * (
const PolynomialFunction < ValueType > & f, 
const PolynomialFunction < ValueType > & g){
 
  423    PolynomialFunction < ValueType > h(RVector(f.
size() + g.
size(), 0.0));
 
  425    for (Index k = 0; k < f.
size(); k ++){ 
 
  426        for (Index j = 0; j < f[k].rows(); j ++){ 
 
  427            for (Index i = 0; i < f[k][j].
size(); i ++){ 
 
  428                for (Index gk = 0; gk < g.
size(); gk ++){ 
 
  429                    for (Index gj = 0; gj < g[gk].rows(); gj ++){ 
 
  430                        for (Index gi = 0; gi < g[gk][gj].
size(); gi ++){ 
 
  431                            h[k + gk][i + gi][j + gj] += f[k][i][j] * g[gk][gi][gj];
 
 
  442template < 
class ValueType > std::ostream & operator << (std::ostream & os, 
const PolynomialFunction < ValueType > & p){
 
  445    if (p.size() == 0) os << 
"0";
 
  448    for (Index k = 0; k < p.size() ; k ++){ 
 
  449        for (Index j = 0; j < p[k].rows(); j ++){ 
 
  450            for (Index i = 0; i < p[k][j].size(); i ++){ 
 
  451                if (i > 0) first = 
false;
 
  455                ValueType v = p[k][i][j];
 
  456                if (v == 0.0) 
continue;
 
  457                if (v > 0.0) si = 
"+";
 
  459                std::string xterm, yterm, zterm, val;
 
  460                if (i == 0) xterm = 
""; 
else if (i == 1) xterm = 
"x"; 
else xterm = 
"x^" + str(i);
 
  461                if (j == 0) yterm = 
""; 
else if (j == 1) yterm = 
"y"; 
else yterm = 
"y^" + str(j);
 
  462                if (k == 0) zterm = 
""; 
else if (k == 1) zterm = 
"z"; 
else zterm = 
"z^" + str(k);
 
  467                    if (v == -1.0) val = 
"-1";
 
  468                    else if (v == 1.0) val = 
"1";
 
  470                    if (::fabs(v + 1.0) < TOLERANCE) val = 
"-";
 
  471                    else if (::fabs(v - 1.0) < TOLERANCE) val = 
"";
 
  474                os << si << val << xterm;
 
  475                if (yterm != 
"") os << yterm;
 
  476                if (zterm != 
"") os << zterm;
 
Definition polynomial.h:33
 
PolynomialFunction(const Vector< ValueType > &ax, const Vector< ValueType > &ay)
Definition polynomial.h:89
 
PolynomialFunction(const Vector< ValueType > &ax)
Definition polynomial.h:80
 
Index size() const
Definition polynomial.h:133
 
PolynomialFunction(const Vector< ValueType > &ax, const Vector< ValueType > &ay, const Vector< ValueType > &az)
Definition polynomial.h:97
 
PolynomialFunction(uint size=0)
Definition polynomial.h:71
 
RVector coeff() const
Definition polynomial.h:240
 
RMatrix & matR(Index k)
Definition polynomial.h:110
 
PolynomialFunction< ValueType > & fill(const Vector< ValueType > &c)
Definition polynomial.h:203
 
PolynomialFunction< ValueType > derive(uint dim) const
Definition polynomial.h:140
 
3 dimensional vector
Definition pos.h:73
 
One dimensional array aka Vector of limited size.
Definition vector.h:186
 
GIMLi main namespace for the Geophyiscal Inversion and Modelling Library.
Definition baseentity.h:24
 
bool operator<(const PolynomialElement< ValueType > &a, const PolynomialElement< ValueType > &b)
Definition polynomial.h:48