00001
00002
00003
00004
00005
00006
00007 #include "Algebraic.h"
00008
00009
00010
00011 REGISTER_IMPLICIT(Algebraic,"Algebraic");
00012
00013
00014
00015
00016
00017 void Algebraic::init(int deg)
00018 {
00019 m_d = deg;
00020
00021 calcNumCoef();
00022 m_a = new double[m_numCoef];
00023 m_x = new int[m_numCoef];
00024 m_y = new int[m_numCoef];
00025 m_z = new int[m_numCoef];
00026 m_xPow = new double[m_d+1];
00027 m_yPow = new double[m_d+1];
00028 m_zPow = new double[m_d+1];
00029
00030 initPowerArrays();
00031 for (int i=0; i<m_numCoef; i++)
00032 m_a[i] = 0.0;
00033 }
00034
00035
00036
00037 Algebraic::Algebraic() : Implicit()
00038 {
00039 init(0);
00040 }
00041
00042 Algebraic::Algebraic(int deg) : Implicit()
00043 {
00044 init(deg);
00045 }
00046
00047 void Algebraic::degree(int deg)
00048 {
00049 int i;
00050
00051 double* m_a_back;
00052 m_a_back = m_a;
00053 int* m_x_back = m_x;
00054 int* m_y_back = m_y;
00055 int* m_z_back = m_z;
00056 double* m_xPow_back = m_xPow;
00057 double* m_yPow_back = m_yPow;
00058 double* m_zPow_back = m_zPow;
00059
00060 int old_numCoef = m_numCoef;
00061 int old_m_d = m_d;
00062
00063 m_d = deg;
00064
00065 calcNumCoef();
00066
00067 m_a = new double[m_numCoef];
00068 m_x = new int[m_numCoef];
00069 m_y = new int[m_numCoef];
00070 m_z = new int[m_numCoef];
00071 m_xPow = new double[m_d+1];
00072 m_yPow = new double[m_d+1];
00073 m_zPow = new double[m_d+1];
00074
00075 for (i = 0; i < gmMin(old_numCoef, m_numCoef); i++)
00076 {
00077 m_a[i] = m_a_back[i];
00078 m_x[i] = m_x_back[i];
00079 m_y[i] = m_y_back[i];
00080 m_z[i] = m_z_back[i];
00081 }
00082
00083 for (i = 0; i < gmMin(old_m_d+1, m_d+1); i++)
00084 {
00085 m_xPow[i] = m_xPow_back[i];
00086 m_yPow[i] = m_yPow_back[i];
00087 m_zPow[i] = m_zPow_back[i];
00088 }
00089
00090 for (i = (int)gmMin(old_numCoef, m_numCoef); i < m_numCoef; i++)
00091 m_a[i] = 0.0;
00092
00093 initPowerArrays();
00094
00095 delete[] m_a_back;
00096 delete[] m_x_back;
00097 delete[] m_y_back;
00098 delete[] m_z_back;
00099 delete[] m_xPow_back;
00100 delete[] m_yPow_back;
00101 delete[] m_zPow_back;
00102 }
00103
00104 Algebraic::~Algebraic()
00105 {
00106 delete[] m_a;
00107 delete[] m_x;
00108 delete[] m_y;
00109 delete[] m_z;
00110
00111 delete[] m_xPow;
00112 delete[] m_yPow;
00113 delete[] m_zPow;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 Intervald Algebraic::m_alrp(int i, Intervald t)
00123 {
00124 double* m_aold = (double *) malloc(m_numCoef * sizeof(double));
00125 getqold(m_aold);
00126 Intervald retval = t * (m_a[i] - m_aold[i]) + Intervald(m_aold[i]);
00127 delete m_aold;
00128 return retval;
00129 }
00130
00131 #ifndef INTERVAL_EVAL_ONLY
00132 double Algebraic::proc(gmVector3 v)
00133 {
00134 int i;
00135 double val = 0.0;
00136
00137 initXYZPowerArrays(v);
00138 for (i=0; i<m_numCoef; i++)
00139 val += m_a[i] * m_xPow[m_x[i]] * m_yPow[m_y[i]] * m_zPow[m_z[i]];
00140 return val;
00141 }
00142
00143 gmVector3 Algebraic::grad(gmVector3 v)
00144 {
00145 return gmVector3(dx(v), dy(v), dz(v));
00146 }
00147
00148 gmMatrix3 Algebraic::hess(gmVector3 v)
00149 {
00150 double dfdxy = dxdy(v), dfdxz = dxdz(v), dfdyz = dydz(v);
00151 double dfdxx = dx2(v), dfdyy = dy2(v), dfdzz = dz2(v);
00152
00153 gmMatrix3 hess(dfdxx, dfdxy, dfdxz,
00154 dfdxy, dfdyy, dfdyz,
00155 dfdxz, dfdyz, dfdzz);
00156 return hess;
00157 }
00158 #endif
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 Intervald Algebraic::proc(Box<double> x)
00170 {
00171 int i;
00172 Intervald val(0.0);
00173
00174 for (i=0; i<m_numCoef; i++)
00175 val += ((x.size() == 3) ? Intervald(m_a[i]) : m_alrp(i,x[3])) *
00176 x[0].pow(m_x[i]) * x[1].pow(m_y[i]) * x[2].pow(m_z[i]);
00177 return val;
00178 }
00179
00180 Box3d Algebraic::grad(Box<double> x)
00181 {
00182 Box3d dx(0.0);
00183 Intervald m_atemp;
00184
00185 for (int i = 0; i < m_numCoef; i++)
00186 {
00187 m_atemp = ((x.size() == 3) ? Intervald(m_a[i]) : m_alrp(i,x[3]));
00188 if (m_x[i] >= 1)
00189 dx[0] += m_atemp * Intervald(m_x[i]) *
00190 (x[0].pow(m_x[i]-1)*x[1].pow(m_y[i]) *x[2].pow(m_z[i]));
00191 if (m_y[i] >= 1)
00192 dx[1] += m_atemp * Intervald(m_y[i]) *
00193 (x[0].pow(m_x[i]) *x[1].pow(m_y[i]-1)*x[2].pow(m_z[i]));
00194 if (m_z[i] >= 1)
00195 dx[2] += m_atemp * Intervald(m_z[i]) *
00196 (x[0].pow(m_x[i]) *x[1].pow(m_y[i]) *x[2].pow(m_z[i]-1));
00197 }
00198 return dx;
00199 }
00200
00201 IMatrix3d Algebraic::hess(Box<double> x)
00202 {
00203 IMatrix3d Vx;
00204 int i;
00205
00206
00207 for (i = 0; i < m_numCoef; i++)
00208 {
00209 if (m_x[i] >= 2)
00210 Vx[0][0] += Intervald(m_a[i]*m_x[i]*(m_x[i]-1))*
00211 (x[0].pow(m_x[i]-2)*x[1].pow(m_y[i]) *x[2].pow(m_z[i]));
00212 if (m_y[i] >= 2)
00213 Vx[1][1] += Intervald(m_a[i]*m_y[i]*(m_y[i]-1))*
00214 (x[0].pow(m_x[i]) *x[1].pow(m_y[i]-2)*x[2].pow(m_z[i]));
00215 if (m_z[i] >= 2)
00216 Vx[2][2] += Intervald(m_a[i]*m_z[i]*(m_z[i]-1))*
00217 (x[0].pow(m_x[i]) *x[1].pow(m_y[i]) *x[2].pow(m_z[i]-2));
00218 if (m_x[i] >= 1 && m_y[i] >= 1)
00219 Vx[1][0] += Intervald(m_a[i]*m_x[i]*m_y[i])*
00220 (x[0].pow(m_x[i]-1)*x[1].pow(m_y[i]-1)*x[2].pow(m_z[i]));
00221 if (m_y[i] >= 1 && m_z[i] >= 1)
00222 Vx[2][1] += Intervald(m_a[i]*m_y[i]*m_z[i])*
00223 (x[0].pow(m_x[i]) *x[1].pow(m_y[i]-1)*x[2].pow(m_z[i]-1));
00224 if (m_x[i] >= 1 && m_z[i] >= 1)
00225 Vx[2][0] += Intervald(m_a[i]*m_x[i]*m_z[i])*
00226 (x[0].pow(m_x[i]-1)*x[1].pow(m_y[i]) *x[2].pow(m_z[i]-1));
00227 }
00228
00229
00230 Vx[0][1] = Vx[1][0];
00231 Vx[1][2] = Vx[2][1];
00232 Vx[0][2] = Vx[2][0];
00233
00234 return Vx;
00235 }
00236
00237
00238
00239
00240
00241
00242
00243 double Algebraic::getCoef(int i, int j, int k)
00244 {
00245 return m_a[getCoefIndex(i, j, k)];
00246 }
00247
00248
00249
00250
00251
00252
00253
00254 void Algebraic::setCoef(int i, int j, int k, double a)
00255 {
00256 m_a[getCoefIndex(i, j, k)] = a;
00257 }
00258
00259 int Algebraic::getNumCoef()
00260 {
00261 return m_numCoef;
00262 }
00263
00264 int Algebraic::degree()
00265 {
00266 return m_d;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 int Algebraic::coefficients(int d)
00296 {
00297 return (6 + d * (11 + d * (6 + d))) / 6;
00298 }
00299
00300
00301
00302
00303 void Algebraic::calcNumCoef()
00304 {
00305 m_numCoef = coefficients(m_d);
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 int Algebraic::getCoefIndex(int i, int j, int k)
00350 {
00351
00352
00353
00354
00355
00356 return coefficients(i+j+k) - (i*i + 2*i*j + j*j + 3*i + 3*j + 2)/2 + j;
00357 }
00358
00359
00360
00361
00362 void Algebraic::initPowerArrays()
00363 {
00364 int i, j, k;
00365 int coefIndex;
00366
00367 for (i=0; i<=m_d; i++)
00368 for (j=0; j<=m_d-i; j++)
00369 for (k=0; k<=m_d-(i+j); k++)
00370 {
00371 coefIndex = getCoefIndex(i, j, k);
00372 m_x[coefIndex] = i;
00373 m_y[coefIndex] = j;
00374 m_z[coefIndex] = k;
00375 }
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 void Algebraic::initXYZPowerArrays(gmVector3 v)
00388 {
00389 int i;
00390
00391
00392 if ((m_xPow[1] == v[0]) && (m_yPow[1] == v[1]) && (m_zPow[1] == v[2]))
00393 return;
00394
00395 m_xPow[0] = m_yPow[0] = m_zPow[0] = 1;
00396 for (i=1; i<=m_d; i++)
00397 {
00398 m_xPow[i] = m_xPow[i-1] * v[0];
00399 m_yPow[i] = m_yPow[i-1] * v[1];
00400 m_zPow[i] = m_zPow[i-1] * v[2];
00401 }
00402 }
00403
00404 double Algebraic::dx(gmVector3 v)
00405 {
00406 double deriv = 0.0;
00407
00408 initXYZPowerArrays(v);
00409 for (int i=0; i<m_numCoef; i++)
00410 {
00411 if (m_x[i] >= 1)
00412 deriv += m_a[i] * m_x[i] *
00413 m_xPow[m_x[i]-1] * m_yPow[m_y[i]] * m_zPow[m_z[i]];
00414 }
00415 return deriv;
00416 }
00417
00418 double Algebraic::dy(gmVector3 v)
00419 {
00420 double deriv = 0.0;
00421
00422 initXYZPowerArrays(v);
00423 for (int i=0; i<m_numCoef; i++)
00424 {
00425 if (m_y[i] >= 1)
00426 deriv += m_a[i] * m_y[i] *
00427 m_xPow[m_x[i]] * m_yPow[m_y[i]-1] * m_zPow[m_z[i]];
00428 }
00429 return deriv;
00430 }
00431
00432 double Algebraic::dz(gmVector3 v)
00433 {
00434 double deriv = 0.0;
00435
00436 initXYZPowerArrays(v);
00437 for (int i=0; i<m_numCoef; i++)
00438 {
00439 if (m_z[i] >= 1)
00440 deriv += m_a[i] * m_z[i] *
00441 m_xPow[m_x[i]] * m_yPow[m_y[i]] * m_zPow[m_z[i]-1];
00442 }
00443 return deriv;
00444 }
00445
00446 double Algebraic::dx2(gmVector3 v)
00447 {
00448 double deriv = 0.0;
00449
00450 initXYZPowerArrays(v);
00451 for (int i=0; i<m_numCoef; i++)
00452 {
00453 if (m_x[i] >= 2)
00454 deriv += m_a[i] * m_x[i] * (m_x[i]-1) *
00455 m_xPow[m_x[i]-2] * m_yPow[m_y[i]] * m_zPow[m_z[i]];
00456 }
00457 return deriv;
00458 }
00459
00460 double Algebraic::dy2(gmVector3 v)
00461 {
00462 double deriv = 0.0;
00463
00464 initXYZPowerArrays(v);
00465 for (int i=0; i<m_numCoef; i++)
00466 {
00467 if (m_y[i] >= 2)
00468 deriv += m_a[i] * m_y[i] * (m_y[i]-1) *
00469 m_xPow[m_x[i]] * m_yPow[m_y[i]-2] * m_zPow[m_z[i]];
00470 }
00471 return deriv;
00472 }
00473
00474 double Algebraic::dz2(gmVector3 v)
00475 {
00476 double deriv = 0.0;
00477
00478 initXYZPowerArrays(v);
00479 for (int i=0; i<m_numCoef; i++)
00480 {
00481 if (m_z[i] >= 2)
00482 deriv += m_a[i] * m_z[i] * (m_z[i]-1) *
00483 m_xPow[m_x[i]] * m_yPow[m_y[i]] * m_zPow[m_z[i]-2];
00484 }
00485 return deriv;
00486 }
00487
00488 double Algebraic::dxdy(gmVector3 v)
00489 {
00490 double deriv = 0.0;
00491
00492 initXYZPowerArrays(v);
00493 for (int i=0; i<m_numCoef; i++)
00494 {
00495 if ((m_x[i] >= 1) && (m_y[i] >= 1))
00496 deriv += m_a[i] * m_x[i] * m_y[i] *
00497 m_xPow[m_x[i]-1] * m_yPow[m_y[i]-1] * m_zPow[m_z[i]];
00498 }
00499 return deriv;
00500 }
00501
00502 double Algebraic::dxdz(gmVector3 v)
00503 {
00504 double deriv = 0.0;
00505
00506 initXYZPowerArrays(v);
00507 for (int i=0; i<m_numCoef; i++)
00508 {
00509 if ((m_x[i] >= 1) && (m_z[i] >= 1))
00510 deriv += m_a[i] * m_x[i] * m_z[i] *
00511 m_xPow[m_x[i]-1] * m_yPow[m_y[i]] * m_zPow[m_z[i]-1];
00512 }
00513 return deriv;
00514 }
00515
00516 double Algebraic::dydz(gmVector3 v)
00517 {
00518 double deriv = 0.0;
00519
00520 initXYZPowerArrays(v);
00521 for (int i=0; i<m_numCoef; i++)
00522 {
00523 if ((m_y[i] >= 1) && (m_z[i] >= 1))
00524 deriv += m_a[i] * m_y[i] * m_z[i] *
00525 m_xPow[m_x[i]] * m_yPow[m_y[i]-1] * m_zPow[m_z[i]-1];
00526 }
00527 return deriv;
00528 }
00529
00530
00531
00532
00533
00534 void Algebraic::procq(gmVector3 x, double* dfdq)
00535 {
00536 int i;
00537
00538 initXYZPowerArrays(x);
00539 for (i=0; i<m_numCoef; i++)
00540 dfdq[i] = m_xPow[m_x[i]] * m_yPow[m_y[i]] * m_zPow[m_z[i]];
00541
00542 }
00543
00544
00545
00546
00547
00548 void Algebraic::procq(Box<double> x, Intervald* dfdq)
00549 {
00550 int i;
00551
00552 for (i=0; i<m_numCoef; i++)
00553 dfdq[i] = x[0].pow(m_x[i]) * x[1].pow(m_y[i]) * x[2].pow(m_z[i]);
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 void Algebraic::gradq(Box<double> x,
00571 Intervald* dfdxdq, Intervald* dfdydq, Intervald* dfdzdq)
00572 {
00573 for (int i = 0; i < m_numCoef; i++)
00574 {
00575 dfdxdq[i] = (Intervald(m_x[i]) *
00576 x[0].pow(m_x[i]-1)*x[1].pow(m_y[i]) *x[2].pow(m_z[i]));
00577 dfdydq[i] = (Intervald(m_y[i]) *
00578 x[0].pow(m_x[i]) *x[1].pow(m_y[i]-1)*x[2].pow(m_z[i]));
00579 dfdzdq[i] = (Intervald(m_z[i]) *
00580 x[0].pow(m_x[i]) *x[1].pow(m_y[i]) *x[2].pow(m_z[i]-1));
00581 }
00582 }
00583
00584 void Algebraic::getq(double* q)
00585 {
00586 int i;
00587
00588 for (i=0; i<m_numCoef; i++)
00589 q[i] = m_a[i];
00590 }
00591
00592 void Algebraic::_setq(double* q)
00593 {
00594 for (int i=0; i<m_numCoef; i++)
00595 m_a[i] = q[i];
00596 }
00597
00598 int Algebraic::qlen()
00599 {
00600 return m_numCoef;
00601 }
00602
00603 void Algebraic::getqname(char** qn)
00604 {
00605 int i;
00606 char s[32];
00607
00608 for (i = 0; i < m_numCoef; i++)
00609 {
00610 qn[i] = new char[32];
00611 qn[i][0] = '\0';
00612 if (m_x[i])
00613 {
00614 if (m_x[i] == 1)
00615 strcat(qn[i],"x");
00616 else
00617 {
00618 sprintf(s,"x^%d",m_x[i]);
00619 strcat(qn[i],s);
00620 }
00621 }
00622 if (m_y[i])
00623 {
00624 if (!qn[i][0])
00625 strcat(qn[i]," ");
00626 if (m_y[i] == 1)
00627 strcat(qn[i],"y");
00628 else
00629 {
00630 sprintf(s,"y^%d",m_y[i]);
00631 strcat(qn[i],s);
00632 }
00633 }
00634 if (m_z[i])
00635 {
00636 if (!qn[i][0])
00637 strcat(qn[i]," ");
00638 if (m_z[i] == 1)
00639 strcat(qn[i],"z");
00640 else
00641 {
00642 sprintf(s,"z^%d",m_z[i]);
00643 strcat(qn[i],s);
00644 }
00645 }
00646 if (!qn[i][0])
00647 strcat(qn[i],"1");
00648 }
00649 }
00650