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