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

125

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

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

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

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

mat( i, j ) = 4;

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

  • 4
    Конечно, я не буду отмечать это как таковой, но, судя по ответам, я бы сказал, что это «в первую очередь основано на мнении». ;-) Я лично не отказался бы от i , j , k в качестве имен переменных универсального цикла.
  • 1
    @ А.Донда ну это твое мнение;)
Показать ещё 1 комментарий
Теги:
naming-conventions
variables

9 ответов

165
Лучший ответ

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

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

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

  • 37
    Стоит также отметить, что, даже если вы ничего не нарушаете, время выполнения все равно жертвуется для разрешения имен переменных i и j .
  • 14
    @Eitan: Можете ли вы подтвердить это каким-либо конкретным убедительным способом в JIT-версии Matlab? Я никогда не обнаруживал, что это так (а простые тесты, вызывающие цикл for 1 миллиард раз, не показывают статистической разницы во времени). Для всего, что мы знаем, есть специальный код для обработки именно этого, и использование переменных, отличных от i и jk ?), На самом деле немного медленнее. И различия, которые существуют, очень малы, чтобы не существовать в реальной жизни. Просто нет причин НЕ использовать i и j как обычные переменные - они просто должны использоваться правильно, как любая другая функция Matlab.
Показать ещё 7 комментариев
55

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

Лично, однако, я часто использую i и j как переменные как индекс коротких циклов. Чтобы избежать проблем с моим собственным кодом, я следую другой хорошей практике относительно i и j: не используйте их для обозначения мнимых чисел. Фактически Соответствует собственной документации Matlab:

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

Поэтому вместо того, чтобы избегать двух очень часто используемых имен переменных из-за потенциального конфликта, я явно о мнимых числах. Это также делает мой код более понятным. В любое время, когда я вижу 1i, я знаю, что он представляет sqrt(-1), потому что он не может быть переменной.

  • 2
    Это действительно хорошая практика, чтобы использовать 1i . Однако изменение значения i и j может привести к трудным для отладки ошибкам, таким как эта .
  • 1
    @Shai Хороший вопрос. Я подправил свой ответ, чтобы признать, что лучше избегать i и j , но объяснил, как мой личный стиль кодирования не следует этому правилу.
Показать ещё 2 комментария
26

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

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

Но это довольно давно, и в настоящее время это немного проблема "зомби", которая на самом деле гораздо менее важна, чем многие люди все еще думают, но отказывается умирать.

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

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


Здесь я вижу много ответов, в которых говорится, что не рекомендуется... не говоря, кто это рекомендует. Здесь приведенные фактические рекомендации MathWorks из текущей документации для i:

Так как я - функция, ее можно переопределить и использовать в качестве переменной. Однако лучше избегать использования я и j для имен переменных, если вы собираетесь использовать их в сложной арифметике. [...] Для скорости и повышенной надежности вы можете заменить сложные я и 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 не могут начинаться с цифры)
  • 2
    @DennisJaheruddin: бесстыдный плагин: используйте мой синтаксис MATLAB, выделяющий пользовательский скрипт для переполнения стека. В последнем примере 1i будет по-разному окрашен как число :)
Показать ещё 1 комментарий
12

Было указано, что 1i является приемлемым и недвусмысленным способом записи sqrt(-1), и поэтому нет необходимости избегать использования i. Опять же, как указал Деннис (https://stackoverflow.com/questions/14790740/using-i-and-j-as-variables-in-matlab), может быть трудно увидеть разницу между 1i и ii. Мое предложение: используйте 1j как мнимую константу, где это возможно. Это тот же трюк, который используют инженеры-электрики - они используют j для sqrt(-1), потому что i уже принято для current.

Лично я никогда не использую i и j; Я использую ii и jj как сокращающие индексирующие переменные (и kk, ll, mm,...) и 1j, когда мне нужно использовать сложные числа.

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

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

  • MATLAB специально: если вы используете coder для генерации исходного кода С++ из вашего кода MATLAB (не так ли, это ужасно), то вы явно предупреждаетесь о том, чтобы не использовать переменные из-за потенциальных конфликтов ввода.

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

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

2

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

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

2

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

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

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

  • 0
    Можете ли вы прокомментировать, когда голосование с понижением. Например, со ссылкой на Mathworks, указывающей, что эта практика не рекомендуется (о чем говорилось несколькими авторами без ссылки на какое-либо официальное руководство). Фактически, использование 'i' в циклах используется в официальных примерах Mathworks. По моему опыту, это делает код ясным и кратким, и это очень распространенная практика.
  • 0
    Цитирование документации «Поскольку i - это функция, ее можно переопределить и использовать в качестве переменной. Однако лучше избегать использования i и j для имен переменных, если вы собираетесь использовать их в сложной арифметике». Это, в сочетании с комментарием Эйтана Т на ответ Оливера (я думаю, он рассчитал), кажется достаточным доказательством.
Показать ещё 2 комментария
2

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

  • 4
    Я не думаю, что это так. i - допустимое имя переменной, поэтому вы можете использовать i и j в качестве имен переменных. как уже упоминалось в предыдущем ответе, оно маскирует воображаемый смысл. 1 не является допустимым именем переменной. это прекрасно, если вы никогда не используете комплексные числа.
  • 0
    @thang, поэтому я сказал «как-то нравится», а не «как». Я знаю, что есть разница. ОП спросил, почему их не следует использовать, я попытался объяснить, что это потому, что они уже выражают число.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню