1#ifndef __FUNCTIONEXPRESSION_HH__
2#define __FUNCTIONEXPRESSION_HH__
4#include "../expressions/expressionoperations.hh"
20 template<
class Operation>
21 struct FunctionExpressionOperation
24 template<
class Operation>
25 struct UnaryFunctionExpressionOperation
26 :
public FunctionExpressionOperation<Operation>
29 template<
class Operation>
30 struct BinaryFunctionExpressionOperation
31 :
public FunctionExpressionOperation<Operation>
35 struct BinaryFunctionExpressionOperation<PlusOperation>
36 :
public FunctionExpressionOperation<PlusOperation>
38 template<
class LeftFunctionType,
class RightFunctionType,
39 class PointType,
class RangeType>
40 static void evaluate (
const LeftFunctionType& f,
const RightFunctionType& g,
41 const PointType &x, RangeType &ret)
53 template<
class LeftFunctionType,
54 class RightFunctionType,
55 class PointType,
class JacobianRangeType,
56 class LeftPWConst = std::false_type,
57 class RightPWConst = std::false_type>
58 static void jacobian (
const LeftFunctionType& f,
const RightFunctionType& g,
59 const PointType &x, JacobianRangeType &ret,
60 const LeftPWConst& fConst = LeftPWConst(),
61 const RightPWConst& gConst = RightPWConst())
73 JacobianRangeType tmp;
81 template<
class LeftFunctionType,
class RightFunctionType,
82 class PointType,
class HessianRangeType,
83 class LeftPWConst = std::false_type,
84 class RightPWConst = std::false_type>
85 static void hessian (
const LeftFunctionType& f,
const RightFunctionType& g,
86 const PointType &x, HessianRangeType &ret,
87 const LeftPWConst& fConst = LeftPWConst(),
88 const RightPWConst& gConst = RightPWConst())
100 HessianRangeType tmp;
106 for (
int i = 0; i < HessianRangeType::dimension; ++i) {
114 struct BinaryFunctionExpressionOperation<MinusOperation>
115 :
public FunctionExpressionOperation<MinusOperation>
117 template<
class LeftFunctionType,
class RightFunctionType,
class Po
intType,
class RangeType>
118 static void evaluate(
const LeftFunctionType& f,
const RightFunctionType& g,
const PointType &x, RangeType &ret)
130 template<
class LeftFunctionType,
131 class RightFunctionType,
132 class PointType,
class JacobianRangeType,
133 class LeftPWConst = std::false_type,
134 class RightPWConst = std::false_type>
135 static void jacobian(
const LeftFunctionType& f,
const RightFunctionType& g,
136 const PointType &x, JacobianRangeType &ret,
137 const LeftPWConst& fConst = LeftPWConst(),
138 const RightPWConst& gConst = RightPWConst())
151 JacobianRangeType tmp;
159 template<
class LeftFunctionType,
class RightFunctionType,
160 class PointType,
class HessianRangeType,
161 class LeftPWConst = std::false_type,
162 class RightPWConst = std::false_type>
163 static void hessian(
const LeftFunctionType& f,
const RightFunctionType& g,
164 const PointType &x, HessianRangeType &ret,
165 const LeftPWConst& fConst = LeftPWConst(),
166 const RightPWConst& gConst = RightPWConst())
178 HessianRangeType tmp;
184 for (
int i = 0; i < HessianRangeType::dimension; ++i) {
194 :
public FunctionExpressionOperation<MultiplyOperation>
197 template<
class Result,
class Matrix,
class Factor,
int numRows,
int dimFactor>
201 static void evaluate(Result& res,
const Matrix& val,
const Factor& factor)
203 static_assert(Result::rows == 1,
204 "Wrong result type for jacobian of multiplication");
207 val.mtv(factor, res[0]);
212 template<
class Result,
class Matrix,
class Factor,
int numRows>
213 struct MulEqHelper<Result, Matrix, Factor, numRows, 1>
215 static void evaluate(Result& res,
const Matrix& val,
const Factor& factor)
223 template<
class Result,
class Matrix,
class Factor,
int dimFactor>
224 struct MulEqHelper<Result, Matrix, Factor, 1, dimFactor>
226 static void evaluate(Result& res,
const Matrix& val,
const Factor& factor)
228 for (
int i = 0; i < dimFactor; ++i) {
229 for (
int j = 0; j < Matrix::cols; ++j) {
230 res[i][j] = val[0][j] * factor[i];
238 template<
class Result,
class Matrix,
class Factor>
239 struct MulEqHelper<Result, Matrix, Factor, 1, 1>
241 static void evaluate(Result& res,
const Matrix& val,
const Factor& factor)
248 template<
class Result,
class Matrix,
class Factor>
249 static void callMulEq(Result& res,
const Matrix& val,
const Factor& factor)
252 MulEqHelper<Result, Matrix, Factor, Matrix::rows, Factor::dimension>::evaluate(res, val, factor);
255 template<
class Left,
class Right,
class Point,
class Result,
256 unsigned dimF,
unsigned dimG,
unsigned dimResult>
257 struct MulEvalHelper;
260 template<
class Left,
class Right,
class Po
int,
class Result,
unsigned dimArg>
261 struct MulEvalHelper<Left, Right, Point, Result, dimArg, dimArg, 1>
263 static void evaluate(
const Left &f,
const Right& g,
const Point& x, Result& res)
265 typename Left::RangeType fval;
266 typename Right::RangeType gval;
276 template<
class Left,
class Right,
class Po
int,
class Result,
unsigned dimResult>
277 struct MulEvalHelper<Left, Right, Point, Result, 1, dimResult, dimResult>
279 static void evaluate(
const Left &f,
const Right& g,
const Point& x, Result& res)
281 typename Left::RangeType fval;
291 template<
class Left,
class Right,
class Po
int,
class Result,
unsigned dimResult>
292 struct MulEvalHelper<Left, Right, Point, Result, dimResult, 1, dimResult>
294 static void evaluate(
const Left &f,
const Right& g,
const Point& x, Result& res)
296 typename Right::RangeType gval;
306 template<
class Left,
class Right,
class Po
int,
class Result>
307 struct MulEvalHelper<Left, Right, Point, Result, 1, 1, 1>
309 static void evaluate(
const Left &f,
const Right& g,
const Point& x, Result& res)
311 typename Right::RangeType gval;
320 template<
class Left,
class Right,
class Po
int,
class Result>
321 static void callMulEval(
const Left& f,
const Right& g,
const Point& x, Result& res)
324 leftDimRange = Left::FunctionSpaceType::dimRange,
325 rightDimRange = Right::FunctionSpaceType::dimRange,
328 MulEvalHelper<Left, Right, Point, Result, leftDimRange, rightDimRange, Result::dimension>
331 HelperType::evaluate(f, g, x, res);
334 template<
class ResultType,
class LeftType,
class RightType,
unsigned LeftDim,
unsigned RightDim>
337 static void evaluate(ResultType& result,
const LeftType& hessian,
const RightType& value)
343 template<
class TensorType,
class ScalarType,
unsigned OuterDim>
344 struct HessianHelper<TensorType, TensorType, ScalarType, OuterDim, 1>
346 static void evaluate(TensorType& result,
const TensorType& hessian,
const ScalarType& value)
349 for (
int k = 0; k < TensorType::dimension; ++k) {
355 template<
class Left,
class Right,
class Result>
356 static void callHessianHelper(Result& result,
const Left& left,
const Right& right)
359 leftDim = Left::dimension,
360 rightDim = Right::dimension
362 HessianHelper<Result, Left, Right, leftDim, rightDim>::evaluate(result, left, right);
365 template<
class LeftFunctionType,
class RightFunctionType,
class Po
intType,
class RangeType>
366 static void evaluate(
const LeftFunctionType& f,
const RightFunctionType& g,
const PointType &x, RangeType &res)
368 callMulEval(f, g, x, res);
371 template<
class LeftFunctionType,
class RightFunctionType,
372 class PointType,
class JacobianRangeType,
373 class LeftPWConst = std::false_type,
374 class RightPWConst = std::false_type>
375 static void jacobian(
const LeftFunctionType& f,
const RightFunctionType& g,
376 const PointType &x, JacobianRangeType &ret,
377 const LeftPWConst& fConst = LeftPWConst(),
378 const RightPWConst& gConst = RightPWConst())
380 typename LeftFunctionType::RangeType fval;
381 typename RightFunctionType::RangeType gval;
383 typename LeftFunctionType::JacobianRangeType fjac;
384 typename RightFunctionType::JacobianRangeType gjac;
389 callMulEq(ret, gjac, fval);
396 callMulEq(ret, fjac, gval);
406 callMulEq(ret, fjac, gval);
407 JacobianRangeType tmp;
408 callMulEq(tmp, gjac, fval);
412 template<
class LeftFunctionType,
class RightFunctionType,
413 class PointType,
class HessianRangeType,
414 class LeftPWConst = std::false_type,
415 class RightPWConst = std::false_type>
416 static void hessian(
const LeftFunctionType& f,
const RightFunctionType& g,
417 const PointType &x, HessianRangeType &ret,
418 const LeftPWConst& fConst = LeftPWConst(),
419 const RightPWConst& gConst = RightPWConst())
421 const int dimDomain = LeftFunctionType::DomainType::dimension;
423 typename LeftFunctionType::RangeType fval;
424 typename RightFunctionType::RangeType gval;
429 typename LeftFunctionType::JacobianRangeType fjac;
430 typename RightFunctionType::JacobianRangeType gjac;
435 typename LeftFunctionType::HessianRangeType fhes;
436 typename RightFunctionType::HessianRangeType ghes;
441 if (LeftFunctionType::RangeType::dimension == 1) {
442 callHessianHelper(ret, ghes, fval);
446 for (
int k = 0; k < RightFunctionType::RangeType::dimension; ++k) {
447 for (
int i = 0; i < dimDomain; ++i) {
448 for (
int j = 0; j < dimDomain; ++j) {
449 ret[k][i][j] += fjac[0][i]*gjac[k][j] + fjac[0][j] * gjac[k][i];
450 ret[k][i][j] += fhes[0][i][j] * gval[k];
454 }
else if (RightFunctionType::RangeType::dimension == 1) {
455 callHessianHelper(ret, fhes, gval);
459 for (
int k = 0; k < LeftFunctionType::RangeType::dimension; ++k) {
460 for (
int i = 0; i < dimDomain; ++i) {
461 for (
int j = 0; j < dimDomain; ++j) {
462 ret[k][i][j] += gjac[0][i]*fjac[k][j] + gjac[0][j]*fjac[k][i];
463 ret[k][i][j] += ghes[0][i][j] * fval[k];
470 const unsigned dimDomain = LeftFunctionType::DomainType::dimension;
471 const unsigned dimRange = LeftFunctionType::RangeType::dimension;
474 for (
unsigned alpha = 0; alpha < dimRange; ++alpha) {
476 ghes[alpha] *= fval[alpha];
477 ret[0] += ghes[alpha];
480 fhes[alpha] *= gval[alpha];
481 ret[0] += fhes[alpha];
484 if (fConst || gConst) {
488 for (
unsigned j = 0; j < dimDomain; ++j) {
489 ret[0][j][j] += 2.0 * fjac[alpha][j] * gjac[alpha][j];
490 for (
unsigned k = j+1; k < dimDomain; ++k) {
491 typename LeftFunctionType::RangeFieldType tmp;
492 tmp = fjac[alpha][j]*gjac[alpha][k] + fjac[alpha][k]*gjac[alpha][j];
505 :
public FunctionExpressionOperation<InvertOperation>
507 template<
class FunctionType,
class Po
intType,
class RangeType>
508 static void evaluate (
const FunctionType& f,
const PointType &x, RangeType &ret)
510 static_assert(FunctionType::RangeType::dimension == 1,
511 "Operand must be scalar for inversion");
517 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
518 static void jacobian (
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
520 static_assert(FunctionType::RangeType::dimension == 1,
521 "Operand must be scalar for inversion");
523 typename FunctionType::RangeType fval;
528 ret /= - fval * fval;
531 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
532 static void hessian(
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
534 static_assert(FunctionType::RangeType::dimension == 1,
"Operand must be scalar for division");
536 typename FunctionType::RangeType fval;
538 typename FunctionType::RangeFieldType factor;
539 factor = fval * fval;
541 typename FunctionType::JacobianRangeType fjac;
549 for (
int i = 0; i < FunctionType::DomainType::dimension; ++i) {
550 ret[0][i][i] += 2.0 * fjac[0][i] * fjac[0][i] / factor;
551 for (
int j = i+1; j < FunctionType::DomainType::dimension; ++j) {
552 typename FunctionType::RangeFieldType tmp;
554 tmp = 2.0 * fjac[0][i] * fjac[0][j] / factor;
566 :
public FunctionExpressionOperation<SMultiplyOperation>
568 template<
class RangeFieldType,
class FunctionType,
class Po
intType,
class RangeType>
569 static void evaluate (
const RangeFieldType& s,
const FunctionType& f,
const PointType &x, RangeType &ret)
576 template<
class RangeFieldType,
class FunctionType,
class Po
intType,
class JacobianRangeType>
577 static void jacobian (
const RangeFieldType& s,
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
584 template<
class RangeFieldType,
class FunctionType,
class Po
intType,
class HessianRangeType>
585 static void hessian (
const RangeFieldType& s,
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
596 :
public FunctionExpressionOperation<IdentityOperation>
598 template<
class FunctionType,
class Po
intType,
class RangeType>
599 static void evaluate (
const FunctionType& f,
const PointType &x, RangeType &ret)
604 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
605 static void jacobian (
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
610 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
611 static void hessian (
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
620 struct UnaryFunctionExpressionOperation<MinusOperation>
621 :
public FunctionExpressionOperation<MinusOperation>
623 template<
class FunctionType,
class Po
intType,
class RangeType>
624 static void evaluate (
const FunctionType& f,
const PointType &x, RangeType &ret)
630 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
631 static void jacobian (
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
637 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
638 static void hessian (
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
641 for (
int k = 0; k < HessianRangeType::dimension; ++k) {
652 struct UnaryFunctionExpressionOperation<ExpOperation>
653 :
public FunctionExpressionOperation<ExpOperation>
655 typedef UnaryFunctionExpressionOperation<ExpOperation> ThisType;
657 template<
class FunctionType,
class Po
intType,
class RangeType>
658 static void evaluate (
const FunctionType& f,
const PointType &x, RangeType &ret)
661 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
662 ret[i] = exp(ret[i]);
666 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
667 static void jacobian (
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
669 typename FunctionType::RangeType val;
670 ThisType::evaluate(f, x, val);
673 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
678 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
679 static void hessian (
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
681 typename FunctionType::RangeType val;
682 ThisType::evaluate(f, x, val);
684 typename FunctionType::JacobianRangeType fjac;
688 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
689 for (
int i = 0; i < FunctionType::DomainType::dimension; ++i) {
690 ret[k][i][i] += fjac[k][i] * fjac[k][i];
691 for (
int j = i+1; j < FunctionType::DomainType::dimension; ++j) {
692 typename FunctionType::RangeFieldType tmp;
693 tmp = fjac[k][i] * fjac[k][j];
704 struct UnaryFunctionExpressionOperation<LogOperation>
705 :
public FunctionExpressionOperation<LogOperation>
707 typedef UnaryFunctionExpressionOperation<LogOperation> ThisType;
709 template<
class FunctionType,
class Po
intType,
class RangeType>
710 static void evaluate (
const FunctionType& f,
const PointType &x, RangeType &ret)
713 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
714 ret[i] =
log(ret[i]);
718 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
719 static void jacobian (
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
721 typename FunctionType::RangeType fval;
725 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
730 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
731 static void hessian (
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
733 typename FunctionType::RangeType fval;
736 typename FunctionType::JacobianRangeType fjac;
740 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
741 for (
int i = 0; i < FunctionType::DomainType::dimension; ++i) {
742 ret[k][i][i] -= fjac[k][i] * fjac[k][i] / fval[k];
743 for (
int j = i+1; j < FunctionType::DomainType::dimension; ++j) {
744 typename FunctionType::RangeFieldType tmp;
745 tmp = fjac[k][i] * fjac[k][j] / fval[k];
756 struct UnaryFunctionExpressionOperation<SqrtOperation>
757 :
public FunctionExpressionOperation<SqrtOperation>
759 typedef UnaryFunctionExpressionOperation<SqrtOperation> ThisType;
761 template<
class FunctionType,
class Po
intType,
class RangeType>
762 static void evaluate (
const FunctionType& f,
const PointType &x, RangeType &ret)
765 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
766 ret[i] = sqrt(ret[i]);
770 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
771 static void jacobian (
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
773 typename FunctionType::RangeType val;
774 ThisType::evaluate(f, x, val);
777 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
778 ret[i] /= 2.0*val[i];
782 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
783 static void hessian (
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
785 typename FunctionType::RangeType fval;
788 typename FunctionType::JacobianRangeType fjac;
792 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
793 for (
int i = 0; i < FunctionType::DomainType::dimension; ++i) {
794 ret[k][i][i] -= fjac[k][i] * fjac[k][i] / 2.0 / fval[k];
795 for (
int j = i+1; j < FunctionType::DomainType::dimension; ++j) {
796 typename FunctionType::RangeFieldType tmp;
797 tmp = fjac[k][i] * fjac[k][j] / 2.0 / fval[k];
802 ret[k] /= 2.0 / sqrt(fval[k]);
808 struct UnaryFunctionExpressionOperation<SquareOperation>
809 :
public FunctionExpressionOperation<SquareOperation>
811 typedef UnaryFunctionExpressionOperation<SquareOperation> ThisType;
813 template<
class FunctionType,
class Po
intType,
class RangeType>
814 static void evaluate (
const FunctionType& f,
const PointType &x, RangeType &ret)
816 typename FunctionType::RangeType tmp;
822 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
823 static void jacobian (
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
825 typename FunctionType::RangeType fval;
829 typename FunctionType::JacobianRangeType fjac;
832 fjac.mtv(fval, ret[0]);
835 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
836 static void hessian(
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
838 typename FunctionType::RangeType fval;
841 typename FunctionType::JacobianRangeType fjac;
844 typename FunctionType::HessianRangeType fhes;
848 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
849 for (
int i = 0; i < FunctionType::DomainType::dimension; ++i) {
850 ret[0][i][i] += 2.0 * (fjac[k][i] * fjac[k][i] + fval[k] * fhes[k][i][i]);
851 for (
int j = i+1; j < FunctionType::DomainType::dimension; ++j) {
852 typename FunctionType::RangeFieldType tmp;
853 tmp = 2.0 * (fjac[k][i]*fjac[k][j] + fval[k] * fhes[k][i][j]);
863 struct UnaryFunctionExpressionOperation<SinOperation>
864 :
public FunctionExpressionOperation<SinOperation>
866 typedef UnaryFunctionExpressionOperation<SinOperation> ThisType;
868 template<
class FunctionType,
class Po
intType,
class RangeType>
869 static void evaluate (
const FunctionType& f,
const PointType &x, RangeType &ret)
872 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
873 ret[i] = std::sin(ret[i]);
877 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
878 static void jacobian (
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
880 typename FunctionType::RangeType fval;
884 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
885 ret[k] *= std::cos(fval[k]);
889 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
890 static void hessian(
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
892 typename FunctionType::RangeType fval;
895 typename FunctionType::JacobianRangeType fjac;
899 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
900 typename FunctionType::RangeFieldType cosval, sinval;
901 cosval = std::cos(fval[k]);
902 sinval = std::sin(fval[k]);
904 for (
int i = 0; i < FunctionType::DomainType::dimension; ++i) {
905 ret[k][i][i] -= fjac[k][i] * fjac[k][i] * sinval;
906 for (
int j = i+1; j < FunctionType::DomainType::dimension; ++j) {
907 typename FunctionType::RangeFieldType tmp;
908 tmp = fjac[k][i] * fjac[k][j] * sinval;
918 struct UnaryFunctionExpressionOperation<CosOperation>
919 :
public FunctionExpressionOperation<CosOperation>
921 typedef UnaryFunctionExpressionOperation<CosOperation> ThisType;
923 template<
class FunctionType,
class Po
intType,
class RangeType>
924 static void evaluate (
const FunctionType& f,
const PointType &x, RangeType &ret)
927 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
928 ret[i] = std::cos(ret[i]);
932 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
933 static void jacobian (
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
935 typename FunctionType::RangeType fval;
939 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
940 ret[k] *= -std::sin(fval[k]);
944 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
945 static void hessian (
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
947 typename FunctionType::RangeType fval;
950 typename FunctionType::JacobianRangeType fjac;
954 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
955 typename FunctionType::RangeFieldType cosval, sinval;
956 cosval = std::cos(fval[k]);
957 sinval = std::sin(fval[k]);
959 for (
int i = 0; i < FunctionType::DomainType::dimension; ++i) {
960 ret[k][i][i] += fjac[k][i] * fjac[k][i] * cosval;
961 for (
int j = i+1; j < FunctionType::DomainType::dimension; ++j) {
962 typename FunctionType::RangeFieldType tmp;
963 tmp = fjac[k][i] * fjac[k][j] * cosval;
973 struct UnaryFunctionExpressionOperation<TanOperation>
974 :
public FunctionExpressionOperation<TanOperation>
976 typedef UnaryFunctionExpressionOperation<TanOperation> ThisType;
978 template<
class FunctionType,
class Po
intType,
class RangeType>
979 static void evaluate(
const FunctionType& f,
const PointType &x, RangeType &ret)
982 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
983 ret[i] = tan(ret[i]);
987 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
988 static void jacobian(
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
990 typename FunctionType::RangeType fval;
994 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
997 ret[k] /= (std::cos(fval[k]) * std::cos(fval[k]));
1001 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
1002 static void hessian(
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
1004 typename FunctionType::RangeType fval;
1005 f.evaluate(x, fval);
1007 typename FunctionType::JacobianRangeType fjac;
1008 f.jacobian(x, fjac);
1011 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
1012 typename FunctionType::RangeFieldType D1, D2;
1013 D1 = 1.0 / (std::cos(fval[k]) * std::cos(fval[k]));
1014 D2 = 2.0 * D1 * tan(fval[k]);
1016 for (
int i = 0; i < FunctionType::DomainType::dimension; ++i) {
1017 ret[k][i][i] += fjac[k][i] * fjac[k][i] * D1;
1018 for (
int j = i+1; j < FunctionType::DomainType::dimension; ++j) {
1019 typename FunctionType::RangeFieldType tmp;
1020 tmp = fjac[k][i] * fjac[k][j] * D2;
1021 ret[k][i][j] += tmp;
1022 ret[k][j][i] += tmp;
1030 struct UnaryFunctionExpressionOperation<AtanOperation>
1031 :
public FunctionExpressionOperation<AtanOperation>
1033 typedef UnaryFunctionExpressionOperation<AtanOperation> ThisType;
1035 template<
class FunctionType,
class Po
intType,
class RangeType>
1036 static void evaluate(
const FunctionType& f,
const PointType &x, RangeType &ret)
1039 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
1040 ret[i] = atan(ret[i]);
1044 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
1045 static void jacobian(
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
1047 typename FunctionType::RangeType fval;
1048 f.evaluate(x, fval);
1051 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
1054 ret[k] /= fval[k] * fval[k] + 1.;
1058 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
1059 static void hessian(
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
1061 typename FunctionType::RangeType fval;
1062 f.evaluate(x, fval);
1064 typename FunctionType::JacobianRangeType fjac;
1065 f.jacobian(x, fjac);
1068 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
1069 typename FunctionType::RangeFieldType D1, D2;
1070 D1 = 1.0 / (fval[k] * fval[k] + 1.);
1071 D2 = -2. * fval[k] * D1 * D1;
1073 for (
int i = 0; i < FunctionType::DomainType::dimension; ++i) {
1074 ret[k][i][i] += fjac[k][i] * fjac[k][i] * D1;
1075 for (
int j = i+1; j < FunctionType::DomainType::dimension; ++j) {
1076 typename FunctionType::RangeFieldType tmp;
1077 tmp = fjac[k][i] * fjac[k][j] * D2;
1078 ret[k][i][j] += tmp;
1079 ret[k][j][i] += tmp;
1087 struct UnaryFunctionExpressionOperation<AsinOperation>
1088 :
public FunctionExpressionOperation<AsinOperation>
1090 typedef UnaryFunctionExpressionOperation<AsinOperation> ThisType;
1092 template<
class FunctionType,
class Po
intType,
class RangeType>
1093 static void evaluate(
const FunctionType& f,
const PointType &x, RangeType &ret)
1096 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
1097 ret[i] = std::asin(ret[i]);
1101 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
1102 static void jacobian(
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
1104 typename FunctionType::RangeType fval;
1105 f.evaluate(x, fval);
1108 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
1111 ret[k] /= std::sqrt(1. - fval[k] * fval[k]);
1115 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
1116 static void hessian(
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
1118 typename FunctionType::RangeType fval;
1119 f.evaluate(x, fval);
1121 typename FunctionType::JacobianRangeType fjac;
1122 f.jacobian(x, fjac);
1125 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
1126 typename FunctionType::RangeFieldType D1, D2;
1127 D1 = 1.0 / std::sqrt(1. - fval[k] * fval[k]);
1128 D2 = fval[k] * D1 * D1 * D1;
1130 for (
int i = 0; i < FunctionType::DomainType::dimension; ++i) {
1131 ret[k][i][i] += fjac[k][i] * fjac[k][i] * D1;
1132 for (
int j = i+1; j < FunctionType::DomainType::dimension; ++j) {
1133 typename FunctionType::RangeFieldType tmp;
1134 tmp = fjac[k][i] * fjac[k][j] * D2;
1135 ret[k][i][j] += tmp;
1136 ret[k][j][i] += tmp;
1144 struct UnaryFunctionExpressionOperation<AcosOperation>
1145 :
public FunctionExpressionOperation<AcosOperation>
1147 typedef UnaryFunctionExpressionOperation<AcosOperation> ThisType;
1149 template<
class FunctionType,
class Po
intType,
class RangeType>
1150 static void evaluate(
const FunctionType& f,
const PointType &x, RangeType &ret)
1153 for (
int i = 0; i < FunctionType::RangeType::dimension; ++i) {
1154 ret[i] = std::acos(ret[i]);
1158 template<
class FunctionType,
class Po
intType,
class JacobianRangeType>
1159 static void jacobian(
const FunctionType& f,
const PointType &x, JacobianRangeType &ret)
1161 typename FunctionType::RangeType fval;
1162 f.evaluate(x, fval);
1165 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
1168 ret[k] /= -std::sqrt(1. - fval[k] * fval[k]);
1172 template<
class FunctionType,
class Po
intType,
class HessianRangeType>
1173 static void hessian(
const FunctionType& f,
const PointType &x, HessianRangeType &ret)
1175 typename FunctionType::RangeType fval;
1176 f.evaluate(x, fval);
1178 typename FunctionType::JacobianRangeType fjac;
1179 f.jacobian(x, fjac);
1182 for (
int k = 0; k < FunctionType::RangeType::dimension; ++k) {
1183 typename FunctionType::RangeFieldType D1, D2;
1184 D1 = -1.0 / std::sqrt(1. - fval[k] * fval[k]);
1185 D2 = fval[k] * D1 * D1 * D1;
1187 for (
int i = 0; i < FunctionType::DomainType::dimension; ++i) {
1188 ret[k][i][i] += fjac[k][i] * fjac[k][i] * D1;
1189 for (
int j = i+1; j < FunctionType::DomainType::dimension; ++j) {
1190 typename FunctionType::RangeFieldType tmp;
1191 tmp = fjac[k][i] * fjac[k][j] * D2;
1192 ret[k][i][j] += tmp;
1193 ret[k][j][i] += tmp;
static UnaryGridFunctionExpression< LogOperation, Function > log(const Fem::Function< typename Function::FunctionSpaceType, Function > &f_)
Component-wise logarithm, log(f)(x) = [log(f(x)_0),...,log(f(x)_N].
Definition: gridfunctionexpression.hh:2844
Identity, i.e. just wrap the object.
Definition: expressionoperations.hh:284
Inversion of an object.
Definition: expressionoperations.hh:275
Multiplication of two objects.
Definition: expressionoperations.hh:248
Multiplication by scalars from the left.
Definition: expressionoperations.hh:257