File indexing completed on 2026-09-28 09:20:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef _MathUtils_FunctorVector_HeaderFile
0015 #define _MathUtils_FunctorVector_HeaderFile
0016
0017 #include <math_Vector.hxx>
0018 #include <math_Matrix.hxx>
0019
0020 #include <cmath>
0021 #include <utility>
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 namespace MathUtils
0032 {
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 template <typename Lambda>
0048 class VectorLambda
0049 {
0050 public:
0051
0052
0053 explicit VectorLambda(Lambda theLambda)
0054 : myLambda(std::move(theLambda))
0055 {
0056 }
0057
0058
0059
0060
0061
0062 bool Value(const math_Vector& theX, double& theY) const { return myLambda(theX, theY); }
0063
0064 private:
0065 Lambda myLambda;
0066 };
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 template <typename ValueLambda, typename GradLambda>
0089 class VectorLambdaWithGradient
0090 {
0091 public:
0092
0093
0094
0095 VectorLambdaWithGradient(ValueLambda theValueLambda, GradLambda theGradLambda)
0096 : myValueLambda(std::move(theValueLambda)),
0097 myGradLambda(std::move(theGradLambda))
0098 {
0099 }
0100
0101
0102
0103
0104
0105 bool Value(const math_Vector& theX, double& theY) const { return myValueLambda(theX, theY); }
0106
0107
0108
0109
0110
0111 bool Gradient(const math_Vector& theX, math_Vector& theG) const
0112 {
0113 return myGradLambda(theX, theG);
0114 }
0115
0116
0117
0118
0119
0120
0121 bool Values(const math_Vector& theX, double& theY, math_Vector& theG) const
0122 {
0123 return myValueLambda(theX, theY) && myGradLambda(theX, theG);
0124 }
0125
0126 private:
0127 ValueLambda myValueLambda;
0128 GradLambda myGradLambda;
0129 };
0130
0131
0132
0133
0134
0135 template <typename Lambda>
0136 VectorLambda<Lambda> MakeVector(Lambda theLambda)
0137 {
0138 return VectorLambda<Lambda>(std::move(theLambda));
0139 }
0140
0141
0142
0143
0144
0145
0146
0147 template <typename ValueLambda, typename GradLambda>
0148 VectorLambdaWithGradient<ValueLambda, GradLambda> MakeVectorWithGradient(ValueLambda theValueLambda,
0149 GradLambda theGradLambda)
0150 {
0151 return VectorLambdaWithGradient<ValueLambda, GradLambda>(std::move(theValueLambda),
0152 std::move(theGradLambda));
0153 }
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 class QuadraticForm
0169 {
0170 public:
0171
0172
0173
0174
0175 QuadraticForm(const math_Matrix& theA, const math_Vector& theB, double theC)
0176 : myA(theA),
0177 myB(theB),
0178 myC(theC)
0179 {
0180 }
0181
0182
0183
0184
0185
0186 bool Value(const math_Vector& theX, double& theY) const
0187 {
0188 theY = myC;
0189
0190 for (int i = theX.Lower(); i <= theX.Upper(); ++i)
0191 {
0192 for (int j = theX.Lower(); j <= theX.Upper(); ++j)
0193 {
0194 theY += theX(i) * myA(i, j) * theX(j);
0195 }
0196 }
0197
0198 for (int i = theX.Lower(); i <= theX.Upper(); ++i)
0199 {
0200 theY += myB(i) * theX(i);
0201 }
0202 return true;
0203 }
0204
0205
0206
0207
0208
0209 bool Gradient(const math_Vector& theX, math_Vector& theG) const
0210 {
0211
0212 for (int i = theX.Lower(); i <= theX.Upper(); ++i)
0213 {
0214 theG(i) = myB(i);
0215 for (int j = theX.Lower(); j <= theX.Upper(); ++j)
0216 {
0217 theG(i) += (myA(i, j) + myA(j, i)) * theX(j);
0218 }
0219 }
0220 return true;
0221 }
0222
0223
0224
0225
0226
0227
0228 bool Values(const math_Vector& theX, double& theY, math_Vector& theG) const
0229 {
0230 return Value(theX, theY) && Gradient(theX, theG);
0231 }
0232
0233 private:
0234 math_Matrix myA;
0235 math_Vector myB;
0236 double myC;
0237 };
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252 class Rosenbrock
0253 {
0254 public:
0255
0256
0257
0258 Rosenbrock(double theA = 1.0, double theB = 100.0)
0259 : myA(theA),
0260 myB(theB)
0261 {
0262 }
0263
0264
0265
0266
0267
0268 bool Value(const math_Vector& theX, double& theY) const
0269 {
0270 const double x = theX(theX.Lower());
0271 const double y = theX(theX.Lower() + 1);
0272 const double t1 = myA - x;
0273 const double t2 = y - x * x;
0274 theY = t1 * t1 + myB * t2 * t2;
0275 return true;
0276 }
0277
0278
0279
0280
0281
0282 bool Gradient(const math_Vector& theX, math_Vector& theG) const
0283 {
0284 const double x = theX(theX.Lower());
0285 const double y = theX(theX.Lower() + 1);
0286 const double t2 = y - x * x;
0287 theG(theG.Lower()) = -2.0 * (myA - x) - 4.0 * myB * x * t2;
0288 theG(theG.Lower() + 1) = 2.0 * myB * t2;
0289 return true;
0290 }
0291
0292
0293
0294
0295
0296
0297 bool Values(const math_Vector& theX, double& theY, math_Vector& theG) const
0298 {
0299 return Value(theX, theY) && Gradient(theX, theG);
0300 }
0301
0302 private:
0303 double myA;
0304 double myB;
0305 };
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 class Sphere
0320 {
0321 public:
0322
0323
0324
0325
0326 bool Value(const math_Vector& theX, double& theY) const
0327 {
0328 theY = 0.0;
0329 for (int i = theX.Lower(); i <= theX.Upper(); ++i)
0330 {
0331 theY += theX(i) * theX(i);
0332 }
0333 return true;
0334 }
0335
0336
0337
0338
0339
0340 bool Gradient(const math_Vector& theX, math_Vector& theG) const
0341 {
0342 for (int i = theX.Lower(); i <= theX.Upper(); ++i)
0343 {
0344 theG(i) = 2.0 * theX(i);
0345 }
0346 return true;
0347 }
0348
0349
0350
0351
0352
0353
0354 bool Values(const math_Vector& theX, double& theY, math_Vector& theG) const
0355 {
0356 return Value(theX, theY) && Gradient(theX, theG);
0357 }
0358 };
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372 class Booth
0373 {
0374 public:
0375
0376
0377
0378
0379 bool Value(const math_Vector& theX, double& theY) const
0380 {
0381 const double x = theX(theX.Lower());
0382 const double y = theX(theX.Lower() + 1);
0383 const double t1 = x + 2.0 * y - 7.0;
0384 const double t2 = 2.0 * x + y - 5.0;
0385 theY = t1 * t1 + t2 * t2;
0386 return true;
0387 }
0388
0389
0390
0391
0392
0393 bool Gradient(const math_Vector& theX, math_Vector& theG) const
0394 {
0395 const double x = theX(theX.Lower());
0396 const double y = theX(theX.Lower() + 1);
0397 const double t1 = x + 2.0 * y - 7.0;
0398 const double t2 = 2.0 * x + y - 5.0;
0399 theG(theG.Lower()) = 2.0 * t1 + 4.0 * t2;
0400 theG(theG.Lower() + 1) = 4.0 * t1 + 2.0 * t2;
0401 return true;
0402 }
0403
0404
0405
0406
0407
0408
0409 bool Values(const math_Vector& theX, double& theY, math_Vector& theG) const
0410 {
0411 return Value(theX, theY) && Gradient(theX, theG);
0412 }
0413 };
0414
0415
0416
0417
0418 class Beale
0419 {
0420 public:
0421
0422
0423
0424
0425 bool Value(const math_Vector& theX, double& theY) const
0426 {
0427 const double x = theX(theX.Lower());
0428 const double y = theX(theX.Lower() + 1);
0429 const double t1 = 1.5 - x + x * y;
0430 const double t2 = 2.25 - x + x * y * y;
0431 const double t3 = 2.625 - x + x * y * y * y;
0432 theY = t1 * t1 + t2 * t2 + t3 * t3;
0433 return true;
0434 }
0435
0436
0437
0438
0439
0440 bool Gradient(const math_Vector& theX, math_Vector& theG) const
0441 {
0442 const double x = theX(theX.Lower());
0443 const double y = theX(theX.Lower() + 1);
0444 const double y2 = y * y;
0445 const double y3 = y2 * y;
0446 const double t1 = 1.5 - x + x * y;
0447 const double t2 = 2.25 - x + x * y2;
0448 const double t3 = 2.625 - x + x * y3;
0449 theG(theG.Lower()) = 2.0 * ((y - 1.0) * t1 + (y2 - 1.0) * t2 + (y3 - 1.0) * t3);
0450 theG(theG.Lower() + 1) = 2.0 * x * (t1 + 2.0 * y * t2 + 3.0 * y2 * t3);
0451 return true;
0452 }
0453
0454
0455
0456
0457
0458
0459 bool Values(const math_Vector& theX, double& theY, math_Vector& theG) const
0460 {
0461 return Value(theX, theY) && Gradient(theX, theG);
0462 }
0463 };
0464
0465
0466
0467
0468
0469 class Himmelblau
0470 {
0471 public:
0472
0473
0474
0475
0476 bool Value(const math_Vector& theX, double& theY) const
0477 {
0478 const double x = theX(theX.Lower());
0479 const double y = theX(theX.Lower() + 1);
0480 const double t1 = x * x + y - 11.0;
0481 const double t2 = x + y * y - 7.0;
0482 theY = t1 * t1 + t2 * t2;
0483 return true;
0484 }
0485
0486
0487
0488
0489
0490 bool Gradient(const math_Vector& theX, math_Vector& theG) const
0491 {
0492 const double x = theX(theX.Lower());
0493 const double y = theX(theX.Lower() + 1);
0494 const double t1 = x * x + y - 11.0;
0495 const double t2 = x + y * y - 7.0;
0496 theG(theG.Lower()) = 4.0 * x * t1 + 2.0 * t2;
0497 theG(theG.Lower() + 1) = 2.0 * t1 + 4.0 * y * t2;
0498 return true;
0499 }
0500
0501
0502
0503
0504
0505
0506 bool Values(const math_Vector& theX, double& theY, math_Vector& theG) const
0507 {
0508 return Value(theX, theY) && Gradient(theX, theG);
0509 }
0510 };
0511
0512
0513
0514
0515
0516
0517 class Rastrigin
0518 {
0519 public:
0520
0521
0522 explicit Rastrigin(double theA = 10.0)
0523 : myA(theA)
0524 {
0525 }
0526
0527
0528
0529
0530
0531 bool Value(const math_Vector& theX, double& theY) const
0532 {
0533 constexpr double aTwoPi = 2.0 * 3.14159265358979323846;
0534 const int n = theX.Upper() - theX.Lower() + 1;
0535 theY = myA * static_cast<double>(n);
0536 for (int i = theX.Lower(); i <= theX.Upper(); ++i)
0537 {
0538 theY += theX(i) * theX(i) - myA * std::cos(aTwoPi * theX(i));
0539 }
0540 return true;
0541 }
0542
0543
0544
0545
0546
0547 bool Gradient(const math_Vector& theX, math_Vector& theG) const
0548 {
0549 constexpr double aTwoPi = 2.0 * 3.14159265358979323846;
0550 for (int i = theX.Lower(); i <= theX.Upper(); ++i)
0551 {
0552 theG(i) = 2.0 * theX(i) + myA * aTwoPi * std::sin(aTwoPi * theX(i));
0553 }
0554 return true;
0555 }
0556
0557
0558
0559
0560
0561
0562 bool Values(const math_Vector& theX, double& theY, math_Vector& theG) const
0563 {
0564 return Value(theX, theY) && Gradient(theX, theG);
0565 }
0566
0567 private:
0568 double myA;
0569 };
0570
0571
0572
0573
0574
0575 class Ackley
0576 {
0577 public:
0578
0579
0580
0581
0582 Ackley(double theA = 20.0, double theB = 0.2, double theC = 2.0 * 3.14159265358979323846)
0583 : myA(theA),
0584 myB(theB),
0585 myC(theC)
0586 {
0587 }
0588
0589
0590
0591
0592
0593 bool Value(const math_Vector& theX, double& theY) const
0594 {
0595 constexpr double aE = 2.718281828459045;
0596 const int n = theX.Upper() - theX.Lower() + 1;
0597 double aSumSq = 0.0;
0598 double aSumCos = 0.0;
0599 for (int i = theX.Lower(); i <= theX.Upper(); ++i)
0600 {
0601 aSumSq += theX(i) * theX(i);
0602 aSumCos += std::cos(myC * theX(i));
0603 }
0604 theY = -myA * std::exp(-myB * std::sqrt(aSumSq / n)) - std::exp(aSumCos / n) + myA + aE;
0605 return true;
0606 }
0607
0608 private:
0609 double myA;
0610 double myB;
0611 double myC;
0612 };
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627 class LinearResidual
0628 {
0629 public:
0630
0631
0632
0633 LinearResidual(const math_Matrix& theA, const math_Vector& theB)
0634 : myA(theA),
0635 myB(theB)
0636 {
0637 }
0638
0639
0640
0641
0642
0643 bool Value(const math_Vector& theX, double& theY) const
0644 {
0645 theY = 0.0;
0646 for (int i = myA.LowerRow(); i <= myA.UpperRow(); ++i)
0647 {
0648 double aResidual = -myB(i);
0649 for (int j = myA.LowerCol(); j <= myA.UpperCol(); ++j)
0650 {
0651 aResidual += myA(i, j) * theX(j);
0652 }
0653 theY += aResidual * aResidual;
0654 }
0655 return true;
0656 }
0657
0658
0659
0660
0661
0662 bool Gradient(const math_Vector& theX, math_Vector& theG) const
0663 {
0664
0665 const int m = myA.UpperRow() - myA.LowerRow() + 1;
0666 math_Vector aResidual(1, m);
0667 for (int i = myA.LowerRow(); i <= myA.UpperRow(); ++i)
0668 {
0669 aResidual(i - myA.LowerRow() + 1) = -myB(i);
0670 for (int j = myA.LowerCol(); j <= myA.UpperCol(); ++j)
0671 {
0672 aResidual(i - myA.LowerRow() + 1) += myA(i, j) * theX(j);
0673 }
0674 }
0675
0676 for (int j = myA.LowerCol(); j <= myA.UpperCol(); ++j)
0677 {
0678 theG(j) = 0.0;
0679 for (int i = myA.LowerRow(); i <= myA.UpperRow(); ++i)
0680 {
0681 theG(j) += 2.0 * myA(i, j) * aResidual(i - myA.LowerRow() + 1);
0682 }
0683 }
0684 return true;
0685 }
0686
0687
0688
0689
0690
0691
0692 bool Values(const math_Vector& theX, double& theY, math_Vector& theG) const
0693 {
0694 return Value(theX, theY) && Gradient(theX, theG);
0695 }
0696
0697 private:
0698 math_Matrix myA;
0699 math_Vector myB;
0700 };
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716 template <typename Lambda>
0717 class SystemLambda
0718 {
0719 public:
0720
0721
0722
0723 SystemLambda(Lambda theLambda, int theNbEquations)
0724 : myLambda(std::move(theLambda)),
0725 myNbEquations(theNbEquations)
0726 {
0727 }
0728
0729
0730
0731 int NbEquations() const { return myNbEquations; }
0732
0733
0734
0735
0736
0737 bool Value(const math_Vector& theX, math_Vector& theF) const { return myLambda(theX, theF); }
0738
0739 private:
0740 Lambda myLambda;
0741 int myNbEquations;
0742 };
0743
0744
0745
0746
0747
0748
0749 template <typename Lambda>
0750 SystemLambda<Lambda> MakeSystem(Lambda theLambda, int theNbEquations)
0751 {
0752 return SystemLambda<Lambda>(std::move(theLambda), theNbEquations);
0753 }
0754
0755 }
0756
0757 #endif