Chances are you mean < instead of <= in your for loops.
Videos
No. Let's first look at it as two dimensional arrays, so we know what we're talking about:
int i[4][4];
int j[4][4];
int k[4][4];
for (int x = 0; x < 4; x++) { // row number of output
for (int y = 0; y < 4; y++) { // column number of output
k[x][y] = 0;
for (int z = 0; z < 4; z++) { // four elements are added for this output
k[x][y] += i[x][z] * j[z][y];
}
}
}
Important difference!!! We start at 0 for the indices!
Now I'll convert it to int[16]s for you assuming that i[1] is the second element of the first row:
int i[16];
int j[16];
int k[16];
for (int x = 0; x < 4; x++) { // row number of output
for (int y = 0; y < 4; y++) { // column number of output
k[4*x+y] = 0;
for (int z = 0; z < 4; z++) { // four elements are added for this output
k[4*x+y] += i[4*x+z] * j[4*z+y];
}
}
}
This is equivalent to your code except for the fact that you start at 1 instead of zero.
@Dan "equivalent ... except .. you start at 1 instead of zero" solves the OP's first problem, but not the OP's second problem.
The OP's second and larger problem is functioning 3x3 matrix multiplier code that reads enough like buggy 4X4 matrix multiplier code to trip up its reviewers. I suspect the problems STARTED with the common mistake of using 1-based counting instead of 0-based indexing. And that was followed by a superficial solution: just pad the indexed vectors so that the 1-based counts are still in range, never mind the unused gaps.
The reviewer sees the idiomatic i*4+j and thinks "AHA! 4 MUST be the matrix dimension." implicitly reasoning "...because otherwise there would be unused gaps".
This miscue can be pinned on the use of "magic numbers", namely 3 and 4. Which of these is the intended matrix dimension? If the magic numbers had been referenced by name/purpose rather than by value, like via
const unsigned int DIMENSION = 3;
const unsigned int ROW_LENGTH = DIMENSION + 1;
the intent would have been clear and the mis-step of padding the vectors much easier to spot.
Or maybe I'm completely wrong and it always was just buggy 4x4 matrix multiplier code that coincidentally gave the right answer for 3x3 matrices.
Regardless, the common wisdom goes: Unless there is a very good reason to do otherwise,
use 0-based indexing, because it's simple, efficient, and idiomatic.
likewise, use the
forloop<idiom for 0-based index iteration:for (unsigned int i = 0; i < DIMENSION; i++) {reference special numbers in the problem domain via named constants, for self-documentation (as well as for flexibility).
Lets start with two arrays:
>>> a
array([0, 1, 2, 3, 4])
>>> b
array([5, 6, 7])
Transposing either array does not work because it is only 1D- there is nothing to transpose, instead you need to add a new axis:
>>> b.T
array([5, 6, 7])
>>> b[:,None]
array([[5],
[6],
[7]])
To get the dot product to work as shown you would have to do something convoluted:
>>> np.dot(a[:,None],b[None,:])
array([[ 0, 0, 0],
[ 5, 6, 7],
[10, 12, 14],
[15, 18, 21],
[20, 24, 28]])
You can rely on broadcasting instead of dot:
a[:,None]*b
Or you can simply use outer:
np.outer(a,b)
All three options return the same result.
You might also be interested in something like this so that each vector is always a 2D array:
np.dot(np.atleast_2d(a).T, np.atleast_2d(b))
An even easier way is to define your array like this:
>>>b = numpy.array([[1,2,3]])
Then you can transpose your array easily:
>>>b.T
array([[1],
[2],
[3]])
And you can also do the multiplication:
>>>[email protected]
[[1 2 3]
[2 4 6]
[3 6 9]]
Another way is to force reshape your vector like this:
>>> b = numpy.array([1,2,3])
>>> b.reshape(1,3).T
array([[1],
[2],
[3]])