2013-12-13 8 views
6

Ho un problema. Sto cercando di implementare questo breve pezzo di codice. enter image description hereestensione di bsxfun per soddisfare particolari indici in una matrice

I passaggi di base che ho già fatto. Si prega di controllare il mio codice qui sotto:

clc;clear all;close all; 
A=round(-3+(6).*rand(5,5)); 
B=round(-3+(6).*rand(5,5)); 
%//The check matrix stores the conditions present on the right side of the equation. 
check = A.*B 
%//upd_max and upd_min are the given as the del_max and del_min in the equation 
upd_max = 0.5; 
upd_min = 0.1; 
%//eta_plus and eta_minus are denoted as nplus and nminus 
nplus = 1.2; 
nminus = 0.5; 
%del_(k-1)_i matrix is given as update_mat 
update_mat = (0.1+(0.4).*rand(size(check))).*ones(size(check)) 
update_new = update_mat.*(check==0) + bsxfun(@min,(nplus.*update_mat.*(check>0)),upd_max)... 
      + bsxfun(@max,nminus.*(update_mat.*(check<0)),upd_min) 

sto dando seguito risultato di un campione del mio pezzo di codice:

check = 

    2 -6  0 -1  2 
    -3 -4  3 -3  4 
    0  2 -2  6  0 
    2 -1 -4 -1 -3 
    -2 -4 -3  0  6 


update_mat = 

    0.4102 0.4173 0.1126 0.2268 0.4964 
    0.4622 0.3750 0.4282 0.3422 0.1495 
    0.4760 0.3820 0.2903 0.3143 0.1473 
    0.3603 0.2861 0.3122 0.3527 0.2908 
    0.3602 0.3696 0.3220 0.2046 0.4746 
update_new = 

    0.5922 0.2087 0.2126 0.1134 0.6000 
    0.2311 0.1875 0.6000 0.1711 0.2794 
    0.5760 0.5584 0.1452 0.4772 0.2473 
    0.5324 0.1431 0.1561 0.1763 0.1454 
    0.1801 0.1848 0.1610 0.3046 0.6000 

Tuttavia questa risposta non è corretto !! Per spiegare sto dividendo la mia risposta in tre parti:

update_mat.*(check==0) 

ans = 

     0   0 0.1126   0   0 
     0   0   0   0   0 
    0.4760   0   0   0 0.1473 
     0   0   0   0   0 
     0   0   0 0.2046   0 

bsxfun(@min,(nplus.*update_mat.*(check>0)),upd_max) 

ans = 

    0.4922   0   0   0 0.5000 
     0   0 0.5000   0 0.1794 
     0 0.4584   0 0.3772   0 
    0.4324   0   0   0   0 
     0   0   0   0 0.5000 

Come si può vedere chiaramente i first due termini siano corretti. Tuttavia il terzo termine è sbagliato. Il terzo termine deriva da questo:

bsxfun(@max,nminus.*(update_mat.*(check<0)),upd_min) 

ans = 

    0.1000 0.2087 0.1000 0.1134 0.1000 
    0.2311 0.1875 0.1000 0.1711 0.1000 
    0.1000 0.1000 0.1452 0.1000 0.1000 
    0.1000 0.1431 0.1561 0.1763 0.1454 
    0.1801 0.1848 0.1610 0.1000 0.1000 

Il terzo termine corretto dovrebbe darmi

 0 0.2087   0 0.1134   0 
0.2311 0.1875   0 0.1711   0 
    0   0 0.1452   0   0 
    0 0.1431 0.1561 0.1763   0 
0.1801 0.1848 0.1610   0 0.1000 

Voglio che il bsxfun per calcolare l'elemento di saggio massima solo per gli elementi non nulli della matrice nminus.*(update_mat.*(check<0)) e non tutte le matrici. È possibile farlo?

Grazie in anticipo! PS: Si prega di dare idee per un codice ottimizzato migliore.

risposta

6

Non è necessario bsxfun poiché hai a che fare con uno scalare, basta indicizzazione logica:

M=nminus.*(update_mat.*(check<0)) 
M((~~M) & (M < upd_min)) = upd_min %// ~~M is the same as M~=0 

(btw questo presuppone che per il suo esempio di dati che hai fatto un errore nella penultima fila dell'ultima colonna in cui hai 0 ma penso che tu voglia 0.1454)

+0

Capisco la tua idea e funziona anche tu! ma non posso usare bsxfun per farlo? Come ho capito, è molto più veloce. – roni

+2

@roni non è quello che fa bsxfun. Dubito fortemente che sarebbe più veloce dell'indicizzazione logica. È spesso più veloce dell'uso di 'repmat' o loop ma quando si ha a che fare con uno scalare, è inutile. Questa è la strada da percorrere. – Dan

+3

@roni Bsxfun viene utilizzato quando è necessario espandere ** vettori ** per abbinare le dimensioni. Con gli scalari è inutile e si aggiunge al sovraccarico. – Oleg