Maple procedure and function - maple

I don't understand how to use a mathematical function in a maple procedure.
For example in this procedure I try to compute the arc length of a function :
proc(f,a,b);
local f,a,b;
L=int(sqrt(1+f'(x)^2),x=a..b);
end proc;
But is doesn't work.
It is my first question here if there is a problem

Firstly, the syntax f'(x) is only valid in Maple's marked up 2S Math, not in plaintext Maple code. So it does not make sense to show us that syntax as code on this site.
Moving on, and using only 1D plaintext code (which makes sense for this site and is, in my opinion, a better choice for learning Maple), you need to understand the difference between procedures and expresssions.
An expressiom and differentiating it:
Fexpr := x^2 + sin(x);
2
Fexpr := x + sin(x)
diff(Fexpr, x);
2 x + cos(x)
An operator, and differentiating it (and applying it, or applying it after differentiating):
F := t -> t^2 + sin(t);
F := t -> t^2 + sin(t)
D(F);
t -> 2*t + cos(t)
D(F)(x);
2 x + cos(x)
F(x);
2
x + sin(x)
diff(F(x), x);
2 x + cos(x)
Here are some examples:
Your task, done with argument f as an expression, and supplying the variable name as an argument:
restart;
myproc := proc(fexpr,a,b,var)
local L;
L:=int(sqrt(1+diff(fexpr,var)^2),var=a..b);
end proc:
myproc(sin(x), 0, Pi, x);
myproc(sin(x), 0.0, evalf(Pi), x);
myproc(sin(t), 0.0, evalf(Pi), t);
myproc(t^2, 0, Pi, t);
A modification of the above, where it figures out the variable name from the expression passed as argument:
restart;
myproc := proc(fexpr,a,b)
local deps,L,x;
deps := indets(fexpr,
And(name,Not(constant),
satisfies(u->depends(fexpr,u))));
x := deps[1];
L:=int(sqrt(1+diff(fexpr,x)^2),x=a..b);
end proc:
myproc(sin(x), 0, Pi);
myproc(sin(x), 0.0, evalf(Pi));
myproc(sin(t), 0.0, evalf(Pi));
myproc(t^2, 0, Pi);
Now, significantly different, passing an procedure (operator) instead of an expression:
restart;
myproc := proc(f,a,b)
local L,x;
L:=int(sqrt(1+D(f)(x)^2),x=a..b);
end proc:
myproc(sin, 0, Pi);
myproc(sin, 0.0, evalf(Pi));
myproc(s -> s^2, 0, Pi);
Lastly (and I do not recommend this way, since the procedure f may not function properly when called with an unassigned name, etc):
restart;
myproc := proc(f,a,b)
local L,x;
L:=int(sqrt(1+diff(f(x),x)^2),x=a..b);
end proc:
myproc(sin, 0, Pi);
myproc(sin, 0.0, evalf(Pi));
myproc(s -> s^2, 0, Pi);

Related

How to plot experimental data at special points?

I have a set of experimental data (P), and I want to obtain plot "experimental vs predicted". In order to do so, I use another set of data which depend on P (Q), plot ScatterPlot, use appropriate fit, then obtain regression line, and use its coefficients in appropriate differential equation. Plot of P looks good, but I need to add there experimental data. For simplicity, I've used interval t=0..150.
How can I plot experimental data so that P(0) = Pvals[1], P(10)=Pvals[2], etc.? Besides, how can I distribute data (say, I have t=0..800 and want to plot Pvals so that P(0) = Pvals[1] and P(800) = Pvals[16])?
Pvals := [3.929, 5.308, 7.24, 9.638, 12.866, 17.069, 23.192, 31.433, 38.558, 50.156, 62.948,
75.996, 91.972, 105.711, 122.775, 131.669]:
for i to 15 do Qval[i] := .1*(Pvals[i+1]/Pvals[i]-1); end do:
Qvals := [seq(Qval[i], i = 1 .. 15), 0.144513895e-1]:
with(Statistics);
ScatterPlot(Pvals, Qvals, fit = [a*v^2+b*v+c, v], thickness = 3,
legend = [points = "Point data", fit = typeset("fit to a", 2^nd, "degree polynomial")]);
with(CurveFitting);
LeastSquares(Pvals, Qvals, v, curve = a*v^2+b*v+c);
de := diff(P(t), t) = (0.370152282598477e-1-0.272504103112702e-3*P(t))*P(t);
sol := dsolve({de, P(0) = 3.929}, P(t));
P := plot(rhs(sol), t = 0 .. 160);
I'm not sure that I entirely follow your methodology. But is this something like what you are trying to accomplish?
restart;
with(Statistics):
Pvals := [3.929, 5.308, 7.24, 9.638, 12.866, 17.069, 23.192, 31.433,
38.558, 50.156, 62.948, 75.996, 91.972, 105.711, 122.775, 131.669]:
for i to 15 do Qval[i] := .1*(Pvals[i+1]/Pvals[i]-1); end do:
Qvals := [seq(Qval[i], i = 1 .. 15), 0.144513895e-1]:
form := a*v^2+b*v+c:
CF := CurveFitting:-LeastSquares(Pvals, Qvals, v, curve = form);
CF := 0.0370152282598477 - 0.000272504103112702 v
-7 2
+ 5.60958249026713 10 v
Now I use CF in the DE (since I don't understand why you dropped the v^2 term),
#de := diff(P(t), t) = (0.370152282598477e-1-0.272504103112702e-3*P(t))*P(t);
de := diff(P(t), t) = eval(CF, v=P(t))*P(t);
d /
de := --- P(t) = \0.0370152282598477 - 0.000272504103112702 P(t)
dt
-7 2\
+ 5.60958249026713 10 P(t) / P(t)
I'll use the numeric option of the dsolve command, and obtain a procedure that computes P(t) for numeric t values.
sol := dsolve({de, P(0) = 3.929}, P(t), numeric, output=listprocedure ):
Pfunc := eval(P(t), sol);
Pfunc := proc(t) ... end;
Pfunc(0.0), Pvals[1];
3.92900000000000, 3.929
Now some rescaling (which, again, is my guess as to your goal),
endpt := fsolve(Pfunc(t)-Pvals[16]);
endpt := 135.2246055
Pfunc(endpt), Pvals[16];
131.669000003321, 131.669
plot(Pfunc(t), t=0 .. endpt, size=[500,200]);
a,b,N := 0.0, 800.0, nops(Pvals);
a, b, N := 0., 800.0, 16
Pfuncscaled := proc(t)
if not t::numeric then
return 'procname'(args);
end if;
Pfunc(t*endpt/b);
end proc:
Pfuncscaled(0), Pvals[1];
3.92900000000000, 3.929
Pfuncscaled(800), Pvals[N];
131.669000003321, 131.669
PLscaled := plot( Pfuncscaled(t), t=a .. b,
color=red, size=[500,200] );
Now to display the Pdata against 0 .. 800 as well,
V := Vector(N, (i)->a+(i-1)*(b-a)/(N-1)):
V[1], V[-1];
0., 800.0000000
Pdatascaled := plot( < V | Vector(Pvals) >,
color=blue, size=[500,200],
style=pointline, symbol=solidcircle );
And, displaying the rescaled data together with the rescaled procedure from dsolve,
plots:-display( PLscaled, Pdatascaled, size=[500,500] );

How to determine the size of an input argument for a function handle

I am creating a function that takes in data (x,y,z) and an anonymous function (M) as inputs. M's inputs are data (x,y,z) and a parameter (theta).
I need to determine the dimension of the parameter theta inside FUNC
EDIT: (To add some context)
I have data that follows a known data generating process (DGP). For example, I can generate data using a linear instrumental variable DGP with 1 endogenous variable (hence theta will be dimension 1):
n = 100; q = 10;
theta0 = 1; % true param value
e = randn(n, 1); % 2nd stage error
u = randn(n, 1); % 1st stage error
z = randn(n, q); % instrument
x = z * ones(q, 1) + u; % endog variable
y = x * theta0 + e; % dependent variable
Then I want to estimate theta0 using my own variation of generalized linear methods (FUNC)
M = #(x,y,z,theta) z' * (y - x * theta); % moment condition
thetahat = FUNC(M, x, y, z); % estimate theta0
and FUNC.m is
function out = FUNC(M, x, y, z)
k = ; % (!!!) <-- this is what I need to find out!
objFunc = #(theta) M(x, y, z, theta)' * M(x, y, z, theta);
out = fminunc(objFunc, ones(1, k)); % <-- this is where its used
end
In the above example, the DGP is a linear IV model. However, I should be able to use my function for any other DGP.
Other DGPs could, for example, define M as follows:
% E.g. 1) theta is dimension 1
M=#(x,y,z,theta) z' * (y - x * theta);
% E.g. 2) theta is dimension 2
M=#(x,y,z,theta) z' * (y - (x * theta(1))^theta(2));
% E.g. 3) theta is dimension 3
M=#(x,y,z,theta) z' * (y - (theta(1) + x * theta(2))^theta(3));
The (super bad) hack that I am currently using for (!!!) is:
for ktest = [3,2,1] % the dimension of theta will never be higher than 3
try
M(x, y, z, ones(1, ktest);
k = ktest;
end
end
Since you know already what the form and requirements of your function M will be when you pass it to FUNC, it doesn't make much sense to then require FUNC to determine it based only on M. It would make much more sense to pass flag values or needed information to FUNC when you pass it M. I would write FUNC in one of two ways:
function out = FUNC(M, x, y, z, k) % Accept k as an argument
...
end
function out = FUNC(M, x, y, z, theta0) % Pass the initial guess, of the correct size
...
end
If you really want to let FUNC do the extra work, then the answer from excaza is how I would do it.
Old answer below. not really valid since the question was clarified, but I'm leaving it temporarily...
I think you have two better options here...
Make M a cell array of anonymous functions:
You could make your input M a cell array of possible anonymous functions and use the number of values in theta as the index. You would pass this M to FUNC:
M = {#(x,y,z,theta) z' * (y - x * theta), ...
#(x,y,z,theta) z' * (y - (x * theta(1))^theta(2)), ...
#(x,y,z,theta) z' * (y - (theta(1) + x * theta(2))^theta(3))};
Then somewhere inside FUNC:
out = M{numel(theta)}(x, y, z, theta);
Make M a normal function instead of an anonymous one:
An anonymous function is good for quick, simple formulas. Add in conditional logic and you should probably just make it a fully-fledged function. Here's an example with a switch statement (good for if you have a number of different formulas):
function out = M(x, y, x, theta)
switch numel(theta)
case 1
out = z' * (y - x * theta);
case 2
out = z' * (y - (x * theta(1))^theta(2));
case 3
out = z' * (y - (theta(1) + x * theta(2))^theta(3));
end
end
And here's an example that sets some defaults for parameters (good for if you have one formula with different ways to set its parameters, like you seem to have):
function out = M(x, y, x, theta)
switch numel(theta)
case 1
p1 = 0;
p2 = theta;
p3 = 1;
case 2
p1 = 0;
p2 = theta(1);
p3 = theta(2);
case 3
p1 = theta(1);
p2 = theta(2);
p3 = theta(3);
end
out = z' * (y - (p1 + x * p2)^p3);
end
MATLAB doesn't store any information about the size of the inputs to an anonymous function. While a better idea would be to modify your code so you don't have to do these kinds of gymnastics, if your function definition is known to fit a narrow band of possibilities you could use a regular expression to parse the function definition itself. You can get this string from the return of functions.
For example:
function [nelements] = findsizetheta(fh)
defstr = func2str(fh);
test = regexp(defstr, 'theta\((\d+)\)', 'tokens');
if isempty(test)
% Assume we have theta instead of theta(1)
nelements = 1;
else
nelements = max(str2double([test{:}]));
end
end
Which returns 1, 2, and 3 for your example definitions of M.
This assumes that theta is present in you anonymous function and that it is defined as a vector.
Also note that MATLAB cautions against utilizing functions in a programmatic manner, as its behavior may change in future releases. This was tested to function in R2017b.

Matlab - define a function that is a summation

I am trying to define I function which I will derivate later and the function is
My code is as below:
syms i q j
syms f(i,q)
f=symsum(((1-q)^(i-j))*j*q,j,0,i)
The f I get shows me 4 terms but in fact I do not know this number. Is it correct or how do I enter this correctly?
First of all, please don't use i and j, because they correspond to the imaginary unit; that causes misunderstandings.
syms N q k
syms f(i,q)
f=symsum(((1-q)^(N-k))*k*q,k,0,N)
piecewise(q == 0, 0, q ~= 0, (q + N*q - q*(1 - q)^N + (1 - q)^N - 1)/q)
The result is a piecewise, and it says that the result is 0 if q is 0, and otherwise the formula given on the right.
You can also evaluate Sum[(1 - q)^(M - k) k q, {k, 0, M}] with WolframAlpha, where you get the same result. As you see, your formula can be written without the sum. You get the derivative with D[Sum[(1 - q)^(M - k) k q, {k, 0, M}],q] on WolframAlpha.

How take coordinates from Vector in maple

Is any way to get coordinates from Vector in maple? For example if I would like have function f(V) = sin(V[0]) + cos(V[1]) + V[2]
Where V = (x,y,z). Is it possible in maple?
In Maple a Vector starts its indexing from 1 (not from 0). So the first entry is V[1], rather than V[0].
Also, a Vector can be constructed with either the Vector command or its angle-bracket shortcut notation. Round brackets do not construct a Vector, as they are delimiters for either grouping or arguments of function application.
restart:
f := V -> sin(V[1]) + cos(V[2]) + V[3]:
W := Vector([a,b,c]):
f(W);
sin(a) + cos(b) + c
Y := <3,7,11>:
f(Y);
sin(3) + cos(7) + 11
An Array is more flexible and can be constructed so as to start its indexing from 0.
g := V -> sin(V[0]) + cos(V[1]) + V[2]:
W := Array(0..2,[q,r,s]):
g(W);
sin(q) + cos(r) + s
Note that the LinearAlgebra package deals with Matrix and Vector. Also, some arithmetic operations (such as .) act in an elementwise manner for Array and not a way you might expect for doing computational linear algebra.
restart:
F := Array(1..3,[q,r,s]):
F . F;
[ 2 2 2]
[q , r , s ]
U := Vector[row]([q,r,s]):
U . U;
_ _ _
q q + r r + s s
Note the complex conjugation occuring in the last example. And in contrast with Matrix structures, 2-dimensional Arrays are also multiplied elementwise under the . operator.

Maple. Dsolve and functions

I have a differential equation that my program solves:
p := dsolve({ic, sys}, numeric, method = rosenbrock);
After solving we have the following:
print(p(10));
[t = 10., alpha(t) = HFloat(0.031724302221312055), beta(t) = HFloat(0.00223975915581258)]
I need use this alpha(t) and beta(t) as follows:
a := t->exp( int(alpha(t)),x=0..t) );
b := t->exp( int(beta(t)),x=0..t) )
And draw a plot:
odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20, thickness = 2, numpoints = 500, color = [red, blue])
The first thing that occurred to do so:
p := dsolve({sys, ic}, numeric, method=rosenbrock);
alpha := t->rhs(p(t)[2] );
beta := t->rhs(p(t)[3;
a := t->exp( int(alphat)),x=0..t) );
b := t->exp( int(betat)),x=0..t) );
odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20, thickness = 2, numpoints = 500, color = [red, blue])
But the code does not work, and Yes, obviously, should act differently.
First, let's try to get your approach to work, with a few syntax and usage changes.
You didn't supply the example's details, so I make up a system of differential equations sys and initial conditions ic so that your computational commands can be performed.
restart:
sys := diff(alpha(t),t) = -1/200*beta(t),
diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2:
ic := alpha(0)=0, beta(0)=-1:
p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure):
alphat := eval(alpha(t),p):
betat := eval(beta(t),p):
a := unapply( exp( Int(alphat , 0..t) ), t, numeric):
b := unapply( exp( Int(betat , 0..t) ), t, numeric):
evalf(a(20.0)), evalf(b(20.0));
-18
5.347592595, 3.102016550 10
st := time():
P := plots:-odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20,
thickness = 2, numpoints = 50, color = [red, blue]):
( time() - st )*`seconds`;
16.770 seconds
P;
I used output=listprocedure so that I could assign the right procedures from solution p to alphat and betat. Those are more efficient to call many times, as opposed to your original which formed a sequence of values for each numeric t value and then had to pick off a certain operand. It's also more robust since its not sensitive to positions (which could change due to a new lexicographic ordering if you altered the names of your variables).
The above took about 16 seconds on an Intel i7. That's not fast. One reason is that the numeric integrals are being computed to higher accuracy than is necessary for the plotting. So let's restart (to ensure fair timing) and recompute with relaxed tolerances on the numeric integrations done for a and b.
restart:
sys := diff(alpha(t),t) = -1/200*beta(t),
diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2:
ic := alpha(0)=0, beta(0)=-1:
p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure):
alphat := eval(alpha(t),p):
betat := eval(beta(t),p):
a := unapply( exp( Int(alphat , 0..t, epsilon=1e-5) ), t, numeric):
b := unapply( exp( Int(betat , 0..t, epsilon=1e-5) ), t, numeric):
evalf(a(20.0)), evalf(b(20.0));
-18
5.347592681, 3.102018090 10
st := time():
P := plots:-odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20,
thickness = 2, numpoints = 50, color = [red, blue]):
( time() - st )*`seconds`;
0.921 seconds
You can check that this gives a plot that appears the same.
Now lets augment the example so that the numeric integrals are computed by dsolve,numeric itself. We can do that by using Calculus. In this way we are leaving it to the numeric ode solver to do its own error estimation, stepsize control, stiffness or singularity detection, etc.
Note that the integrands alphat and betat are not functions for which we have explicit functions -- their accuracy is intimately tied to the numerical ode solving. This is not quite the same as simplistically using a numerical ode routine to replace a numeric quadrature routine for a problem with an integrand which we expect to be computed directly to any desired accuracy (including on either side of any singularity).
restart:
sys := diff(alpha(t),t) = -1/200*beta(t),
diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2,
diff(g(t),t) = alpha(t), diff(h(t),t) = beta(t):
ic := alpha(0)=0, beta(0)=-1,
g(0)=0, h(0)=0:
p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure):
alphat := eval(alpha(t),p):
betat := eval(beta(t),p):
gt := eval(g(t),p):
ht := eval(h(t),p):
exp(gt(20.0)), exp(ht(20.0));
-18
5.34759070530497, 3.10201330730572 10
st := time():
P := plots:-odeplot(p, [[t, exp(g(t))], [t, exp(h(t))]], 0 .. 20,
thickness = 2, numpoints = 50, color = [red, blue]):
( time() - st )*`seconds`;
0.031 seconds
P;