I am very very new to MATLAB and have spent the majority of my day dancing around issues and I just couldn't Google my way out of this one.
My issue is that I am trying to use a vector in a nested if statement in such a way that I can evaluate a formula for a circuit. Doing some testing I found MATLAB will execute if( t >=0 ) and if( t <= 1e-2) but will not work for if( t <= 1e-3). This is an issue for me as my specifications require my Period = 1e-3, is there any way to get around this issue with my current instructions or do I have to completely redo my structure?
t = 0:1e-4:1e-2;
if (t >= 0 & t <= DutyCycle.*Period)
ti = 0;
tf = DutyCycle.*Period;
Vci = 0;
else
if (t>= DutyCycle.*Period & t <= Period.*n)
ti = t;
tf = Period.*n;
Vci = Vs;
else
if(t == Period)
ti = t;
tf = DC.*Period.*n;
n = (n + 1);
Vci = Vs;
end
end
end
Related
The code segment I'm working on is given below:
NphaseSteps = 6;
phases = exp( 2*pi*1i * (0:(NphaseSteps-1))/NphaseSteps );
i = 1;
while i <= 10 %number of iterations
ind = randi([1 NphaseSteps],10,10);
inField{i} = phases(ind);
save('inField.mat', 'inField')
i = i + 1;
end
Now, what I want is to keep track of these randomly created matrices "inField{i}" and eliminate the ones that are equal to each other. I know that I can use "if" condition but since I'm new to programming I don't know how to use it more efficiently so that it doesn't take too much time. So, I need your help for a fast working program that does the job. Thanks in advance.
My actual code segment (after making the changes suggested by #bisherbas) is the following. Note that I actually want to use the variable "inField" inside the loop for every random created matrix and the loop advances only if the result satisfies a specific condition. So, I think the answer given by #bisherbas doesn't really eliminate the equal inField matrices before they are used in the calculation. This is, of course, my fault since I didn't declare that in the beginning.
NphaseSteps = 6;
phases = exp( 2*pi*1i * (0:(NphaseSteps-1))/NphaseSteps );
nIterations = 5;
inField = cell(1,nIterations);
i = 1;
j = 1;
while i <= nIterations % number of iterations
ind = randi([1 NphaseSteps],TMsize,TMsize);
tmp = phases(ind);
idx = cellfun(#(x) isequal(x,tmp),inField);
if ~any(idx)
inField{i} = tmp;
end
j = j+1;
outField{i} = TM * inField{i};
outI = abs(outField{i}).^2;
targetIafter{i} = abs(outField{i}(focusX,focusY)).^2;
middleI = targetIafter{i} / 2;
if (max(max(outI)) == targetIafter{i})...
&& ( sum(sum((outI > middleI).*(outI < max(max(outI))))) == 0 )
save('inFieldA.mat', 'inField')
i = i + 1;
end
if mod(j-1,10^6) == 0
fprintf('The number of random matrices tried is: %d million \n',(j-1)/10^6)
end
end
Additionally, I've written a seemingly long expression for my loop condition:
if (max(max(outI)) == targetIafter{i})...
&& ( sum(sum((outI > middleI).*(outI < max(max(outI))))) == 0 )
save('inFieldA.mat', 'inField')
i = i + 1;
end
Here I want a maximum element at some point (focusX, focusY) in the outField matrix. So the first condition decides whether the focus point has the maximum element for the matrix. But I additionally want all other elements to be smaller than a specific number (middleI) and that's why the second part of the if condition is written. However, I'm not very comfortable with this second condition and I'm open to any helps.
Try this:
NphaseSteps = 6;
phases = exp( 2*pi*1i * (0:(NphaseSteps-1))/NphaseSteps );
i = 1;
inField = cell(1,NphaseSteps);
while i <= NphaseSteps %number of iterations
ind = randi([1 NphaseSteps],NphaseSteps,NphaseSteps);
tmp = phases(ind);
idx = cellfun(#(x) isequal(x,tmp),inField);
if ~any(idx)
inField{i} = tmp;
end
save('inField.mat', 'inField')
i = i + 1;
end
Read more on cellfun here:
https://www.mathworks.com/help/matlab/ref/cellfun.html
For faster implementation , I would like to vectorize below matlab code :
A=randi([0 1],20,20);
B=zeros(20);
for row = 5:15
for column = 5:15
if(A(row,column)==1 && (A(row+1,column)~=1 ||A(row,column+1)~=1))
B(row,column)=1;
end
end
end
How can I do that?
Just calculate all A(row, column)==1 and such at once for the whole loop, then use ordinary boolean operations. This should work just fine for the case you presented (though short-circuiting stuff operates a little bit differently, so this might not be always possible).
row = 5:15;
col = 5:15;
firstCond = A(row, col) == 1;
secondCond = A(row+1, col) ~= 1;
thirdCond = A(row, col+1) ~= 1;
allCond = firstCond & (secondCond | thirdCond);
B(row, col) = double(allCond);
I hope this one will work for you.
A=randi([0 1],20,20);
B=zeros(20);
z = find(A(5:15,5:15) == 1 & (A(6:16,5:15)~=1 | A(5:15,6:16)~=1));
y = B(5:15,5:15);
y(z) = 1;
B(5:15,5:15) = y;
I have a for loop testing the max of a function:
function Start
max_i = 0;
max_j = 0;
max_value = 0;
for i =1:3500
for j = 1:3500
new_value = CalcUFamily(i,j);
if new_value > max_value;
max_value = new_value;
max_i = i;
max_j = j;
end
end
end
max_i
max_j
end
function uFamily = CalcUFamily(hh,hw) %h = male, w = wife
(code)
end
The basic is that it is testing a function that I have been trying to optimize (with some help from here) but which I have so far failed to do. I therefore want to test to make a loop that tests all possible values, work hours for a husband and a wife, from 1 h to 3500 h (yearly). I then want to get the highest utility value from CalcUFamily and its corresponding input variables, hh and hw (called i and j in the function above).
My code works well, apart from the fact that it takes too long to run since it runs 12 250 000 times. I therefore want to rase the test interval from 1 to 10 or maybe even 100. Is this possible with the for code, or do I have to rewrite it somehow?
Thanks a lot for your help!
Reshape CalcUFamily into a vector using colon (or reshape) and use max to find the maximum value (max_value) and its linear index. Now use ind2sub to convert this linear index into the equivalent row (hh or max_i) and column (hw or max_j) subscripts.
[max_value, max_Ind] = max(CalcUFamily(:));
[hh, hw] = ind2sub(size(CalcUFamily), max_Ind);
I found a solution myself! :)
max_hh = 0;
max_hw = 0;
max_value_hhhw = -50000;
max_value_u = -50000;
hh = 1;
hw = 1;
runs = 0;
interval = 10;
datestr(clock)
while hw < 3501
while hh < 3501 %runs hh to all posible values
new_value = CalcUFamily(hh,hw);
if new_value > max_value_u
max_value_hhhw = [hh hw]; %working hour husband, working hour wife, and its utility value
max_value_u = new_value;
end
hh = hh + interval;
runs = runs + 1; % number of runs
end
hh = 1;
hw = hw + interval;
end
runs
datestr(clock)
max_value_hhhw
I am trying to plot some bump function supported on the interval (0,3). I've defined the function piecewise so that it is zero outside the interval. Here is the function:
function d = bump2(t)
region1 = (t > 0) & (t < 3);
d(region1) = exp(1./(t(region1).^2 - 3*t(region1)));
region2 = (t <= 0) & (t >= 3);
d(region2) = 0;
end
If I set x = -1:.01:4 and try to run plot(x,bump2(x)) I get an error telling me that my vectors aren't the same length. This is indeed true since length(x) = 501 and length(bump2(x)) = 400 However, when I set x = .01:.01:2.99, then everything checks out fine and the lengths of the vectors are equal.
Also, strangely, I have another, similar function
function b = bump(t)
region1 = abs(t) < 1;
b(region1) = exp(-1./(1 - ((t(region1)).^2)));
region2 = abs(t) >= 1;
b(region2) = 0;
end
with which I've never had this problem. Why are these two functions different? And why does the first function work when I exclude the points 0 and 3, even though I've defined the function to avoid possible singularities there?
This is because the b(region1) is trimming off the ends of your vector x so that it is not the same size.
Consider if you set x = -1:3 and then run the code plot(x, bump3(x)); with:
function d = bump3 (t)
region1 = (t > 0) & (t < 3);
d(region1) = t(region1);
end
Then you get the same problem. The issue is that inside bump3 you have
K>> region1
region1 =
0 0 1 1 0
Now this is the trick. This region1 is of data type logical so MATLAB interprets the next line
d(region1) = t(region1);
as
d(find(region1)) = t(find(region1));
But if you wrote
d = [];
d(5) = 1;
Then you would get a bunch of zeros at the zero, so you do here.
You might consider modifying to say d = t(region1); to get only the good values, but then you still have a sizing problem. A solution is to return the indices you used with the new value as an additional return value in bump like this:
Execute:
x = -1:3;
[y region1] = bump4(x);
plot(x(region1), y);
Where you modify your bump function like this:
function [d region1] = bump4 (t)
region1 = (t > 0) & (t < 3);
d = t(region1);
end
EDIT:
If you really do want those extra zeros on the left and right you can also fix this problem by initializing d before using it in your code like this:
function d = bump2(t)
region1 = (t > 0) & (t < 3);
d = zeros(size(t));
d(region1) = exp(1./(t(region1).^2 - 3*t(region1)));
region2 = (t <= 0) & (t >= 3);
d(region2) = 0;
end
Because I set d = zeros(...) then you have zeros outside the region and your bump function within it. Another way of looking at the problem is that MATLAB is padding on the left side but not on the right because you never set a blank value out there. This fixes that problem by telling MATLAB how big d should be.
I am very new in Matlab. I made a for loop with i to m ,and j to n. I wrote this code to take a submatrix of a matrix but it keeps giving me this error
Subscript indices must either be real positive integers or logicals.
this is the code
for i=1:m,
for j = 1:n,
display(i);
display(j);
edgeil = 2;
edgeib = 2;
edgejb = 2;
edgejl = 2;
if((i-CenteriSE)< 0)
edgeib = CenteriSE - (-1)*(i-CenteriSE);
end
if((i+ CenteriSE)> m)
temp = i+ CenteriSE - m;
edgeil = CenteriSE - temp;
end
if((j-CenterjSE)< 0)
edgejb = CenterjSE- (-1)*(j-CenterjSE);
end
if((j+ CenterjSE)> n)
temp2 = j+ CenterjSE - n;
edgejl = CenterjSE - temp2;
end
bok1 = round(edgeib);
bok2 = round(edgeil);
bok3 = round(edgejb);
bok4 = round(edgejl);
display(bok1);
display(bok2);
if( (bok1 == round(bok1)) && (bok2 == round(bok2)) && (bok3 == round(bok3)) && (bok4 == round(bok4)))
B = circles(i-round(bok1):i+round(bok2),j-round(bok3):j+round(bok4));
end
I wrote that if statement and round s to correct it but it doesnt work. Please help me how can I fix this?
well, it's simple. first let's just remove all the clutter. you say CenteriSE=2, so this statement
edgeib = CenteriSE - (-1)*(i-CenteriSE); is equivalent to edgeib=i for i=1.
Now if you go to your last statement, B = circles(i-round(bok1):i+round(bok2),j-round(bok3):j+round(bok4));, you're doing i-round(bok1), which is just i-i=0 when i=1. Matlab's indexing start from 1, and this is why you get this error.