string input to anonymous function in MATLAB - matlab

In matlab i know i can convert string into anonymous function with str2func.
For example;
s= '#(x) x.^2';
h= str2func(s);
h(2) would be 4
But what if i do not know the number of unknown? Let's say user of this program will enter lots of function to get a numerical solution of a system. When the user enters x^2, i should add #(x) to its beginning then convert it to a function. But in programming time i do not know how many function the user will enter with how many unknown. #(x) may should be #(x,y) as well as #(x,y,z). If the user enters the number of unknowns, how can i create and add the necessary prefix at runtime?
ps: number of unknown can be any integer number.

You need to know not only the quantity of variables but also their names and order. An expression may read x(c). Even if you know that the expression has two variables in it and are able to parse out x and c, you won't be able to tell if the user intended to define something like #(x, c) x(c), #(c, x) x(c) or even something like #(c, d) x(c) where x is actually a function.
Parsing the expressions just to get the names they use is something that you shouldn't have to do.
Restricting the variable names that are allowed can be messy. If the user is expecting MATLAB syntax and you are parsing as MATLAB, why make your life harder? Also, when you introduce a restriction like one-letter variable names only, you have to ask yourself if there will ever be a situation where you need more than 27 variables.
It would be much safer all around to have the user list the names of the variables they plan on using before the function, e.g. (x, y, pi) pi*(x^2 + y). Now all you have to do is prepend # and not worry about whether pi is a built-in or an argument. In my opinion the notation is quite clean.

Related

Defining a natural variable n in TI-Nspire CAS

I'm wondering if it's possible to define a natural variable n in TI-Nspire CAS. For example I'd like to write:
You can't define your own natural variables. However, Nspire has the following special variables you can use:
#n0...#n255: Restricted to natural numbers
#c0...#c255: Restricted to real numbers
You can replace the original variables with them by hand or for convience just put |x=#n0 and y=#n1 at the end of line.
Example: You are calculating fourier coefficients and know that variable k will only get real numbers from Σ operation. Replacing k with #n1 will simpilfy the function.
Picture
(Calculator needs to be in RAD mode if you want to try)
The answer is no. Variables in NSpire store a value. A variable has no type. Solve might return #n1 in a result to indicate an arbitrary natural number, but you can tell solve to look for integer solutions only.

How to define custom functions in Maple?

I'm new to Maple and I'm looking for a simple way to automate some tasks. In particular, I'm looking for a way to define custom "action" that perform some steps automatically.
As as an example I would like to define a quick way to compute the determinant of the Hessian of a polynomial. Currently the way I do this is opening Maple, create a new worksheet than performing the following commands:
p := (x, y) -> x^2*y + 3*x^3 + y^3
with(VectorCalculus):
h := Hessian(p(x, y), [x, y])
Determinant(h)
What I would like to do is to compute the hessian determinant directly with something like
HessDet(p)
where HessDet would be a custom command that performs the operations above. How does one achieve something like this in Maple?
First things first: The value assigned to your p is a procedure which can return a polynomial expression, but not itself a polynomial. It's important not to muddle expressions and procedures. Doing so is a common cause of problems for new users.
Being able to throw around p(x,y) may be visually pleasing to your eye, but it serves little programmatic purpose here. The fact that the formal parameters of procedure p happen to be called x and y, along with the fact that you called procedure p with arguments x and y, is actually just another common source of confusion. Don't create procedures merely to call them in this way.
Also, your call p(x,y) makes it look magic that your code snippet "knows" how many arguments would be required by procedure p. So it's already a muddle to have your candidate HessDet accept p as a procedure.
So instead let's keep it straightforward, by writing HessDet to accept a polynomial rather than a procedure. We can programmatically ascertain the names in which this expression of of type polynom.
restart;
HessDet:=proc(p::algebraic)
local H,vars;
vars:=indets(p,
And(name,Non(constant),
satisfies(u->type(p,polynom(anything,u)))));
H:=VectorCalculus:-Hessian(p,[vars[]]);
LinearAlgebra:-Determinant(H);
end proc:
Now some examples of using it,
P := x^2*y + 3*x^3 + y^3;
HessDet(P);
p := (x, y) -> x^2*y + 3*x^3 + y^3;
HessDet(p(x,y));
HessDet(x^3-x^2+4*x);
HessDet(s^2*t + 3*s^3 + t^3);
HessDet(s[r]^2*t[r] + 3*s[r]^3 + t[r]^3);
You might also wonder how you could re-use this custom procedure across sessions, without having to type it in each time. Two reasonable ways are:
Put the (above) defining plaintext definition of HessDet inside a personal initialization file.
Create a (.mla) Maple Library Archive file, then Save your HessDet to that, and then augment the Library search path in your initialization file.
It might look like 2) is more effort, but only the Save step is needed for repeats, and you can store many custom procedures to the same archive. Your choice...
[edit] The OP has asked for clarification of the first part of the above procedure HessDet, which I suspect means the call to indets.
If P is assigned an expression then then the call indets(P,name) will return a set of all the names present in that expression. Basically, it returns the set of all indeterminate subexpressions of the expression which are of type name in Maple's technical sense.
For example,
P := x*y + sin(a*Pi)*x;
x y + sin(a Pi) x
indets( P,
name );
{Pi, a, x, y}
Perhaps the name of the constant Pi is not wanted here. Ie,
indets( P,
And( name,
Non(constant) ) );
{a, x, y}
Perhaps we want only the non-constant names in which the expression is a polynomial? Ie,
indets( P,
And( name,
Non(constant),
satisfies(u->type(p,polynom(anything,u))) ) );
{x, y}
That last result is an advanced way of using the following tests:
type(P, polynom(anything, x));
true
type(P, polynom(anything, y));
true
type(P, polynom(anything, a));
false
A central issue here is that the OP made no mention of what kind of polynomials are to be handled by the custom procedure. So I guessed with some defensive coding, in hope of less surprises later on. The original Question states that the input could be a "polynomial", but we weren't told what kind of coefficients there might be.
Perhaps the coefficients will always be real and exact or numeric. Perhaps the custon procedure should throw an error when not supplied such. These details weren't mentioned in the Question.

Making symbolic functions without hard-coding in MATLAB

I want to make symbolic functions theta1(t), theta2(t), theta3(t),...,thetaN(t) where N is some parameter I can define in MATLAB. I know that I can use something like sym('theta',[1 N]) to get [theta1, theta2, theta3,..., thetaN]. However, how can I do the same thing with theta being a function of t? The way to hard-code it would be like syms theta1(t) theta2(t) theta3(t) ... thetaN(t), but I want to make this general.
I do not want to directly use the sym command here because "support of character vectors that are not valid variable names and do not define a number will be removed in a future release", meaning something like sym('theta1(t)') would not be valid in future releases.
Any suggestions?
Figured part of it out. I could do something like the following
for i = 1:N
syms(strcat('theta',num2str(i),'(t)'))
end
However, if I want to assign a variable that contains all the symbolic expressions I'm still stuck. If I try
for i = 1:N
my_array(i) = syms(strcat('theta',num2str(i),'(t)'))
end
I get Error using syms (line 133). Using input and output arguments simultaneously is not supported. It works if I use sym instead of syms, but this leads to the warning I mentioned in my original post.

Can I vectorize the following?

Suppose I have a m file fun.m such that fun(t,x,g) gives a particular value. However, fun is a black box, I do not know what exactly it does, as that m file may be written by another programmer. Here, fun accept scalar input of t and x; g is a function. What I can input is t,x and the function g which are decided by user. However, if I decide to use g to be specific function, I won't change the function, i.e. if I decide to use g=#(y)y.^2, then I want to write a program allowing another user to input a vector t and a scalar value of x. For example, if the user choose t=[1,2,3,4] and x=5, my program can output fun([1,2,3,4],5,#(t)t^2), while if the user choose t=[1,2,3,4,6] and x=10, my program can output fun([1,2,3,4,6],10,#(t)t^2).
Originally, I use for loop to solve the problem, and I want to use arrayfun if possible, what I write is as follow:
g=#(y)y.^2
TEST=#(T,t)arrayfun(#(s,x)fun(s,x,#(y)g(y)),T,t),
Unfortunately, TEST([1,2,3,4],5) gives error, saying that dimension does not match. I want to ask: is it possible to use arrayfun to do my task? If so, how to correct the above code to get the result?

How can I get Matlab to use the variable value instead of name

In my code, I have a line that looks like this:
f=#(test) bf{i}(5);
where bf is a cell array with functions from str2func() stored in it, i is a variable storing an integer, and the 5 is the argument to pass to the function. How can I get matlab to evaluate the line using the current value of i? Right now when I display f it outputs:
#(test)bf{i}(5)
Lets say i=1, I want it to output:
#(test)bf{1}(5)
Although technically the bf{1} should also be replaced with whatever function is stored in bf{1}. How can I force matlab to evaluate the variables in this statement?
When you create a function handle, the workspace variables are copied and the expression is evaluated when you call the function handle (Typically not a problem in memory consumption, matlab stores only changes).
Now the problem is, to tell Matlab when to evaluate what part of the expression.
If you are aiming for a better performance, pre-evaluate all constant parts of the function. Let's say your function is #(x)(g(3).*f(x)), in this case matlab would evaluate g(3) on every call.
Instead use:
f=#(x)(x.^2)
g_3=g(3)
h=#(x)(g_3.*f(x))
Now having the constant parts evaluated, you want to see the constants instead of the variabe name. I know two ways to achieve this.
You can use the symbolic toolbox, basically converting the function handle to a symbolic function, then to a function handle again. This not only displays the constants, but also substitutes f. This is not possible for all functions.
>> matlabFunction(h(sym('x')))
ans =
#(x)x.^2.*4.2e1
Another possibility is to use eval:
h=eval(['#(x)',sprintf('%e',g_3),'.*f(x)'])
Pre-evaluating constant parts of the expressions as I did in the first step is typically recommendable, but both solutions to get the constant visible in your function handle aren't really recommendable. The first solution using matlabFunction only applies to some functions, while the second comes with all the disadvantages of eval.