Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def get_derivative(self, s):
# Case 1: s is a constant, e.g. MX(5)
if ca.MX(s).is_constant():
return 0
# Case 2: s is a symbol, e.g. MX(x)
elif s.is_symbolic():
if s.name() not in self.derivative:
if len(self.for_loops) > 0 and s in self.for_loops[-1].indexed_symbols:
# Create a new indexed symbol, referencing to the for loop index inside the vector derivative symbol.
for_loop_symbol = self.for_loops[-1].indexed_symbols[s]
s_without_index = self.get_mx(ast.ComponentRef(name=for_loop_symbol.tree.name))
der_s_without_index = self.get_derivative(s_without_index)
if ca.MX(der_s_without_index).is_symbolic():
return self.get_indexed_symbol(ast.ComponentRef(name=der_s_without_index.name(), indices=for_loop_symbol.tree.indices), der_s_without_index)
else:
return 0
else:
der_s = _new_mx("der({})".format(s.name()), s.size())
# If the derivative contains an expression (e.g. der(x + y)) this method is
# called with MX variables that are the result of a ca.symvar call. This
# ca.symvar call strips the _modelica_shape field from the MX variable,
# therefore we need to find the original MX to get the modelica shape.
der_s._modelica_shape = \
self.nodes[self.current_class][s.name()]._modelica_shape
self.derivative[s.name()] = der_s
self.nodes[self.current_class][der_s.name()] = der_s
return der_s
else:
return self.derivative[s.name()]
def exitExpression(self, tree: ast.Expression):
if isinstance(tree.operator, ast.ComponentRef):
op_name = tree.operator.name
else:
op_name = tree.operator
if len(tree.operands) == 1:
self.xml[tree] = E(
'operator', name=op_name,
*[self.xml[c] for c in tree.operands])
else:
self.xml[tree] = E(
'apply', builtin=op_name,
*[self.xml[c] for c in tree.operands])
def get_derivative(self, s):
# Case 1: s is a constant, e.g. MX(5)
if ca.MX(s).is_constant():
return 0
# Case 2: s is a symbol, e.g. MX(x)
elif s.is_symbolic():
if s.name() not in self.derivative:
if len(self.for_loops) > 0 and s in self.for_loops[-1].indexed_symbols:
# Create a new indexed symbol, referencing to the for loop index inside the vector derivative symbol.
for_loop_symbol = self.for_loops[-1].indexed_symbols[s]
s_without_index = self.get_mx(ast.ComponentRef(name=for_loop_symbol.tree.name))
der_s_without_index = self.get_derivative(s_without_index)
if ca.MX(der_s_without_index).is_symbolic():
return self.get_indexed_symbol(ast.ComponentRef(name=der_s_without_index.name(), indices=for_loop_symbol.tree.indices), der_s_without_index)
else:
return 0
else:
der_s = _new_mx("der({})".format(s.name()), s.size())
# If the derivative contains an expression (e.g. der(x + y)) this method is
# called with MX variables that are the result of a ca.symvar call. This
# ca.symvar call strips the _modelica_shape field from the MX variable,
# therefore we need to find the original MX to get the modelica shape.
der_s._modelica_shape = \
self.nodes[self.current_class][s.name()]._modelica_shape
self.derivative[s.name()] = der_s
self.nodes[self.current_class][der_s.name()] = der_s
return der_s