MiniTensor Version of the Day
Loading...
Searching...
No Matches
MiniTensor_TestFunctions.h
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MiniTensor Package
4//
5// Copyright 2016 NTESS and the MiniTensor contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#if !defined(MiniTensor_TestFunctions_h)
11#define MiniTensor_TestFunctions_h
12
13#include "MiniTensor_Solvers.h"
14
15namespace minitensor {
16
19
20//
21// Define some nonlinear systems (NLS) to test nonlinear solution methods.
22//
23
24//
25//
26//
32template<typename S, Index M = 1>
33class SquareRoot : public Function_Base<SquareRoot<S, M>, S, M>
34{
35public:
36
41 SquareRoot(S const c) : c_(c)
42 {
43 }
44
48 static constexpr
49 char const * const
50 NAME{"Square Root"};
51
56
57 // Default value.
61 template<typename T, Index N>
62 T
64 {
65 return Base::value(*this, x);
66 }
67
68 // Explicit gradient.
72 template<typename T, Index N>
74 gradient(Vector<T, N> const & x) const
75 {
76 Index const
77 dimension = x.get_dimension();
78
79 assert(dimension == Base::DIMENSION);
80
82 r(dimension);
83
84 r(0) = x(0) * x(0) - c_;
85
86 return r;
87 }
88
89 // Default AD hessian.
93 template<typename T, Index N>
96 {
97 return Base::hessian(*this, x);
98 }
99
100private:
104 S const
105 c_{0.0};
106};
107
108//
109//
110//
116template<typename S, Index M = 2>
117class Quadratic : public Function_Base<Quadratic<S, M>, S, M>
118{
119public:
126 Quadratic(S const a, S const b, S const c) : a_(a), b_(b), c_(c)
127 {
128 }
129
133 static constexpr
134 char const * const
135 NAME{"Quadratic"};
136
141
142 // Default value.
146 template<typename T, Index N>
147 T
149 {
150 return Base::value(*this, x);
151 }
152
153 // Explicit gradient.
157 template<typename T, Index N>
159 gradient(Vector<T, N> const & x) const
160 {
161 Index const
162 dimension = x.get_dimension();
163
164 assert(dimension == Base::DIMENSION);
165
167 r(dimension);
168
169 r(0) = 2.0 * c_ * (x(0) - a_);
170 r(1) = 2.0 * c_ * (x(1) - b_);
171
172 return r;
173 }
174
175 // Default AD hessian.
179 template<typename T, Index N>
182 {
183 return Base::hessian(*this, x);
184 }
185
186private:
190 S const
191 a_{0.0};
192
196 S const
197 b_{0.0};
198
202 S const
203 c_{0.0};
204};
205
206//
207//
208//
215template<typename S, Index M = 2>
216class Gaussian : public Function_Base<Gaussian<S, M>, S, M>
217{
218public:
225 Gaussian(S const a, S const b, S const c) : a_(a), b_(b), c_(c)
226 {
227 }
228
232 static constexpr
233 char const * const
234 NAME{"Inverted Gaussian"};
235
240
241 // Default value.
245 template<typename T, Index N>
246 T
248 {
249 return Base::value(*this, x);
250 }
251
252 // Explicit gradient.
256 template<typename T, Index N>
258 gradient(Vector<T, N> const & x) const
259 {
260 Index const
261 dimension = x.get_dimension();
262
263 assert(dimension == Base::DIMENSION);
264
266 r(dimension);
267
268 T const
269 xa = (x(0) - a_) * c_;
270
271 T const
272 xb = (x(1) - b_) * c_;
273
274 T const
275 e = std::exp(- xa * xa - xb * xb);
276
277 r(0) = 2.0 * xa * e * c_ * c_;
278 r(1) = 2.0 * xb * e * c_ * c_;
279
280 return r;
281 }
282
283 // Default AD hessian.
287 template<typename T, Index N>
290 {
291 return Base::hessian(*this, x);
292 }
293
294private:
298 S const
299 a_{0.0};
300
304 S const
305 b_{0.0};
306
310 S const
311 c_{0.0};
312};
313
314//
315//
316//
323template<typename S, Index M = 2>
324class Banana : public Function_Base<Banana<S, M>, S, M>
325{
326public:
327
332 {
333 }
334
338 static constexpr
339 char const * const
340 NAME{"Rosenbrock's Banana"};
341
346
347 // Default value.
351 template<typename T, Index N>
352 T
354 {
355 return Base::value(*this, x);
356 }
357
358 // Explicit gradient.
362 template<typename T, Index N>
364 gradient(Vector<T, N> const & x) const
365 {
366 Index const
367 dimension = x.get_dimension();
368
369 assert(dimension == Base::DIMENSION);
370
372 r(dimension);
373
374 r(0) = 2.0 * (x(0) - 1.0) + 400.0 * x(0) * (x(0) * x(0) - x(1));
375 r(1) = 200.0 * (x(1) - x(0) * x(0));
376
377 return r;
378 }
379
380 // Default AD hessian.
384 template<typename T, Index N>
387 {
388 return Base::hessian(*this, x);
389 }
390
391};
392
393//
394//
395//
402template<typename S, Index M = 2>
403class Matyas : public Function_Base<Matyas<S, M>, S, M>
404{
405public:
406
411
415 static constexpr
416 char const * const
417 NAME{"Matyas"};
418
423
424 // Default value.
428 template<typename T, Index N>
429 T
431 {
432 return Base::value(*this, x);
433 }
434
435 // Explicit gradient.
439 template<typename T, Index N>
441 gradient(Vector<T, N> const & x) const
442 {
443 Index const
444 dimension = x.get_dimension();
445
446 assert(dimension == Base::DIMENSION);
447
449 r(dimension);
450
451 r(0) = (13.0 * x(0) - 12.0 * x(1)) / 25.0;
452 r(1) = (13.0 * x(1) - 12.0 * x(0)) / 25.0;
453
454 return r;
455 }
456
457 // Default AD hessian.
461 template<typename T, Index N>
464 {
465 return Base::hessian(*this, x);
466 }
467
468};
469
470//
471//
472//
479template<typename S, Index M = 2>
480class McCormick : public Function_Base<McCormick<S, M>, S, M>
481{
482public:
483
488
492 static constexpr
493 char const * const
494 NAME{"McCormick"};
495
500
501 // Default value.
505 template<typename T, Index N>
506 T
508 {
509 return Base::value(*this, x);
510 }
511
512 // Explicit gradient.
516 template<typename T, Index N>
518 gradient(Vector<T, N> const & x) const
519 {
520 Index const
521 dimension = x.get_dimension();
522
523 assert(dimension == Base::DIMENSION);
524
526 r(dimension);
527
528 r(0) = std::cos(x(0) + x(1)) + 2.0 * x(0) - 2.0 * x(1) - 1.5;
529 r(1) = std::cos(x(0) + x(1)) - 2.0 * x(0) + 2.0 * x(1) + 2.5;
530
531 return r;
532 }
533
534 // Default AD hessian.
538 template<typename T, Index N>
541 {
542 return Base::hessian(*this, x);
543 }
544
545};
546
547//
548//
549//
558template<typename S, Index M = 2>
559class StyblinskiTang : public Function_Base<StyblinskiTang<S, M>, S, M>
560{
561public:
562
567
571 static constexpr
572 char const * const
573 NAME{"Styblinski-Tang"};
574
579
580 // Default value.
584 template<typename T, Index N>
585 T
587 {
588 return Base::value(*this, x);
589 }
590
591 // Explicit gradient.
595 template<typename T, Index N>
597 gradient(Vector<T, N> const & x) const
598 {
599 Index const
600 dimension = x.get_dimension();
601
602 assert(dimension == Base::DIMENSION);
603
605 r(dimension);
606
607 r(0) = 2.0 * x(0) * x(0) * x(0) - 16.0 * x(0) + 2.5;
608 r(1) = 2.0 * x(1) * x(1) * x(1) - 16.0 * x(1) + 2.5;
609
610 return r;
611 }
612
613 // Default AD hessian.
617 template<typename T, Index N>
620 {
621 return Base::hessian(*this, x);
622 }
623
624};
625
626//
627// Define some nonlinear functions (NLF) to test nonlinear optimization methods.
628//
629
630//
631// Paraboloid of revolution
632//
638template<typename S, Index M = 2>
639class Paraboloid : public Function_Base<Paraboloid<S, M>, S, M>
640{
641public:
642
648 Paraboloid(S xc = 0.0, S yc = 0.0) : xc_(xc), yc_(yc)
649 {
650 }
651
655 static constexpr
656 char const * const
657 NAME{"Paraboloid"};
658
663
664 // Explicit value.
668 template<typename T, Index N>
669 T
671 {
672 assert(x.get_dimension() == Base::DIMENSION);
673
674 T const
675 a = x(0) - xc_;
676
677 T const
678 b = x(1) - yc_;
679
680 T const
681 f = a * a + b * b;
682
683 return f;
684 }
685
686 // Default AD gradient.
690 template<typename T, Index N>
693 {
694 return Base::gradient(*this, x);
695 }
696
697 // Default AD hessian.
701 template<typename T, Index N>
704 {
705 return Base::hessian(*this, x);
706 }
707
708private:
712 S
713 xc_{0.0};
714
718 S
719 yc_{0.0};
720};
721
722//
723//
724//
731template<typename S, Index M = 2>
732class Rosenbrock : public Function_Base<Rosenbrock<S, M>, S, M>
733{
734public:
735
742 Rosenbrock(S a = 1.0, S b = 100.0) : a_(a), b_(b)
743 {
744 }
745
749 static constexpr
750 char const * const
751 NAME{"Rosenbrock's Function 2D"};
752
757
758 // Explicit value.
762 template<typename T, Index N>
763 T
765 {
766 T const
767 a = (a_ - x(0));
768
769 T const
770 b = (x(1) - x(0) * x(0));
771
772 return a * a + b_ * b * b;
773 }
774
775 // Default AD gradient.
779 template<typename T, Index N>
782 {
783 return Base::gradient(*this, x);
784 }
785
786 // Default AD hessian.
790 template<typename T, Index N>
793 {
794 return Base::hessian(*this, x);
795 }
796
797private:
801 S
802 a_{1.0};
803
807 S
808 b_{100.0};
809};
810
811//
812// Beale's function
813//
819template<typename S, Index M = 2>
820class Beale : public Function_Base<Beale<S, M>, S, M>
821{
822public:
823
827 Beale() {}
828
832 static constexpr
833 char const * const
834 NAME{"Beale"};
835
840
841 // Explicit value.
845 template<typename T, Index N>
846 T
848 {
849 assert(X.get_dimension() == Base::DIMENSION);
850
851 T const &
852 x = X(0);
853
854 T const &
855 y = X(1);
856
857 T const
858 a = 1.5 - x + x * y;
859
860 T const
861 b = 2.25 - x + x * y * y;
862
863 T const
864 c = 2.625 - x + x * y * y * y;
865
866 T const
867 f = a * a + b * b + c * c;
868
869 return f;
870 }
871
872 // Default AD gradient.
876 template<typename T, Index N>
879 {
880 return Base::gradient(*this, x);
881 }
882
883 // Default AD hessian.
887 template<typename T, Index N>
890 {
891 return Base::hessian(*this, x);
892 }
893
894};
895
896//
897// Booth's function
898//
904template<typename S, Index M = 2>
905class Booth : public Function_Base<Booth<S, M>, S, M>
906{
907public:
908
912 Booth() {}
913
917 static constexpr
918 char const * const
919 NAME{"Booth"};
920
925
926 // Explicit value.
930 template<typename T, Index N>
931 T
933 {
934 assert(X.get_dimension() == Base::DIMENSION);
935
936 T const &
937 x = X(0);
938
939 T const &
940 y = X(1);
941
942 T const
943 a = x + 2 * y - 7;
944
945 T const
946 b = 2 * x + y - 5;
947
948 T const
949 f = a * a + b * b;
950
951 return f;
952 }
953
954 // Default AD gradient.
958 template<typename T, Index N>
961 {
962 return Base::gradient(*this, x);
963 }
964
965 // Default AD hessian.
969 template<typename T, Index N>
972 {
973 return Base::hessian(*this, x);
974 }
975
976};
977
978//
979// Goldstein-Price function
980//
988template<typename S, Index M = 2>
989class GoldsteinPrice : public Function_Base<GoldsteinPrice<S, M>, S, M>
990{
991public:
992
997
1001 static constexpr
1002 char const * const
1003 NAME{"Goldstein-Price"};
1004
1009
1010 // Explicit value.
1014 template<typename T, Index N>
1015 T
1017 {
1018 assert(X.get_dimension() == Base::DIMENSION);
1019
1020 T const &
1021 x = X(0);
1022
1023 T const &
1024 y = X(1);
1025
1026 T const
1027 a = x + y + 1;
1028
1029 T const
1030 b = 19 - 14 * x + 3 * x * x - 14 * y + 6 * x * y + 3 * y * y;
1031
1032 T const
1033 c = 2 * x - 3 * y;
1034
1035 T const
1036 d = 18 - 32 * x + 12 * x * x + 48 * y - 36 * x * y + 27 * y * y;
1037
1038 T const
1039 e = 1 + a * a * b;
1040
1041 T const
1042 f = 30 + c * c * d;
1043
1044 T const
1045 fn = e * f;
1046
1047 return fn;
1048 }
1049
1050 // Default AD gradient.
1054 template<typename T, Index N>
1057 {
1058 return Base::gradient(*this, x);
1059 }
1060
1061 // Default AD hessian.
1065 template<typename T, Index N>
1068 {
1069 return Base::hessian(*this, x);
1070 }
1071
1072};
1073
1074//
1075// Failure function to test failed mechanism
1076//
1082template<typename S, Index M = 1>
1083class Failure : public Function_Base<Failure<S, M>, S, M>
1084{
1085public:
1086
1091
1095 static constexpr
1096 char const * const
1097 NAME{"Failure"};
1098
1103
1104 // Explicit value.
1109 template<typename T, Index N>
1110 T
1112 {
1113 // Set the flag to signal that an unrecoverable error happened.
1114 this->set_failed("Testing failure mechanism");
1115
1116 T const
1117 fn = 0.0;
1118
1119 return fn;
1120 }
1121
1122 // Default AD gradient.
1126 template<typename T, Index N>
1129 {
1130 return Base::gradient(*this, x);
1131 }
1132
1133 // Default AD hessian.
1137 template<typename T, Index N>
1140 {
1141 return Base::hessian(*this, x);
1142 }
1143
1144};
1145
1146//
1147// Non-monotonic function to test monotonicity enforcement.
1148//
1155template<typename S, Index M = 1>
1156class Mesa : public Function_Base<Mesa<S, M>, S, M>
1157{
1158public:
1159
1163 Mesa() {}
1164
1168 static constexpr
1169 char const * const
1170 NAME{"Mesa"};
1171
1176
1177 // Explicit value.
1181 template<typename T, Index N>
1182 T
1184 {
1185 T const &
1186 x = X(0);
1187
1188 T
1189 y = x * x;
1190
1191 if (-1.0 <= x && x <= 1.0) {
1192 y = y + 100.0;
1193 }
1194
1195 return y;
1196 }
1197
1198 // Default AD gradient.
1202 template<typename T, Index N>
1205 {
1206 return Base::gradient(*this, x);
1207 }
1208
1209 // Default AD hessian.
1213 template<typename T, Index N>
1216 {
1217 return Base::hessian(*this, x);
1218 }
1219
1220};
1221
1222//
1223// Function to test boundedness or residual enforcement.
1224//
1231template<typename S, Index M = 1>
1232class Sigmoid : public Function_Base<Sigmoid<S, M>, S, M>
1233{
1234public:
1235
1240
1244 static constexpr
1245 char const * const
1246 NAME{"Sigmoid"};
1247
1252
1253 // Explicit value.
1257 template<typename T, Index N>
1258 T
1260 {
1261 T const &
1262 x = X(0);
1263
1264 T const
1265 x2 = x * x;
1266
1267 T const
1268 x4 = x2 * x2;
1269
1270 T const
1271 x8 = x4 * x4;
1272
1273 T const
1274 x16 = x8 * x8;
1275
1276 T const
1277 x32 = x16 * x16;
1278
1279 T
1280 y = x * x32;
1281
1282 return y;
1283 }
1284
1285 // Default AD gradient.
1289 template<typename T, Index N>
1292 {
1293 return Base::gradient(*this, x);
1294 }
1295
1296 // Default AD hessian.
1300 template<typename T, Index N>
1303 {
1304 return Base::hessian(*this, x);
1305 }
1306
1307};
1308
1309//
1310// Functions to test constraint interface.
1311//
1312
1313//
1314// Identity
1315//
1320template<typename S, Index NC, Index NV>
1321class Identity : public Equality_Constraint<Identity<S, NC, NV>, S, NC, NV>
1322{
1323public:
1324
1329
1333 static constexpr
1334 char const * const
1335 NAME{"Identity Map"};
1336
1341
1342 // Explicit value.
1346 template<typename T, Index N>
1349 {
1350 assert(x.get_dimension() == NV);
1351 return x;
1352 }
1353
1354 // Default AD gradient.
1358 template<typename T, Index N>
1361 {
1362 return Base::gradient(*this, x);
1363 }
1364};
1365
1366//
1367// A nonlinear function
1368//
1375template<typename S, Index NC = 3, Index NV = 5>
1376class Nonlinear01 : public Equality_Constraint<Nonlinear01<S, NC, NV>, S, NC, NV>
1377{
1378public:
1379
1384
1388 static constexpr
1389 char const * const
1390 NAME{"Nonlinear 01"};
1391
1396
1397 // Explicit value.
1401 template<typename T, Index N = 5>
1404 {
1405 assert(x.get_dimension() == NV);
1406
1408 c(Filler::ZEROS);
1409
1410 c(0) = dot(x, x) - 10.0;
1411
1412 c(1) = x(1) * x(2) - 5.0 * x(3) * x(4);
1413
1414 c(2) = x(0) * x(0) * x(0) + x(1) * x(1) * x(1) + 1.0;
1415
1416 return c;
1417 }
1418
1419 // Default AD gradient.
1423 template<typename T, Index N = 5>
1426 {
1427 return Base::gradient(*this, x);
1428 }
1429};
1430
1431//
1432// Circumference feasible region
1433//
1440template<typename S, Index NC = 1, Index NV = 2>
1441class Circumference : public Equality_Constraint<Circumference<S, NC, NV>, S, NC, NV>
1442{
1443public:
1444
1451 Circumference(S const r, S const xc = S(0.0), S const yc = S(0.0)) : r_(r)
1452 {
1453 c_(0) = xc;
1454 c_(1) = yc;
1455 }
1456
1460 static constexpr
1461 char const * const
1462 NAME{"Circumference"};
1463
1468
1469 // Explicit value.
1473 template<typename T, Index N = 2>
1476 {
1477 assert(x.get_dimension() == NV);
1478
1480 f(Filler::ZEROS);
1481
1482 f(0) = r_ * r_ - norm_square(x - c_);
1483
1484 return f;
1485 }
1486
1487 // Default AD gradient.
1491 template<typename T, Index N = 2>
1494 {
1495 return Base::gradient(*this, x);
1496 }
1497
1498private:
1502 S
1503 r_{0.0};
1504
1510};
1511
1512//
1513// Circle feasible region
1514//
1521template<typename S, Index NC = 1, Index NV = 2>
1522class Circle : public Inequality_Constraint<Circle<S, NC, NV>, S, NC, NV>
1523{
1524public:
1525
1532 Circle(S const r, S const xc = S(0.0), S const yc = S(0.0)) : r_(r)
1533 {
1534 c_(0) = xc;
1535 c_(1) = yc;
1536 }
1537
1541 static constexpr
1542 char const * const
1543 NAME{"Circle constraint"};
1544
1549
1550 // Explicit value.
1554 template<typename T, Index N = 2>
1557 {
1558 assert(x.get_dimension() == NV);
1559
1561 f(Filler::ZEROS);
1562
1563 f(0) = r_ * r_ - norm_square(x - c_);
1564
1565 return f;
1566 }
1567
1568 // Default AD gradient.
1572 template<typename T, Index N = 2>
1575 {
1576 return Base::gradient(*this, x);
1577 }
1578
1579private:
1583 S
1584 r_{0.0};
1585
1591};
1592
1594} // namespace minitensor
1595
1596#endif // MiniTensor_TestFunctions_h
Tensor< T, N > hessian(Vector< T, N > const &x)
static constexpr char const *const NAME
T value(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x) const
T value(Vector< T, N > const &X)
Vector< T, N > gradient(Vector< T, N > const &x)
Tensor< T, N > hessian(Vector< T, N > const &x)
static constexpr char const *const NAME
Vector< T, N > gradient(Vector< T, N > const &x)
static constexpr char const *const NAME
T value(Vector< T, N > const &X)
Tensor< T, N > hessian(Vector< T, N > const &x)
Matrix< T, NC, NV > gradient(Vector< T, N > const &x)
Circle(S const r, S const xc=S(0.0), S const yc=S(0.0))
static constexpr char const *const NAME
Vector< T, NC > value(Vector< T, N > const &x)
Matrix< T, NC, NV > gradient(Vector< T, N > const &x)
Circumference(S const r, S const xc=S(0.0), S const yc=S(0.0))
Vector< T, NC > value(Vector< T, N > const &x)
static constexpr char const *const NAME
Tensor< T, N > hessian(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x)
T value(Vector< T, N > const &X)
static constexpr char const *const NAME
static constexpr char const *const NAME
Tensor< T, N > hessian(Vector< T, N > const &x)
Gaussian(S const a, S const b, S const c)
T value(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x) const
T value(Vector< T, N > const &X)
Tensor< T, N > hessian(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x)
static constexpr char const *const NAME
static constexpr char const *const NAME
Vector< T, NC > value(Vector< T, N > const &x)
Matrix< T, NC, NV > gradient(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x) const
static constexpr char const *const NAME
Tensor< T, N > hessian(Vector< T, N > const &x)
T value(Vector< T, N > const &x)
static constexpr char const *const NAME
Tensor< T, N > hessian(Vector< T, N > const &x)
T value(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x) const
T value(Vector< T, N > const &X)
static constexpr char const *const NAME
Tensor< T, N > hessian(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x)
Vector< T, NC > value(Vector< T, N > const &x)
Matrix< T, NC, NV > gradient(Vector< T, N > const &x)
static constexpr char const *const NAME
T value(Vector< T, N > const &x)
static constexpr char const *const NAME
Tensor< T, N > hessian(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x)
Quadratic(S const a, S const b, S const c)
T value(Vector< T, N > const &x)
static constexpr char const *const NAME
Vector< T, N > gradient(Vector< T, N > const &x) const
Tensor< T, N > hessian(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x)
T value(Vector< T, N > const &x)
Tensor< T, N > hessian(Vector< T, N > const &x)
static constexpr char const *const NAME
Tensor< T, N > hessian(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x)
T value(Vector< T, N > const &X)
static constexpr char const *const NAME
static constexpr char const *const NAME
Tensor< T, N > hessian(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x) const
T value(Vector< T, N > const &x)
T value(Vector< T, N > const &x)
Vector< T, N > gradient(Vector< T, N > const &x) const
Tensor< T, N > hessian(Vector< T, N > const &x)
static constexpr char const *const NAME
KOKKOS_INLINE_FUNCTION Index get_dimension() const
KOKKOS_INLINE_FUNCTION Vector< typename Promote< S, T >::type, M > dot(Matrix< T, M, N > const &A, Vector< S, N > const &u)
KOKKOS_INLINE_FUNCTION T norm_square(Vector< T, N > const &u)
Vector< T, N > gradient(FunctionDerived &f, Vector< T, N > const &x)
Tensor< T, N > hessian(FunctionDerived &f, Vector< T, N > const &x)
T value(FunctionDerived &f, Vector< T, N > const &x)
void set_failed(char const *const msg=nullptr)
Matrix< T, NC, NV > gradient(Identity< S, NC, NV > &c, Vector< T, N > const &x)
static constexpr Index DIMENSION
uint32_t Index
Indexing type.