Well, I know, for a normal case, if I define
syms x,y
K = f(x,y)
as an explicit expression on x and y, we can do diff(K, x) or diff(K, y) to obtain what we want.
But right now, if I have another function
J = g(K)
And I want to do
diff(J, K)
then error occurs as:
'The second argument must be a variable or a non negative integer specifying the number of differentiations.'
So, in a nutshell, how to solve this kind of 'chained expression differentiation'? (Sorry for this ambiguous description.)
According to the diff function in Matlab,
The first argument should be the function you want to differentiate
and the remaining arguments must be either the symbolic variables or a
non-negative number which represents the number of differentiation.
So, the error.
The second argument must be a variable or a non negative integer specifying the number of differentiations.
In the code diff(J, K) is saying that K is a symbolic variable to the Matlab but in actual case, K is an expression in the terms of x and y. So, this is the reason why Matlab is throwing that error.
So if you want to differentiate a chained function with variables x, y then you need to mention each symbolic variables explicitly within the diff() function whenever you want to differentiate that expression. The code to do so is below.
% define the symbolic functions
% as f(x,y) and g(K)
syms f(x,y) g(K)
% create the functions
K = f(x,y)
J = g(K)
% differentiate the functions with
% respect to x and y respectively.
% ------------------------
% differentiate w.r.t x
diff_K_x = diff(K, x)
% differentiate w.r.t y
diff_K_y = diff(K, y)
% -----------------------
% differentiate the function J with respect to x and y both
diff_K_xy = diff(J,x,y)
Related
I am new to Octave (and matlab for that matter). I have a function that looks like this
I would like to plot g(x,0.5,5) say.
Here it is what I tried in Octave
I defined an anonymous function
f=#(n,x,t) 1./n.*log(n.*pi.*t).*sin(n.*pi.*x);
then another anonymous function
g=#(m,x,t)x.^2+sum(f([1:m],x,t));
Finally defined
x=-1:0.1:1;
plot(x,g(5,x,0.5))
but I get an error. Is this the right way of plotting this function? I must be doing a simple beginner error?
When you call f(n,x,t), you are passing a 1-by-5 vector for n and a 1-by-21 vector for x. These have different numbers of elements, and therefore can't be multiplied element-by-element. However, you can rewrite f to accommodate vectors for each and perform the sum from g by using matrix multiplication:
f = #(n, x, t) (1./n.*log(n.*pi.*t))*sin(pi.*n(:)*x);
g = #(m, x, t) x.^2 + f(1:m, x, t);
And now your plot will work:
x = -1:0.1:1;
plot(x, g(5, x, 0.5));
I get an error when trying to multiply a symbolic function and a symbolic integral:
eta02=vpa(-i*omega2/((i*alpha2*lambda_0)^(2/3)),prec); %whatever
eta_inf2=vpa(vpa(((i*alpha2*lambda_0)^(1/3))*YMAX,prec)+eta02,prec); %whatever
%%
syms lu
syms x
myairyf(lu)= airy(lu);
mybairyf(lu)=airy(2,lu);
Gi2(x)=-(mybairyf*int(myairyf,lu,[eta_inf2,(x)])-myairyf*int(mybairyf,lu,[eta02,(x)]));
Error using sym/subsindex (line 769)
Invalid indexing or function definition. When defining a function, ensure that the arguments are symbolic variables and the body of the
function is a SYM expression. When indexing, the input must be numeric, logical, or ':'.
How can this be done? Additionally, how could I plot Gi2(x), given that it's symbolic?
By using the symfun function.
Gi2 = sumfun(-(mybairyf*int(myairyf,lu,[eta_inf2,(x)])-myairyf*int(mybairyf,lu,[eta02,(x)])), x);
Now Gi2(val) will evaluate the function for the value ´val´
Plotting then can be done by evaluating this function for the values you want to plot for, storing them in a vector, and plot the x and y values.
xvals = linspace(0,10,100);
yvals = Gi2(xvals);
figure
plot(xvals,vals)
I am trying to compute the second derivative of the airy function. Only its first derivative is a predefined function in MATLAB (airy(1,x))
Is there a way to compute its symbolic derivative? without resorting to finite differences, etc
I tried this
syms x
aiprime = #(x) airy(1,x);
aisecond = diff(airy(1,x));
plot(-10:0.01:10,aiprime,aisecond)
But didn't work.
Error using plot
Invalid second data argument
The problem is your plot statement. You specify the desired x-data, but did not evaluate your function in these points:
syms x
aiprime(x) = airy(1,x); % I would define it as a symbolic function instead of a function handle, although it works too.
aisecond(x) = diff(airy(1,x)); % Define as a function, to be able to evaluate the function easily
xs = -10:0.01:10; % define your desired x points
plot(xs,aiprime(xs),xs, aisecond(xs)) % evaluate your functions and plot data
I made the following function handler:
fhapprox1 = #(x, y) sum ([1:x] .^ y)
This works fine when called with arguments like fhapprox1(3,5). However, when passing this function to ezmesh (using ezmesh(fhapprox1)), I get the following error:
error: operator .^: nonconformant arguments (op1 is 1x0, op2 is 60x60)
What is happening here? How can I rewrite this to get the 3d graph I'm expecting?
This is because your function is only designed to handle single values of x and y. ezmesh uses a grid of co-ordinates and x and y are actually 2D matrices when you use ezmesh. You get undefined behaviour when trying to call up ezmesh this way. In addition, ezmesh plots between -2*pi <= (x,y) <= 2*pi by default.
Because x can be < 0, doing 1:x when x is negative will give you an empty array, which is why you get that error. You need to rethink how your function can be defined so that it takes in a grid of co-ordinates and outputs the values you want. I can't provide anything further because I don't know how your function would be defined for negative values of x. Once I get this information, I'll update my answer.
Edit
We can modify your fhapprox1 function so that it can take in a grid of values. I can't think of a way to vectorize this code right now other than doing nested for loops, but let's try and get something working first. Basically, make a separate M-file that's called fhapprox1.m. After, put this into the file:
function [Z] = fhapprox1(X, Y)
Z = zeros(size(X));
for x = 1 : size(X,1)
for y = 1 : size(X,2)
Z(x,y) = sum((1:X(x,y)) .^ Y(x,y));
end
end
The above code will do what you were doing for single values of (x,y), but now it can take in a grid of (x,y) co-ordinates. By doing this, then calling ezmesh in the way you specified in your comments, this is what we get:
ezmesh(#fhapprox1, [1,1000,1,3])
I would like to numerically integrate a vector which represents a function f(x) over the range of x specified by bounds x0 and x1 in Matlab. I would like to check that the output of the integration is correct and that it converges.
There are the quad and quadl functions that serve well in identifying the required error tolerance, but they need the input argument to be a function and not the resulting vector of the function. There is also the trapz function where we can enter the two vectors x and f(x), but then it computes the integral of f(x) with respect to x depending on the spacing used by vector x. However, there is no given way using trapz to adjust the tolerance as in quad and quadl and make sure the answer is converging.
The main problem why I can't use quad and quadl functions is that f(x) is the following equation:
f(x) = sum(exp(-1/2 *(x-y))), the summation is over y, where y is a vector of length n and x is an element that is given each time to the function f(x). Therefore, all elements in vector y are subtracted from element x and then the summation over y is calculated to give us the value f(x). This is done for m values of x, where m is not equal to n.
When I use quadl as explained in the Matlab manual, where f(x) is defined in a separate function .m file and then in the main calling file, I use Q = quadl(#f,x0,x1,tolerance,X,Y); here X is a vector of length m and Y is a vector of length L. Matlab gives an error: "??? Error using ==> minus
Matrix dimensions must agree." at the line where I define the function f(x) in the .m function file. f(x) = sum(exp(-1/2 *(x-y)))
I assume the problem is that Matlab treats x and y as vectors that should be of the same length when they are subtracted from each other, whereas what's needed is to subtract the vector Y each time from a single element from the vector X.
Would you please recommend a way to solve this problem and successfully numerically integrate f(x) versus x with a method to control the tolerance?
From the documentationon quad it says:
The function y = fun(x) should accept a vector argument x and return a vector result y, the integrand evaluated at each element of x.
So every time we call the function, we need to evaluate the integrand at each given x.
Also, to parameterize the function call with the constant vector Y, I recommend an anonymous function call. There's a reasonable demo here. Here's how I implemented your problem in Matlab:
function Q = test_num_int(x0,x1,Y)
Q = quad(#(x) myFun(x,Y),x0,x1);
end
function fx = myFun(x,Y)
fy = zeros(size(Y));
fx = zeros(size(x));
for jj=1:length(fx)
for ii=1:length(Y)
fy(ii) = exp(-1/2 *(x(jj)-Y(ii)));
end
fx(jj) = sum(fy);
end
end
Then I called the function and got the following output:
Y = 0:0.1:1;
x0 = 0;
x1 = 1;
Q = test_num_int(x0,x1,Y)
Q =
11.2544
The inputs for the lower and upper bound and the constant array are obviously just dummy values, but the integral converges very quickly, almost immediately. Hope this helps!
I believe the following would also work:
y = randn(10,1);
func = #(x) sum(exp(-1/2 *(x-y)));
integral(func,0,1,'ArrayValued',true)