Использование i и j в качестве переменных в Matlab

142

iи jявляются очень популярными именами переменных (см., например, этот вопрос и этот ).

Например, в циклах:

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

Как индексы в матрицу:

mat( i, j ) = 4;

Почему они не должны использоваться как имена переменных в Matlab?

Шай
источник
5
Конечно, я не буду отмечать это как таковой, но, судя по ответам, я бы сказал, что это «в первую очередь основано на мнении». ;-) Я бы лично не отказываться от i, j, kкак общие имена переменных цикла.
А. Донда
1
@ А.Донда, это твое мнение;)
Шай
@Shai, это ваше последнее предложение в этом вопросе: «Почему они не должны использоваться в качестве имен переменных в Matlab?» Так что очень непонятно, почему вы отвергаете мое издание по вашему вопросу ?! Я изменил ваш заголовок на более конструктивный заголовок «Почему НЕ следует использовать i и j в качестве переменных в Matlab»
Сейфи

Ответы:

176

Потому что iи jобе функции обозначают мнимую единицу :

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

Возможные решения включают использование iiи в jjкачестве переменных цикла вместо этого, или использование 1iвсякий раз, когда iтребуется представить мнимую единицу.

Оливер Чарльзуорт
источник
42
Также стоит отметить, что, даже если вы ничего не нарушаете, время выполнения все равно жертвуется для разрешения имен переменных iи j.
Eitan T
14
@Eitan: Можете ли вы подтвердить это каким-либо конкретным убедительным образом в JIT-версии Matlab? Я никогда не обнаруживал, что это так (а простые тесты, вызывающие forцикл 1 миллиард раз, не показывают статистической разницы во времени). Для всего, что мы знаем, есть специальный код для обработки именно этого, и использование переменных, отличных от iи jk?), На самом деле немного медленнее. И различия, которые существуют, очень малы, чтобы не существовать в реальной жизни. Просто нет причин НЕ использовать iи jкак обычные переменные - они должны использоваться правильно, как любая другая функция Matlab.
Horchler
5
@horchler Ну, официальные документы утверждают , здесь что переопределение стандартных классов MATLAB данных «может отрицательно сказаться на производительность», и здесь подразумеваются , чтобы избежать переопределений сложных констант по соображениям скорости, а также надежность. В более старых документах R2009b это явно рекомендуется для переопределения сложных констант, так как это может препятствовать ускорению JIT. Разрешение имен переменных, возможно, незначительно, но оно может быть значительным, если оно повторяется миллионы раз.
Эйтан Т
14
В древних версиях Matlab возможно. Я видел это сам. Но больше не с 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)потому что это не может быть переменной.

shoelzer
источник
2
Это действительно хорошая практика для использования 1i. Однако изменение значения iи jможет привести к трудным для отладки ошибкам, таким как эта .
Шай
1
@Shai Хороший вопрос. Я подправил свой ответ, чтобы признать, что избегать iи jлучше всего, но объяснил, как мой личный стиль кодирования не следует этому правилу.
Shoelzer
2
Обратите внимание, что упомянутая скорость не кажется очень значительной: stackoverflow.com/questions/18163454/…
Деннис Джаэруддин
Полностью согласен! Хорошей практикой является ВСЕГДА использовать, 1iа не iдля сложной математики. Давайте подумаем о мнимом числе как о мнимом числе 1iи возьмем iплохую практику. А не наоборот. Использование i, ii, iiiявляется обычной практикой в Matlab , и нет никаких проблем , когда люди придерживаются 1iи 1jдля комплексного числа. Также Matlab уважает это, и это не снижает производительность (насколько я тестировал), как указано в предыдущем ответе.
SdidS
Я и j не должны использоваться в любом случае - эти числа что- то значат - используйте имя, которое описывает цель (row_n, elementNo, listItemIndex и т. д.). Так намного проще для кого - то , чтобы понять , что вы делаете, для отладки и т.д. Дополнительное время , потраченное больше , чем стоит выигрыш в долгосрочной ремонтопригодности для чего - то более , чем одноразовая сценарий - даже с Matlab Editor будучи далеко позади большинство других современных IDE.
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 и 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, выделяющий пользовательский скрипт для переполнения стека. В последнем примере 1iбудет по-разному окрашен как число :)
Amro
2
Прямо из doc iи doc j: «Для увеличения скорости и надежности вы можете заменить комплекс i и j на 1i». ИМО, в нынешнем Matlab нет причин не использовать iи jв циклах и т. Д., Или использовать что-либо, кроме 1iобозначения мнимой единицы ( 1jработает тоже). Единственное исключение - при передаче строк в слегка несовместимый символьный движок. Странно , что help 1iи doc 1iне работать , хотя.
Horchler
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когда мне нужно использовать комплексные числа.

Floris
источник
2
«может быть трудно увидеть разницу между 1iи ii» И даже больше разницу между 1и lи между Oи 0. Вот почему первый шаг в новой установке MATALB - это изменение размера шрифта по умолчанию.
glglgl
6

Путаница с мнимой единицей здесь хорошо освещена, но есть и другие более прозаические причины, почему эти и другие однобуквенные имена переменных иногда не поощряются.

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

  2. Как правило, и в зависимости от вашей IDE, однобуквенное имя переменной может привести к хаосу с подсветкой и поиском / заменой. MATLAB не страдает от этого, и я считаю, что Visual Studio не имела проблем в течение некоторого времени, но стандарты кодирования C / C ++, такие как MISRA и т. Д., Как правило, рекомендуют их снова.

Я, со своей стороны, избегаю всех однобуквенных переменных, несмотря на очевидные преимущества прямой реализации математических источников. Первые несколько сотен раз, когда вы делаете это, требуется немного дополнительных усилий, но после этого вы перестаете замечать, и преимущества, когда вы или какая-то другая бедная душа приходят читать ваш код, легион.

xenoclast
источник
4

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

Или, по крайней мере, удвоение первой буквы массива, который он индексирует, например, ssиндексировать subjectList, ttиндексировать taskList, но неii или jjкоторый не помогает мне легко определить, какой массив они индексируют из моего кратного цикла for.

Прадип Редди Рамана
источник
3

По умолчанию iи jобозначают мнимый блок. Таким образом, с точки зрения MATLAB, использование iв качестве переменной похоже на использование 1в качестве переменной.

Эй'
источник
5
Я не думаю, что это так. i - допустимое имя переменной, поэтому вы можете использовать i и j в качестве имен переменных. как уже упоминалось в предыдущем ответе, оно маскирует воображаемый смысл. 1 не является допустимым именем переменной. это прекрасно, если вы никогда не используете комплексные числа.
Тханг
@thang, поэтому я сказал «как-то нравится», а не «как». Я знаю, что есть разница. ОП спросил, почему их не следует использовать, я попытался объяснить, что это потому, что они уже выражают число.
лет»
2
хорошо, извините, я не знаю, что значит как-то нравится . для меня это явно отличается, потому что хорошо, вы не можете использовать 1 в качестве переменной, даже если вы хотите ... но я вижу, откуда вы.
Тханг
Вы можете использовать их, также как вы можете использовать существующие имена функций для переменных (и в то же время повредить эти встроенные функции / константы для дальнейшего использования). Если вы действительно хотите, это другое дело (простой ответ: нет)
Гюнтер Стрейф
1
Извините, но это объяснение не имеет смысла. iИ jфактически функция , возвращающее значение мнимой единицы. Можно использовать переменную с тем же именем, что и функция в области видимости. Это однако затеняет функцию.
Патрик
2

Если вы не очень запутанный пользователь, я думаю, что использовать имена переменных i и j очень мало, и я использую их регулярно. Я не видел никаких официальных указаний на то, что этой практики следует избегать.

Хотя это правда, что слежка за мнимой единицей может вызвать некоторую путаницу в каком-то контексте, как упоминалось в других постах, в целом я просто не рассматриваю это как главную проблему. Есть много более запутанных вещей, которые вы можете сделать в MATLAB, например, определениеfalse=true

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

gregswiss
источник
Можете ли вы прокомментировать, когда голосование с понижением. Например, со ссылкой на Mathworks, указывающей, что практика не рекомендуется (что было заявлено несколькими авторами без ссылки на какое-либо официальное руководство). Фактически, использование 'i' в циклах используется в официальных примерах Mathworks. По моему опыту, это делает код ясным и кратким, и это очень распространенная практика.
gregswiss
1
Ссылаясь на документацию: «Поскольку iэто функция, ее можно переопределить и использовать в качестве переменной. Однако лучше избегать использования iи jдля имен переменных, если вы собираетесь использовать их в сложной арифметике». Это, в сочетании с комментарием Эйтана Т на ответ Оливера (я полагаю, он рассчитал это), кажется достаточным доказательством.
Adriaan
1
Также обратите внимание, что уже есть ответ 2013 года с комментарием, упомянутым @Adriaan.
Андрас Дик
1
поэтому в документации говорится, ЕСЛИ вы собираетесь использовать сложную арифметику, иначе это не применимо - не знаю, почему все так суетятся по этому поводу здесь! Я просто предлагал альтернативную точку зрения.
gregswiss