2009-05-07 6 views
3

Dire que j'ai l'instruction if de base suivante:Elementwise ifs dans matlab - existent-ils?

if (A ~= 0) 
    % do something like divide your favorite number by A 
else 
    % do something like return NaN or infinity 
end 

Le problème est que A est pas un nombre simple, mais un vecteur. Matlab renvoie vrai si aucun élément dans A n'est égal à 0. Qu'est-ce que je recherche est un vectorisé? façon de percevoir l'instruction if ci-dessus pour chaque élément dans A.

En fait, je veux simplement le faire aussi vite que possible.

+0

Je pense que vous voulez dire si (A ~ = 0) – MatlabDoug

Répondre

4
B = zeros(size(A)); 
B(A~=0) = FAV./A(A~=0); 
B(A==0) = NaN; 
0

Cherchez-vous tous les éléments non-zéro? Vous pouvez le faire de deux façons.

nonzero = find(A); % returns indicies to all non-zero elements of A 
y = x./A(nonzero); % divides x by all non-zero elements of A 
        % y will be the same size as nonzero 

Ou pour une seule ligne, vous pouvez utiliser un conditionnel à la place de indicies

y = x./A(A~=0); % divides x by all non-zero elements of A 
+0

Cette déclaration entraînera y être plus courte que A si un élément de A est nul, ce qui peut être désiré ou non. –

0

Ce que vous devez faire est d'identifier les éléments que vous souhaitez opérer. J'utiliserais FIND. Je stocke les résultats dans VI (Indicateurs valides) et l'utilise pour peupler la matrice.

clear 
clc 

den = [2 0 2; 0 2 0; -2 -2 -2] 
num = ones(size(den)); 
frac = nan(size(den)); 

vi = (den ~=0) 

frac(vi) = num(vi)./den(vi) 

vi = (den == 0) 

frac(vi) = nan %just for good measure... 
+1

fyi: vous n'avez pas besoin d'utiliser find, vous pouvez utiliser des matrices booléennes directement. La valeur de find est d'extraire des valeurs d'index particulières, et/ou d'économiser de l'espace mémoire si seulement quelques valeurs sont vraies. –

+0

enlevé TROUVER comme demandé par JASON S – MatlabDoug

6

Les ifs vectorisés n'existent pas, mais il existe certaines options. Si vous voulez tester tout ou partie des éléments, utilisez la fonction tout ou n'importe quel.

Voilà un exemple de modification conditionnelle des valeurs d'une matrice:

b = A ~= 0;  % b is a boolean matrix pointing to nonzero indices 
       % (b could be derived from some other condition, 
       % like b = sin(A)>0 
A(b) = f(A(b)) % do something with the indices that pass 
A(~b) = g(A(~b)) % do something else with the indices that fail 
+0

Je n'avais pas réalisé que b (la matrice booléenne) existait jusqu'à ce que vous le montriez. Merci! – AnnaR

1

En général, pour effectuer une opération sur des éléments d'une matrice et une autre opération sur les éléments restants, une seule ligne la solution est:

Z = B .* X + ~B .* Y; 

où B est une matrice logique. A titre d'exemple,

Z = (A == 0) .* -1 + (A ~= 0) .* A; 

copie A mais affecte -1 partout où A est zéro.

Cependant, parce que la question porte sur l'infini ou NaN, il peut être fait encore plus succinctement:

Z = FAV ./ A; % produces inf where A == 0 
Z = (A ~= 0) .* FAV ./ A; % produces NaN where A == 0 
+0

+1: Un revêtement intelligent! – gnovice