How to convert logical conditions to a variable of a function - matlab

I would like to achieve the above for the following:
Rn = 0.009; % Resolution of simulation (in m^3)
Xs = -1 : Rn : 1;
Ys = -1 : Rn : 1;
Zs = 0 : Rn : 1;
[X Y Z] = meshgrid(Xs, Ys, Zs);
alpha = atan2(Z,X);
ze = x.^2 + y.^2; % define some condition
m = 0.59; % manual input
cond = (pi/3 <= alpha) & ...
(alpha <= (2*pi/3)) & ...
(m <= Z) & ...
(Z <= ze); % more conditions
xl = nnz(cond); % the number of non-zero elements
f = abs(xl*1000 - 90) % guessing m to get f as low as possible
How do I turn m into a variable for some f function so I can call fminsearch to quickly find the corresponding m for f ≈ 0?

In order to use m as a variable, you need to define a function handle. So you need to write:
cond = #(m) ((pi/3) <= alpha) & (alpha <= (2*pi/3)) & (m <= Z) & (Z <= ze);
However, you cannot use a function handle in the nnz routine, since it only accepts matrices as inputs. But, the solution to the problem is that you only have Boolean variables in cond. This means, you can simply sum over cond and get the same result as with nnz.
The only issue I see is how to implement the sum in fminsearch. Unfortunately, I do not have access to fminsearch, however I would assume that you can do something with reshape and then multiply with dot (i.e. .*) with the unity vector to get a sum. But you'll have to try that one out, not sure about it.

Related

How to use matlab to quickly judge whether a function is convex?

For example, FX = x ^ 2 + sin (x)
Just for curiosity, I don't want to use the CVX toolbox to do this.
You can check this within some interval [a,b] by checking if the second derivative is nonnegative. For this you have to define a vector of x-values, find the numerical second derivative and check whether it is not too negative:
a = 0;
b = 1;
margin = 1e-5;
point_count = 100;
f=#(x) x.^2 + sin(x);
x = linspace(a, b, point_count)
is_convex = all(diff(x, 2) > -margin);
Since this is a numerical test, you need to adjust the parameter to the properties of the function, that is if the function does wild things on a small scale we might not be able to pick it up. E.g. with the parameters above the test will falsely report the function f=#(x)sin(99.5*2*pi*x-3) as convex.
clear
syms x real
syms f(x) d(x) d1(x)
f = x^2 + sin(x)
d = diff(f,x,2)==0
d1 = diff(f,x,2)
expSolution = solve(d, x)
if size(expSolution,1) == 0
if eval(subs(d1,x,0))>0
disp("condition 1- the graph is concave upward");
else
disp("condition 2 - the graph is concave download");
end
else
disp("condition 3 -- not certain")
end

Matlab: Plotting the conditions output of symbolic solve

I have a loop where I symbolically solve for intervals. Each iteration of the loop gives exactly one interval, for example:
v=[x+1,-x+4];
v = v > 0;
sol=solve(v,x,'ReturnConditions',true);
cond = sol.conditions;
ezplot(cond)
Would I be able to plot the 1x1 symbolic array " cond = -1 < x & x < 4 " at a y value of my choosing? When I use ezplot it always plots at y=1.
Maybe by multiplying the cond by the y value you wish to use. In that case the title must be changed to match the original condition, cond by casting it as a string. In the example below I plotted the condition/region at a height of y = 2. To implement this in the for-loop I'd probably make a y a vector a retrieve one value/cell upon each iteration.
syms x
v = [x+1,-x+4];
v = v > 0;
sol = solve(v,x,'ReturnConditions',true);
cond = sol.conditions;
y = 2;
ezplot(y*cond);
ylim([0 y*1.2]);
title(string(cond));

Plotting the Impulsefunction

so I'm new to Matlab and had to draw the Impulsefunction with y(n) is only 1 if n == 3, else 0. The following code works:
n = -5:5;
f = n; % allocate f
for i = 1 : length(n)
f(i) = dd1(n(i)-3);
end
stem(n, f);
function y = dd1(n)
y = 0;
if n == 0
y = 1;
end
end
But I feel like it's to complicated, so I tried the following:
n = -5:5
stem(n, fo)
function y = fo(n)
y = 0
if n == 3
y=1
end
end
This returns
Not enough input arguments.
Error in alternative>fo (line 5)
if n == 3
Error in alternative (line 2)
stem(n, fo)
I feel like I'm missing something trivial here.
if is no vector-wise operation but expects a single boolean (or at least a scalar that it can cast to a boolean).
But you can do this vector-wise:
lg = n == 3;
This produces a logical (MATLAB's name for boolean) array (because n is an array and not a vector), which is true where n is equal (==) to three. So you don't need a function, because you can make use of MATLAB's ability to work with vectors and arrays implicitly.
(for your code it would be f = (n-3) == 3)
A last hint: if you have a state-space system (ss-object), you can use the function step to get the step-response as a plot.

How to determine the size of an input argument for a function handle

I am creating a function that takes in data (x,y,z) and an anonymous function (M) as inputs. M's inputs are data (x,y,z) and a parameter (theta).
I need to determine the dimension of the parameter theta inside FUNC
EDIT: (To add some context)
I have data that follows a known data generating process (DGP). For example, I can generate data using a linear instrumental variable DGP with 1 endogenous variable (hence theta will be dimension 1):
n = 100; q = 10;
theta0 = 1; % true param value
e = randn(n, 1); % 2nd stage error
u = randn(n, 1); % 1st stage error
z = randn(n, q); % instrument
x = z * ones(q, 1) + u; % endog variable
y = x * theta0 + e; % dependent variable
Then I want to estimate theta0 using my own variation of generalized linear methods (FUNC)
M = #(x,y,z,theta) z' * (y - x * theta); % moment condition
thetahat = FUNC(M, x, y, z); % estimate theta0
and FUNC.m is
function out = FUNC(M, x, y, z)
k = ; % (!!!) <-- this is what I need to find out!
objFunc = #(theta) M(x, y, z, theta)' * M(x, y, z, theta);
out = fminunc(objFunc, ones(1, k)); % <-- this is where its used
end
In the above example, the DGP is a linear IV model. However, I should be able to use my function for any other DGP.
Other DGPs could, for example, define M as follows:
% E.g. 1) theta is dimension 1
M=#(x,y,z,theta) z' * (y - x * theta);
% E.g. 2) theta is dimension 2
M=#(x,y,z,theta) z' * (y - (x * theta(1))^theta(2));
% E.g. 3) theta is dimension 3
M=#(x,y,z,theta) z' * (y - (theta(1) + x * theta(2))^theta(3));
The (super bad) hack that I am currently using for (!!!) is:
for ktest = [3,2,1] % the dimension of theta will never be higher than 3
try
M(x, y, z, ones(1, ktest);
k = ktest;
end
end
Since you know already what the form and requirements of your function M will be when you pass it to FUNC, it doesn't make much sense to then require FUNC to determine it based only on M. It would make much more sense to pass flag values or needed information to FUNC when you pass it M. I would write FUNC in one of two ways:
function out = FUNC(M, x, y, z, k) % Accept k as an argument
...
end
function out = FUNC(M, x, y, z, theta0) % Pass the initial guess, of the correct size
...
end
If you really want to let FUNC do the extra work, then the answer from excaza is how I would do it.
Old answer below. not really valid since the question was clarified, but I'm leaving it temporarily...
I think you have two better options here...
Make M a cell array of anonymous functions:
You could make your input M a cell array of possible anonymous functions and use the number of values in theta as the index. You would pass this M to FUNC:
M = {#(x,y,z,theta) z' * (y - x * theta), ...
#(x,y,z,theta) z' * (y - (x * theta(1))^theta(2)), ...
#(x,y,z,theta) z' * (y - (theta(1) + x * theta(2))^theta(3))};
Then somewhere inside FUNC:
out = M{numel(theta)}(x, y, z, theta);
Make M a normal function instead of an anonymous one:
An anonymous function is good for quick, simple formulas. Add in conditional logic and you should probably just make it a fully-fledged function. Here's an example with a switch statement (good for if you have a number of different formulas):
function out = M(x, y, x, theta)
switch numel(theta)
case 1
out = z' * (y - x * theta);
case 2
out = z' * (y - (x * theta(1))^theta(2));
case 3
out = z' * (y - (theta(1) + x * theta(2))^theta(3));
end
end
And here's an example that sets some defaults for parameters (good for if you have one formula with different ways to set its parameters, like you seem to have):
function out = M(x, y, x, theta)
switch numel(theta)
case 1
p1 = 0;
p2 = theta;
p3 = 1;
case 2
p1 = 0;
p2 = theta(1);
p3 = theta(2);
case 3
p1 = theta(1);
p2 = theta(2);
p3 = theta(3);
end
out = z' * (y - (p1 + x * p2)^p3);
end
MATLAB doesn't store any information about the size of the inputs to an anonymous function. While a better idea would be to modify your code so you don't have to do these kinds of gymnastics, if your function definition is known to fit a narrow band of possibilities you could use a regular expression to parse the function definition itself. You can get this string from the return of functions.
For example:
function [nelements] = findsizetheta(fh)
defstr = func2str(fh);
test = regexp(defstr, 'theta\((\d+)\)', 'tokens');
if isempty(test)
% Assume we have theta instead of theta(1)
nelements = 1;
else
nelements = max(str2double([test{:}]));
end
end
Which returns 1, 2, and 3 for your example definitions of M.
This assumes that theta is present in you anonymous function and that it is defined as a vector.
Also note that MATLAB cautions against utilizing functions in a programmatic manner, as its behavior may change in future releases. This was tested to function in R2017b.

Implementing a filter in Matlab

I am trying to implement the following filter on a discrete signal x:
I'm supposed to write a MATLAB function that takes a length-M (> N) vector x and a scalar N as input. The output should be a length-M vector y.
I should then test the filter with M = 50, x[n]=cos(n*pi/5)+dirac[n-30]-dirac[n-35] and N = 4, 8, 12.
Here is my try, which returns Inf with the given input and N:
function y = filt( x, N )
% filter function
if(~isvector(x))
error('Input must be a vector')
end
y = zeros(1,length(x));
temp = zeros(1,length(x));
n=1;
for v = x(:)
temp(n) = v(n);
if(n <= N-1)
y(n) = max(x);
n = n+1;
elseif(n >= N-1)
y(n) = max(temp);
end
end
end
I also tried using the built-in filter function but I can't get it to work.
Code for using the filter:
p = zeros(1,50);
for i=0:50
p(i+1)= cos(i*pi/5)+dirac(i-30)-dirac(i-35)
end
y = filt(p,4)
Thanks in advance.
That's because dirac(0) gives you Inf. This will happen in two places in your signal, where n=30 and n=35. I'm assuming you want the unit impulse instead. As such, create a signal where at n = 31 and n = 36, the output is 1, then add this with your cosine signal. This is because MATLAB starts indexing at 1 and not 0, and so dirac[0] would mean that the first point of your signal is non-zero, so translating this over by 30: dirac[n-30] would mean that the 31st point is non-zero. Similar case for dirac[n-35], so the 36th point is non-zero:
p = zeros(1,50);
p(31) = 1; p(36) = 1;
p = p + cos((0:49)*pi/5);
y = filt(p,4);
I also have some reservations with your code. It doesn't do what you think it's doing. Specifically, I'm looking at this section:
n=1;
for v = x(:)
temp(n) = v(n);
if(n <= N-1)
y(n) = max(x);
n = n+1;
elseif(n >= N-1)
y(n) = max(temp);
end
end
Doing v = x(:) would produce a column vector, and using a loop with a column vector will have unintentional results. Specifically, this loop will only execute once, with v being the entire signal. You also aren't checking the conditions properly for each window. You are doing max(x), which applies the maximum to the entire signal, and not the window.
If I can suggest a rewrite, this is what you should be doing instead:
function y = filt( x, N )
% filter function
if(~isvector(x))
error('Input must be a vector')
end
y = zeros(1,length(x));
%///// CHANGE
for n = 1 : numel(x)
if (n <= N)
y(n) = max(x(1:n));
else
y(n) = max(x(n:-1:n-N+1));
end
end
end
Take note that the if statement is n <= N. This is because in MATLAB, we start indexing at 1, but the notation in your equation starts indexing at 0. Therefore, instead of checking for n <= N-1, it must now be n <= N.