Używanie i i j jako zmiennych w Matlabie

142

ii jsą bardzo popularnymi nazwami zmiennych (patrz np. to pytanie i to ).

Na przykład w pętlach:

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

Jako wskaźniki do macierzy:

mat( i, j ) = 4;

Dlaczego nie powinny być używane jako nazwy zmiennych w Matlabie?

Shai
źródło
5
Oczywiście nie oznaczę tego jako takiego, ale sądząc po odpowiedziach, powiedziałbym, że jest to „oparte głównie na opinii”. ;-) Ja osobiście nie dałoby się na i, j, kjako ogólnych nazw zmiennych pętli.
A. Donda
1
@ A.Donda no cóż, taka jest twoja opinia;)
Shai
@Shai, to jest twoje ostatnie zdanie w tym pytaniu: "Dlaczego nie powinny być używane jako nazwy zmiennych w Matlabie?" Więc jest bardzo niejasne, dlaczego odrzucasz moje wydanie na swoje pytanie ?! Zmieniłem tytuł na bardziej konstruktywną tytułem „Dlaczego nie powinno się używać i oraz j jako zmienne w programie MATLAB”
Seyfi

Odpowiedzi:

176

Ponieważ obie funkcje oznaczające urojoną jednostkęii jsą :

Tak więc zmienna wywołuje je ilub jbędzie je zastępować, potencjalnie powodując ciche uszkodzenie kodu wykonującego złożone obliczenia.

Możliwe rozwiązania obejmują użycie zamiast nich iii jjjako zmiennych pętli lub użycie 1iilekroć ijest wymagane do przedstawienia jednostki urojonej.

Oliver Charlesworth
źródło
42
Warto również zauważyć, że nawet jeśli niczego nie zepsujesz, czas wykonania nadal jest poświęcany, aby rozwiązać nazwy zmiennych ii j.
Eitan T
14
@Eitan: Czy możesz rzeczywiście potwierdzić to w jakikolwiek konkretny, rozstrzygający sposób w skompilowanej przez JIT wersji Matlab? Nigdy nie stwierdziłem, że tak jest (a proste testy wywołujące forpętlę 1 miliard razy nie wykazują statystycznej różnicy w czasie). Z tego, co wiemy, istnieje specjalny kod, który dokładnie to obsługuje, a używanie zmiennych innych niż ii j(i k?) Jest w rzeczywistości nieco wolniejsze. A różnice, które istnieją, są znikome lub nieistniejące w prawdziwym życiu. Po prostu nie ma powodu, aby NIE używać, ia jjako zwykłe zmienne - po prostu muszą być używane poprawnie, jak każda inna funkcja Matlab.
horchler
5
@horchler Cóż, oficjalna dokumentacja stwierdza tutaj, że nadpisywanie standardowych klas danych MATLAB "może negatywnie wpływać na wydajność", a tutaj zakłada się, że należy unikać nadpisywania złożonych stałych ze względu na szybkość, a także niezawodność. W starszych dokumentach R2009b wyraźnie odradza się nadpisywanie złożonych stałych, ponieważ może to utrudniać przyspieszenie JIT. Rozdzielczość nazw zmiennych jest być może znikoma, ale może być znacząca, jeśli zostanie powtórzona miliony razy.
Eitan T
14
Może w starożytnych wersjach Matlab. Sam to widziałem. Ale już nie z R2012a + (OS X). I nie widziałem różnicy, kiedy wywoływałem forpętlę 1 miliard razy i próbowałem różnych schematów czasowych. Widzę, jak nowym użytkownikom SO mówi się, że całkowicie poprawny kod jest zły, ponieważ używają ii jiterują pętle. Szczerze mówiąc, jest to po prostu głupie i ludzie pomijają ważniejszy punkt tego pytania: to ii jnie powinno być nawet używane w wyimaginowanej jednostce, jeśli chce się napisać czytelny, nowoczesny kod Matlab.
horchler
12
Moją największą oszczędnością czasu jest wyszukiwanie ii. Poszukiwanie mnie może być prawdziwym bólem
Craq
62

Dobrą praktyką jest unikanie zmiennych ii jzapobieganie nieporozumieniom co do tego, że są zmiennymi lub jednostką urojoną.

Osobiście jednak używam ii jjako zmiennych dość często jako indeksu krótkich pętli. Aby uniknąć problemów we własnym kodzie, postępuję zgodnie z inną dobrą praktyką dotyczącą ii j: nie używaj ich do oznaczania liczb urojonych. W rzeczywistości własna dokumentacja Matlab stwierdza :

Dla poprawy szybkości i wytrzymałości, można zastąpić skomplikowane ii jprzez 1i.

Więc zamiast unikać dwóch bardzo często używanych nazw zmiennych z powodu potencjalnego konfliktu, wyraźnie mówię o liczbach urojonych. Dzięki temu mój kod jest bardziej przejrzysty. Za każdym razem, gdy widzę 1i, wiem, że to reprezentuje, sqrt(-1)ponieważ nie może być zmienną.

shoelzer
źródło
2
To naprawdę dobra praktyka 1i. Jednak zmiana znaczenia ii jmoże prowadzić do trudnych do debugowania błędów, takich jak ten .
Shai,
1
@Shai Słuszna uwaga. Poprawiłem odpowiedź, aby przyznać, że unikanie ii jjest najlepsze, ale wyjaśniłem, że mój osobisty styl kodowania nie jest zgodny z tą zasadą.
shoelzer
2
Zauważ, że wspomniana prędkość nie wydaje się być bardzo znacząca: stackoverflow.com/questions/18163454/…
Dennis Jaheruddin
Kompletnie się zgadzam! Dobrą praktyką jest ZAWSZE używać, 1ia nie iskomplikowanej matematyki. Pomyślmy o liczbie urojonej jako o liczbie urojonej 1ii potraktujmy ją ijako złą praktykę. Nie na odwrót. Korzystanie i, ii, iiijest powszechną praktyką w Matlab i nie ma problemu, gdy ludzie trzymać się 1ii 1jdla liczby zespolonej. Matlab również to szanuje, a ten nie zmniejsza wydajności (o ile testowałem), jak stwierdzono w poprzedniej odpowiedzi.
SdidS
i i j nie powinny być używane - te liczby coś znaczą - użyj nazwy opisującej cel (row_n, elementNo, listItemIndex itp.). O wiele łatwiej jest komuś zrozumieć, co robisz, debugować itp. Dodatkowy czas spędzony na utrzymaniu jest więcej niż warty zyskania na długoterminowej obsłudze czegokolwiek więcej niż jednorazowego skryptu - nawet jeśli Edytor Matlab jest daleko w tyle większość innych nowoczesnych IDE.
LightCC
27

W starszych wersjach MATLAB-a istniał dobry powód, aby unikać używania ii jjako nazw zmiennych - wczesne wersje MATLAB JIT nie były wystarczająco sprytne, aby stwierdzić, czy używasz ich jako zmiennych, czy jako jednostek urojonych, a zatem wyłącz wiele możliwych optymalizacji.

Twój kod stałby się zatem wolniejszy tylko przez samą obecność zmiennych ii jjako zmienne i przyspieszyłby, gdybyś zmienił je na coś innego. Dlatego, jeśli przeczytasz dużo kodu MathWorks, zobaczysz iii będziesz jjużywany dość powszechnie jako indeksy pętli. Przez pewien czas MathWorks mógł nawet nieoficjalnie doradzać ludziom, aby robili to sami (chociaż zawsze oficjalnie radzą ludziom, aby programowali pod kątem elegancji / łatwości konserwacji, a nie tego, co robi obecny JIT, ponieważ jest to ruchomy cel każdej wersji).

Ale to raczej dawno temu, a obecnie jest to trochę problem z zombie, który jest naprawdę o wiele mniej ważny, niż wielu ludzi wciąż myśli, ale nie chce umrzeć.

W każdej najnowszej wersji to naprawdę osobiste preferencje, czy używać ii jjako nazw zmiennych, czy nie. Jeśli wykonujesz dużo pracy z liczbami zespolonymi, możesz chcieć uniknąć ii jjako zmiennych, aby uniknąć małego potencjalnego ryzyka pomyłki (chociaż możesz również / zamiast tego używać tylko 1ilub 1jdla jeszcze mniejszego zamieszania i trochę lepszej wydajności ).

Z drugiej strony, w mojej typowej pracy nigdy nie zajmuję się liczbami zespolonymi, a mój kod wydaje mi się bardziej czytelny, jeśli mogę swobodnie używać ii jjako indeksów pętli.


Widzę tutaj wiele odpowiedzi, które mówią, że to nie jest zalecane ... bez mówienia, kto robi to polecanie. Oto zakres rzeczywistych zaleceń MathWorks z aktualnej dokumentacji wydania dla i:

Ponieważ i jest funkcją, można ją przesłonić i użyć jako zmiennej. Jednak najlepiej jest unikać używania i i j dla nazw zmiennych, jeśli zamierzasz używać ich w złożonej arytmetyce. [...] Aby uzyskać szybkość i lepszą odporność, można zastąpić złożone i i j przez 1i.

Sam Roberts
źródło
15

Jak opisano w innych odpowiedziach, używanie iogólnego kodu nie jest zalecane z dwóch powodów:

  • Jeśli chcesz użyć liczby urojonej, możesz ją pomylić z indeksem lub nadpisać nim
  • Jeśli użyjesz go jako indeksu, może on nadpisać lub zostać pomylony z liczbą urojoną

Zgodnie z sugestią: 1ii iisą zalecane. Jednak, chociaż są to drobne odstępstwa od i, nie jest zbyt przyjemne używanie obu tych alternatyw razem.

Oto przykład, dlaczego (osobiście) mi się to nie podoba:

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

Jeden nie będzie łatwo odczytany z dwóch lub trzech, ale dwa i trzy są do siebie podobne.

Dlatego moja osobista rekomendacja byłaby taka: jeśli czasami pracujesz ze złożonym kodem, zawsze używaj 1ikombinacji z inną zmienną pętli.

Przykłady wskaźników pojedynczą literę że jeśli nie korzystać z wielu zmiennych, pętli i listów wystarczyć: t, u, kip

Przykład dłuższych indeksach: i_loop, step, walkit_now

Oczywiście jest to również kwestia osobistego gustu, ale nie powinno być trudno znaleźć indeksy, które będą miały jasne znaczenie, bez zbytniego wydłużania się.

Dennis Jaheruddin
źródło
1
1i oznacza jednostkę urojoną (również nazwy zmiennych Matlaba nie mogą zaczynać się liczbą)
lib
2
@DennisJaheruddin: bezwstydna wtyczka: Użyj mojej składni MATLAB-a podświetlającej skrypt użytkownika dla przepełnienia stosu. W ostatnim przykładzie 1ibędzie różnie kolorowana jako liczba :)
Amro
2
Prosto z doc ii doc j: „Aby uzyskać szybkość i lepszą wytrzymałość, można zastąpić złożone i i j przez 1i”. IMO, w obecnym Matlabie nie ma powodu, aby nie używać ii jw pętlach itp., Ani używać niczego innego niż 1ioznaczanie wyimaginowanej jednostki ( 1jdziała też). Jedynym wyjątkiem jest przekazywanie ciągów znaków do zawsze nieznacznie niekompatybilnego silnika Symbolic. Dziwne, że help 1ii doc 1inie działają jednak.
horchler
11

Zwrócono uwagę, że 1ijest to akceptowalny i jednoznaczny sposób pisania sqrt(-1)i jako taki nie ma potrzeby unikania używania i. Z drugiej strony, jak wskazał Dennis ( https://stackoverflow.com/a/14893729/1967396 ), może być trudno dostrzec różnicę między 1ii ii. Moja sugestia: 1jjeśli to możliwe, używaj jako wyimaginowanej stałej. To ten sam trik, który inżynierowie elektrycy zatrudnić - używają jdo sqrt(-1)ponieważ ijest już zajęta przez prąd .

Osobiście nigdy nie używam ii j; Używam iii jjjako skrótowych zmiennych indeksujących (i kk, ll, mm, ...) i 1jkiedy muszę użyć liczb zespolonych.

Floris
źródło
2
„może być trudno dostrzec różnicę między 1ii ii” A jeszcze bardziej różnicę między 1i li między Oa 0. Dlatego pierwszym krokiem, który wykonuję w nowej instalacji MATALB, jest zmiana domyślnego rozmiaru czcionki.
glglgl
6

Pomieszanie z jednostką urojoną zostało tutaj dobrze omówione, ale istnieją inne, bardziej prozaiczne powody, dla których te i inne jednoliterowe nazwy zmiennych są czasami odradzane.

  1. W szczególności MATLAB: jeśli używasz kodera do generowania źródła C ++ ze swojego kodu MATLAB (nie rób tego, to okropne), jesteś wyraźnie ostrzeżony, aby nie używać ponownie zmiennych z powodu potencjalnych konfliktów podczas pisania.

  2. Ogólnie iw zależności od IDE, jednoliterowa nazwa zmiennej może spowodować spustoszenie w podświetlaczach i wyszukiwaniu / zamianie. MATLAB nie cierpi z tego powodu i uważam, że Visual Studio od jakiegoś czasu nie miał problemu, ale standardy kodowania C / C ++, takie jak MISRA itp., Zwykle radzą im przeciwdziałać.

Ze swojej strony unikam wszystkich zmiennych jednoliterowych, pomimo oczywistych zalet wynikających z bezpośredniego implementowania źródeł matematycznych. Zajmuje to trochę więcej wysiłku, gdy robisz to pierwsze kilkaset razy, ale potem przestajesz zauważać, a korzyści płynące z tego, że ty lub jakaś inna biedna dusza przychodzą, aby przeczytać twój kod, są ogromne.

ksenoklast
źródło
4

Każdy nietrywialny kod zawiera wiele forpętli, a najlepsze praktyki zalecają użycie opisowej nazwy wskazującej na jego cel i zakres. Dla niepamiętnych czasów (i chyba jej 5-10 linii skryptu, że nie zamierzam zapisać), zawsze byłem przy użyciu nazw zmiennych, takich jak idxTask, idxAnotherTaski idxSubTasketc.

Lub przynajmniej podwojenie pierwszej litery tablicy, którą indeksuje, np. ssDo indeksowania subjectList, ttdo indeksowania taskList, ale nie iilub jjco nie pomaga mi bez wysiłku zidentyfikować, którą tablicę indeksują z moich wielokrotnych pętli for.

Pradeep Reddy Raamana
źródło
3

Domyślnie ii joznacza wyimaginowaną jednostkę. Zatem z punktu widzenia MATLAB- ia używanie jako zmiennej jest w pewnym sensie podobne do używania 1jako zmiennej.

Siema'
źródło
5
nie sądzę, że tak jest. i jest prawidłową nazwą zmiennej, więc faktycznie możesz używać i i j jako nazw zmiennych. będzie, jak wspomniano w poprzedniej odpowiedzi, maskować wyobrażone znaczenie. 1 nie jest prawidłową nazwą zmiennej. jest całkowicie w porządku, jeśli nigdy nie używasz liczb zespolonych.
thang
@thang, dlatego powiedziałem „jakoś lubię”, a nie „lubię”. Wiem, że jest różnica. OP zapytał, dlaczego nie powinny być używane, próbowałem wyjaśnić, że to dlatego, że już podają liczbę.
yo '
2
ok, przepraszam, nie wiem, co jakoś to znaczy. dla mnie jest to wyraźnie inne, ponieważ cóż, nie możesz użyć 1 jako zmiennej, nawet jeśli chcesz ... ale widzę, skąd pochodzisz.
thang
Państwo może ich używać, jak można również wykorzystać istniejące nazwy funkcji zmiennych (i jednocześnie uszkadzając tych funkcji wbudowanych / stałe do dalszego użytku). To, czy naprawdę tego chcesz, to inna sprawa (imo prosta odpowiedź: nie)
Gunther Struyf,
1
Przepraszamy, ale to wyjaśnienie nie ma sensu. Funkcje ii jsą w rzeczywistości funkcjami zwracającymi wartość jednostki urojonej. W zakresie można użyć zmiennej o tej samej nazwie, co funkcja. Będzie to jednak zaciemniać funkcję.
patrik
2

Chyba że jesteś bardzo zdezorientowany użytkownik myślę, że istnieje bardzo małe ryzyko w użyciu nazw zmiennych I i J i używam ich regularnie. Nie widziałem żadnych oficjalnych wskazówek, że należy unikać tej praktyki.

Chociaż prawdą jest, że cieniowanie wyimaginowanej jednostki może powodować pewne zamieszanie w pewnym kontekście, jak wspomniano w innych postach, ogólnie po prostu nie uważam tego za poważny problem. W MATLAB-ie jest znacznie więcej zagmatwanych rzeczy, na przykład definiowaniefalse=true

Moim zdaniem jedyny przypadek, w którym prawdopodobnie powinieneś ich unikać, to sytuacja, w której Twój kod dotyczy konkretnie liczb urojonych.

gregswiss
źródło
Czy możesz skomentować głosowanie przeciw. Na przykład z linkiem Mathworks wskazującym, że praktyka nie jest zalecana (co zostało stwierdzone na wielu plakatach bez odniesienia do żadnych oficjalnych wytycznych). W rzeczywistości użycie „i” w pętlach jest używane w oficjalnych przykładach przez Mathworks. Z mojego doświadczenia wynika, że ​​czyni to kod przejrzystym i zwięzłym i jest to bardzo powszechna praktyka.
gregswiss
1
Cytując dokumentację „Ponieważ ijest funkcją, można ją przesłonić i wykorzystać jako zmienną. Jednak najlepiej unikać używania ii jdla nazw zmiennych, jeśli zamierzasz używać ich w złożonej arytmetyce”. To, w połączeniu z komentarzem Eitana T na temat odpowiedzi Olivera (myślę, że to on ustalił) wydaje się wystarczającym dowodem.
Adriaan
1
Zwróć również uwagę, że jest już odpowiedź z 2013 r. Z komentarzem, o którym wspomniał @Adriaan.
Andras Deak
1
więc dokumentacja stwierdza, że ​​JEŻELI zamierzasz używać w złożonej arytmetyce, w przeciwnym razie nie ma to zastosowania - nie wiem, dlaczego wszyscy są tutaj tak wybredni! Po prostu zaproponowałem inny punkt widzenia.
gregswiss