Post Reply 
Calling a function with an arbitrary number of arguments
05-02-2019, 02:08 AM
Post: #1
Calling a function with an arbitrary number of arguments
How can I call a user-defined function with an arbitrary number of parameters from a program? Given the list of arguments and the function itself.

I tried using the python argument expansion syntax ``function(*args)`` with no luck.
Find all posts by this user
Quote this message in a reply
05-02-2019, 06:05 AM
Post: #2
RE: Calling a function with an arbitrary number of arguments
Hello,

PPL does not have this type of functionality.

You can however have a function with a single list argument which the function can then process as 1 variable list of arguments.

Cyrille

Although I work for the HP calculator group, the views and opinions I post here are my own. I do not speak for HP.
Find all posts by this user
Quote this message in a reply
05-02-2019, 10:56 AM
Post: #3
RE: Calling a function with an arbitrary number of arguments
args inside a CAS program returns the function and arguments. For example
f():=begin return args; end
then f(1,23) or f(1)
Find all posts by this user
Quote this message in a reply
05-03-2019, 01:43 AM (This post was last modified: 05-03-2019 01:48 AM by compsystems.)
Post: #4
RE: Calling a function with an arbitrary number of arguments
in Xcas and the Python syntax you can create functions and then call with a variable number of arguments

example

PHP Code:
#cas
def legendre_nevalX="" ):
    
local pxxtype2argpurge(x)
    if 
getType(n) == "NUM":
      
px := 1/(2^n*n!)*diff((x^2-1)^n,x,n)
      
type2arg := getType(evalX)   
      if 
type2arg == "NUM" or type2arg == "EXPR" or type2arg == "VAR":
        
px := subst(px,x=evalX)
      
elif type2arg == "STR" and evalX=="LIST":
        
px:=symb2poly(px)   
      return 
px
    
return "Error, an integer number is expected in the first argument."
#end 

#hpprime
PHP Code:
#cas
def legendre_nevalX="" ):
    
local pxxtype2argpurge(x)
    if 
TYPE(n) == 0:
      
px := 1/(2^n*n!)*diff((x^2-1)^n,x,n)
      
type2arg := TYPE(evalX)   
      if 
type2arg == or type2arg == 8:
        
px := subst(px,x=evalX)
      
elif type2arg == and evalX=="LIST":
        
px:=symb2poly(px)   
      return 
px
    
return "Error, an integer number is expected in the first argument."
#end 

legendre_(2) # 1 arg [enter]
1/8*(12*x^2-4)

legendre_(2,y), legendre_(2,"LIST"), legendre_(2,10), legendre_(2,cos(t)) # 2 arg [enter]
1/8*(12*y^2-4), poly1[3/2,0,-1/2], 299/2, 1/8*(12*cos(t)^2-4)

LO SUFICIENTEMENTE BUENO ES ENEMIGO DE LA EXCELENCIA.
Find all posts by this user
Quote this message in a reply
05-04-2019, 03:37 PM (This post was last modified: 05-05-2019 04:02 AM by Han.)
Post: #5
RE: Calling a function with an arbitrary number of arguments
Here is a short (CAS) program that takes a variable number of inputs. In this case, we expect 2 inputs but the program handles cases where more (or fewer) than 2 inputs are provided (by returning an error message). Here, the input is the variable 'args' which is (conceptually speaking) a list of values, which are then turned into a vector of values called 'argv' by encapsulating the list of values in square brackets. Non-CAS programs cannot handle variable inputs; but one way to get around this is to create a "wrapper" CAS program that handles the input and then passes it to your non-CAS program(s).

Code:
#cas
jacob(args):=
begin
local argv, argc, mat, f, var, fn, j, k,  gr, vd;
argv:=[args];
argc:=size(argv);
IF argc !=2 THEN
     return "Input:[f1(x1,...,xn),...,fm(x1,...,xn)], [x1,...,xn]"; 
ELSE
     return transpose(diff(argv[1],argv[2]));
END;
end;
#end

Graph 3D | QPI | SolveSys
Find all posts by this user
Quote this message in a reply
06-13-2019, 08:31 PM
Post: #6
RE: Calling a function with an arbitrary number of arguments
This is the hack I was able to come up with, it will call the function given with as many arguments as dimensions the vector passed after it has.

Code:
#cas
// Calls a function passing a veriable number
// of arguments, contained in the iterable ``args_``.
// example ``vcall(fun1, [a, b, c])`` -> ``fun1(a, b, c)``
vacall(func_, args_):= begin
  local args_sum_, i_;
  local args_sym_;
  purge(args_sym_);
  args_sum_ = 0;
  for i_ from 1 to size(args_) do
    args_sum_ := args_sum_ + args_sym_[i_];
  end;
  args_sum_[1] := func_;
  args_sym_ := args_;
  return eval(args_sum_); 
end;

// Convers an iterable to a sequence
toseq(vec_):= begin
  local func_sym_;
  purge(func_sym_);
  return vacall(func_sym_, vec_)[3];
end;
#end

How does this work? Why do you sum the arguments? Why do you index a sum?
The sum operator is used to construct an instruction that will translate to a function call similar to ``sum(a[1], a[2], a[3])``, originated from ``a[1] + a[2] + a[3]``, the more elements you sum to that expression, the more arguments the function will receive. Some symbolic expressions besides vectors in CAS are indexable, indexing them will return parts of the expression, you can also modify the contents of the expression that way.
Knowing this I created a sum with symbolic values and swapped the ``+`` operator by the function passed, then you can assign the arguments passed to the symbolic arguments used in the addition, before returning the expression we should evaluate it to perform the substitutions.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)