How can I use the return of a MAPLE procedure as a function directly - maple

This may be very basic, but I can't seem to figure it out: I am trying to use the output of a procedure directly as a function. The Procedure is a prefabricated one, namely the dsolve option in MAPLE. Specifically, I would like to say
dsolve({diff(y(t), t) = y(t)*t, y(1) = 1}, y(t), series, t = 1, order = 7)
The result is
y(t) = t+1-1+(t-1)^2+(2/3)*(t-1)^3+(5/12)*(t-1)^4+(13/60)*(t-1)^5+(19/180)*(t-1)^6+O((t-1)^7)
Which is great, but I can't use this as a function directly, i.e., when I type in y(3), I get y(3). I'm sure this is because the procedure is returning a statement instead of a function. I guess the most basic way around this would be to copy and paste the expression and say y:=t-> whatever, but this is inelegant. How can I get around this?
Thank you

Yes, you are getting back an equation of the form y(t)=<some series> from your dsolve call.
dsol := dsolve({diff(y(t), t) = y(t)*t, y(1) = 1}, y(t), series, t = 1, order = 5);
2 2 3 5 4 / 5\
dsol := y(t) = 1 + (t - 1) + (t - 1) + - (t - 1) + -- (t - 1) + O\(t - 1) /
3 12
You can also convert the series structure on the right-hand side of that to a polynomial (ie. get rid of the big-O term).
convert( dsol, polynom );
2 2 3 5 4
y(t) = t + (t - 1) + - (t - 1) + -- (t - 1)
3 12
You can also evaluate the expression you want, y(t), at that equation. (Or you could just use the rhs command. For sets of equations in the multivariable case the eval approach is more robust and straighforward.)
eval( y(t), convert( dsol, polynom ) );
2 2 3 5 4
t + (t - 1) + - (t - 1) + -- (t - 1)
3 12
And, finally, you can also produce an operator from this expression.
Y := unapply( eval( y(t), convert( dsol, polynom ) ), t );
2 2 3 5 4
Y := t -> t + (t - 1) + - (t - 1) + -- (t - 1)
3 12
That operator is a procedure, and can be applied to whatever point you want.
Y(3);
19
The way I have it above, the statement which assigns to Y happens to contain all the individual steps. And that's the only statement above which you'd need to execute, to get the operator that I assigned to Y.If you prefer you could do each step separately and assign each intermediate result to some name. It just depends on whether you want them for any other purpose.
restart:
dsol := dsolve({diff(y(t), t) = y(t)*t, y(1) = 1}, y(t), series, t = 1, order = 5):
peq := convert( dsol, polynom ):
p := eval( y(t), peq ):
Y := unapply( p, t ):
Y(3);
19

Related

MATLAB | f=#(x) function handle with range + conv

I have these functions with the code that aims to plot the two signals - x(t) and h(t) - alongside their time range then find the convolution of the two signals.
x=#(t) 2.*((-2<=t&&t<=1)+2).^2.*18.*(2<=t&&t<=3).*-9.*((4<=t&&t<=5)-5);
tx=-2:0.01:5;
h=#(t) 3*(0<=t&&t<=2) -6*((4<=t&&t<=4)-3);
th=0:0.01:4;
c=conv(x(tx),h(th));
tc=(tx(1)+th(1)):0.01:(tx(end)+th(end));
figure(1)
subplot(3,1,1); plot(tx,x(tx));
subplot(3,1,2); plot(th,h(th));
subplot(3,1,3); plot(tc,c);
However, I got this error.
Operands to the || and && operators must be convertible to logical scalar values.
Error in #(t)2.*((-2<=t&&t<=1)+2).^2.*18.*(2<=t&&t<=3).*-9.*((4<=t&&t<=5)-5)
I want to use function handle to plot them.
Is there a way to fix this problem?
Thanks in advance for your answers.
The error message is pretty clear about the problem: the double operators && and || are only suitable for scalar values (they are called short-circuit operators. For vector-wise computation use their single versions & and | (so-called element-wise operators.
The difference is crucial if it comes to runtime:
With logical short-circuiting, the second operand, expr2, is evaluated only when the result is not fully determined by the first operand, expr1.
so simply change your code to
x = #(t) 2.*( ((-2 <= t) & (t <= 1)) +2).^2.*18.*((2 <= t) & (t <= 3)).*-9.*( ((4 <= t) & (t <= 5)) -5);
h = #(t) 3*((0 <= t) & (t <= 2)) -6*( ((4 <= t) & (t <=4) ) -3);
ADDED Although this was not your answer, you can get the desired plot with the following snippet
% upper level
upLvl = 17;
x_cnst = #(t) upLvl.*(t>=1 & t<3);
x_lin = #(t) (upLvl-(upLvl/2.*(t-3))).*(t>=3 & t<=5);
x_exp = #(t) upLvl/exp(3)*exp(t+2).*(t<1);
x = #(t) x_exp(t) + x_cnst(t) + x_lin(t);
h = #(t) 3.*t.*(t < 2) +(6-3.*(t-2)).*( t >= 2);
I broke the function up into the individual sections to keep a better overview. Nevertheless, I recommend to rather write a complete function with if-elseif statements than to use anonymous function handles in this case.

Restricting domain of function for Fourier transform [duplicate]

I am trying to generate a piecewise symbolic function in Matlab. The reason it has to be symbolic is I want to be able to integrate/differentiate the function afterwards and/or insert actual values. I have the following function:
x^3/6 -> 0 < x <= 1
(1/6)*(-3*x^3+12*x^2-12x+4) -> 1 < x <= 2
(1/6)*(3*x^3-24*x^2+60x-44) -> 2 < x <= 3
(1/6)*(4-x)^3 -> 3 < x <= 4
0 -> otherwise
For example, I want to put this function in a variable (let's say f) and then call
int(diff(f, 1)^2, x, 0, 4) % numbers could be different
and get the (scalar) result 2/3.
I tried various things, involving the piecewise() function and symbolic comparisions, but nothing worked... can you help? :-)
One option is to use the heaviside function to make each equation equal zero outside of its given range, then add them all together into one equation:
syms x;
f = (heaviside(x)-heaviside(x-1))*x^3/6 + ...
(heaviside(x-1)-heaviside(x-2))*(1/6)*(-3*x^3+12*x^2-12*x+4) + ...
(heaviside(x-2)-heaviside(x-3))*(1/6)*(3*x^3-24*x^2+60*x-44) + ...
(heaviside(x-3)-heaviside(x-4))*(1/6)*(4-x)^3;
double(int(diff(f, 1)^2, x, 0, 4))
ans =
0.6667
Another alternative is to perform your integration for each function over each subrange then add the results:
syms x;
eq1 = x^3/6;
eq2 = (1/6)*(-3*x^3+12*x^2-12*x+4);
eq3 = (1/6)*(3*x^3-24*x^2+60*x-44);
eq4 = (1/6)*(4-x)^3;
total = int(diff(eq1, 1)^2, x, 0, 1) + ...
int(diff(eq2, 1)^2, x, 1, 2) + ...
int(diff(eq3, 1)^2, x, 2, 3) + ...
int(diff(eq4, 1)^2, x, 3, 4)
total =
2/3
UPDATE:
Although it's mentioned in the question that the piecewise function didn't work, Karan's answer suggests it does, at least in newer versions. The documentation for piecewise currently says it was introduced in R2016b, but it was clearly present much earlier. I found it in the documentation for the Symbolic Math Toolbox as far back as R2012b, but the calling syntax was different than it is now. I couldn't find it in earlier documentation for the Symbolic Math Toolbox, but it did show up as a function in other toolboxes (such as the Statistics and Spline Toolboxes), which explains its mention in the question (and why it didn't work for symbolic equations at the time).
Starting R2016b, use the piecewise function
syms x
y = piecewise(x<0, -1, x>0, 1)
y =
piecewise(x < 0, -1, 0 < x, 1)
For this case:
syms x
f = piecewise( ...
0< x <=1, x^3/6, ...
1 < x <= 2, (1/6)*(-3*x^3+12*x^2-12*x+4), ...
2 < x <= 3, (1/6)*(3*x^3-24*x^2+60*x-44), ...
3 < x <= 4, (1/6)*(4-x)^3, ...
0)
f =
piecewise(x in Dom::Interval(0, [1]), x^3/6, x in Dom::Interval(1, [2]), - x^3/2 + 2*x^2 - 2*x + 2/3, x in Dom::Interval(2, [3]), x^3/2 - 4*x^2 + 10*x - 22/3, x in Dom::Interval(3, [4]), -(x - 4)^3/6, 0)
int(diff(f, 1)^2, x, 0, 4)
ans =
2/3

Trapezodial Rule Matlab

I am completing an assignment for a class. We were to follow a flow chart to find the values for the trap rule code. I believe the problem is with my main code.
I am not sure if there is a problem with my function code or my main code, any help would be appreciated.
when I run the section, it display the function as the answer
The following is my mainscript code:
f = #(x) (4*sin (x)) / (exp(2*x)) ;
trap_haskell(f , 0 , 3 , 7)
The rest is my trapezoidal rule code
function [f] = trap_haskell(f, a, b, n)
x = a ;
h = (b - a) / n ;
s = f (a) ;
for k=1:1:n-1
x = x + h ;
s = s + 2 * f(x) ;
end
s = s + f(b) ;
I = (b - a) * s / (2 * n) ;
end
You're returning f as the output argument of trap_haskell which is the input function into trap_haskell itself. The variable I in your code actually stores the integral so it's simply a matter of changing the output variable of the function definition to return the integral instead:
%// ------ Change here
%// |
%// V
function [I] = trap_haskell(f, a, b, n)

Matlab - define a general variable

I want to calculate Fourier series for some function func.
I build this method:
function y = CalcFourier(accurate, func, a, b, val_x)
f = #(x) eval(func);
% calculate coefficients
a0 = (2 / (b - a)) * calcArea(func, a , b);
an = (2 / (b - a)) * calcArea(strcat(func, '*cos(2*n*pi*x / (b - a))'), a , b);
an = (2 / (b - a)) * calcArea(strcat(func, '*sin(2*n*pi*x / (b - a))'), a , b);
partial = 0;
an_f = #(n) an;
bn_f = #(n) bn;
for n = 1:accurate
partial = partial + an_f(n)* cos(2*n*pi*val_x / (b - a)) + bn_f(n) * sin(2*n*pi*val_x / (b - a));
end
y = (a0 / 2) + partial;
end
And this - to approximate the coefficient's:
function area = calcArea(func, a, b)
f = #(x) eval(func);
area = (a - b) * (f(a) - f(b)) / 2;
end
On line an = (2 / (b - a)) * calcArea(strcat(func, '*cos(2*n*pi*x / (b - a))'), a , b); I'm getting error:
??? Error using ==> eval
Undefined function or variable 'n'.
Error in ==> calcArea>#(x)eval(func) at 2
f = #(x) eval(func);
Error in ==> calcArea at 3
area = (a - b) * (f(a) - f(b)) / 2;
Error in ==> CalcFourier at 5
an = (2 / (b - a)) * calcArea(strcat(func,
'*cos(2*n*pi*x / (b - a))'), a , b);
>>
Is there any option to declate n as "some constant"? Thanks!
You try to use a variable called n in line 4 of your code. However at that time n is not defined yet, that only happens in the for loop. (Tip: Use dbstop if error at all times, that way you can spot the problem more easily).
Though I don't fully grasp what you are doing I believe you need something like this:
n=1 at the start of your CalcFourier function. Of course you can also choose to input n as a variable, or to move the corresponding line to a place where n is actually defined.
Furthermore you seem to use n in calcArea, but you don't try to pass it to the function at all.
All of this would be easier to find if you avoided the use of eval, perhaps you can try creating the function without it, and then matlab will more easily guide you to the problems in your code.
if the symbolic toolbox is available it can be used to declare symbolic variables , which can be treated as 'some variable' and substituted with a value later.
however a few changes should be made for it to be implemented, generally converting anonymous functions to symbolic functions and any function of n to symbolic functions. And finally the answer produced will need to be converted from a symbolic value to some more easy to handle value e.g. double
quickly implementing this to your code as follows;
function y = test(accurate, func, a, b, val_x)
syms n x % declare symbolic variables
%f = symfun(eval(func),x); commented out as not used
The two lines above show the declaration of symbolic variables and the syntax for creating a symbolic function
% calculate coefficients
a0 = symfun((2 / (b - a)) * calcArea(func, a , b),x);
an = symfun((2 / (b - a)) * calcArea(strcat(func, '*cos(2*n*pi*x / (b - a))'),...
... a , b),[x n]);
bn = symfun((2 / (b - a)) * calcArea(strcat(func, '*sin(2*n*pi*x / (b - a))'),...
... a , b),[x n]);
partial = 0;
the function definitions in in your code are combined into the lines above, note they functions are of x and n, the substitution of x_val is done later here...
for n = 1:accurate
partial = partial + an(val_x,n)* cos(2*n*pi*val_x / (b - a)) +...
... bn(val_x,n) * sin(2*n*pi*val_x / (b - a));
end
The for loop which now replaces the symbolic n with values and calls the symbolic functions with x_val and each n value
y = (a0 / 2) + partial;
y = double(y);
end
Finally the solution is calculated and then converted to double;
Disclaimer: I have not checked if this code generates the correct solution, however I hope it gives you enough information to understand what has been changed and why to carry out the process given in your code above, using the symbolic toolbox to address the issue...

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.