Numel with loop for+if condition
显示 更早的评论
Hello everybody :
I have the following matrix of 6*6 elements
1 -2 1 1 -3
4 1 2 2 5
7 3 5 4 -7
-8 4 -8 -4 -1
-1 5 -7 7 1
-7 9 4 -2 1
I want to set condition for negative numbers and another condition for positive numbers and calculate a new matrix named B
B=zeros(size(A))
for i=1:numel(A)-1
for j=2:numel(A)
if (A(i)<0)
B(i)=2*sind(A(i))
else
B(i)=1.5*sind(A(i))-2*tand(A(j))
end
end
end
The problem here is that I want to skip the last element of each row I mean :
i is not supposed to reach the last element of each row. it stops always at the before last element, j contrariwise can reach the last element, but the matrix B elements depends on i.
*1* *-2* *1* *1* *-3* ===> not supposed to be reached by *j*
4 1 2 2 5
7 3 5 4 -7
-8 4 -8 -4 -1
-1 5 -7 7 1
*-7* *9* *4* *-2* *1* ===> not supposed to be reached by *i*
I know that numel calculates for all the matrix elements and as I am writing, the code skips only the last element of the matrix and not every last element of a row ; so how to do, please ?
采纳的回答
numel isn't the builtin you're looking for here, it's the product(size(A)) --> 36, not 6.
But, you "don't need no steenkin' loop" anyway; use Matlab vectorized operations--
ADDENDUM/ERRATUM Updated to reflect latest comment re: indexing
OK, for lack of time to consider optimization fully, a working solution using a couple of temporary arrays--
A1=A(1:end-1,:);A2=A(2:end,:); % the two subset sections accounting for offset
ix=A1<0; % as before, the -ive locations in base area
B=zeros(size(ix)); % initialize output to that size
B(ix)=2*sind(A1(ix)); % negative values use same locations only
B(~ix)=1.5*sind(A1(~ix)) ...
-2*tand(A2(~ix)); % +ive also use row below for second term
There's a syntax problem trying to write the subscripting expression using only the one A array that in time I had available couldn't seem to wrap head around for a usable way to write--needed indexing expression that can apply to a result without a temporary a la Octave but not available in Matlab. Came up with same conundrum with either route of trying to shift or use the subarea from the full array for the index so since have other commitments just backed off to the straightforward solution.
To illustrate it operates, here's the result of a test for the above A that shows each of the two values in A being addressed by row for the summing operation without the sind so can pick the locations out easily by eye...
>> [A1(~ix) A2(~ix)]
ans =
1 4
4 7
7 -8
1 3
3 4
4 5
5 9
1 2
2 5
5 -8
1 2
2 4
4 -4
7 -2
5 -7
1 1
>>
This matches the circled locations in your figure...
15 个评论
Hello, dpb, thank you very much for your answer , it's an elegant way to process, but here it's not the aim of my code.
i is going from 1st element to the before last element of each row and j is going from the 2nd element to the last element of the each row. the final resul will be a 5*6 matrix elements.
first condition for positive numbers , second for negatives
Well that's a different problem description than the first...so which element is the one to be looked at as the negative one, the LH set or the RH set?
Well.. the first element in the matrix will be -8
I tried something like :
B=zeros(size(A)
[l s]=size(A)
for i=1:l-1
for j=2:l
for k=1:s
if A(i,k)<0
B(i,k)= 2*sind(A(i,k));
else
B(i,k)=1.5*sind(A(i,k))-2*tand(A(j,k));
end
end
end
end
But here , I have a problem of overwriting the matrix ...
OK, so the decision on +/- is made on the 2nd:Last row, 1:Last column.
ix=A(2:end,:)<0;
B(ix)=2*sind(A(ix));
Now, for
B(~ix)=?;
, the complement of the elements of B(ix) (the else clause), the question is what the indices for the second term are supposed to be in what you've written as A(j,k). Show for a particular set which you think those should be.
B=A(1:end,:);
ix=A(1:end-1,:)<0;
B(ix)=2*sind(A(ix));
B(~ix)=1.5*sind(~ix)- 2*tand(~ix+1); ==>
the element comming after the detected positive element
( so while ~ix=A(1:end-1,:) (~ix+1=2:end,:)
the sign of the after positive element ~ix+1 is not important, just take the element comming after the positive one detected..
and if we will put something like :
B=A(1:end,:);
ix=A(1:end-1,:)<0;
B(ix)=2*sind(A(ix));
jx=A(2:end,:)
B(~ix)=1.5*sind(~ix)- 2*tand(jx)
this will not be possible I guess
Subscript indices must either be real positive integers or logicals.
@heir ancestors: posting broken code does not help dpb to answer your question. Posting the information that they asked for does help them:
"Show for a particular set which you think those should be"

Thank you stephan, I appologise maybe I wasn't enough clear , So As shown by the image , if B(~xi) is the detected positive element the A(j,k) is the element comming after him for exemple if the positive element is 1 in blue A(j,k)=4 , if positive =4 , A(j,k)=7, 7==>-8 ...and then the second row ...etc. I didn't circle all the elements of the others rows 2:5 , just two other examples , I really hope I 'm clear :( , for exemple in the last row when the last element checked positive will be (~xi)=1 , the element comming after him (A(j,k)=1).
I just correct that
OK, so the decision on +/- is made on the 1st: before Last row, 1:Last column.
ix=A(1:end-1,:)<0;
B(ix)=2*sind(A(ix));
There is no image and this is still undecipherable as to what you really mean. (ADDENDUM the image now does show up--dpb)
...
So the rule for +-ive locations is to use the location one row below, it appears.
I really don't know what to write to express something understandable. So : for the negative elements the first part you wrote is perfect with changing just that the decision of +/- is made on 1:end-1 row, 1:Last column
ix=A(1:end-1,:)<0;
B(ix)=2*sind(A(ix));
ok ..Now if the element is postive (~ix), so here is the Matrix A, the element between / / are the positive elements of the first row
/1/ -2 1 1 -3
/4/ 1 2 2 5
/7/ 3 5 4 -7
-8 4 -8 -4 -1
-1 5 -7 7 1
-7 9 4 -2 1
this will introduce the second equation for positive elements,
sind here took the value of the positive element, and tand took the value of the element comming after this positive element in the row ( we don't care of it is positive or negative), here are the calculations for the first row ... and the same for the others ...etc
B(~ix)=1.5*sind(1)- 2*tand(4)
B(~ix)=1.5*sind(4)- 2*tand(7)
B(~ix)=1.5*sind(7)- 2*tand(-8)
..
please tell me this was clear :(
"...the element between / / are the positive elements of the first row"
There's where a lot of the confusion comes from; your nomenclature can be confusing--that is a column, not a row which mixup is where got off on wrong foot in the very firstest posting...
That aside, this confirms the supposition made before of the 2nd term is the element in same column one row after the subject position. See the revised Answer for first shot; I thought I had it initially but realized there's an issue in which row is being addressed from the subject array by using the smaller subset of the full array for the indexing to get the last row--it never reaches there so need to fix that. As noted, I've got to go the "day job" for a while but that should get you started thinking in the right direction methinks...
...
ADDENDUM OK, I posted a revised solution that I believe does work correctly for these ground rules; it ends up using a couple of temporaries to effect the shift as developed some addressing issues that were more complex than have time to delve into further trying to avoid them and work with only the one array and dynamic subsets thereof...
[Moved OP's Answer to Comment for cleanliness in thread--dpb]
Hello Again Dpb, Thank you very much for your time , and I'm sorry for the confusion That I created between Columns and rows :/ , the code of the first answer is just working Beautifully, I learned a lot from your answers. just a little oblivion in the code :
B(ix)=2*sind( A1(ix)); % A1 not A. :)
thank you again DPB :)
Yeah, I had noticed and fixed that; perhaps overlapped your observing the result.
The 'row/column' thing I understand I think; you were looking at the elements in the vector processing and thinking of them as a "row of numbers" whereas I was trying to interpret which values were intended in the looping construct as the object of the indices and so was needing to know "who's who in the zoo" from a memory/addressing standpoint in the array...
I'm still really snowed; mayhaps later on I can come back and look at the issue of how to write without the temporaries, but unless the actual arrays were to become huge, the penalty here isn't large and you can clear them immediately after use or write a utility function in which they become automagic temporaries which only exist during the lifetime of the function.
Ahein, Thank you again DPB four all the clarifications and all the Matlab tricks : )
更多回答(0 个)
类别
在 帮助中心 和 File Exchange 中查找有关 Data Type Identification 的更多信息
标签
另请参阅
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)
