20 template<
typename X1,
typename X2>
21 static std::string str(
const X1& x1,
const X2& x2)
23 return x1->str(!x1->is_str_leaf()) +
"×" + x2->str(!x2->is_str_leaf());
26 template<
typename X1,
typename X2>
27 static std::pair<Index,Index> output_shape([[maybe_unused]]
const X1& s1, [[maybe_unused]]
const X2& s2)
32 static IntervalVector fwd(
const IntervalVector& x1,
const IntervalVector& x2);
33 static VectorType fwd_natural(
const VectorType& x1,
const VectorType& x2);
34 static VectorType fwd_centered(
const VectorType& x1,
const VectorType& x2);
35 static void bwd(
const IntervalVector& y, IntervalVector& x1, IntervalVector& x2);
42 cross_prod(
const VectorExpr& x1,
const VectorExpr& x2)
44 return { std::make_shared<AnalyticOperationExpr<CrossProdOp,VectorType,VectorType,VectorType>>(x1,x2) };
49 inline IntervalVector CrossProdOp::fwd(
const IntervalVector& x1,
const IntervalVector& x2)
51 assert_release(x1.size() == 3 && x2.size() == 3);
53 x1[1]*x2[2] - x1[2]*x2[1],
54 x1[2]*x2[0] - x1[0]*x2[2],
55 x1[0]*x2[1] - x1[1]*x2[0]
59 inline VectorType CrossProdOp::fwd_natural(
const VectorType& x1,
const VectorType& x2)
63 x1.def_domain && x2.def_domain
67 inline VectorType CrossProdOp::fwd_centered(
const VectorType& x1,
const VectorType& x2)
69 if(centered_form_not_available_for_args(x1,x2))
70 return fwd_natural(x1,x2);
72 assert(x1.da.cols() == x2.da.cols());
73 IntervalMatrix d(3,x1.da.cols());
74 for (Index i=0;i<x1.da.cols();i++) {
75 d(0,i) = x1.da(1,i)*x2.a[2] + x1.a[1]*x2.da(2,i)
76 - x1.da(2,i)*x2.a[1] - x1.a[2]*x2.da(1,i);
77 d(1,i) = x1.da(2,i)*x2.a[0] + x1.a[2]*x2.da(0,i)
78 - x1.da(0,i)*x2.a[2] - x1.a[0]*x2.da(2,i);
79 d(2,i) = x1.da(0,i)*x2.a[1] + x1.a[0]*x2.da(1,i)
80 - x1.da(1,i)*x2.a[0] - x1.a[1]*x2.da(0,i);
87 x1.def_domain && x2.def_domain
91 inline void CrossProdOp::bwd([[maybe_unused]]
const IntervalVector& y, [[maybe_unused]] IntervalVector& x1, [[maybe_unused]] IntervalVector& x2)
93 assert_release(y.size() == 3 && x1.size() == 3 && x2.size() == 3);