Vector inputs when converting symbolic expression to function handle - matlab

I have a symbolic ODE:
syms x1 x2 cs ks ms t2 real
xx=[x1 x2];
fun_sym=[xx(2); (cs/ms)*(xx(1)^2-1)*xx(2) - (ks/ms)*xx(1)];
I want to solve it using ODE function, but first I need to convert it into function handle:
v=matlabFunction(fun_sym,'vars', [t2,xx,cs,ks,ms]);
[T,x]= ode15s(#(t2,xx) v,t,[1 0]);
where t=[0:0.1:1]. Matlab gives an error:
#(T2,XX)V returns a vector of length 1, but the length of initial conditions vector is 2.
I think this is because it interpret v as: #(t2,x1,x2,cs,ks,ms), so it expects the second argument to be x1, which is a 1-by-1 element, even though I have defined v as [t2,xx,...], where xx is a 1-by-2 element. How can I solve this issue?

This works, but you need to give values to the other parameters as well (cs, ks, and ms)
v=matlabFunction(fun_sym,'vars', [t2,x1,x2,cs,ks,ms]);
[T,x]= ode15s(#(t2,xx) v(t2,xx(1),xx(2),cs,ks,ms),t,[1 0]);

Related

Series-function with vector-coefficients in Matlab

I have a vector v and would like to define a function x using following formular:
Now I try to define this in Matlab, but for some reason I can't access an array within a symsum.
v = [1 2 3 4];
syms k
x = #(t) symsum(v(k) * exp(2*pi*i*k*t/size(v)), k, 1, size(x_n));
When I try to evaluate this Function x(4) I get an exception:
Error using sym/subsindex (line 796)
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 ':'.
Do you know, why? Do you have a solution or workaround?

Get an array of results of a function using as input an array of values (in Matlab)

I want to get the array of results of a function using as input an array of values. The function receives two variables (x1, x2) and a constant x3, so I'm trying to input all combination of it in a range using mesh.
The result is incorrect, I'm missing something.
Sample:
fun = #(x1,x2,x3) (x2-x1^2)^2+(1-x1)^2 + x3;
x3 = 7;
fun2 = #(x) fun(x(1,1),x(1,2),x3);
x0 = [2 3];
min = fminsearch(fun2, x0);
disp(min);
x = min(1)-10:1:min(1)+10;
y = min(2)-10:1:min(2)+10;
[X,Y] = meshgrid(x,y);
% I'm getting strange values here, like z < 0, how it is possible if everything is squared in the function.
Z = fun(X,Y,x3);
It's important to note that there is a difference between matrix and element-wise operations in MATLAB.
Matrix operations are defined via plain operators, such as *, or ^. So for example, A*B performs a matrix multiplication between A and B.
Element-wise operators make use of the dot . before the operator, i.e., .*, .^, and so on. Thus, A.*B performs an element-wise multiplication of A and B. The end result of this operation is an array of the same size as A and B (whose sizes must be equal), where the jj'th element of the array is equal to A(jj)*B(jj).
Now, consider your definition of fun:
fun = #(x1,x2,x3) (x2-x1^2)^2+(1-x1)^2 + x3;
What happens when MATLAB evaluates this expression is that it applies the matrix operations, such as ^ to the input arrays. However, to obtain your desired result of applying the operation to every individual element in your input arrays x1, x2, you should be using element-wise operations.
A new definition
fun = #(x1,x2,x3) (x2-x1.^2).^2+(1-x1).^2 + x3;
should provide the desired result.

Use fminsearch to find local minimizer and the minima at that value

I am having trouble using fminsearch: getting the error that there were not enough input arguments for my function.
f = #(x1,x2,x3) x1.^2 + 3.*x2.^2 + 4.*x3.^2 - 2.*x1.*x2 + 5.*x1 + 3.*x2 + 2.*x3;
[x, val] = fminsearch(f,0)
Is there something wrong with my function? I keep getting errors anytime I want to use it as an input function with any other command.
I am having trouble using fminsearch [...]
Stop right there and think some more about the function you're trying to minimize.
Numerical optimization (which is what fminsearch does) is unnecessary, here. Your function is a quadratic function of vector x; in other words, its value at x can be expressed as
x^T A x + b^T x
where matrix A and vector b are defined as follows (using MATLAB notation):
A = [ 1 -1 0;
-1 3 0;
0 0 4]
and
b = [5 3 2].'
Because A is positive definite, your function has one and only one minimum, which can be computed in MATLAB with
x_sol = -0.5 * A \ b;
Now, if you're curious about the cause of the error you ran into, have a look at fuesika's answer; but do without fminsearch whenever you can.
It is exactly what Matlab is telling you: your function expects three arguments. You are passing only one.
Instead of
[x, val] = fminsearch(f,0)
you should call it like
[x, val] = fminsearch(f,[0,0,0])
since you define the function f to accept a three dimensional vector as input only.
You can read more about the specification of fminsearch in the online documentation at http://mathworks.com/help/matlab/ref/fminsearch.html:
x = fminsearch(fun,x0) starts at the point x0 and returns a value x
that is a local minimizer of the function described in fun. x0 can be
a scalar, vector, or matrix. fun is a function_handle.

How do I put in two variables in a matlab function (ERROR: inner matrix dimensions must agree)?

When I try to plot a function h in MATLAB, using a variable omega which is defined as its own function, I get an Inner matrix dimensions must agree, error using _*_ response from the console.
The function works when I use a + between the seperate function-components of h; It does not work when I try multiplying the two inner functions in h, which is, from what I guess, what causes the matrix dim error.
function h = freqp(omega)
k = (1:1024-1);
hh = (1:1024-1);
omega = zeros(length(k),1);
omega = (k-1)*((2*pi)/1024);
hh = 2*exp((-3j)*omega)*cos(omega); % This works for ...omega) + cos(...
% but not for ...omega) * cos(, why?
y = fft(hh);
stem(real(y), omega);
How can I solve this? I read the info on mathworks but it only gives a solution for e.g. loading a file. Any help would be greatly appreciated!
Since Omega is a vector, the addition works. But multiplication of two vectors will result as a matrix. You can modify
hh = 2*exp((-3j)*omega)*cos(omega);
as
hh = 2*exp((-3j)*omega)*(cos(omega))';
or looking for element wise multiplication,
use
hh = 2*exp((-3j)*omega).*cos(omega);
The part exp((-3j)*omega worked fine because -3j is a complex scalar and omega a vector. Thus, MATLAB multiplies each element of omega with -3i. However, that result is a vector itself. Also cos(omega) is a vector, and both are row vectors.
In this case, with two vectors, the *-operator means dot product but that would be calculated between a column vector and a row vector, not two row vectors. So, [1 2 3] * [4 5 6] will raise the same error you are reporting, but [1 2 3] * [4 5 6]' yields 32.
From invoking fft on hh your code looks, however, as if you never intended to calculate a dot product (a scalar) but instead were looking for element-wise multiplication. The operator for element-wise multiplication is .*, such that your expression would be instead
hh = 2*exp((-3j)*omega).*cos(omega);

Matlab Function with Varying parameters

I need help figuring out how to code the following problem. Any help would be greatly appreciated!
Create a function that will take a vector/array input for x (1 by n) and a scalar input for a, and produce the output defined by the following equation:
y(x,a)=((xsin(ax-2))/(sqrt(1+(ax)^2)
-π ≤ x ≤ π
a={.5 1 1.5 2}
The equation must be vectorized in terms of x and the output from the function is the array y which has the same dimension as the array x.
Write a script that calls this function to compute y(x,a) for the range of x defined above and each value of the parameter a. Results should be stored in a solution matrix using a different row of the solution matrix for each value of a.
So far for my function I have:
function [y] = part1(a,x)
y=((x*sin(a*x-2))/(sqrt(1+(a*x).^2)));
end
I'm not sure how to output this into the solution matrix
For my script I have:
%%
clear,clc
a={0.5 1 1.5 2};
x=-pi:0.1:pi;
for
part1(x,a)
end
I'm getting the following errors when I run this now:
Undefined function 'mtimes' for input arguments of type 'cell'.
Error in part1 (line 4)
y=((x*sin(a*x-2))/(sqrt(1+(a*x).^2)));
Error in labtest2 (line 8)
y(i,:)=part1(x,a(i));
EDIT
I've made some changes and am still getting some errors that I cannot resolve.
Here is my full code for function followed by full code for script:
Function
function [y] = part1(x,a)
nx=numel(x);
na=numel(a);
y=((x.*sin(a.*x-2))./(sqrt(1+(a.*x).^2)));
size(y)=[nx na]
end
Script
%%
clear,clc
a={0.5 1 1.5 2};
x=-pi:0.1:pi;
for i = 1:length(a)
y(i,:)=part1(x,a(i));
end
Errors
Undefined function 'times' for input arguments of type 'cell'.
Error in part1 (line 6)
y=((x.*sin(a.*x-2))./(sqrt(1+(a.*x).^2)));
Error in labtest2 (line 8)
y(i,:)=part1(x,a(i));
The reason you're getting Undefined function 'times' for input arguments of type 'cell' is because your variable a is a cell array. You need to change your assignment of a from
a={0.5 1 1.5 2};
to
a=[0.5 1 1.5 2];
which will make it just a normal array. Alternatively, you need to reference it with cell array notation: a{i} instead of a(i).
You're almost there. Note that you've written
function [y] = part1(a,x)
but you call it in your script as
part1(x,a)
so you should probably correct that.
A few things jump out at me:
You never assign the output of part1(x,a) to anything. You're told that
Results should be stored in a solution matrix using a different row of the solution matrix for each value of a.
What I take this to mean is that the 1st row corresponds to part1() evaluated for the 1st element of a. Since we're operating on x which is a vector, that row will have multiple columns. Your output is indeed a matrix. In your case, length(-pi:0.1:pi) == 63, therefore size(y) == [4 63], where y is your output matrix.
Your for loop is backwards. You're told to accept scalar a and vector x. Therefore, your script should be something like:
a = 0.5:0.5:2;
x = -pi:0.1:pi;
for i = 1:length(a)
y(i,:) = part1(x, a(i));
end
Note the use of length and the : operator. I want to iterate between 1 to length(a) (in this case, length(a) == 4) so that I can use the current a(i) value as an index into my output matrix, y. The : operator in y(i,:) signifies "The ith row and all columns of y will take the value output by part1(x,a(i))."
Your function needs to be changed up for element-by-element operations. Notice that, for instance, x*sin(a*x-2) works for scalar x but not vectors. This is because x is a vector and sin(a*x-2) is also a vector (since the sin call will operate element-by-element and a is a scalar). Trying to multiply two vectors together will result in errors since MATLAB will try to perform a matrix multiplication. Resolve this by replacing * with .*. This way it is unambiguous that you are going to multiply these two vectors element-by-element. You'll also need to change / to ./.
On another note, thank you for attempting to do your homework before asking SO for help. We've been getting a huge influx of questions from students that have made no attempt to do their own work before dumping it on us, so it's refreshing that we regulars of the MATLAB tag get to actual help out instead of telling people to do their own work.
Finally got the whole thing worked out.
Function
function [y] = part1(x,a)
y=((x.*sin(a.*x - 2))./(sqrt(1 + (a.*x).^2)));
end
Script
%%
clear all;
clc;
close all;
x=[-pi:.1:pi];
a=[.5:.5:2];
for i=1:length(a)
y(i,:)=part1(x,a(i));
plot(x,y)
end
Sol=[y]