I have a small matrix A of size (n+1)x(n+1) with n=O(10). I need to build N=(n+1)^m much larger matrices B_i, each one of size Nxm, where m=O(10) also. Luckily, I need to store just one B_i at the time, so memory is not an issue. To generate each B_i I have a matrix I of indices, of size Nxm. I contains all the possible m-ples of integers between 1 and n+1. For example, let n=4,m=4, then
I=[1 1 1 1;
2 1 1 1;
3 1 1 1;
4 1 1 1;
5 1 1 1;
1 2 1 1;
.
.
5 5 5 5]
The indices in row i of I are the column indices in A of the elements of the corresponding column of B_i. For example, consider i=3, i.e., B_3=C. Then column 1 of matrix C is assembled using elements from column 3 of A, while columns 2 to 4 use elements from column 1 of A. In the same way, indices from column j of I are the row indices in A of the elements of column j of B_i. Consider again B_3=C:
C(1,1) = A(1,3)
C(2,1) = A(2,3)
C(3,1) = A(3,3)
C(4,1) = A(4,3)
C(5,1) = A(5,3)
C(6,1) = A(1,3)
.
.
C(N,1) = A(5,3)
C(1,2) = A(1,1)
C(2,2) = A(1,1)
C(3,2) = A(1,1)
C(4,2) = A(1,1)
C(5,2) = A(1,1)
C(6,2) = A(2,1)
.
.
C(N,2) = A(5,1)
And so on. It's trivial to build each B_i with a double for loop. However, since I have to build N B_i, the resulting triple for loop takes forever. Can you show me some clever MATLAB trick to build these matrices super-quickly?
By the way, I don't really need the the B_i, but just the elementwise product of their columns, i.e.
PolyMD=prod(C,2)
which is an Nx1 column vector. As I said before, I store just one B_i at a time, so computing B_i first and then PolyMD is not a big issue. Still, if there's a fast and simple way to get PolyMD directly, I'd love to know.
EDIT: here is a full example to hopefully make the question more clear.
% input
n=2;
m=3;
A=[1.000000000000000e+00 -1.732050807568877e+00 1.414213562373095e+00;
1.000000000000000e+00 1.160285448625519e-16 -7.071067811865475e-01;
1.000000000000000e+00 1.732050807568877e+00 1.414213562373095e+00];
I=[ 1 1 1;
2 1 1;
3 1 1;
1 2 1;
2 2 1;
3 2 1;
1 3 1;
2 3 1;
3 3 1;
1 1 2;
2 1 2;
3 1 2;
1 2 2;
2 2 2;
3 2 2;
1 3 2;
2 3 2;
3 3 2;
1 1 3;
2 1 3;
3 1 3;
1 2 3;
2 2 3;
3 2 3;
1 3 3;
2 3 3;
3 3 3];
% desired output for B_2 (I skip B_1 since it's trivial, and B_3,....B_27 for brevity!)
B_2=[ -1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
1.160285448625519e-16 1.000000000000000e+00 1.000000000000000e+00;
1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
-1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
1.160285448625519e-16 1.000000000000000e+00 1.000000000000000e+00;
1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
-1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
1.160285448625519e-16 1.000000000000000e+00 1.000000000000000e+00;
1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
-1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
1.160285448625519e-16 1.000000000000000e+00 1.000000000000000e+00;
1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
-1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
1.160285448625519e-16 1.000000000000000e+00 1.000000000000000e+00;
1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
-1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
1.160285448625519e-16 1.000000000000000e+00 1.000000000000000e+00;
1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
-1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
1.160285448625519e-16 1.000000000000000e+00 1.000000000000000e+00;
1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
-1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
1.160285448625519e-16 1.000000000000000e+00 1.000000000000000e+00;
1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
-1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00;
1.160285448625519e-16 1.000000000000000e+00 1.000000000000000e+00;
1.732050807568877e+00 1.000000000000000e+00 1.000000000000000e+00];