Використання i і j як змінних у Matlab


142

iі jє дуже популярними назвами змінних (див. наприклад, це питання і це ).

Наприклад, у циклі:

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

Як показники в матрицю:

mat( i, j ) = 4;

Чому їх не слід використовувати як імена змінних у Matlab?


5
Звичайно, я не позначатиму це як таке, але судячи з відповідей, я б сказав, що це "насамперед на основі думки". ;-) Я б особисто не відмовлятися від i, j, kяк загальні імена змінних циклу.
А.Донда

1
@ A.Donda добре, це ваша думка;)
Шай

@Shai, це ваше останнє речення в цьому запитанні: "Чому їх не слід використовувати як імена змінних у Matlab?" Тож дуже незрозуміло, чому ти відкидаєш моє видання у своєму питанні ?! Я змінив вашу назву на більш конструктивну назву "Чому НЕ слід використовувати i та j як змінні в Matlab"
Сейфі

Відповіді:


176

Тому що iі jобидві функції позначають уявну одиницю :

Таким чином, названа змінною iабо jїх перекриє, потенційно мовчки порушуючи код, який робить складну математику.

Можливі рішення включають в себе замість цього iiі jjяк змінні циклу, або використання1i коли iпотрібно для представлення уявної одиниці.


42
Варто також зазначити, що навіть якщо ви нічого не порушуєте, час виконання все ще призначається для вирішення імен iі jзмінних.
Ейтан Т

14
@Eitan: Чи можете ви насправді створити резервну копію в будь-якому конкретному переконливому варіанті у складеній JIT версії Matlab? Я ніколи не виявив, що це так (а прості тести, що викликають forцикл в 1 мільярд разів, не показують статистичної різниці в термінах). Для всіх, що ми знаємо, існує спеціальний код для вирішення саме цього, а використання змінних, відмінних від iта jk?), Насправді трохи повільніше. І відмінності, які існують, є мізерними до неіснуючих в реальному житті. Просто немає причин НЕ використовувати iі jяк звичайні змінні - їх просто потрібно використовувати належним чином, як і будь-яку іншу функцію Matlab.
хорхлер

5
@horchler Ну, офіційні документи тут заявляють, що перевищення стандартних класів даних MATLAB "може негативно вплинути на продуктивність", і тут мається на увазі уникати переосмислення складних констант з міркувань швидкості, а також надійності. У старих документах R2009b явно рекомендується проти переважаючих складних констант, оскільки це може перешкоджати прискоренню JIT. Роздільна здатність імен може бути мізерною, але вона може бути значною, якщо повторити мільйони разів.
Ейтан Т

14
У стародавніх версіях Матлаба, можливо. Раніше я це бачив сам. Але вже не з R2012a + (OS X) принаймні. І я не бачив різниці, коли викликав forцикл в 1 мільярд разів і намагався всілякі схеми синхронізації. Я бачу, як нові користувачі SO розповідають, що абсолютно дійсний код неправильний, оскільки вони використовують iі jповторюють цикли. Відверто кажучи , це просто нерозумно , і люди пропали безвісти понад важливий момент цього питання: що iі jне повинні використовуватися навіть для уявної одиниці , якщо один хоче , щоб написати читається сучасний код Matlab.
хорхлер

12
моя основна економія часу - це коли я шукаю ii. Шукати мене може бути справжнім болем
craq

62

Це хороша практика , щоб уникнути iі jзмінних , щоб запобігти плутанині їх бути змінними або уявна одиниця.

Особисто я, однак, використовую iі jяк змінні досить часто, як індекс коротких циклів. Для того, щоб уникнути проблем в моєму власному коді, я дотримуюся за іншу хорошу практику в відношенні iі j: НЕ використовувати їх для позначення уявних чисел. Насправді у власній документації Matlab зазначено :

Для швидкості та покращеної надійності ви можете замінити складні iта jна 1i.

Тому замість того, щоб уникати двох найчастіше використовуваних імен змінних через потенційний конфлікт, я чітко кажучи про уявні числа. Це також робить мій код більш зрозумілим. Щоразу, коли я бачу 1i, я знаю, що це являє собою, sqrt(-1)тому що він не міг би бути змінною.


2
Це дійсно хороша практика використання 1i. Однак зміна значення iта jможе призвести до важких помилок, таких як ця .
Шай

1
@Шай Добре. Я змінив свою відповідь, щоб визнати, що це уникати iі jнайкраще, але пояснив, як мій особистий стиль кодування не відповідає цьому правилу.
шпалер

2
Зверніть увагу , що зазначена швидкість не здається дуже значним: stackoverflow.com/questions/18163454 / ...
Dennis Jaheruddin

Повністю згоден! Гарна практика полягає в тому, що ВЖЕ ВИНАГИ використовувати, 1iа не iдля складної математики. Давайте подумаємо як уявне число 1iі візьмемо iяк уявне число погану практику. Не навпаки. Використання i, ii, iiiє звичайною практикою в Matlab , і немає ніяких проблем , коли люди дотримуються 1iі 1jдля комплексного числа. Також Matlab поважає це, і це не знижує продуктивність (наскільки я тестував), як сказано в попередній відповіді.
SdidS

я і j не слід використовувати в будь-якому випадку - ці цифри щось означають - використовувати ім’я, яке описує мету (row_n, elementNo, listItemIndex тощо). Настільки легше комусь зрозуміти, що ви робите, налагодити і т. Д. Додатковий витрачений час більш ніж вартий виграшу в довгостроковій ремонтопридатності за що-небудь більше, ніж викинутий сценарій - навіть якщо редактор Matlab сильно відстає більшість інших сучасних ІДЕ.
LightCC

27

У старих версіях MATLAB раніше були вагомі причини уникати використання iтаj в якості імен змінних - ранні версії MATLAB JIT були досить розумний , щоб сказати , чи були ви використовувати їх в якості змінних або уявних одиниць, і буде , отже , вимкніть багато можливих оптимізацій.

Тому ваш код стане повільнішим саме через наявність iі jяк змінні, і прискориться, якби ви змінили їх на щось інше. Ось чому, якщо ви прочитаєте багато коду MathWorks, ви побачите iiі jjвикористовуєте досить широко в якості індексів циклу. На деякий час MathWorks, можливо, навіть неофіційно радив людям робити це самостійно (хоча вони завжди офіційно радять людям програмувати на елегантність / ремонтопридатність, а не на те, що робить поточний JIT, оскільки це рухома ціль кожної версії).

Але це досить давно, і сьогодні це дещо "зомбі" питання, яке насправді набагато менш важливе, ніж багато людей досі думають, але відмовляється померти.

У будь-якій останній версії, це дійсно особисті переваги, використовувати iчи jяк імена змінних чи ні. Якщо ви багато працюєте зі складними номерами, можливо, ви хочете уникати iі jяк змінних, щоб уникнути будь-якого невеликого потенційного ризику плутанини (хоча ви також можете / натомість хочете використовувати лише 1iабо 1jдля ще меншої плутанини, і трохи кращу ефективність ).

З іншого боку, у своїй типовій роботі я ніколи не маю справу зі складними числами, і я вважаю свій код більш читабельним, якщо я почуваюся вільним у використанні iта jв якості циклівних індексів.


Я бачу тут багато відповідей, які говорять, що це не рекомендується ... не кажучи, хто це робить, рекомендуючи. Ось ступінь актуальних рекомендацій MathWorks з поточної документації на випуск для i:

Оскільки i є функцією, її можна переосмислити і використовувати як змінну. Однак найкраще уникати використання i та j для імен змінних, якщо ви маєте намір використовувати їх у складній арифметиці. [...] Для швидкості та покращеної надійності ви можете замінити складні i та j на 1i.


15

Як описано в інших відповідях, використання iзагального коду не рекомендується з двох причин:

  • Якщо ви хочете використовувати уявне число, його можна переплутати або переписати індексом
  • Якщо ви використовуєте його як індекс, він може перезаписуватися або плутати з уявним числом

Як пропонується: 1iі iiрекомендуються. Однак, хоч і обидва відхилення від них i, не дуже приємно використовувати обидві ці альтернативи разом.

Ось приклад, чому мені (особисто) це не подобається:

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

Один не буде легко помилитися на двох-трьох, але два і три нагадують один одного.

Тому моєю особистою рекомендацією було б: У випадку, якщо ви іноді працюєте зі складним кодом, завжди використовуйте 1iкомбіновану з різною змінною циклу.

Приклади окремих індексів буквених що , якщо ви не використовуєте багато змінних циклу і буде досить для листів: t, u, kіp

Приклад довгих індексів: i_loop, step, walk, іt_now

Звичайно, це також питання особистого смаку, але не повинно бути важким знайти індекси, які мають чітке значення, не надто довго зростаючи.


1
1i позначає уявну одиницю (також імена змінних Matlab не можуть починатися з числа)
lib

2
@DennisJaheruddin: безсоромний модуль: Використовуйте мій синтаксис MATLAB, що виділяє usercript для переповнення стека. В останньому прикладі 1iбуде по-різному забарвлена ​​як цифра :)
Amro

2
Прямо від doc iта doc j: "Для швидкості та покращеної надійності ви можете замінити складні i та j на 1i." IMO, в поточному Matlab немає причин не використовувати iі jв циклі тощо, або використовувати щось інше, ніж 1iдля позначення уявної одиниці (також 1jпрацює). Єдиний виняток - це передавання рядків у завжди трохи несумісний двигун Symbolic. Дивно, help 1iале doc 1iце не працює.
хорхлер

11

Було зазначено, що 1iце прийнятний та однозначний спосіб написання sqrt(-1), і що як такого немає необхідності уникати використання i. Потім, як зазначав Денніс ( https://stackoverflow.com/a/14893729/1967396 ), може бути важко помітити різницю між 1iі ii. Моя пропозиція: використовуйте 1jяк уявну константу, де це можливо. Це той самий трюк, який використовують інженери-електрики - вони використовують jдля того, sqrt(-1)що iвже прийнято за струм .

Особисто я ніколи не використовую iі j; Я використовую iiі jjяк скорочену змінну індексації (і kk, ll, mm, ...), і 1jколи мені потрібно використовувати складні числа.


2
"може бути важко помітити різницю між 1iі ii" І тим більше різницю між 1і lі між Oі 0. Ось чому перший крок, який я роблю в новій установці MATALB, - це зміни розміру шрифту за замовчуванням.
glglgl

6

Плутанина з уявною одиницею тут добре висвітлена, але є деякі інші більш прозаїчні причини, чому ці та інші однобуквені назви змінних іноді не перешкоджають.

  1. MATLAB конкретно: якщо ви використовуєте кодер для створення джерела C ++ зі свого коду MATLAB (не варто, це жахливо), тоді вас явно попереджають не використовувати повторно змінні через потенційні введення стилів.

  2. Як правило, і залежно від вашої IDE, однобуквене ім’я змінної може спричинити загрозу виділенням і пошуку / заміни. MATLAB не страждає від цього, і я вважаю, що Visual Studio вже не має проблем протягом певного часу, але стандарти кодування C / C ++, такі як MISRA тощо, як правило, не рекомендують їм ознайомитися.

Зі свого боку я уникаю всіх однобуквенних змінних, незважаючи на очевидні переваги безпосередньо впровадження математичних джерел. Перших декількох сотень разів вам потрібно докласти додаткових зусиль, але після цього ви перестаєте помічати, і переваги, коли ви або якась інша бідна душа приходить прочитати ваш код, - легіон.


4

Будь-який нетривіальний код містить декілька forциклів, а найкращі практики рекомендують використовувати описову назву, що вказує на її призначення та сферу застосування. Для незапам'ятних часів (і якщо його 5-10 рядків сценарію , що я не збираюся рятувати), я завжди використовую імена змінних , як idxTask, idxAnotherTaskі idxSubTaskт.д.

Або щонайменше подвоєння першої літери масиву, яку він індексує, наприклад, ssдля індексації subjectList, ttіндексації taskList, але ні iiабоjj це не допомагає мені без особливих зусиль визначити, який масив вони індексують з мого множини для циклів.


3

За замовчуванням iі jпозначайте уявну одиницю. Отже, з точки зору MATLAB, використовувати iяк змінну так чи інакше, як використовувати 1як змінну.


5
я не думаю, що це зовсім так. i є законним ім'ям змінної, тому ви фактично можете використовувати i та j як імена змінних. це, як згадується в попередній відповіді, замаскує уявний сенс. 1 не є законною назвою змінної. це абсолютно добре, якщо ви ніколи не використовуєте складні числа.
thang

@thang, тому я сказав "якось подобається", а не "як". Я знаю, що є різниця. ОП запитав, чому їх не слід використовувати, я намагався пояснити, що це тому, що вони вже виражають число.
йо '

2
ОК, вибачте, я не знаю, що якось таке означає. для мене це явно по-іншому, тому що добре, ви не можете використовувати 1 як змінну, навіть якщо хотіли ... але я бачу, звідки ви родом.
thang

Ви можете використовувати їх, оскільки ви також можете використовувати існуючі назви функцій для змінних (і в той же час пошкоджувати ці вбудовані функції / константи для подальшого використання). Чи дійсно ви хочете, що це інша річ (imo проста відповідь: ні)
Gunther Struyf

1
Вибачте, але це пояснення не має сенсу. Функції iі jє насправді, що повертають значення уявної одиниці. Можна використовувати змінну з тим же ім'ям, що і функція в області. Однак це затінить функцію.
патрик

2

Якщо ви не дуже збентежений користувачем Я думаю , що є дуже мало ризику у використанні імен змінних I і J , і я використовую їх на регулярній основі . Я не бачив жодних офіційних ознак того, що слід уникати цієї практики.

Хоча це правда, що затінення уявної одиниці може спричинити певну плутанину в якомусь контексті, як згадується в інших публікаціях, загалом я просто не вважаю це головним питанням. Є набагато більше заплутаних речей, які ви можете зробити в MATLAB, наприклад, визначившисьfalse=true

На мою думку, єдиний час, коли ви, ймовірно, повинні їх уникати, якщо ваш код спеціально має уявні числа.


Чи можете ви прокоментувати, будь ласка, під час голосування. Наприклад, із посиланням Mathworks, що вказує на те, що практика не рекомендується (що було заявлено декількома афішами, не посилаючись на будь-яку офіційну інструкцію). Насправді використання "i" в циклі використовується в офіційних прикладах Mathworks. На мій досвід, це робить код чітким і стислим і є дуже поширеною практикою.
gregswiss

1
Наводячи в документацію «Оскільки iце функція, вона може бути подолана і використовується в якості змінного. Тим НЕ менше, краще уникати використання iі jдля імен змінних , якщо ви збираєтеся використовувати їх в складних арифметичних діях .» Це, у поєднанні з коментарем Ейтана Т на відповідь Олівера (я думаю, він приурочив) здається достатнім доказом.
Адріан

1
Також зауважте, що вже є відповідь з 2013 року з коментарем, згаданим @Adriaan.
Андрас Дек

1
тому в документації зазначено, що якщо ви маєте намір використовувати складну арифметику, інакше це не застосовується - не знаю, чому тут такі метушні! Я просто пропонував альтернативну точку зору.
gregswiss
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.