MATLAB Unable to Store Symbolic Function with Multiple Variables - matlab

I'm trying to take the definite integral from -1 to 1 of a function with respect to x. The function has variables a, b, c, d, and x, all of which I've defined as syms variables. I'm trying to keep a, b, c, d in my final integral because I'll later be differentiating with respect to each one for an optimization problem. Here's the current code that I have:
syms f(x);
syms a b c d;
f(x)= (exp(x)-a*(1/sqrt(2))-b*(sqrt(3/2)*x)-c((sqrt(45/8))*(x^2-(1/3)))+d((sqrt(175/8))*((x^3)-(3/5)*(x))))^2;
integral = int(f, x, [-1 1]);
disp(integral);
Similar code worked when I tried it using only variables x and y for a smaller function. However, when I try this code, I get:
Error using sym/subsindex (line 825) Invalid indexing or function
definition. Indexing must follow MATLAB indexing. Function arguments
must be symbolic variables, and function body must be sym expression.
Error in sym/subsref (line 870)
R_tilde = builtin('subsref',L_tilde,Idx);
Error in HW11 (line 4)
f(x)= (exp(x)-a*(1/sqrt(2))-b*(sqrt(3/2)x)-c((sqrt(45/8))(x^2-(1/3)))+d((sqrt(175/8))((x^3)-(3/5)(x))))^2;
I'm pretty new to symbolic functions and syms variables in MATLAB, why is MATLAB rejecting this code? The similar code that I tried that worked was:
syms f(x);
syms y;
f(x) = (x^2) + y;
integral = int(f, x, [0 3]);
disp(integral);

As mentioned in the comment by Adam, you probably forgot to add a multiplication operator * after the the c and d, so when you write c(...) and d(...) MATLAB treats these as indexing of an array but you cannot index arrays with symbolic variables or expressions. You need to change it to c*(...) and d*(...).
Replace:
f(x)= (exp(x)-a*(1/sqrt(2))-b*(sqrt(3/2)*x)-c((sqrt(45/8))*(x^2-(1/3)))+d((sqrt(175/8))*((x^3)-(3/5)*(x))))^2;
With:
f(x)= (exp(x)-a*(1/sqrt(2))-b*(sqrt(3/2)*x)-c*((sqrt(45/8))*(x^2-(1/3)))+d*((sqrt(175/8))*((x^3)-(3/5)*(x))))^2;

Related

Octave integration does not evaluate definite integral with symbolic variables

I am trying to evaluate a convolution integral using the symbolic int() function and instead of returning a useful answer, my program is returning the integral itself. Here is my code
clc; clear;
pkg load symbolic
syms t tau Wn % Declare symbolic variables
f = tau^2 * sin( Wn *(t-tau) );
convolution = int( f, tau, [0 t] ); % Specify tau as the integration variable
% and integration limits are from 0 to t
pretty(convolution)
The code runs, but does not return something useful. Instead of returning an answer, it returns this:
t
⌠
⎮ 2
⎮ τ ⋅sin(Wn⋅t - Wn⋅τ) dτ
⌡
0
i.e. the original integral with the function inside of it.
I've tried troubleshooting the problem in the following ways:
Copy/pasting example code from the Octave int() help page, this works and evaluates the definite integral
Changing the integration syntax from 0, t to [0, t] this changes nothing
Making variable f and storing the function there, instead of the function being inside of int(). This changes nothing
I know the symbolic package is working, because the example code returns the correct definite integral.
Thanks.
You can use eval in order to "evaluate" (duh) the integral. E.g. with your code above, I get:
octave:9> eval( convolution )
ans = (sym)
⎧ 2
⎪t 2⋅cos(Wn⋅t) 2
⎪── + ─────────── - ─── for Wn > -∞ ∧ Wn < ∞ ∧ Wn ≠ 0
⎨Wn 3 3
⎪ Wn Wn
⎪
⎩ 0 otherwise
Note that if you actually 'define' some of those symbols on the workspace, then these get taken into account:
octave:10> Wn = 1; % or preferably `sym('1')` ...
octave:11> eval( convolution )
ans = (sym)
2
t + 2⋅cos(t) - 2

How to use matrix entries in a double symsum?

I am trying to implement the following double summation in a function:
f(x,y)=\sum_{k=0}^{S}\sum_{l=0}^{S}{a_{kl}x^ky^l}.
Here is my first attempt:
function [ a ] = MyFun( S )
a=randi([0 9],S+1);
syms x y k l;
f(x,y)=symsum(symsum(a(k,l)*x^k*y^l,l,1,S+1),k,1,S+1);
f(1,2)
end
Actually, my code evaluates f in a loop later on, but that does not seem relevant here. Trying something like MyFun(3) results in an error:
Error using sym/subsindex (line 766) 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 ':'.
Error in MyFun (line 4)
f(x,y)=symsum(symsum(a(k,l)*x^(k-1)*y^(l-1),l,1,S+1),k,1,S+1);
Everything works fine if a(k,l)* is removed from the inner symsum, so I suspect that there is something wrong with the indices. Is it not possible to use the symbolical variables k and l as indices? If not, how can I solve this?
Indexing a matrix using a symbolic value does not seem to work. As an alternative you can use elementwise multiplication as follows:
function f = MyFun( S )
a=randi([0 9],S+1);
k = repmat((0:S)', 1, S+1);
l = repmat((0:S), S+1, 1);
syms x y;
f(x, y) = sum(sum(a .* x.^k .* y.^l));
end

How to use derive.m function to get central differentioation of f(x)

I've a function that can calculate central difference of f(x) but I'm basic user of matlab and I can't define f(x) for function I've mentioned.
Can any body help me and define f(x) for this function?
INPUTS are a function f; a value
of h; a specific point a; the number of rows n. The input function f(x)
should be defined as an M-file.
My f(x) is : S(x) = 10*x-sin(x) with steps: 0.1
I want to get df(x) near the piont=pi/6
I wrote:
clc
syms x
derive(10*x-sin(x),0.1,pi/6,14)
but I've got this error :
Error using feval
Argument must contain a string or function_handle.
Error in derive (line 7)
D(1,1)=(feval(f,a+h)-feval(f,a-h))/(2*h);
Error in centre(line 2)
========================================
the function derive.m is here:
function derive(f,h,a,n)
% Approximate the derivative of a function at x = a.
disp(' Derivative table')
disp('______________________________________________')
disp(' i h Di,1 Di,2 Di,3 ... ')
disp('______________________________________________')
D(1,1)=(feval(f,a+h)-feval(f,a-h))/(2*h);
fprintf('%2.0f %8.4f %12.4f\n',1,h,D(1,1));
for i=1:n-1
h=h/2;
D(i+1,1)=(feval(f,a+h)-feval(f,a-h))/(2*h);
fprintf('%2.0f %8.4f %12.4f',i+1,h,D(i+1,1));
for k=1:i
D(i+1,k+1)=D(i+1,k)+(D(i+1,k)-D(i,k))/((4^k)-1);
fprintf('%12.4f',D(i+1,k+1));
end
fprintf('\n');
end
feval expects a function handle, that is a MatLab function handle. What you provided (10*x-sin(x)) is a symbolic expression.
You can define a function handle as follows:
f(x) = 10*x-sin(x);
Now f is a MatLab function handle, and you can use it as you wish:
derive(f,0.1,pi/6,14)
EDIT
You can also use an anonymous functions
derive((x)(10*x-sin(x)),0.1,pi/6,14)
END EDIT
Note, you do not need syms x, it defines x as a symbol, but in your function definition you use the parameter x defined in f(x).
EDIT
If you want to use a symbolic function, you can convert it to a MatLab function handle using matlabFunction

Numerical integration of symbolic differentiation - MATLAB

The following is a MATLAB problem.
Suppose I define an function f(x,y).
I want to calculate the partial derivative of f with respect to y, evaluated at a specific value of y, e.g., y=6. Finally, I want to integrate this new function (which is only a function of x) over a range of x.
As an example, this is what I have tried
syms x y;
f = #(x, y) x.*y.^2;
Df = subs(diff(f,y),y,2);
Int = integral(Df , 0 , 1),
but I get the following error.
Error using integral (line 82)
First input argument must be a function
handle.
Can anyone help me in writing this code?
To solve the problem, matlabFunction was required. The solution looks like this:
syms x y
f = #(x, y) x.*y.^2;
Df = matlabFunction(subs(diff(f,y),y,2));
Int = integral(Df , 0 , 1);
Keeping it all symbolic, using sym/int:
syms x y;
f = #(x, y) x.*y.^2;
Df = diff(f,y);
s = int(Df,x,0,1)
which returns y. You can substitute 2 in for y here or earlier as you did in your question. Not that this will give you an exact answer in this case with no floating-point error, as opposed to integral which calculated the integral numerically.
When Googling for functions in Matlab, make sure to pay attention what toolbox they are in and what classes (datatypes) they support for their arguments. In some cases there are overloaded versions with the same name, but in others, you may need to look around for a different method (or devise your own).

why isn't the result a scalar?

i'm stuck with this error:
In an assignment A(I) = B, the number of elements in B and I must be the same.
yres(1)=((u - uc).^2) + ((y - yc).^2) -(d.^2);
i don't understand, why this won't get a skalar?since the elements are all scalar. what should be changed to get a scalar?
best regards
edit: thanks sloede, all inputs are scalar, but i still get this error
In an assignment A(I) = B, the number of elements in B and I must be the
same.
Error in myfun (line 7)
yres(1)=sqrt(((u - uc).^2) + ((y - yc).^2) ) -d;
Error in fsolve (line 241)
fuser = feval(funfcn{3},x,varargin{:});
Error in modfsolve (line 26)
x= fsolve(#myfun,x0,options,uc,d,spacing_amplitude,spacing_width);
Caused by:
Failure in initial user-supplied objective function evaluation. FSOLVE
cannot continue.*
The "." before an operator means that the following operation should be applied element-wise and not on the vector as a whole. Thus
a = b.^2
will give you as a result all elements of b squared and saved back to a. Therefore, in your code statement above, if any of u, uc, y, yc, d are not scalar but a vector, your result will be a vector as well.
Otherwise there seems to be nothing wrong with your code.
read the documentation of fsolve: http://www.mathworks.nl/help/toolbox/optim/ug/fsolve.html
it states:
fun
The nonlinear system of equations to solve. fun is a function that accepts a vector x and returns a vector F, the nonlinear equations evaluated at x.
Obviously your function myfun doesn't handle vector input.
You can solve this by adding the following construction inside your function (and of course change it to your needs/your parameters):
function out = myfun(in)
if ~isscalar(in)
% assuming it's a matrix or vector
out = reshape(arrayfun(#myfun,in(:)),size(in));
else
% your actual function execution statements
out = dostuffon(in);
end
end
or properly vectorize your function (if that's possible)