/**
 * This class creates a new instance of 
 * a Shift Uin Matrix (ShiftUinMat). 
 * Uin is the input unitary matrix.
 * The matrix looks like this for numBits = 3.
 * (matrix dimension is 2^numBits = 8)
 * and a shift of 3. It takes |j> to |j+3>,
 * where the addition is mod 8.
 * 
 * {0,0,0,1,0,0,0,0},
 * {0,0,0,0,1,0,0,0},
 * {0,0,0,0,0,1,0,0},
 * {0,0,0,0,0,0,1,0},
 * {0,0,0,0,0,0,0,1},
 * {1,0,0,0,0,0,0,0},
 * {0,1,0,0,0,0,0,0},
 * {0,0,1,0,0,0,0,0}
 * 
 * 
 */

public class ShiftUinMat {
    private int _numBits;
    private int _shift;
    private int[][] _matrix;
/**
 * 
 */
    public ShiftUinMat(int numBits, int shift) {
    	
        Throw.If(numBits<1, "number of bits must be >= 1");                  
        _numBits = numBits;
        
		int numRows = 1<<numBits;
		Throw.If(Math.abs(shift)>= numRows, 
			"shift is out of bounds");
		if(shift<0){shift = numRows + shift;}
		_shift = shift;

        
        //_matrix automatically initialized to zero
        _matrix = new int[numRows][numRows];
        
        int col;
        for(col=_shift; col<numRows; col++){
        	_matrix[col - _shift][col] = 1;
        }
        for(col=0; col<_shift; col++){
        	_matrix[numRows-_shift + col][col] = 1;
        }
    }
/**
 * 
 */   
	public String toString(){
       int numRows = _matrix.length;
       String output = "";
       output += "numRows = "+ numRows + '\n';
       int row, col;
       for(row=0; row<numRows; row++){
    	   for(col=0; col<numRows; col++){
    		   output += _matrix[row][col] + " ";
    	   }
    	   output += '\n';
       }
       return output;
   }
/**
 *
 */
	public int getEntry(int row, int col) {
		return _matrix[row][col];
	}
/**
* 
*/    
	public static void main(String[] args){
		int numBits = 3;
		int shift = -2;

		System.out.println("numBits = " + numBits);
		System.out.println("shift = " + shift);
		ShiftUinMat mat = new ShiftUinMat(numBits, shift);
        System.out.println(mat.toString());
      
   }

}
