How to assemble a new function out of existing functions? - matlab

I have a function kappa that contains two other functions sigma_ and sigma__.
The error I get is
error: binary operator '.^' not implemented for 'function handle' by 'scalar' operations
error: called from
at line -1 column -1
My code is
>> syms epsilon
>> a = 0.36990
>> b = 2.6474
>> sigma = #(epsilon) 10 .^ (a * log (epsilon) + b)
>> sigma_=#(epsilon) diff(sigma)
>> sigma__=#(epsilon) diff(sigma_)
>> kappa=#(epsilon) (sigma__)/(1+sigma_.^2).^(3/2)
>> kappa(1)
error: binary operator '.^' not implemented for 'function handle' by'scalar' operations
error: called from
at line -1 column -1
I edited my code:
>> sigma_ = #(epsilon) diff (sigma (epsilon))
>> sigma__=#(epsilon) diff(sigma_(epsilon))
>> sigma_(1)
ans = [](0x0)
>> kappa=#(epsilon) (sigma__(epsilon))/(1+sigma_(epsilon).^2).^(3/2)
>> kappa(1)
ans = [](0x0)

Related

Multiple anonymous function MATLAB

My goal is to compute the derivative of a function and use this result as another function. Clearly, it means :
f = #(x) (x-1)*(x-2); %A simple function
derivative = jacobian(f,x) %MATLAB output : "2*x - 3"
df = #(x) derivative %= #(x) 2*x - 3
df(2) %= "2*x -3" instead of 2*2 - 3
How can I do such a thing ? I tried syms x but it doesn't help.
You want matlabFunction:
g = matlabFunction(f) converts the symbolic expression or function f to a MATLAB function with handle g.
In your example:
>> syms x
>> f = #(x) (x-1)*(x-2);
>> derivative = jacobian(f,x);
>> df = matlabFunction(derivative)
df =
function_handle with value:
#(x)x.*2.0-3.0
>> df(2)
ans =
1

Substitute symbolic variables with vectors

Consider the script
syms a b;
f = a.*b;
a = [1 2];
b = [0 2];
subs(f)
This yields a vector as output ([0, 4]), but the intended output is a scalar (4), given the element-wise multiplication that should be performed.
How can I properly utilize vectors when substituting symbolic functions?
I believe you're making two mistakes. The first is that you're overwriting your symbolic variables with double arrays, so you're not actually calling subs for a symbolic object:
>> syms a;
>> class(a)
ans =
sym
>> a = [1 2];
>> class(a)
ans =
double
The second is that preventing this will still give a wrong answer:
>> syms a b;
>> f = a.*b
f =
a*b
>> subs(f,{a,b},{[1, 2], [0,2]})
ans =
0 4
That's because, as you see in the printed version of f, the symbolic engine treats a and b as scalars.
So to do what you probably want to do you need to define your syms to be 2-element arrays:
> a = sym('a',[1 2])
a =
[ a1, a2]
>> b = sym('b',[1 2])
b =
[ b1, b2]
>> f = a.*b
f =
[ a1*b1, a2*b2]
>> subs(f,[a,b],[[1,2],[0,2]])
ans =
0 4
But anyway, as you can see, the result is still an array since .* (or symbolic *) is elementwise multiplication. In order to get a scalar product, use sym/dot:
>> dot(a,b)
ans =
b1*conj(a1) + b2*conj(a2)
>> subs(dot(a,b),[a,b],[[1,2],[0,2]])
ans =
4

How do I know if an element in a syms vector is assigned (MATLAB)?

Define a syms vector
f = sym('f', [1 100]);
Define a syms variable x
syms x
The elements in vector f may be accessed and assigned, e.g.,
f(i) = x
Given any k, then how do I know if f(k) is assigned?
Short answer
Let k be the index of the entry of f to be inspected. Then
isAssigned = ~isempty(whos(char(f(k))));
is true (or 1) if the k-th entry of f has been assigned and false (or 0) otherwise.
Long answer
From the documentation (boldface added)
A = sym('a',[m,n]) creates an m-by-n symbolic matrix filled with automatically generated elements. The generated elements do not appear in the MATLAB workspace.
For example,
>> clear all
>> f = sym('f', [1 10])
>> f =
[ f1, f2, f3, f4, f5, f6, f7, f8, f9, f10]
>> whos
Name Size Bytes Class Attributes
f 1x10 112 sym
which indeed shows that f1, f2 etc don't appear in the workspace. However, if you then assign
>> syms x;
>> f(3) = x
f =
[ f1, f2, x, f4, f5, f6, f7, f8, f9, f10]
the variable x of course does appear in the workspace:
>> whos
Name Size Bytes Class Attributes
f 1x10 112 sym
x 1x1 112 sym
So, a way to check if a particular entry of f has been assigned is to check for its existence in the workspace using the functional form of whos. Compare
>> whos('f2') %// produces no output because no variable f2 exists in the workspace
and
>> whos('x') %// produces output because variable x exists in the workspace
Name Size Bytes Class Attributes
x 1x1 112 sym
Given the index k of the entry of f to be inspected, you can automatically generate the corresponding string ('f2' or 'x' in the above example) using char(f(k)):
>> k = 2;
>> char(f(k))
ans =
f2
>> k = 3;
>> char(f(k))
ans =
x
It only remains to assign the output of whos(char(f(k))) to a variable, which will be empty if f(k) has not been assigned, and non-empty if it has been assigned:
>> k = 2;
>> t = whos(char(f(k)))
t =
0x1 struct array with fields:
name
size
bytes
class
global
sparse
complex
nesting
persistent
>> k = 3;
>> t = whos(char(f(k)))
t =
name: 'x'
size: [1 1]
bytes: 112
class: 'sym'
global: 0
sparse: 0
complex: 0
nesting: [1x1 struct]
persistent: 0
Thus, applying ~isempty to this t produces true (1) if the k-th entry of f has been assigned and false (0) otherwise:
>> k = 2;
>> isAssigned = ~isempty(whos(char(f(k))))
isAssigned =
0
>> k = 3;
>> isAssigned = ~isempty(whos(char(f(k))))
isAssigned =
1

Convolution in matlab

I'm trying to calculate this convolution:
x[n] = δ[n+1] + δ[n] - δ[n-1]
h[n] = (1/2)^n * u[n] . u[n] is the step function.
Here's my code:
>> n=[-10:10];
>> x=zeros(1,length(n));
>> x(n==-1)=1;
>> x(n==0)=1;
>> x(n==1)=-1;
>> u=heaviside(n);
>> h=(1/2).^n * u;
??? Error using ==> mtimes
Inner matrix dimensions must agree.
How do you exactly type my h[n]? What if it's u[n-1] instead?
>> n=[-10:10];
>> x=zeros(1,length(n));
>> x(n==-1)=1;
>> x(n==0)=1;
>> x(n==1)=-1;
>> u=heaviside(n);
>> h=(1/2).^n .* u; %Note the element wise operation .*
>> conv(x,h)

How to save array of structres in .mat file in matlab

How to save array of structures in .mat file in Matlab? Is it possible?
p(1).x=0;
p(1).y=0;
p(2).x=1;
p(2).y=1;
save('matfilename','-struct','p');
% ??? Error using ==> save
% The argument to -STRUCT must be the name of a scalar structure variable.
You can use save without the -struct parameter:
>> p(1).x = 0;
>> p(1).y = 0;
>> p(2).x = 1;
>> p(2).y = 1;
>> save('myvars.mat', 'p');
>> clear p;
>> load('myvars.mat');
>> p(1)
ans =
x: 0
y: 0
>> p(2)
ans =
x: 1
y: 1
If you want want to store x and y as separate arrays (as -store would if p was a scalar struct) then you'll need to do it yourself (you can use the fieldnames function to collect the names of all fields in a struct).