Python – Nested loops with a variable number of loops

Nested loops with a variable number of loops… here is a solution to the problem.

Nested loops with a variable number of loops

I have a function that outputs the matrix on a new basis. However, depending on the size of the matrix, the number of base matrices varies. So in the simplified “Matlab pseudocode”:

if matrixsize==1
   for a1=1:4
      out(a1)=Matrix*basis(a1)
   end

elseif matrixsize==2
   for a1=1:4
      for a2=a1:4
         out(a1,a2)=Matrix*basis(a1)*basis(a2)
      end
   end

elseif matrixsize==3
   for a1=1:4
      for a2=a1:4
          for a3=a2:4
             out(a1,a2,a3)=Matrix*basis(a1)*basis(a2)*basis(a3)
          end
      end
   end

elseif ...

And so on

Is it possible to write this code for any value of the matrix size?
In other words: is it possible to create a loop that automatically creates the loop above?
If this doesn’t work in Matlab, is there a solution in Python?

(Background: This question comes from quantum physics, I want to write about the quantum state of Pauliki).

This is a valid Matlab code that shows the problem:

function T=newbasis(n)

%create a random matrix
m=2^n;
M=randn(m);

%Pauli matrices
s{1}=sparse([1,0;0,1]);
s{2}=sparse([0,1; 1,0]);
s{3}=sparse([0,-1i; 1i,0]);
s{4}=sparse([1,0;0,-1]);

if n==1
    for a1=1:4
        T(a1)=trace(M*betterkron(s{a1}));
    end

elseif n==2
    for a1=1:4
        for a2=a1:4
            T(a1,a2)=trace(M*betterkron(s{a1},s{a2}));
        end
    end

elseif n==3
    for a1=1:4
        for a2=a1:4
            for a3=a2:4    
                T(a1,a2,a3)=trace(M*betterkron(s{a1},s{a2},s{a3}));
            end
        end
    end    

else
    T=[]
end

%Not very clever but just to keep it simple
function krn=betterkron(A,varargin)
    krn = A;
    for j = 2:nargin;
        krn = kron(krn,varargin{j-1});
    end   
end

end

Solution

Although in principle such multiple loops can be done with recursive functions, it will be complicated. Fortunately, using multiple loops is not the best approach. MATLAB allows you to convert back and forth between N-dimensional subscripts and 1-dimensional linear indexes. So you can make a loop on the linear index and then convert it back to an N-dimensional subscript. So like this :

for i=1:numel(Matrix)  % loop over linear index 
    inds = ind2sub(size(Matrix), i);  % convert linear index to subscript

% Each index should be greater than or equal to the previous
    % e.g. a2=a1:4, a2 starts at a1 so cannot be less than a1
    if any(diff(inds) < 0)
        continue
    end

% Do the calculation
    % s{inds} is equivalent to s{i1}, s{i2}, ...
    T(i) = trace(M*betterkron(s{inds}));
end

Related Problems and Solutions