Detect where an array becomes negative
65 views (last 30 days)
Show older comments
Hi everyone,
I have an array of size 401 x 381 which has positive and negative values. I would like to detect which row in each column this change of sign occurs for the purposes of comparison. If anyone has any ideas they will be appreciated. If you need to see the full code then just ask, I thought I would leave it out for the sake of simplicity.
Thanks, John.
6 Comments
dpb
on 26 Jul 2016
Edited: dpb
on 26 Jul 2016
Then for the latter columns there isn't a transition from + to -, it's t'other way 'round. So you're actually looking for the sign transition. Is zero a possible element in the array, too? What is the result in that column if so? Posted a solution that will give the zero location in that case.
Answers (2)
dpb
on 25 Jul 2016
Edited: dpb
on 26 Jul 2016
Sometimes it's just as easy to loop...it's unfortunate in cases like this find isn't vectorized; a cleaner syntax doesn't pop into mind at the moment altho I suspect there is something I'm just not seeing at the moment...
nc=size(x,2); % number of columns
ix=zeros(1,nc); % preallocate for the index
for i=1:nc
ix(i)=find(x(:,i)<0,1); % the first negative location in ith column
end
ADDENDUM As Per notes, the above presumes there is a valid entry in every column, if it's possible that's not so then include test that the result from find isn't empty...
for i=1:nc
idx=find(x(:,i)<0,1); % the first negative location in ith column
if ~isempty(idx) % if none, find returns empty array
ix(i)=idx; % save the valid ones...
end
end
As a design note, I chose the above so the resulting vector would have same length as number of columns in original array consistent with other Matlab behavior of things that operate over columns/rows. Since indices are always one-based, zero is unique indicator of missing value; one could also use NaN as the initial value as well for more obvious flag.
ADDENDUM 2
With the addition of the other conditional, the above works with a slight modification --
nc=size(x,2); % number of columns
ix=zeros(1,nc); % preallocate for the index
for i=1:nc
ix(i)=find([0;diff(sign(m(:,i)))],1);
end
With the caveat that, as described, there will be a sign change in each column so the empty condition doesn't occur...the defensive strategem has already been demonstrated above just in case.
ERRATUM I just note I left out the subscripting expression on the x array initially; what one gets for "keyboard debugging" instead of cut 'n paste. Fixed all instances I believe...if missed one, should be apparent.
0 Comments
Star Strider
on 25 Jul 2016
Edited: Star Strider
on 25 Jul 2016
This one approach:
[r,c] = find(A < 0);
Uc = unique(c);
R = {Uc accumarray(c, r, [], @(c) {r(c)})};
celldisp(R)
It produces ‘R’, a cell with the first column being the column numbers and the other cells being the corresponding rows with the negative values.
EDIT — Note that this outputs only columns with at least one negative number (my reason for using the unique function). A column with no negative number does not appear.
2 Comments
Star Strider
on 26 Jul 2016
I’m not certain what you mean by ‘linear indexed’. See if this does what you want:
A = randi([-9 9], 5, 6); % Create Data
[r,c] = find(A < 0);
R = {[1:size(A,2)]' accumarray(c, r, [], @(c) {r(c)})};
for k1 = 1:size(A,2)
Rk(k1,:) = R{2}{k1}(1);
end
Result = [R{1} Rk]'
See Also
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!