/**
 * This class creates a 2 dimensional matrix
 * exp(i*(angleX*sigX + angleY*sigY + angleZ*sigZ))
 * where sigX, sigY and sigZ are the Pauli matrices
 * and angleX, angleY, angleZ are real numbers.
 * Entries of this matrix can be accessed via getEntry(row, col)
 */
public class OneBitRot extends OneBitGate{
    private double _angleX;// all internal angles in radians
    private double _angleY;
    private double _angleZ;
    
    public final static int NOT_XYZ = 0;
    public final static int X_AXIS = 1;
    public final static int Y_AXIS = 2;
    public final static int Z_AXIS = 3;
    
    private int _axis = NOT_XYZ;
   
    
/**
 *
 */
    public OneBitRot(double angleX, double angleY, double angleZ) {
        _angleX = angleX;
        _angleY = angleY;
        _angleZ = angleZ;
        double n = Math.sqrt(angleX*angleX + angleY*angleY +angleZ*angleZ);
        if (Math.abs(n)<1e-12){
            _entries[0][0] = new Complex(1.0);
            _entries[0][1] = new Complex(0.0);
            _entries[1][0] = new Complex(0.0);
            _entries[1][1] = new Complex(1.0);
        }else{
            double nx = angleX/n;
            double ny = angleY/n;
            double nz = angleZ/n;
            double c = Math.cos(n);
            double s = Math.sin(n);
            _entries[0][0] = new Complex(c, s*nz );
            _entries[0][1] = new Complex(s*ny, s*nx);
            _entries[1][0] = new Complex(-s*ny, s*nx);
            _entries[1][1] = new Complex(c, -s*nz);       
        }    
    }
/**
 *
 */
    public OneBitRot(double angle, int axis) {
        double c = Math.cos(angle);
        double s = Math.sin(angle);
        switch(axis){
            case X_AXIS:
                _angleX = angle;
                _angleY = 0.0;
                _angleZ = 0.0;
                _axis = axis;
                _entries[0][0] = new Complex(c, 0.0);
                _entries[0][1] = new Complex(0.0, s);
                _entries[1][0] = new Complex(0.0, s);
                _entries[1][1] = new Complex(c, 0.0);
                break;
            case Y_AXIS:
                _angleX = 0.0;
                _angleY = angle;
                _angleZ = 0.0;
                _axis = axis;
                _entries[0][0] = new Complex(c, 0.0);
                _entries[0][1] = new Complex( s, 0.0);
                _entries[1][0] = new Complex(-s, 0.0);
                _entries[1][1] = new Complex(c, 0.0);       
                break;
            case Z_AXIS:
                _angleX = 0.0;
                _angleY = 0.0;
                _angleZ = angle;
                _axis = axis;
                _entries[0][0] = new Complex(c, s);
                _entries[0][1] = Globals.complexZero;
                _entries[1][0] = Globals.complexZero;
                _entries[1][1] = new Complex(c, -s);       
                break;
            default:
                throw new RuntimeException("unsupported axis for OneBitRot");
        }
                    

        
    }
/**
 *
 */    
    public double getAngleX(){
        return _angleX;
    }
/**
 *
 */    
    public double getAngleY(){
        return _angleY;
    }
/**
 *
 */    
    public double getAngleZ(){
        return _angleZ;
    }
/**
 *
 */    
    public int getAxis(){
        return _axis;
    }

}
