Matlab - how to plot step function - matlab

I am having a hard time plotting a step function. The function involves is the Haar scaling function which is defind as:
ø(x) = 1 if 0 ≤ x < 1
ø(x) = 0 otherwise
I am supposed to plot the following function:
f(x) = 2ø(4x) + 2ø(4x - 1) + ø(4x - 2) - ø(4x - 3)
This is supposed to give me a plot where f = 2 on the interval 0 ≤ x < 0.5; f = 1 on the interval 0.5 ≤ x < 0.75; f = -1 on the interval 0.75 ≤ x < 1, and f = zero otherwise.
I tried the following code:
f = #(t) 2*(4*t > 0) + 2*(4*t > 1) + (4*t > 2) - (4*t > 3);
t = linspace(-2,2,100);
stairs(t,f(t))
However, this does not give me an accurate graph. So what am I doing wrong here? Any help will be greatly appreciated!

Your implementation of f only deals with half of your specification of phi.
f = #(t) 2*(4*t > 0) + 2*(4*t > 1) + (4*t > 2) - (4*t > 3);
In each of the terms applies the inequality 0 < X, rather than 0 <= X. Also nothing is done about the X < 1 inequality.
Rather than trying to make a custom version for each term, why not code up your formula directly?
phi = #(x) x >= 0 & x < 1;
f = #(x) 2*phi(4*x) + 2*phi(4*x-1) + phi(4*x - 2) - phi(4*x - 3);

it should be:
f = #(t) 2*(4*t > 0 & 4*t < 1) + 2*(4*t > 1 & 4*t < 2) + (4*t > 2 & 4*t < 3) - (4*t > 3);
Because every segment should be defined precisely with start and end values.

Related

How to plot a surface plot with constraints

I'm trying to plot a function subject to three constraints (see code)
Now I tried the following
function value = example(x1, x2)
if x1 < 0 || x2 < 0 || x1+2*x2 > 6
value = NaN;
else
value = abs(x1 - x2) + exp(-x1 - x2);
end
[X, Y] = meshgrid(-10:10, -10:10);
Z = example(X,Y);
surf(X, Y, Z)
Now, this raises an error since the if clause cannot be evaluated for inputs X and Y. Any idea how to make this work?
As #Cris mentioned, use logical indexing.
The basic idea is (x1 < 0 | x2 < 0 | x1+2*x2 > 6) will gives you a matrix (same size as value) of zeros and ones. The positions of ones correspond to the true condition. Try this:
function value = example(x1, x2)
value = abs(x1 - x2) + exp(-x1 - x2);
value(x1 < 0 | x2 < 0 | x1+2*x2 > 6) = NaN;
Output:

Sum of rectangles in Matlab

I have a code which doesnt work the way I want to. The problem is i need a sum of all rctangles from a picture as below.
My code:
imH = size(I, 1);
imW = size(I, 2);
windowWidth = 30;
windowHeight = 30;
step = 1;
for r = 1:step:imH - windowHeight + 1
for c = 1:step:imW - windowWidth + 1
Win = I(r:r + windowHeight - 1, c:c + windowWidth - 1, :);
post =[c r windowHeight windowWidth];
I think I lack sum here
%stop = waitforbuttonpress;
subplot(121); imshow(I); title 'Image';
hold on;
rectangle('Position', pos, 'EdgeColor', 'r');
hold off;
subplot (122); imshow(W); title 'ooo';
drawnow;
pause(0.0000001);
end
end
Everything works great but I need to sum separately every rectangle values
You only need to add & in the 1st and 2nd rgb intervals as below:
matchNh = (R > 45 & R < 180) & (G > 50 & G < 185) & (B > 160 & B < 215);
matchNd = (R > 40 & R < 115) & (G > 6 & G < 80) & (B > 10 & B < 75);
Then you are doing right to count the nonzero pixels i.e.
Nh = nnz(matchNh);
Nd = nnz(matchNd);
If you want to use for more than one image , then you can use another for loop outside the two for loops e.g.
imgnames = dir('*.jpg'); % get list of jpg images in current directory
NN = length(imgnames)
%sliding window size
windowWidth = 64;
windowHeight = 64;
%step
step = 64;
Nh = 0;
Nd = 0;
for ii = 1 : NN
I = imread(imgnames(ii).name);
% your code i.e. two for loops as you have written above
imH = size(I, 1);
imW = size(I, 2);
for r = 1:step:imH - windowHeight + 1
for c = 1:step:imW - windowWidth + 1
%sliding window value
W = I(r:r + windowHeight - 1, c:c + windowWidth - 1, :);
pos =[c r windowHeight windowWidth];
R = W(:,:,1);
G = W(:,:,2);
B = W(:,:,3);
% RGB intervals for every sliding window
matchNh = (R > 45 & R < 180) & ...
(G > 50 & G < 185) & ...
(B > 160 & B < 215);
matchNd = (R > 40 & R < 115) & ...
(G > 6 & G < 80) & ...
(B > 10 & B < 75);
Nh = Nh + nnz(matchNh);
Nd = Nd + nnz(matchNd);
end
end
PIc = Nd / (Nh + Nd)
end

Matlab, k = 1.000000000000000 but k == 1 returns 0

I already read the other discussion here on SO but I still cannot understand why the code does not work as expected.
In my code I check that k is approximately equal to 1, but still it does not work:
if approx(k, 1, eps)
display('Approx equal');
else
k
k == 1
approx(k, 1, eps)
abs(k - 1) < eps
end
Instead of displaying the string, this is the result (I have enabled format long):
k = 1.000000000000000
ans = 0
ans = 0
ans = 0
This is baffling! I also tried to increase the error by k * 1e20 but the result is still 1e20... What to do here?
Note: although not really relevant to the question, here is the definition of approx:
function r = approx(a, b, tol)
r = a <= b + tol && a >= b - tol;
end
EDIT: I changed the approx function to avoid catastrophic cancellation:
function r = approx(a, b, tol)
r = a <= b + tol && a + tol >= b; % assumes tol is positive
end
Try displaying:
k - 1.000000000000000
I think you will find that there is a tiny but non-zero residual value.

if statement in MatLab environment

I used the following simple code to check the properties of elseif command in MATLAB:
x = 10;
if x < 0
y = x;
elseif 0 <= x < 2
y = 3*x;
elseif x >= 2
y = 8*x;
end
y
I would have expected the result of this to be 80 since x >= 2. But something amazing happened! The result is 30, not 80!
But why? Any ideas?
Update: when I change the code (as recommended in the answers) to
x = 10;
if x < 0
y = x;
elseif (0 <= x) && ( x < 2 )
y = 3*x;
elseif x >= 2
y = 8*x;
end
y
I get 80 as expected. It's that double condition that threw me off.
When you write
if 0 <= x < 2
you are really writing (without realizing it)
if (0 <= x) < 2
Which is evaluated as
if (true) < 2
which is true, since true evaluates to 1.
So here is what is happening, line by line:
x = 10; % x is set to 10
if x < 0 % false
y = x; % not executed
elseif 0 <= x < 2 % condition is (true) < 2, thus true
y = 3*x; % y is set to 3*x, i.e. 30
elseif x >= 2 % since we already passed a condition, this is not evaluated
y = 8*x; % skipped
end % end of composite if
y % display the value of y - it should be 30
As an aside, when you use scalars, you should really use the && operator, not the & operator. See for example What's the difference between & and && in MATLAB?
0 <= x < 2 doesn't behave as you may expect. Use (0 <= x) & (x < 2)
How does 0 <= x < 2 behave? It is evaluated from left to right. First 0 <= x gives 1 (true), and then 1 < 2 gives 1 (true). So the condition gives true, not false as you would expect.
Since the second condition in your code (0 <= x < 2) is true, you get a value 30 for y. Changing the condition to (0 <= x) & (x < 2) you get a value 80 for y.

how to plot 3d inequalities on matlab [duplicate]

This question already has answers here:
Draw 3d Inequality on Matlab
(1 answer)
matlab - plot inequality in 3d with surf
(1 answer)
Closed 1 year ago.
I want to plot a 3d region in MATLAB bounded from a set of inequalities.
For example:
0 <= x <= 1
sqrt(x) <= y <= 1
0 <= z <= 1 - y
I found a 2d example that someone has done on this site but I'm not sure how to convert that to 3d. How to plot inequalities.
Edit:
From #Tobold's help I modified the code to restrict the points that are plotted to those that are defined by all three regions, but it plots only 2 or 3 points. It looks like the points in the vectors X1, Y1 and Z1 are right but for some reason its plotting only a few. Any ideas why it is only plotting a few points from the X1, Y1 and Z1 vectors instead of all of them?
[X,Y,Z]=meshgrid(0:0.1:1,0:0.1:1,0:0.1:1); % Make a grid of points between 0 and 1
p1=0.1; p2=0.2; % Choose some parameters
X1 = (X >= 0 & X <= 1) & (Y >= sqrt(X) & Y <= 1) & (Z >= 0 & Z <= 1 - Y);
Y1 = (X >= 0 & X <= 1) & (Y >= sqrt(X) & Y <= 1) & (Z >= 0 & Z <= 1 - Y);
Z1 = (X >= 0 & X <= 1) & (Y >= sqrt(X) & Y <= 1) & (Z >= 0 & Z <= 1 - Y);
ineq1 = (X >= 0 & X <= 1) * 2;
ineq2 = (Y >= sqrt(X) & Y <= 1) * 4;
ineq3 = (Z >= 0 & Z <= 1 - Y) * 8;
all = ineq1 & ineq2 & ineq3;
colors = zeros(size(X))+ineq1+ineq2+ineq3;
scatter3(X1(:),Y1(:),Z1(:),3,colors(:)','filled')
You can do almost the same thing as in the 2d case that you linked to. Just write down your three inequalities, use a 3d meshgrid, multiply each inequality with a number from a set of three numbers that has unique subset sums (e.g. 2, 4, 8) and use scatter3:
[X,Y,Z]=meshgrid(0:0.1:1,0:0.1:1,0:0.1:1); % Make a grid of points between 0 and 1
p1=0.1; p2=0.2; % Choose some parameters
ineq1 = (X >= 0 & X <= 1) * 2;
ineq2 = (X >= sqrt(X) & Y <= 1) * 4;
ineq3 = (Z >= 0 & Z <= 1 - Y) * 8;
colors = zeros(size(X))+ineq1+ineq2+ineq3;
scatter3(X(:),Y(:),Z(:),3,colors(:),'filled')
I've been trying to figure out the same thing, and the trick is to make the size of everything not in the intersection 0. Tobold's scatter3 line uses '3' as the option for size, meaning all points will show up as point 3. This can be substituted for a matrix of equal size to X1 with the set of sizes. The easiest way to do this is just make s = 3*all:
all = ineq1 & ineq2 & ineq3;
colors = zeros(size(X))+all;
sizes = 3 * all;
scatter3(X1(:),Y1(:),Z1(:),sizes,colors(:)','filled')
That should get you just the area in the intersection.
--
edit: The color variable needs to change too. You just want the intersection, not the other inequalities.
I don't understand several things in the code that you wrote as modification of #Tobold's help. For example what are the parameters p1 and p2 doing in your code?
Anyway, The code plotting only the points of your grid satisfying all of your inequalities;
[X,Y,Z]=meshgrid(0:0.1:1,0:0.1:1,0:0.1:1);
ineq1 = (X >= 0 & X <= 1);
ineq2 = (Y >= sqrt(X) & Y <= 1);
ineq3 = (Z >= 0 & Z <= 1 - Y);
all = ineq1 & ineq2 & ineq3;
scatter3(X(all),Y(all),Z(all),'b','filled')
The result is brought in the following image.