Using for loops in MATLAB?
1 次查看(过去 30 天)
显示 更早的评论
I am stuck on part d in the attached document, my histogram is not coming out right at all. Could someone please help me? I attached my code.
采纳的回答
Geoff Hayes
2015-11-6
Nick - if you have everything working up to part d, then why have you commented out part b?
As for part d, look closely at what your assignment requires:
Set up a for loop that: repeats 10000 times, and computes random values for resistor 1 and resistor 2 using the randn function as follows:
resistor_value = nominal_value + range/2*randn(1);
where resistor_value is the randomly computed value for the resistor, nominal_value is the expected value for the resistor, and range is the product of the tolerance for the resistor and the nominal resistor value. Stores the voltages on resistors 1 and 2 in vectors counts the number of circuits that do not meet the voltage tolerances.
So you need two arrays of size 10000x1 for each resistor. You will create a for loop that, on each iteration of the loop, will generate two values according to the above equation for each resistor. You will take these two values and determine a voltage for each resistor which you will store in the two arrays.
Presumably you are doing the above for each of the two trials described in step c, so you will have the appropriate nominal/expected value and tolerance that will be used in the above equation. The voltage source, along with the two resistor values, will be used to determine the voltage for each resistor.
Then use hist or histogram to create the histogram given the voltages for each resistor.
24 个评论
Nick Haufler
2015-11-6
编辑:Nick Haufler
2015-11-6
Does this look right? I just want some guidance that will help me, not an answer. I created two vectors that go up to 10,000. Started my for loops for resistor 1 and 2, so I changed the equation to match my variable names. Calculated my voltages for each resistor and stored them in the same vector I used for my size to go up to 10,000. I started if statements to determine if the values are within the acceptable range. Lastly is the histogram command.
vr1=linspace(minr1,maxr1,10000);
vr2=linspace(minr1,maxr1,10000);
count=0
for k=1:length(vr1)
for k1=1:length(vr2)
resistor_value1 = r1 + (tolerance1*r1)/2*randn(1);
resistor_value2 = r2 + (tolerance2*r2)/2*randn(1);
vr1=(resistor_value1(k)/(resistor_value1(k)+resistor_value2(k1)))*vol;
vr2=(resistor_value2(k1)/(resistor_value1(k)+resistor_value2(k1)))*vol;
if v1>=minv1 && v1<=maxv1 || v2>=minv1 && v2<=maxv1;
count=count+1
else
count=count
end
end
end
h=histogram(v1,100)
Nick Haufler
2015-11-6
Can you disregard the code on my last comment and refer to this code instead thanks!
R1nom=1000; %Nominal resistance values
R2nom=2000;
t1=1; %Resistor tolerances in %
t2=1;
vol=6;
n=10000; %Number of trials
m=0; %
for i=1:n
R1=(R1nom + (t1*R1nom))/(2*randn(1)); %actual resistance values
R2=(R2nom + (t2*R2nom))/(2*randn(1));
v1=(R1/(R1+R2))*vol;
v2=(R2/(R1+R2))*vol; %voltage divider gain
if v1<t1 && v2<t2
m=m+1;
end
end
histogram(v1,100)
Geoff Hayes
2015-11-7
Nick - review the question again and in particular the statement ..stores the voltages on resistors 1 and 2 in vectors.... Where in your above code are you storing the data in a vector (or array)? On each iteration of the for loop, you are calculating the voltages v1 and v2 and then disregarding then overwriting them on the next iteration of the for loop. So to create a fixed sized array, you could do something like
myArray = zeros(n,1);
which will create an nx1 array of all zeros. To update the kth element of myArray you would do something like
myArray(k) = 3.14;
How could you then update your code using the above information?
Nick Haufler
2015-11-7
I updated the voltage calculation now to be stored in arrays. The arrays will then be updated by a value. The i is up to 10000, which is the number of times it will run through the loop.
for i=1:n
R1=(R1nom + (t1*R1nom))/(2*randn(1)); %actual resistance values
R2=(R2nom + (t2*R2nom))/(2*randn(1));
v1=(R1/(R1+R2))*vol;
v2=(R2/(R1+R2))*vol; %voltage divider gain
v1=zeros(1);
v2=zeros(1);
v1(i)=();
v2(i)=();
end
Geoff Hayes
2015-11-7
Nick - please use the Debugger to step through your code so that you can convince yourself that the above will not work. Look closely at the lines of code for v1. You assign a voltage (which is fine) as
v1=(R1/(R1+R2))*vol;
then create a 1x1 array as
v1=zeros(1);
which overwrites the voltage that you had just computed! Then there is the line
v1(i)=();
which is supposed to do what exactly? Please describe why you are attempting the above. How does that follow from my previous comment?
Nick Haufler
2015-11-7
Okay, sorry, I see what you're saying. I'm pretty much changing the value for v1 from what the calculation gives me (which is totally wrong). I need to change the array's from v1 to something new. The part where I had v1(i), I was trying to update the array, but since I have already calculated v1 that makes no sense. Let me step through it again, and see if I can figure it out before I show the code again.
Nick Haufler
2015-11-7
When I go through to update it wouldn't I want to use my variable i, so something like array(i), because i is where I have the loop start from 1 to 10000 for the number of trials.
Geoff Hayes
2015-11-7
编辑:Geoff Hayes
2015-11-7
Yes, use the indexing variable from your for loop to update the appropriate element within the array. Though use k instead since MATLAB also uses i and j to represent the imaginary number. For example,
for k=1:n
v1 = some calculation;
myArray(k) = v1;
end
Nick Haufler
2015-11-8
I used a nested loop, and set up the conditions for both voltages. Should I do it this way or the way I had it before where everything's in one for loop.
R1nom=1000; %Nominal resistance values
R2nom=2000;
t1=1; %Resistor tolerances in %
t2=1;
vol=6;
n=10000; %Number of trials
m=0; %
for k=1:n
R1=(R1nom + (t1*R1nom))/(2*randn(1)); %actual resistance values
R2=(R2nom + (t2*R2nom))/(2*randn(1));
while v1==(R1/(R1+R2))*vol;
voltarray1=zeros(n,1);
voltarray1(k)=v1;
while v2==(R2/(R1+R2))*vol; %voltage divider gain
voltarray2=zeros(n,1);
voltarray2(k)=v2;
end
end
end
histogram(v1,100)
Geoff Hayes
2015-11-8
Nick - again, step through the code with the debugger to see what is happening. You must get errors with the above because of the
while v1==(R1/(R1+R2))*vol;
with v1 not being defined. What are you expecting this line of code to do? Why use a nested while loop? And even if this condition were somehow to pass, look at the line
voltarray1=zeros(n,1);
which re-initializes voltarray1 on each iteration of the loop! That would mean that you overwrite any values you may have stored in this array on previous iterations of the loop.
This is the pseudocode for your assignment:
- create the voltage arrays for the two resistors
- start loop iterating from one to 10000
- generate random resistor values
- calculate voltage for resistor one and assign to resistor one voltage array * calculate voltage for resistor two and assign to resistor two voltage array
- once all iterations have completed, compute the histogram
That's what is required for you to implement.
Nick Haufler
2015-11-8
Yeah my voltarray's were getting overwritten which was throwing my values off, so i need it outside the loop iterations. I have the code below so far, and I really do want to get this. I think my voltage arrays for the two resistors which is the first part of my code might be a problem?
Create voltage arrays for two resistors
voltarray1=zeros(n,1);
voltarray2=zeros(n,1);
Start loop iterating from one to 10,000
for k=1:n %n=10,000
Generate random resistor values
R1=(R1nom + (t1*R1nom))/(2*randn(1)); %actual resistance values
R2=(R2nom + (t2*R2nom))/(2*randn(1));
Calculate voltages and assign to arrays
v1=(R1/(R1+R2))*vol;
voltarray1(k)=v1;
v2=(R2/(R1+R2))*vol; %voltage divider gain
voltarray2(k)=v2;
Compute histogram
histogram(v1,100)
Geoff Hayes
2015-11-9
Nick - why do you think the above might be a problem? As you haven't posted all of your code, I can't comment on what may be incorrect. What happens when you run the above? Are there errors? Do you have the histogram code outside of the for loop? Are you using the debugger?
Nick Haufler
2015-11-9
I have the histogram outside of the for loop, and I dont get any errors, but my histogram is not coming out correct. Ive used the debugger, but I cant find anything wrong. It may lie in my calculations, and im just not seeing it. It looks like it should work though; I dont understand.
R1nom=1000; %Nominal resistance values
R2nom=2000;
t1=1; %Resistor tolerances in %
t2=1;
vol=6;
n=10000; %Number of trials
m=0; %
voltarray1=zeros(n,1);
voltarray2=zeros(n,1);
for k=1:n
R1=(R1nom + (t1*R1nom))/(2*randn(1)); %actual resistance values
v1=(R1/(R1+R2))*vol;
voltarray1(k)=v1;
R2=(R2nom + (t2*R2nom))/(2*randn(1));
v2=(R2/(R1+R2))*vol; %voltage divider gain
voltarray2(k)=v2;
end
histogram(v1,100)
Geoff Hayes
2015-11-9
Nick - look at your call to histogram
histogram(v1,100)
You are passing a single voltage and not the array as
histogram(voltarray1,100);
Nick Haufler
2015-11-9
The histogram still only shows one vertical bar, and it's supposed to show multiple.
Geoff Hayes
2015-11-9
Nick - trying to execute your code (from above) fails with the error
Undefined function or variable 'R2'.
This is because of the following lines of code
R1=(R1nom + (t1*R1nom))/(2*randn(1)); %actual resistance values
v1=(R1/(R1+R2))*vol;
voltarray1(k)=v1;
R2=(R2nom + (t2*R2nom))/(2*randn(1));
Note how R2 is initialized after you have used it in the calculation of v1. The reason why running your code may not create the same error is because you are running it as a script and so the workspace variables are still present. Sometimes it is preferable to create and run your code as a function instead. See the MATLAB documentation for the differences between scripts and functions.
As for why you only get one bar in your histogram. Look closely at how you are calculating the resistor one and resistor two values, R1 and R2.
R1=(R1nom + (t1*R1nom))/(2*randn(1));
R2=(R2nom + (t2*R2nom))/(2*randn(1));
Now look at how the equation is defined in your assignment
resistor_value = nominal_value + range/2*randn(1);
The differences between how you have coded the equation and how it is defined, while slight, contribute to the errors that you are observing.
Also, your initialization of the tolerance variables, t1 and t2, are incorrect. Again, refer back to your assignment to see how they should be defined (not as percentages). Look at how the R1min and R1max values are calculated.
Nick Haufler
2015-11-9
Thanks for the help, im close, but for the equation the document says
where resistor_value is the randomly computed value for the resistor, nominal_value is the expected value for the resistor, and range is the product of the tolerance for the resistor and the nominal resistor value.
My nominal values are defined as R1nom and R2nom. The range says it should be the product of the tolerance and the nominal value. That would be t1*R1nom which is my tolerance multiplied by the nominal value. Ive looked over the equation multiple times, but nothings going off in my head as to why its wrong. As for the min/max calculation they would be defined as
minR1=R1-(t1/100)*R1
maxR1=R1+(t1/100)*R1
Geoff Hayes
2015-11-10
编辑:Geoff Hayes
2015-11-10
But see the difference between the two!
minR1=R1-(t1/100)*R1
vs
R1=(R1nom + (t1*R1nom))/(2*randn(1));
Doesn't this mean that your R1 and R2 should be
R1 = R1nom + (t1*R1nom/100)/2*randn(1);
The removal of the brackets and the dividing by 100..that is what you are missing. You must divide the tolerance by 100 i.e. the 1% tolerance becomes 0.01 exactly as you have shown in the minR1 and maxR1 calculations.
Nick Haufler
2015-11-10
You're totally right, the tolerances were changed, but I didn't divide by 100. I divided by 100 in part b, but just totally forgot. I feel so stupid, but thanks for taking the time to help me with this. I'll finish up the if statements on whether the circuits meet the voltage tolerances to end it. Thanks again!
Image Analyst
2015-11-10
Nick, you can also "Thank" him by "Accepting his answer and Voting for his answer to give him "reputation points".
更多回答(1 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Startup and Shutdown 的更多信息
标签
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)