Let's create SymbolicGetArg(expr e, int n):
--- a/src/libasr/pass/intrinsic_function_registry.h
+++ b/src/libasr/pass/intrinsic_function_registry.h
@@ -84,6 +84,7 @@ enum class IntrinsicScalarFunctions : int64_t {
SymbolicMulQ,
SymbolicPowQ,
SymbolicLogQ,
+ SymbolicGetArg,
// ...
};
Which will take the expression e, call get_args on it, and return the n-th argument as an expression.
The SymEngine's getargs are slow anyway, since it returns std::vector<Basic> and internally SymEngine does not store the arguments in a vector, and so it must construct it (slow). Consequently, the SymbolicGetArg will be slow as well. We can start by using basic_get_args, implemented in SymEngine as:
CWRAPPER_OUTPUT_TYPE basic_get_args(const basic self, CVecBasic *args)
{
CWRAPPER_BEGIN
args->m = self->m->get_args();
CWRAPPER_END
}
and then extract the n-th argument using vecbasic_get, implemented as:
CWRAPPER_OUTPUT_TYPE vecbasic_get(CVecBasic *self, size_t n, basic result)
{
CWRAPPER_BEGIN
SYMENGINE_ASSERT(n < self->m.size());
result->m = self->m[n];
CWRAPPER_END
}
Let's create
SymbolicGetArg(expr e, int n):Which will take the expression
e, call get_args on it, and return then-th argument as an expression.The SymEngine's getargs are slow anyway, since it returns
std::vector<Basic>and internally SymEngine does not store the arguments in a vector, and so it must construct it (slow). Consequently, theSymbolicGetArgwill be slow as well. We can start by usingbasic_get_args, implemented in SymEngine as:and then extract the
n-th argument usingvecbasic_get, implemented as: