2017-07-27 6 views
1

j'ai écrit une fonction que j'espère avoir l'entrée et la sortie vectorisé:Comment vectoriser l'entrée de fonction de matlab quand NaN pourrait être l'entrée?

function output = myfunction(input1,input2) 
if input1 == 0 
    output = equation1 ; 
else 
    output = equation2 ; 
end 

Je l'ai testé avec input1 = 0 et input1 = 0.5 et myfunction fonctionne bien. input1 et input2 sont en réalité des matrices 3D. J'essaie d'avoir un calcul plus efficace au lieu d'exécuter une boucle pour un calcul élément par élément. Si input1 sont tous les éléments non-zéro, myfunction fonctionne correctement. Il semble qu'une fois que j'ai entré une matrice avec des éléments zéro et non nul, il ne peut pas passer par le if-statement correctement. Ma fonction me donnera NaN pour l'élément qui a input1==0.

Comment puis-je le modifier afin que myfunction peut prendre un nombre ou une matrice dans un if-statement?

Merci!

[EDIT:]

La fonction réelle ressemble à ceci:

function output = myfunction(input1 , frequency , input2 , input3) 

zero_ind = input1 == 0 ; 
output = zeros(size(input1)) ; 
output(zero_ind) = input3(zero_ind)/frequency ./ input2(zero_ind) ; ; 
temp1(~zero_ind) = input1(~zero_ind)/frequency ; 
temp2(~zero_ind) = input2(~zero_ind) * frequency ; 
output(~zero_ind) = input3(~zero_ind) .* (1 + temp1(~zero_ind)).^temp2(~zero_ind) .* temp1(~zero_ind) ./ ((1 + temp1(~zero_ind)).^temp2(~zero_ind) - 1) ; 
+0

Est-ce que les deux équations utilisent 'input1' et' input2'? – EBH

+0

'equation1' utilise input2 et' equation2' utilise input1 et input2. Cela fera-t-il quelque chose de différent? – Ying

+0

Ce n'est pas exactement clair pour moi ce que vous voulez faire. Est-ce que 'all (input1 (:))' est ce que vous cherchez? – Poelie

Répondre

1

Voici une suggestion générale de vectorisation. Cela devrait être changé correctement à votre type de calculs:

function output = myfunction(input1,input2) 
zero_ind = input1==0; % this replaces the if statement 
output = zeros(size(input1)); % initialize output to wanted size and shape 
output(zero_ind) = input2(zero_ind).^2; % equation1 
output(~zero_ind) = input1(~zero_ind).*input2(~zero_ind); % equation2 
end 

L'idée principale est d'utiliser logical indexing au lieu de la déclaration if. Je suppose ici (entre autres, je suppose) que toutes vos entrées et sorties sont de la même taille. Cela pourrait être assoupli, mais cela dépend du calcul que vous faites.

EDIT:

En réponse à votre édition avec la fonction réelle, voici ma suggestion (j'ai changé les noms d'entrée juste pour le rendre un peu plus compact):

function output = myfunction(in1,frequency,in2,in3) 
temp1 = in1/frequency ; 
temp2 = in2*frequency ; 
output = in3.*(1+temp1).^temp2.*temp1./((1+temp1).^temp2-1); 
zero_ind = in1 == 0; 
output(zero_ind) = in3(zero_ind)./frequency./in2(zero_ind); 
end 

Ce que je l'ai fait est de calculer tous output comme il n'y a pas de zéros dans in1, puis remplacez uniquement les endroits dans output qui correspond à un zéro dans in1 à une autre valeur. De cette façon, vous n'utilisez zero_ind que lorsque cela est nécessaire et minimisez l'opération d'indexation.

+0

Oui, j'ajuste la variable d'entrée à la même taille pour éviter d'utiliser bsxfun que je ne suis pas vraiment familier. Je suppose que cela pourrait être une solution réalisable, mais mon 'equation2' doit utiliser' (~ zero_ind) 'peut-être 8 fois. Et il semble que cela prend trop de mémoire et le message suivant. 'Le tableau demandé 249901x249901 (465,3GB) dépasse la taille maximale du tableau. La création de tableaux supérieurs à cette limite peut prendre beaucoup de temps et entraîner le blocage de MATLAB. Pour plus d'informations, reportez-vous à la section Limite de taille de tableau ou panneau de préférences. – Ying

+0

@Ying D'abord, la vectorisation n'est pas une magie, il faut beaucoup de mémoire pour accélérer les choses. C'est un compromis fondamental entre la mémoire et la vitesse.Deuxièmement, je pense que vous pouvez aborder ce problème de manière incorrecte, il se peut que vous deviez vous familiariser avec 'bsxfun' (implicitement implémenté depuis 2016b). De toute façon, je ne peux pas vous aider plus que cela sans voir votre vrai calcul. Votre question est simplement trop vague. – EBH

+0

Merci d'avoir mentionné l'indexation logique. Est-ce une méthode qui va prendre beaucoup de mémoire lors du calcul? – Ying