MCPcopy Create free account
hub / github.com/casadi/casadi / get_binary

Method get_binary

casadi/core/mx_node.cpp:788–841  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

786 }
787
788 MX MXNode::get_binary(casadi_int op, const MX& y) const {
789 // If-else-zero nodes are always simplified at top level to avoid NaN propagation
790 if (y.op() == OP_IF_ELSE_ZERO) {
791 if (op == OP_MUL) {
792 // (Rule 1.) x * if_else_zero(c, y), simplified to if_else_zero(c, x * y)
793 // Background: x is often a partial derivative and may evaluate to INF or NAN.
794 // The simplification ensures that the zero seed corresponding to an inactive branch does
795 // not give rise to any NaN contribution to the derivative due to NaN * 0 == NaN.
796 return if_else_zero(y.dep(0), shared_from_this<MX>() * y.dep(1));
797 } else if (op == OP_ADD && this->op() == OP_IF_ELSE_ZERO && MX::is_equal(dep(0), y.dep(0))) {
798 // (Rule 2.) if_else_zero(c, x) + if_else_zero(c, y) is simplified to if_else_zero(c, x + y)
799 // Background: During the backward propagation, seeds are added together. Without this rule,
800 // the addition node can prevent rule (1.) from working in subsequent steps.
801 return if_else_zero(y.dep(0), dep(1) + y.dep(1));
802 }
803 } else if (this->op() == OP_IF_ELSE_ZERO && op == OP_MUL) {
804 // Same as Rule 1. above, but with factors swapped. For symmetry.
805 return if_else_zero(dep(0), dep(1) * y);
806 }
807 // Create binary node
808 if (sparsity().is_scalar(false)) {
809 if (nnz()==0) {
810 if (operation_checker<F0XChecker>(op)) return MX::zeros(Sparsity(y.size()));
811 return to_matrix(MX(0)->_get_binary(op, y, true, false), y.sparsity());
812 } else {
813 return to_matrix(_get_binary(op, y, true, false), y.sparsity());
814 }
815 } else if (y.is_scalar()) {
816 if (y.nnz()==0) {
817 if (operation_checker<FX0Checker>(op)) return MX::zeros(Sparsity(size()));
818 return to_matrix(_get_binary(op, MX(0), false, true), sparsity());
819 } else {
820 return to_matrix(_get_binary(op, y, false, true), sparsity());
821 }
822 } else {
823 casadi_assert(sparsity().size() == y.sparsity().size(), "Dimension mismatch.");
824 if (sparsity()==y.sparsity()) {
825 // Matching sparsities
826 return _get_binary(op, y, false, false);
827 } else {
828 // Get the sparsity pattern of the result
829 // (ignoring structural zeros giving rise to nonzero result)
830 const Sparsity& x_sp = sparsity();
831 const Sparsity& y_sp = y.sparsity();
832 Sparsity r_sp = x_sp.combine(y_sp, operation_checker<F0XChecker>(op),
833 operation_checker<FX0Checker>(op));
834
835 // Project the arguments to this sparsity
836 MX xx = project(shared_from_this<MX>(), r_sp);
837 MX yy = project(y, r_sp);
838 return xx->_get_binary(op, yy, false, false);
839 }
840 }
841 }
842
843 MX MXNode::_get_binary(casadi_int op, const MX& y, bool scX, bool scY) const {
844 casadi_assert_dev(sparsity()==y.sparsity() || scX || scY);

Callers 1

binaryMethod · 0.80

Calls 15

if_else_zeroFunction · 0.85
to_matrixFunction · 0.85
is_equalFunction · 0.70
nnzFunction · 0.70
SparsityClass · 0.70
MXClass · 0.70
sizeFunction · 0.70
opMethod · 0.45
depMethod · 0.45
is_scalarMethod · 0.45
sizeMethod · 0.45
_get_binaryMethod · 0.45

Tested by

no test coverage detected