Create a matrix with a for loop

2 views (last 30 days)
Colin Lynch
Colin Lynch on 11 Feb 2018
Edited: John BG on 15 Mar 2018
Hey there!
I am attempting to create a matrix which has n, s, k, and i as columns. However, I keep getting this error no matter how I try to make the matrix:
Subscript indices must either be real positive integers or logicals.
Is there a way around this problem considering that I need to make a list that comprises of numbers that aren't positive integers?
for i = -3:.5:2
k = 10^i;
n = (100 / k);
s = sqrt((-.5^2 .* ((100 / k)-(.5.*(100 / k)))./(100-(100 / k)))./((((100 / k)-(.5.*(100 / k)))./(100-(100 / k)))-1));
if (0<s) && (s<=1)
s = s;
elseif s > 1 || (isnan(s)==1)
s = 1;
elseif isreal(s) == 1
s = 0;
else
s = 0;
end
RTIlogk{i} = [i k n s];
end
  4 Comments
per isakson
per isakson on 18 Feb 2018
No but it's still a relevant comment.
John BG
John BG on 18 Feb 2018
Edited: John BG on 21 Feb 2018
the initial s is as follows:
s =
Column 1
0.000000000000000 + 0.288771407778945i
Column 2
0.000000000000000 + 0.288979906876575i
Column 3
0.000000000000000 + 0.289642223181746i
Column 4
0.000000000000000 + 0.291767011359047i
Column 5
0.000000000000000 + 0.298807152333598i
Column 6
0.000000000000000 + 0.324953285195147i
Column 7
NaN + 0.000000000000000i
Column 8
0.274222586190323 + 0.000000000000000i
Column 9
0.121267812518166 + 0.000000000000000i
Column 10
0.064418039894926 + 0.000000000000000i
Column 11
0.035623524993955 + 0.000000000000000i
if you decide to apply isreal(s), look what happens:
isreal(s)
ans =
logical
0
despite some of the values of s are clearly real, applying isreal() does not return those with null imaginary.
Instead, look for those components of s that have null imag(s), please have a look at my answer, thanks in advance
John BG

Sign in to comment.

Accepted Answer

John BG
John BG on 18 Feb 2018
Edited: John BG on 18 Feb 2018
Hi Colin
this is John BG jgb2012@sky.com
1.
is there need for the for loop?
i = -3:.5:2;
k = 10.^i;
n = (100 ./ k);
s = sqrt((-.5^2 .* ((100 ./ k)-(.5.*(100 ./ k)))./(100-(100 ./ k)))./((((100 ./ k)-(.5.*(100 ./ k)))./(100-(100 ./ k)))-1));
2.
NaNs to 1
s(find(isnan(s)))=1
3.
abs(s)>1 to 1, instead of
if s >1
get the indices of s meeting constrain abs(s)>1 with command find
s(find(s(abs(s)>1)))=1
4.
if you want the previous 2 constraints combined then, instead of
if s > 1 % || (isnan(s)==1)
s = 1;
use
intersect(find(s(abs(s)>1), find(isnan(abs(s)))
5. instead of
isreal(s)
use
s(find(imag(s)==0))=0
6.
instead of
if (s>0) && (s<=1)
s = s;
use
intersect( s(abs(s)>0), s(abs(s)<=1))
but wouldn't it be just fine to leave these remaining as they are?
7.
the last
else
s = 0;
would zero useful data, omitted
so all together
i = -3:.5:2;
k = 10.^i;
n = (100 ./ k);
s = sqrt((-.5^2 .* ((100 ./ k)-(.5.*(100 ./ k)))./(100-(100 ./ k)))./((((100 ./ k)-(.5.*(100 ./ k)))./(100-(100 ./ k)))-1));
s(find(isnan(s)))=1 % NaNs to 1
s(find(s(abs(s)>1)))=1 % abs(s)>1
s(find(imag(s)==0))=0 % zero reals
.
for the generation of RT do you want to use
[i k n abs(s)]
or
RTIlogk= [i' k' n' abs(s)']
RTIlogk =
1.0e+05 *
Columns 1 through 3
-0.000030000000000 0.000000010000000 1.000000000000000
-0.000025000000000 0.000000031622777 0.316227766016838
-0.000020000000000 0.000000100000000 0.100000000000000
-0.000015000000000 0.000000316227766 0.031622776601684
-0.000010000000000 0.000001000000000 0.010000000000000
-0.000005000000000 0.000003162277660 0.003162277660168
0 0.000010000000000 0.001000000000000
0.000005000000000 0.000031622776602 0.000316227766017
0.000010000000000 0.000100000000000 0.000100000000000
0.000015000000000 0.000316227766017 0.000031622776602
0.000020000000000 0.001000000000000 0.000010000000000
Column 4
0.000002887714078
0.000002889799069
0.000002896422232
0.000002917670114
0.000002988071523
0.000003249532852
0
0
0
0
0
if you find this answer useful would you please be so kind to consider marking my answer as Accepted Answer?
To any other reader, if you find this answer useful please consider clicking on the thumbs-up vote link
thanks in advance for time and attention
John BG
  2 Comments
Walter Roberson
Walter Roberson on 18 Feb 2018
Most of those find() are not needed. For example,
s(find(isnan(s)))=1
can be
s(isnan(s)) = 1;
Also, be careful with the order of the statements:
>> abs(3-5i) > 1
ans =
logical
1
but 3-5i should probably be replaced by 0 under the ~isreal() rule.
John BG
John BG on 21 Feb 2018
No, why should 3-5i be zeroed?
the rule regarding real is
elseif isreal(s) == 1
s = 0;
or as you have pointed out
elseif isreal(s)
s = 0;
I recommend to instead replace this with
elseif imag(s) ==0
s = 0;
or
elseif imag(s) < err1
s = 0;
Walter, let's comment the rules supplied in the question, shall we?
1.
if (0<s) && (s<=1)
s = s;
this to me means if s<0 do nothing, which as you said, since s may or may not be complex, doesn't help much.
Perhaps Colins means
if (real(s)<0) && (abs(s)<=1)
s = s;
but so far no comment from the question originator, and in any case,
s=s
same as do nothing.
2.
elseif s > 1 || (isnan(s)==1)
s = 1;
Again, let me start with the NaN
NaN+5i or -3+NaN*1j is same as NaN, as long as there's a NaN, doesn't matter whether in real or imaginary parts, the value is NaN, so all NaNs to 1.
I assumed
abs(s)>1
3.
elseif isreal(s) == 1
s = 0;
to me this is the same as
if imag(s)==0
then don't care about real(s) and zero it.
4.
else
s = 0;
this last else bring everything down to zero, shouldn't be here, why starting any calculation if it all ends up being zeroed?
therefore I encourage the question originator Mr Lynch to add some comments to help decide what answer does qualify to accepted answer.

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 18 Feb 2018
Change
RTIlogk{i} = [i k n s];
to
RTIlogk{2*i+7} = [i k n s];
Or, better yet, learn this pattern:
ivals = -3:.5:2;
num_i = length(ivals);
RTIlogk = cell(num_i,1);
for i_idx = 1 : num_i
i = ivals(i_idx);
...
RTIlogk{i_idx} = ...
end
This pattern does not require that the values be equally spaced or even real valued.
  2 Comments
Walter Roberson
Walter Roberson on 18 Feb 2018
And be careful: the < operator ignores any complex component for the comparison. You should always check for complex before using the relative comparison operators.
John BG
John BG on 15 Mar 2018
Edited: John BG on 15 Mar 2018
And
1.
assert(3>4)
Assertion failed.
as expected throws error if condition false.
2.
assert does nothing if condition true:
assert(3<4)
4.
as Walter mentions above, in the following line operators < > do not compute imaginary numbers, returning false for the real parts only, and in turn assert returns error
assert(1j*3<1j*4)
Assertion failed.
assert(0+1j*3<0+1j*4)
Assertion failed.
assert(3i<4i)
Assertion failed.
5.
However, to further warn about the use of operators < > with figures that have non-null imaginary parts
assert(3i<4)
now assert does nothing, which implies that
3i<4
returns true
and
assert(3i>4)
Assertion failed.
6.
As Walter points out,
avoid using operators
<
>
with numbers that have non null imaginary parts.
apply abs() real() or any other function before using < > to precisely avoid href = ""</a> dealing with complex figures.
Regards
John BG

Sign in to comment.

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!