I've been trying to plot a graph of function f(x) on interval 0,6. For some reason maple doesn't plot the graph when I use 'f(x)' as an argument. It works fine when I substitute assigned function as an argument. What can be the reason? How can I plot it using 'f(x)' as an argument?
My code is as follows and the error is on the pictures:
mystep:=proc(x,a,b,c)
if x<a
then
b;
else
c;
end if:
end proc:
f(x):=mystep(x,3,-2,7);
plot('f(x)', x=0..6);
enter image description here
Your syntax for creation of the operator (that you hope to assign to f) is incorrect for 1D plaintext input.
Here is the usual syntax for creation of such an operator, and assignment to name f.
restart;
mystep:=proc(x,a,b,c)
if x<a then b; else c; end if:
end proc:
f:=x->mystep(x,3,-2,7);
These should now all work as you expect.
plot('f(x)', x=0..6);
plot(f, 0..6);
plot(x->mystep(x,3,-2,7), 0..6);
In recent versions of Maple the syntax that you used can work in (only) 2D Input mode. But it is a poor syntax to use, since is easily confused with the 1D syntax for assigning into the remember table of an operator (and with even more confusion ensuing). You should avoid ambiguous syntax.
The type of function you have is piecewise-defined function (see this wikipedia page https://en.wikipedia.org/wiki/Piecewise). And in Maple there is already a command for defining this type of a function, piecewise, see its help page for a complete explanation of how to use it. Now for your mysetup, you have a condition x < a, and a value for when this happens, b, and a value for otherwise, c. So you want piecewise( x < a, b, c ). I think it is better to just use this command, but if it is really necessary to define a new procedure, then your mysetup becomes like the following.
mystep := proc(x, a, b, c)
return( piecewise( x < a, b, c ) ):
end proc:
Now for your plot you can use either
plot( piecewise( x < 3, -2, 7 ), x = 0..6 );
or
f(x) := mystep(x, 3, -2, 7);
plot( f(x), x = 0..6);
Related
Where does the following matlab code go wrong?
C=sym('a',[2,1]);
A=sym('aa',2);
A(1,1)=C(1)-10*C(2)*C(2);
A(2,2)=C(2);
subs(A(1,1),C(1),solve(trace(A)==1,C(1)));
disp(A);
As I understand it, the diagonal elements of A are set to functions of a1 and a2. Then, in the expression at position A(1,1), substitute for C(1) (which is a1), the solution to trace(A)==1 for the variable C(1). But when you display the matrix A, it seems unchanged.
What is the error? Why is subs not working as intended? The above is the smallest non-working example of large code.
There is no error in the code. The subs = subs(s, old, new) function returns by definition a copy of s after all occurrences of old are replaced with new, and then evaluates s.
What your code does is: Define A, call subs and then display A. Since subs does not effect the entries of A by the above explanation, you get the "old" A displayed.
Hence, if you want to replace the value A(1, 1) with the expression which subs created for you, you should e.g. use
A(1, 1) = subs(C(1) , solve(trace(A) == 1, C(1)));
As I understand you try to replace the element at A(1,1) with the result from solving the equation. In this case, you should do something like that:
C = sym('a',[2,1]);
A = sym('aa',2);
A(1,1) = C(1);
A(2,2) = C(2);
A(1,1) = subs(C(1),solve(trace(A) == 1, C(1)));
disp(A);
This will display the following:
[ 1 - a2, aa1_2]
[ aa2_1, a2]
I have written a function called "tension.m" in which I have used if else condition as shown below.
function [T,T_earlyvalues,T_latervalues] = tension(u,sigma,G,N,K)
%the values of sigma,G,N,K can be taken arbitrary.
sigma=2; G=3;N=8;K=1; v=1;
w=2.2;
if u<w
T =v*sqrt(sigma+G^2/(N-K));
T_earlyvalues=T;
else
T=(2*v)*sqrt(sigma+G^2/(N+K));
T_latervalues=T;
end
Now in another script "myvalues.m" I need to call T_earlyvalues and T_latervalues separately.
%have some coding before this part
sigma0=2400; lambda=1.3; v=2; sigma=2; G=3;N=8;K=1;
u=0:0.01:5;
T=tension(u,sigma,G,N,K);
T_earlyvalues=tension(u,sigma,G,N,K);
T_latervalues=tension(u,sigma,G,N,K);
deltaA=T_earlyvalues*sigma0*pi;
deltaB=T_latervalue*lambda*pi/2;
%have some coding after this part
How could I call the said values which are under if-else statement from tension.m function to myvalues.m script?
You have defined the tension function such that it returns three outputs.
If you call that function by requiring only one output, the function returns the first value, in your case, T
This implies that
T=tension(u,sigma,G,N,K);
shoud work since T is the first output parameter
T_earlyvalues=tension(u,sigma,G,N,K);
T_latervalues=tension(u,sigma,G,N,K);
are not working, since, actually tension returns the first value (T, whjikle you are expecting the second and the third respectively.)
You can cahnge the two above calls this way:
[~,T_earlyvalues,~]=tension(u,sigma,G,N,K);
[~,~,T_latervalues]=tension(u,sigma,G,N,K);
The ~ allows to avoid the function return the output paraemter.
You can find additional information here
Notice that in your function T_earlyvalue is not set in the else block, same for T_latervalue in the if block.
This will generate an error such as
Output argument T_earlyvalue (and maybe others) not assigned during call to tension
or
Output argument T_latervalues (and maybe others) not assigned during call to tension
You can initialize the output values to default values, at the beginning of the function, for example:
T=NaN
T_earlyvalue=NaN
T_latervalues=NaN
You can then use these special values (or any other you want to use) to trace, for example, if the if block has been executed or the else.
There seem to be a number of issues here, not the least of which is some confusion about how output argument lists work when defining or calling functions. I suggest starting with this documentation to better understand how to create and call functions. However, this issue is somewhat moot because the larger problem is how you are using your conditional statement...
You are trying to pass a vector u to your function tension, and from what I can tell you want to return a vector T, where the values of T for u < w are computed with a different formula than the values of T for u >= w. Your conditional statement will not accomplish this for you. Instead, you will want to use logical indexing to write your function like so:
function [T, index] = tension(u, sigma, G, N, K)
T = zeros(size(u)); % Initialize T to a vector of zeroes
w = 2.2;
index = (u < w); % A logical vector, with true where u < w, false where u >= w
T(index) = u(index)*v*sqrt(sigma+G^2/(N-K)); % Formula for u < w
T(~index) = 2*(u(~index)-v)*sqrt(sigma+G^2/(N+K)); % Formula for u >= w
end
Now you can call this function, capturing the second output argument to use for identifying "early" versus "late" values:
sigma0 = 2400; lambda = 1.3; v = 2; sigma = 2; G = 3; N = 8; K = 1;
u = 0:0.01:5;
[T, earlyIndex] = tension(u, sigma, G, N, K); % Call function
T_earlyvalues = T(earlyIndex); % Use logical index to get early T values
T_latervalues = T(~earlyIndex); % Use negated logical index to get later T values
And you can then use the subvectors T_earlyvalues and T_latervalues however you like.
I've calculated coefficients an, bn (100, T=2*pi) in c++ and checked that they are correct using few sources. Now i try to generate Fourier series graph for given example function in Scilab:
(x+2)*abs(cos(2*x*(x-pi/6)))
M=csvRead(filename, ";", [], 'double')
n=size(M,1)
for i = 1:n
A(i)=M(i)
B(i)=M(i + n)
end
function series=solution(x)
series=A(1)/2;
for i = 2:n
series=series+(A(i)*cos(i*x)+B(i)*sin(i*x));
end
endfunction
function series=solution2(x)
series=(x+2).*abs(cos(2.*x.*(x-%pi/6)));
endfunction
x = -%pi:%pi/100:%pi
plot2d(x, solution(x), 3)
x2 = -%pi:%pi/100:%pi
plot2d(x2, solution2(x2), 4)
Here is the result:
It clearly looks that tendency is ok but the beginning and the end of the period are wrong (reversed?). Do you see any issues in Scilab code? What could cause the problem - values in sin/cos in function solution(x)? Should i provide an, bn values and check for miscalculation there?
I don't know how did you calculated your A & B coefficients, but I assume that you used the usual notations to get the first line of the below formula:
Thus n starts from 1. Since Scilab starts vector indexing from 1, you correctly made your loop from 2, but forgot to compensate for this "offset".
Your function should be something like this:
function series=solution(x)
series=A(1)/2;
for i = 2:n
series=series+(A(i)*cos((i-1)*x)+B(i)*sin((i-1)*x));
end
endfunction
Since you didn't provided A & B, I can not check the result.
Additional note: Syntactically more correct if you explicitly define all input variables in a function, like this:
function series=solution(x,A,B)
This way you may be sure that your input is not changed somewhere else in the code.
I have the following code:
s(i+1)=NRK(Dt*f(tv(i+1),x)+s(i)-x,s(i));
Where NRK=NRK(function , numeric scalar) This was the symbolic implementation, with f=symbolic function, and x a symbolic array of unknowns.
The thing is that working with symbolic expressions can solve the issue, but this goes inside a loop, and symbolic tools slow down suprisingly the performance in a ratio of 100 times! However, anonymous functions do a perfect job.
My try was the following:
h=#([arguments (i.e. a, b, c, ...])Dt*f(t(i+1),[arguments (i.e. a, b, c,...])+s(i)-[a b c ...];
s(i+1)=NRK(#h,s(i));
How can I write these arguments? Is it possible?
You can specify them in the parenthesis:
h = #( a, b, c ) Dt*f( t(ii+1), a, b, c ) + s(ii);
Then call
s(ii+1) = NRK( h, s(ii) );
Some remarks:
- You do not need to write an extra # when providing h to NRK, since h is already defined as a function handle.
- It is best not to use i as a variable name in Matlab.
I am writing a program in Matlab and I have a function defined this way.
sum (i=1...100) (a*x(i) + b*y(i) + c)
x and y are known, while a, b and c are not: I need to find values for them such that the total value of the function is minimized. There is no additional constraint for the problem.
I thought of using fminsearch to solve this minimization problem, but from Mathworks I get that functions which are suitable inputs for fminsearch are defined like this (an example):
square = #(x) x.^2
So in my case I could use a vector p=[a, b, c] as the value to minimize, but then I don't know how to define the remaining part of the function. As you can see the number of possible values for the index i is huge, so I cannot simply sum everything together explicitly, but I need to represent the summation in some way. If I write the function somewhere else then I am forced to use symbolic calculus for a, b and c (declaring them with syms) and I'm not sure fminsearch would accept that.
What can I do? Of course if fminsearch turns out to be unfeasible for my situation I accept links to use something else.
The most general solution is to use x and y in the definition of the objective function:
>> objfun = #(p) sum( p(1).*x + p(2).*y + p(3) );
>> optp = fminsearch( objfun, po, ... );