Usando i e j come variabili in Matlab


142

ie jsono nomi di variabili molto popolari (vedi ad esempio, questa domanda e questa ).

Ad esempio, nei loop:

for i=1:10,
    % do something...
end

Come indici in matrice:

mat( i, j ) = 4;

Perché non dovrebbero essere usati come nomi di variabili in Matlab?


5
Ovviamente non lo contrassegnerò come tale, ma a giudicare dalle risposte direi che questo è "principalmente basato sull'opinione". ;-) Io personalmente non rinunciare i, j, kcome i nomi delle variabili ciclo generici.
A. Donda,

1
@A.Donda bene, questa è la tua opinione;)
Shai

@Shai, questa è la tua ultima frase in questa domanda: "Perché non dovrebbero essere usati come nomi di variabili in Matlab?" Quindi non è molto chiaro perché rifiuti la mia edizione sulla tua domanda ?! Ho cambiato il tuo titolo in un titolo più costruttivo "Perché NON usare iej come variabili in Matlab"
Seyfi,

Risposte:


176

Perché ie jsono entrambe le funzioni che indicano l' unità immaginaria :

Quindi una variabile ha chiamato io jli sovrascriverà, potenzialmente rompendo silenziosamente codice che compie calcoli matematici complessi.

Le possibili soluzioni includono invece l'uso iie jjcome variabili di ciclo, oppure l'utilizzo 1iogni volta che iè richiesto per rappresentare l'unità immaginaria.


42
Vale anche la pena notare che anche se non stai rompendo nulla, il tempo di esecuzione viene comunque sacrificato per risolvere i nomi delle variabili ie j.
Eitan T

14
@Eitan: Puoi davvero sostenerlo in modo concreto e conclusivo in una versione compilata JIT di Matlab? Non ho mai trovato il caso (e i semplici test che chiamano un forloop 1 miliardo di volte non mostrano alcuna differenza statistica nei tempi). Per quanto ne sappiamo, esiste un codice speciale per gestire esattamente questo e l'utilizzo di variabili diverse da ie j(e k?) È in realtà leggermente più lento. E le differenze che esistono sono minuscole inesistenti nella vita reale. Semplicemente non vi è alcun motivo per NON utilizzare ie jcome variabili regolari, devono solo essere usate correttamente come qualsiasi altra funzione di Matlab.
Horchler,

5
@horchler Bene, i documenti ufficiali dichiarano qui che l'override delle classi di dati MATLAB standard "può influire negativamente sulle prestazioni", e qui è implicito evitare l'override di costanti complesse per motivi di velocità e robustezza. Nei documenti più vecchi di R2009b è espressamente raccomandato di ignorare le costanti complesse, poiché ciò potrebbe ostacolare l'accelerazione JIT. La risoluzione dei nomi delle variabili è forse minuscola, ma può essere significativa se ripetuta milioni di volte.
Eitan T

14
Forse nelle versioni antiche di Matlab. Lo vedevo io stesso. Ma non più con R2012a + (OS X) almeno. E non ho visto alcuna differenza quando ho chiamato un forloop 1 miliardo di volte e ho provato tutti i tipi di schemi di temporizzazione. Sto vedendo dire ai nuovi utenti SO che il codice perfettamente valido è sbagliato perché stanno usando ie jper iterare i loop. Francamente è solo stupido e alla gente manca il punto più importante di questa domanda: quello ie jnon dovrebbe nemmeno essere usato per l'unità immaginaria se si vuole scrivere un codice Matlab moderno leggibile.
Horchler,

12
il mio principale risparmio di tempo è quando faccio una ricerca per ii. La ricerca di me può essere un vero dolore
craq

62

È buona norma evitare ie le jvariabili impedire la confusione sul fatto che siano variabili o unità immaginaria.

Personalmente, tuttavia, utilizzo ie jcome variabili abbastanza spesso come l'indice di cicli brevi. Per evitare problemi nel mio codice, seguo un'altra buona pratica riguardante ie j: non usarli per indicare numeri immaginari. In effetti, la documentazione propria di Matlab afferma :

Per la velocità e una maggiore robustezza, è possibile sostituire complessi ie jdi 1i.

Quindi, piuttosto che evitare due nomi di variabili molto comunemente usati a causa di un potenziale conflitto, sono esplicito sui numeri immaginari. Rende anche il mio codice più chiaro. Ogni volta che vedo 1i, so che rappresenta sqrt(-1)perché non potrebbe essere una variabile.


2
È davvero una buona pratica da usare 1i. Tuttavia, la modifica del significato ie jpuò comportare errori difficili da eseguire il debug come questo .
Shai,

1
@Shai buon punto. Ho modificato la mia risposta per riconoscere che evitare ied jè il migliore, ma ho spiegato come il mio stile di codifica personale non segua quella regola.
shoelzer,

2
Si noti che la velocità menzionato non sembra essere molto significativo: stackoverflow.com/questions/18163454/...
Dennis Jaheruddin

Completamente d'accordo! La buona pratica è SEMPRE utilizzare 1ie non iper la matematica complessa. Pensiamo al numero immaginario come 1ie prendiamo icome numero immaginario una cattiva pratica. Non il contrario. Usando i, ii, iiiè prassi comune in Matlab e non c'è nessun problema quando la gente bastone a 1ie 1jper numero complesso. Anche Matlab rispetta questo e questo non diminuisce le prestazioni (per quanto ho testato) come indicato nella risposta precedente.
SdidS

iej non dovrebbero essere usati comunque - quei numeri significano qualcosa - usare un nome che descriva lo scopo (row_n, elementNo, listItemIndex, ecc.). Quindi molto più facile per qualcuno per capire cosa si sta facendo, per eseguire il debug, ecc Il tempo in più speso è più che vale il guadagno in manutenzione a lungo termine per qualcosa di più di uno script e getta - anche con l'editor Matlab essere molto indietro la maggior parte degli altri IDE moderni.
LightCC

27

Nelle vecchie versioni di MATLAB, c'era una buona ragione per evitare l'uso di ie jcome nomi di variabili - le prime versioni di MATLAB JIT non erano abbastanza intelligenti da dire se le stavi usando come variabili o come unità immaginarie, e quindi disattiva molte ottimizzazioni altrimenti possibili.

Il tuo codice sarebbe quindi più lento solo per la presenza stessa di ie jcome variabili e accelererebbe se le cambiassi in qualcos'altro. Ecco perché, se leggi molto codice MathWorks, vedrai iie jjutilizzerai abbastanza ampiamente come indici di loop. Per un po ', MathWorks avrebbe persino potuto consigliare alle persone ufficiosamente di farlo da soli (anche se consigliano sempre ufficialmente alle persone di programmare l'eleganza / la manutenibilità piuttosto che qualunque cosa faccia l'attuale JIT, poiché è un obiettivo mobile ogni versione).

Ma è molto tempo fa, e al giorno d'oggi è un po 'un problema di "zombi" che è davvero molto meno importante di quanto molti pensano ancora, ma rifiuta di morire.

In qualsiasi versione recente, è davvero una preferenza personale se usare ie jcome nomi di variabili o meno. Se lavori molto con numeri complessi, potresti voler evitare ie jcome variabili, evitare qualsiasi piccolo potenziale rischio di confusione (anche se potresti anche / invece voler usare solo 1io 1jper meno confusione e prestazioni leggermente migliori ).

D'altra parte, nel mio lavoro tipico non ho mai a che fare con numeri complessi e trovo il mio codice più leggibile se mi sento libero di usare ie jcome indici di loop.


Vedo molte risposte qui che dicono che non è raccomandato ... senza dire chi lo sta facendo raccomandando. Ecco la portata delle attuali raccomandazioni di MathWorks, dalla documentazione di rilascio corrente per i:

Poiché i è una funzione, può essere sovrascritta e utilizzata come variabile. Tuttavia, è meglio evitare di usare i e j per i nomi delle variabili se si intende usarli in aritmetica complessa. [...] Per la velocità e una maggiore robustezza, è possibile sostituire i e j complessi con 1i.


15

Come descritto in altre risposte, l'uso del icodice generale non è raccomandato per due motivi:

  • Se si desidera utilizzare il numero immaginario, può essere confuso o sovrascritto da un indice
  • Se lo usi come indice, può sovrastare o essere confuso con il numero immaginario

Come suggerito: 1ie iisono raccomandati. Tuttavia, sebbene queste siano entrambe deviazioni eccellenti da i, non è molto bello usare entrambe queste alternative insieme.

Ecco un esempio del perché (personalmente) non mi piace:

val2 = val + i  % 1
val2 = val + ii % 2
val2 = val + 1i % 3

Uno non sarà facilmente letto male per due o tre, ma due e tre si assomigliano.

Pertanto la mia raccomandazione personale sarebbe: nel caso in cui a volte lavori con codice complesso, usa sempre 1icombinato con una variabile di ciclo diversa.

Esempi di indici singole lettere che per se non si utilizza molte variabili di loop e lettere bastano: t, u, kep

Esempio di indici più lunghi: i_loop, step, walk, et_now

Ovviamente anche questa è una questione di gusti personali, ma non dovrebbe essere difficile trovare indici da usare che abbiano un significato chiaro senza crescere troppo a lungo.


1
1i indica l'unità immaginaria (anche i nomi delle variabili Matlab non possono iniziare con un numero)
lib

2
@DennisJaheruddin: plug spudorato: usa la mia sintassi MATLAB mettendo in evidenza lo script utente per StackTranslate.it. Nell'ultimo esempio, 1isarà colorato diversamente come un numero :)
Amro

2
Direttamente da doc ie doc j: "Per la velocità e una maggiore robustezza, è possibile sostituire i e j complessi con 1i." IMO, nell'attuale Matlab non c'è motivo di non usare ie jin loop, ecc., O di usare qualcosa di diverso da quello 1iper indicare l'unità immaginaria ( 1jfunziona anche). L'unica eccezione è quando si passano le stringhe al motore simbolico sempre leggermente incompatibile. Strano help 1ie comunque doc 1inon funziona.
Horchler,

11

È stato sottolineato che 1iè un modo accettabile e inequivocabile di scrivere sqrt(-1)e che come tale non è necessario evitare di utilizzarlo i. Quindi, come sottolineato da Dennis ( https://stackoverflow.com/a/14893729/1967396 ), può essere difficile vedere la differenza tra 1ie ii. Il mio consiglio: usare 1jcome costante immaginaria ove possibile. E 'lo stesso trucco che gli ingegneri elettrici impiegano - che usano jper sqrt(-1)quanto iè già stato preso per la corrente .

Personalmente non uso mai ie j; Uso iie jjcome variabili di indicizzazione abbreviata, (e kk, ll, mm, ...) e 1jquando ho bisogno di usare numeri complessi.


2
"Può essere difficile vedere la differenza tra 1ie ii" E ancora di più la differenza tra 1e le tra Oe 0. Ecco perché il primo passo che faccio in una nuova installazione MATALB sta cambiando la dimensione del carattere predefinita.
glglgl,

6

La confusione con l'unità immaginaria è stata ben coperta qui, ma ci sono alcune altre ragioni più prosaiche per cui a volte questi e altri nomi di variabili a lettera singola sono scoraggiati.

  1. In particolare MATLAB: se stai usando il programmatore per generare sorgente C ++ dal tuo codice MATLAB (no, è orribile) allora sei esplicitamente avvisato di non riutilizzare le variabili a causa di potenziali conflitti di battitura.

  2. In generale, e in base al tuo IDE, un nome di variabile a una lettera può causare il caos con gli evidenziatori e cercare / sostituire. MATLAB non soffre di questo e credo che Visual Studio non abbia avuto problemi da qualche tempo, ma gli standard di codifica C / C ++ come MISRA ecc. Tendono a consigliarli.

Da parte mia, evito tutte le variabili a lettera singola, nonostante gli ovvi vantaggi per l'implementazione diretta delle fonti matematiche. Ci vuole un piccolo sforzo extra le prime centinaia di volte che lo fai, ma dopo smetti di notare e i vantaggi quando tu o qualche altra povera anima venite a leggere il vostro codice sono legioni.


4

Qualsiasi codice non banale contiene più forloop e le migliori pratiche raccomandano di utilizzare un nome descrittivo indicativo del suo scopo e ambito. Per i tempi immemorabili (e meno che il suo script di 5-10 righe che non ho intenzione di salvare), sono sempre stato con i nomi delle variabili come idxTask, idxAnotherTaske idxSubTaskcosì via

O almeno raddoppiando la prima lettera dell'array che sta indicizzando, ad esempio ssper indicizzare subjectList, ttper indicizzare taskList, ma non iio jjche non mi aiuta a identificare senza sforzo quale array stanno indicizzando dal mio multiplo per i loop.


3

Di default ie jrappresenta l'unità immaginaria. Quindi dal punto di vista di MATLAB, usare icome variabile è in qualche modo come usare 1come variabile.


5
non penso sia abbastanza. i è un nome di variabile legittimo, quindi puoi effettivamente usare iej come nomi di variabili. come menziona una risposta precedente, maschererà il significato immaginario. 1 non è un nome di variabile legittimo. va benissimo se non usi mai numeri complessi.
thang

@thang è per questo che ho detto "in qualche modo mi piace" e non "mi piace". So che c'è una differenza. OP ha chiesto perché non dovrebbero essere usati, ho cercato di spiegare che è perché esprimono già un numero.
giovedì

2
ok, scusa, non so cosa significhi in qualche modo. per me è chiaramente diverso perché bene, non puoi usare 1 come variabile anche se volessi ... ma vedo da dove vieni.
Grazie

si può usarli, come è anche possibile utilizzare nomi di funzioni esistenti per le variabili (e allo stesso tempo corrompere quelle funzioni interne / costanti per un ulteriore uso). Se vuoi davvero che sia un'altra cosa (imo semplice risposta: no)
Gunther Struyf

1
Ci dispiace, ma questa spiegazione non ha senso. Le ie jsono in realtà funzioni che restituiscono il valore dell'unità immaginaria. È possibile utilizzare una variabile con lo stesso nome di una funzione in un ambito. Questo tuttavia oscurerà la funzione.
Patrik,

2

Se non sei un utente molto confusa penso che ci sia molto poco rischio nell'utilizzo di nomi di variabili i e j e li uso regolarmente. Non ho visto alcuna indicazione ufficiale che questa pratica dovrebbe essere evitata.

Mentre è vero che l'ombra dell'unità immaginaria potrebbe causare confusione in alcuni contesti, come menzionato in altri post, nel complesso semplicemente non lo vedo come un grosso problema. Ci sono cose molto più confuse che puoi fare in MATLAB, prendi ad esempio la definizionefalse=true

Secondo me l'unica volta che dovresti probabilmente evitarli è se il tuo codice si occupa specificamente di numeri immaginari.


Potete per favore commentare durante il voto negativo. Ad esempio, con un collegamento Mathworks che indica che la pratica non è consigliata (che è stata dichiarata da più poster senza fare riferimento a nessuna linea guida ufficiale). Infatti, l'utilizzo di "i" nei loop viene utilizzato negli esempi ufficiali da Mathworks. Nella mia esperienza rende il codice chiaro e conciso ed è una pratica molto comune.
Gregregwiss,

1
Citando la documentazione "Poiché iè una funzione, può essere sovrascritta e utilizzata come variabile. Tuttavia, è meglio evitare di usare ie jper nomi di variabili se si intende utilizzarli in aritmetica complessa." Che, in combinato disposto con il commento di Eitan T sulla risposta di Oliver (immagino abbia cronometrato) sembra una prova sufficiente.
Adriaan,

1
Si noti inoltre che c'è già una risposta dal 2013 con il commento menzionato da @Adriaan.
Andras Deak,

1
quindi la documentazione afferma SE intendi usare in aritmetica complessa, altrimenti non si applica - non so perché qui tutti sono così esigenti al riguardo! Stavo solo offrendo un punto di vista alternativo.
Gregregwiss,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.