Detect where an array becomes negative
48 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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 commentaires
dpb
le 26 Juil 2016
Modifié(e) : dpb
le 26 Juil 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.
Réponses (2)
dpb
le 25 Juil 2016
Modifié(e) : dpb
le 26 Juil 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 commentaires
Star Strider
le 25 Juil 2016
Modifié(e) : Star Strider
le 25 Juil 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 commentaires
Star Strider
le 26 Juil 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]'
Voir également
Catégories
En savoir plus sur Creating and Concatenating Matrices dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!