Because the symbols i
and j
can represent significantly different things in MATLAB, their use as loop indices has split the MATLAB user community since ages. While some historic performance reasons could help the balance lean to one side, this is no longer the case and now the choice rest entirely on you and the coding practices you choose to follow.
The current official recommendations from Mathworks are:
- Since
i
is a function, it can be overridden and used as a variable. However, it is best to avoid usingi
andj
for variable names if you intend to use them in complex arithmetic.- For speed and improved robustness in complex arithmetic, use
1i
and1j
instead ofi
andj
.
In MATLAB, by default, the letters i
and j
are built-in function
names, which both refer to the imaginary unit in the complex domain.
So by default i = j = sqrt(-1)
.
>> i
ans =
0.0000 + 1.0000i
>> j
ans =
0.0000 + 1.0000i
and as you should expect:
>> i^2
ans =
-1
MATLAB allows using built-in function name as a standard variable. In this case the symbol used will not point to the built-in function any more but to your own user defined variable. This practice, however, is not generally recommended as it can lead to confusion, difficult debugging and maintenance (see other example do-not-name-a-variable-with-an-existing-function-name).
If you are ultra pedantic about respecting conventions and best practices, you will avoid using them as loop indices in this language. However, it is allowed by the compiler and perfectly functional so you may also choose to keep old habits and use them as loop iterators.
>> A = nan(2,3);
>> for i=1:2 % perfectly legal loop construction
for j = 1:3
A(i, j) = 10 * i + j;
end
end
Note that loop indices do not go out of scope at the end of the loop, so they keep their new value.
>> [ i ; j ]
ans =
2
3
In the case you use them as variable, make sure they are initialised before they are used. In the loop above MATLAB initialise them automatically when it prepare the loop, but if not initialised properly you can quickly see that you may inadvertently introduce complex
numbers in your result.
If later on, you need to undo the shadowing of the built-in function (=e.g. you want i
and j
to represent the imaginary unit again), you can clear
the variables:
>> clear i j
You understand now the Mathworks reservation about using them as loop indices if you intend to use them in complex arithmetic. Your code would be riddled with variable initialisations and clear
commands, best way to confuse the most serious programmer (yes you there!...) and program accidents waiting to happen.
If no complex arithmetic is expected, the use of i
and j
is perfectly functional and there is no performance penalty.
If your code has to deal with complex
numbers, then i
and j
will certainly come in handy. However, for the sake of disambiguation and even for performances, it is recommended to use the full form instead of the shorthand syntax. The full form is 1i
(or 1j
).
>> [ i ; j ; 1i ; 1j]
ans =
0.0000 + 1.0000i
0.0000 + 1.0000i
0.0000 + 1.0000i
0.0000 + 1.0000i
They do represent the same value sqrt(-1)
, but the later form:
i
or j
was a variable or
the imaginary unit).Note that the full syntax 1i
is valid with any number preceding the symbol:
>> a = 3 + 7.8j
a =
3.0000 + 7.8000i
This is the only function which you can stick with a number without an operator between them.
While their use as imaginary unit OR variable is perfectly legal, here is just a small example of how confusing it could get if both usages get mixed:
Let's override i
and make it a variable:
>> i=3
i =
3
Now i
is a variable (holding the value 3
), but we only overrid the shorthand notation of the imaginary unit, the full form is still interpreted correctly:
>> 3i
ans =
0.0000 + 3.0000i
Which now lets us build the most obscure formulations. I let you assess the readability of all the following constructs:
>> [ i ; 3i ; 3*i ; i+3i ; i+3*i ]
ans =
3.0000 + 0.0000i
0.0000 + 3.0000i
9.0000 + 0.0000i
3.0000 + 3.0000i
12.0000 + 0.0000i
As you can see, each value in the array above return a different result. While each result is valid (provided that was the initial intent), most of you will admit that it would be a proper nightmare to read a code riddled with such constructs.