/**
 * This class creates a new instance of 
 * a Line Incidence Matrix (LineIncMat). 
 * The matrix looks like this for numBits = 3.
 * (matrix dimension is 2^numBits = 8)
 *
 * 
 * {0,1,0,0,0,0,0,0},
 * {1,0,0,1,0,0,0,0},
 * {0,0,0,1,0,0,1,0},
 * {0,1,1,0,0,0,0,0},
 * {0,0,0,0,0,1,0,0},
 * {0,0,0,0,1,0,0,1},
 * {0,0,1,0,0,0,0,1},
 * {0,0,0,0,0,1,1,0}
 * 
 * 
 */
public class LineIncMat {
    private int _numBits;
    
    private int[][] _matrix;
/**
 *
 */
    public LineIncMat(int numBits) {
        Throw.If(numBits<1, "number of bits must be >= 1");                  
        _numBits = numBits;
        int numRows = 1<<numBits;
        
        //_matrix automatically initialized to zero
        _matrix = new int[numRows][numRows];
        

        for(int row = 0; row<numRows; row++){

        	//first 1 of row
        	//given by sigx(0)
        	_matrix[row][row^1]=1;
        	
        	//second 1 of row
        	//given by 
        	//sigx(targetBit)n(targetBit-1)nbar(targetBit-2)...nbar(0)
        	if(numBits>1){       			        	
	        	for(int targetBit = numBits-1; targetBit>=1; targetBit--){
	        		boolean agrees = true;
	        		
	        		//n(targetBit-1) constraint
	        		if(((row>>(targetBit-1))&1) != 1){ 
	        			agrees = false;
	        		}
	        		
	        		//nbar(targetBit-2)...nbar(0) constraint
	        		if(agrees){
		        		for(int delta = 2; delta<= targetBit; delta++){
		        			if(((row>>(targetBit-delta))&1) == 1){ 
		        				agrees = false;
		        				break;
		        			}
		        		}
	        		}
	        		
	        		if(agrees){
	        			_matrix[row][row^(1<<targetBit)] = 1;
	        			break;
	        		}
	        	}//targetBit loop
        	}//if numBits>1
        	
        }//row loop
    }
/**
 * 
 */   
   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){
       System.out.println("numBits = 1:");
       System.out.println((new LineIncMat(1)).toString());
       System.out.println("numBits = 3:");
       System.out.println((new LineIncMat(3)).toString());
      
   }
		
}
