]> www.ginac.de Git - ginac.git/blobdiff - ginac/function.cppy
Functions can define a custom expand() now.
[ginac.git] / ginac / function.cppy
index fb83cdc4f05b1f2683589a87e2f4d8fb928504d9..2a9080cf698e43d519bce298bdc435833250125c 100644 (file)
@@ -78,8 +78,8 @@ void function_options::initialize()
 {
        set_name("unnamed_function", "\\\\mbox{unnamed}");
        nparams = 0;
-       eval_f = evalf_f = real_part_f = imag_part_f = conjugate_f = derivative_f
-               = power_f = series_f = 0;
+       eval_f = evalf_f = real_part_f = imag_part_f = conjugate_f = expand_f
+               = derivative_f = power_f = series_f = 0;
        evalf_params_first = true;
        use_return_type = false;
        eval_use_exvector_args = false;
@@ -87,6 +87,7 @@ void function_options::initialize()
        conjugate_use_exvector_args = false;
        real_part_use_exvector_args = false;
        imag_part_use_exvector_args = false;
+       expand_use_exvector_args = false;
        derivative_use_exvector_args = false;
        power_use_exvector_args = false;
        series_use_exvector_args = false;
@@ -360,15 +361,6 @@ next_context:
        }
 }
 
-ex function::expand(unsigned options) const
-{
-       // Only expand arguments when asked to do so
-       if (options & expand_options::expand_function_args)
-               return inherited::expand(options);
-       else
-               return (options == 0) ? setflag(status_flags::expanded) : *this;
-}
-
 ex function::eval(int level) const
 {
        if (level>1) {
@@ -756,6 +748,34 @@ ex function::power(const ex & power_param) const // power of function
        throw(std::logic_error("function::power(): no power function defined"));
 }
 
+ex function::expand(unsigned options) const
+{
+       GINAC_ASSERT(serial<registered_functions().size());
+       const function_options &opt = registered_functions()[serial];
+
+       // No expand defined? Then return the same function with expanded arguments (if required)
+       if (opt.expand_f == NULL) {
+               // Only expand arguments when asked to do so
+               if (options & expand_options::expand_function_args)
+                       return inherited::expand(options);
+               else
+                       return (options == 0) ? setflag(status_flags::expanded) : *this;
+       }
+
+       current_serial = serial;
+       if (opt.expand_use_exvector_args)
+               return ((expand_funcp_exvector)(opt.expand_f))(seq,  options);
+       switch (opt.nparams) {
+               // the following lines have been generated for max. @maxargs@ parameters
++++ for N in range(1, maxargs + 1):
+               case @N@:
+                       return ((expand_funcp_@N@)(opt.expand_f))(@seq('seq[%(n)d]', N, 0)@, options);
+---
+               // end of generated lines
+       }
+       throw(std::logic_error("function::expand(): no expand of function defined"));
+}
+
 std::vector<function_options> & function::registered_functions()
 {
        static std::vector<function_options> rf = std::vector<function_options>();