how to create a pulse train using anonymous function - Matlab - matlab

I have a pulse shape that is a function of t, call it h(t), that is in the form of:
h = #(t) function of t
I want to create a pulse train that is consisted of N pulses h(t).
I did this by:
for n=0:N-1
comb = comb + h(t - n);
end
However, once I do that I can't change t in the train.
How can I create this train so that it will also be a function of t?
Thanks.

You just need to make comb an anonymous function too. You can initialise it to some trivial function (i.e. it always outputs 0), and then repeatedly modify it. Since variables declared before an anonymous function declaration, including anonymous functions, are kind of "frozen" to the definition at that point this will work.
h = #(t) _______ % some function of 't'
comb = #(t) 0;
for n = 0:N-1
comb = #(t) comb(t) + h(t - n);
end
We can test this with h = #(t) sin(t) and N=3:
>> comb(pi/2)
ans = 1.1242
>> h(pi/2) + h(pi/2-1) + h(pi/2-2)
ans = 1.1242
Note that just displaying comb can be a bit misleading, since information about the recursive definition is somewhat lost
disp(comb)
#(t)comb(t)+h(t-n)

Related

Maximize a function that involves summation in MATLAB

I want to maximize this function using fminbnd in MATLAB.
I am not able to correctly define the function in MATLAB. How can I create a loop for i to define the function accordingly and finally apply fminbnd?. Here's my code (which is actually wrong):
k = 0.1;
L = sum(k - (i/n)) + sum(((i/n) - k)*log(k - (i/n))) + k;
fminbnd(-L, [], []);
Any help will be very appreciated.
There are two things concerning your problem.
First: the thing with the loop
MATLAB is great at vectorizing stuff. The command sum adds-up a vector, so you need to create the vector i = 1:n (from 1 to n... spaced by 1) yourself:
n = 10; % maximum in sum
i = 1:n; % line-space => use MATLAB's vetorization
in = i/n; % put this in a new variable for the sake of conciseness
k = 10; % some random value
L = sum( (k - in) + (in - k).*log(k - in) + k )
the output is:
L =
-17.7921
Second: the thing with optimizing a function
Handing over functions in MATLAB can be done with function handles. Essentially, this is an object pointing to a function. In your case, we in fact need an anonymous function handle:
L = #(k) sum( (k - in) + (in - k).*log(k - in) + k )
The variable in is "frozen". For the anonymous function handle it is as if in was hard coded. The # indicates a function handle and the followed (k) denotes that the variable k should be considered as the first input of this new function (this is why it is an anonymous function handle. The variable k becomes and anonym input).
So you could now call
L(10)
and would obtain
L =
-17.7921
as before.
Now the optimization function can use this (note that you need to include the minus in the function handle, so we just wrap it in a new one:)
fnc = #(k) -L(k)
lb = 1+10-9; % lower bound
ub = 100; % upper bound
[k_opt,fval] = fminbnd(fnc ,lb,ub)
k_opt =
3.2835
fval =
-32.5310
Be aware that your function becomes complex for values k <= 1, which is why I have restricted the minimum bound here to larger values.

Problems attaching a function handle on Matlab to integral expression

I have an integral expression which I defined on Matlab using
x = 0:1/1000:1;
g = #(x) (exp(-1./x.^2).*heaviside(x)).*(exp(-1./(1-x).^2).*heaviside(1-x));
t = 0:1/1000:1;
f = zeros(size(t));
for i = 1:length(t)
f(i) = integral(g,0,t(i));
end
I can plot it, for example, using plot(t,f), but for other purposes I would like to attach a function handle to f, i.e. something like f = #(t) zeros(size(t)). I have not been able to figure it out thus far. f = #(t) integral(#(x)g(x),0,t) is also not sufficient.
Sorry, I can't comment yet. But does this work?
funcHand= #(t) integral(g,0,t);
You don't have to define x in your code above, since the input to integral is a function handle.
Then to check it's the same:
f2 = zeros(size(t));
for i = 1:length(t)
f2(i) = funcHand(t(i));
end
Whoops, the other answer said all the above (just replaced the for loop with arrayfun. I didn't see it while writing the answer.
Edit
If you want to build-in the for loop, try:
funcHand= #(t) arrayfun(#(u) integral(g, 0, u),t);
And test:
plot(funcHand(t))
Try
f = #(u) integral(g, 0, u)
The additional level of indirection in g seems superfluous. Note that I have called the input u. Keep in mind that f will not accept vectors as its inputs. So doing something like f(t) in your current workspace will not create the same array as your for loop is doing. You will have to iterate through the array. The convenience function arrayfun will do this for you:
o = arrayfun(f, t)
It is roughly equivalent to the loop you have now:
o = zeros(size(t));
for i = 1:length(o)
o(i) = f(t(i));
end
arrayfun can actually be incorporated into your function handle to allow it to process vector arguments:
h = #(t) arrayfun(f, t)
To avoid the proliferation of unnecessary function handles, you can do
f = #(t) arrayfun(#(u) integral(g, 0, u), t)

Trying to minimise a function wrt 2 variables for robust portfolio optimisation. How to do this with fmincon?

I am currently involved in a group project where we have to conduct portfolio selection and optimisation. The paper being referenced is given here: (specifically page 5 and 6, equations 7-10)
http://faculty.london.edu/avmiguel/DeMiguel-Nogales-OR.pdf
We are having trouble creating the optimisation problem using M-Portfolios, given below
min (wrt w,m) (1/T) * sum_(rho)*(w'*r_t - m) (Sorry I couldn't get the formatting to work)
s.t. w'e = 1 (just a condition saying that all weights add to 1)
So far, this is what we have attempted:
function optPortfolio = portfoliofminconM(returns,theta)
% Compute the inputs of the mean-variance model
mu = mean(returns)';
sigma = cov(returns);
% Inputs for the fmincon function
T = 120;
n = length(mu);
w = theta(1:n);
m = theta((n+1):(2*n));
c = 0.01*ones(1,n);
Aeq = ones(1,(2*n));
beq = 1;
lb = zeros(2,n);
ub = ones(2,n);
x0 = ones(n,2) / n; % Start with the equally-weighted portfolio
options = optimset('Algorithm', 'interior-point', ...
'MaxIter', 1E10, 'MaxFunEvals', 1E10);
% Nested function which is used as the objective function
function objValue = objfunction(w,m)
cRp = (w'*(returns - (ones(T,1)*m'))';
objValue = 0;
for i = 1:T
if abs(cRp(i)) <= c;
objValue = objValue + (((cRp(i))^2)/2);
else
objValue = objValue + (c*(abs(cRp(i))-(c/2)));
end
end
The problem starts at our definitions for theta being used as a vector of w and m. We don't know how to use fmincon with 2 variables in the objective function properly. In addition, the value of the objective function is conditional on another value (as shown in the paper) and this needs to be done over a rolling time window of 120 months for a total period of 264 months.(hence the for-loop and if-else)
If any more information is required, I will gladly provide it!
If you can additionally provide an example that deals with a similar problem, can you please link us to it.
Thank you in advance.
The way you minimize a function of two scalars with fmincon is to write your objective function as a function of a single, two-dimensional vector. For example, you would write f(x,y) = x.^2 + 2*x*y + y.^2 as f(x) = x(1)^2 + 2*x(1)*x(2) + x(2)^2.
More generally, you would write a function of two vectors as a function of a single, large vector. In your case, you could rewrite your objfunction or do a quick hack like:
objfunction_for_fmincon = #(x) objfunction(x(1:n), x(n+1:2*n));

Undefined function or variable

I have a simple function as below:
function dz = statespace(t,z)
dz = A*z + B*k*z
end
My main script is :
clear all;close all;format short;clc;
% step 1 -- input system parameters
% structure data
M1 = 1; M2= 1; M3= 1; %Lumped Mass(Tons)
M= diag([M1,M2,M3]);
k(1)= 980; k(2)= 980; k(3)= 980; %Stiffness Coefficient(KN/M)
K = zeros(3,3);
for i=1:2
K(i,i)=k(i)+k(i+1);
end
K(3,3)=k(3);
for i=1:2
K(i,i+1)=-k(i+1);
end
for i=2:3
K(i,i-1)=-k(i);
end %Stiffness Matrix(KN/M)
c(1)= 1.407; c(2)= 1.407; c(3)= 1.407; %Damping Coefficient(KN.sec/M)
C = zeros(3,3);
for i=1:2
C(i,i)=c(i)+c(i+1);
end
C(3,3)=c(3);
for i=1:2
C(i,i+1)=-c(i+1);
end
for i=2:3
C(i,i-1)=-c(i);
end %Damping Matrix(KN.sec/M)
A = [zeros(3) eye(3);-inv(M)*K -inv(M)*C]
H = [1;0;0]
B = [0;0;0;inv(M)*H]
k = [-1 -1 -1 -1 -1 -1]
t = 0:0.004:10;
[t,z] = ode45(statespace,t);
When I run my main script it comes with following error:
Undefined function or variable 'A'.
Error in statespace (line 2)
dz = A*z + B*k*z
As you can see I defined A in main script. Why this problem happening?
There multiple things wrong with your code. First, you need to supply the values of A and B to your function but as you are invoking it (incorrectly without the # and additional parameter y0 as I commented below) in the toolbox ode45, you have to keep just two parameters so you cannot supply A and B as additional parameters. If you define A and B within your function or share them via global variables you will get further. However, as noted below the definitions don't seem to be correct as A * z and B * k * z don't have the same dimensions. z is a scalar so B * k needs to be same size and shape as A which currently it is not.
Edit from:
As Jubobs suggested change your function's parameters to include A, B and k. Also you don't need t as it is never used in the function. So:
function dz = statespace(A, B, k, z)
dz = A*z + B*k*z
end
As others have pointed out, A, B and k are not defined in the function workspace, so you either need to define them again (ugly, not recommended), declare them as global variables (slightly better, but still not good practice), or pass them as arguments to your function (the better solution). However, because you then want to use the function with ode45, you need to be a bit careful with how you do it:
function dz = statespace(t,z,A,B,k)
dz = A*z + B*k*z
end
and then the call to ode45 would like this:
[t,z] = ode45(#(t,z)statespace(t,z,A,B,k),[0 Tf],z0); % where Tf is your final time and z0 your initial conditions
See Error using ode45 and deval for a similar problem.

Using inline function with constant arguments in MATLAB

This is a part of my code.
clear all;
clc;
p = 50;
t = [-6 : 0.01 : 6];
f = inline('(t+2).*sin(t)', 't')
v = inline('3*f(p*t+2)','t','f','p')
plot(t,f(t));
v(t,f,p);
figure;
plot(t,v(t,f,p));
Here I have two questions.
Why I have to pass p into the function v even though p is a constant which has already declared ?
How I can get an expression for v completely in terms of t as 3*[(50*t+2)*sin(50*t+2)] or in its simplified form ?
Update
This is an update for the second question
Let
f(x) = 1 + x - x^2
g(x) = sin(x)
If I give f(g(x)), I wanna get the output in words, like this
f(g(x)) = (cos(X))^2 + sin(x)
not in numerical value. Is there any function capable to do that?
1) Why do I have to pass p to v even though p is a constant which has already been declared?
Well, a MATLAB's inline function object has an eval wrapper, so the only variables in its scope are those which were automatically captured from the expression or explicitly specified.
In other words, if you want v to recognize p, you have no other option but declaring it when creating the inline object and passing it to v explicitly. The same goes for f as well!
2) How I can get an expression for v completely in terms of t as 3*[(50*t+2)*sin(50*t+2)] or in its simplified form?
Use anonymous functions, like Shai suggested. They are more powerful, more elegant and much faster. For instance:
v = #(t)(3*(50*t+2)*sin(50*t+2))
Note that if you use a name, which is already in use by a variable, as an argument, the anonymous function will treat it as an argument first. It does see other variables in the scope, so doing something like g = #(x)(x + p) is also possible.
EDIT #1:
Here's another example, this time a function of a function:
x = 1:5;
f = #(x)(x .^ 3); %// Here x is a local variable, not as defined above
g = #(x)(x + 2); %// Here x is also a local variable
result = f(g(x));
or alternatively define yet another function that implements that:
h = #(x)f(g(x)); %// Same result as h = #(x)((x + 2) .^ 3)
result = h(x);
The output should be the same.
EDIT #2:
If you want to make an anonymous function out of the expression string, concatenate the '#(x)' (or the correct anonymous header, as you see fit) to the beginning and apply eval, for example:
expr = '(x + 2) .^ 3';
f = eval(['#(x)', expr]) %// Same result as f = #(x)((x + 2) .^ 3)
Note that you can also do char(f) to convert it back into a string, but you'll have to manually get rid of the '#(...)' part.
EDIT #3:
If you're looking for a different solution, you can explore the Symbolic Toolbox. For example, try:
syms x
f(x) = x + 2
g(x) = x ^ 3
or can also use sym, like so:
f(x) = sym('x + 2');
g(x) = sym('x ^ 3');
Use subs to substitute values and evaluate the symbolic expression.
How about using anonymous functions:
p = 50;
t = -6:0.01:6;
f = #(x) (x+2).*sin(x);
v = #(x) 3*f(p*x+2);
figure;
subplot(1,2,1); plot( t, f(t) ); title('f(t)');
subplot(1,2,2); plot( t, v(t) ); title('v(t)');
Is this what you wanted?
Adding a constant into an inline can be done during its definition.
Instead of
p = 50;
v = inline('3*f(p*t+2)','t','f','p')
You can write
p = 50;
v = inline( sprintf('3*f(%f*t+2)', p), 't','f')