package math.equation;

/**
 * @author Daniel Weschke
 */
public class RationalPolynomial {
	public Polynomial a;
	public Polynomial b;
	
	public RationalPolynomial(){
	}
	
	public RationalPolynomial(Polynomial a, Polynomial b){
		this.a = a;
		this.b = b;
	}
	
	public RationalPolynomial(Polynomial a, String b){
		this.a = a;
		this.b = new Polynomial(b);
	}
	
	public RationalPolynomial(String a, Polynomial b){
		this.a = new Polynomial(a);
		this.b = b;
	}
	
	public RationalPolynomial(String a, String b){
		this.a = new Polynomial(a);
		this.b = new Polynomial(b);
	}
	
	public RationalPolynomial(double a, String b){
		this.a = new Polynomial(a);
		this.b = new Polynomial(b);
	}
	
	public RationalPolynomial(double a, double b){
		this.a = new Polynomial(a);
		this.b = new Polynomial(b);
	}
	
    public RationalPolynomial(String ab){
    	String[] a_b = ab.split(";");
    	if(a_b.length == 1){
    		a = new Polynomial(a_b[0]);
    		b = new Polynomial(1);
    	}
    	if(a_b.length == 2){
    		a = new Polynomial(a_b[0]);
    		b = new Polynomial(a_b[1]);
    	}
    }
    
    /**
     * set the symbolic of all polynomials
     * @param symb symbolic
     */
    public void setSymbolic(String symb){
    	a.setSymbolic(symb);
    	b.setSymbolic(symb);
    }
    
    public RationalPolynomial plus(RationalPolynomial g){
    	Polynomial a = new Polynomial(this.a.times(g.b)).plus((g.a.times(b)));
    	Polynomial b = new Polynomial(this.b.times(g.b));
    	return new RationalPolynomial(a, b);
    }
    
    public RationalPolynomial minus(RationalPolynomial g){
    	Polynomial a = new Polynomial(this.a.times(g.b)).minus((g.a.times(b)));
    	Polynomial b = new Polynomial(this.b.times(g.b));
    	return new RationalPolynomial(a, b);
    }
	
	public RationalPolynomial times(RationalPolynomial g){
		Polynomial a = new Polynomial(this.a).times(g.a);
		Polynomial b = new Polynomial(this.b).times(g.b);
		return new RationalPolynomial(a, b);
	}

    // use Horner's method to compute and return the polynomial evaluated at x
	public double evaluate(double x){
		return a.evaluate(x) / b.evaluate(x);
	}
	
	public double mod(double x){
		return new RationalPolynomialComplex(this).mod(x);
	}
	
	public double argd(double x){
		return new RationalPolynomialComplex(this).argd(x);
	}
    
	@Override
	public String toString(){
		String p = ""+a;
		String q = ""+b;
		int size = p.length() > q.length() ? p.length() : q.length();
		String sep = "";
		for(int i=0; i<size; i++)
			sep += "-";
		String s = p+"\n";
		if(b.getCoef(0) != 1 || b.degree() != 0) s += sep+"\n" + q+"\n";
		return s;
	}
	
	public static void main(String[] args){
		RationalPolynomial PT1 = new RationalPolynomial("2; 4 1");
		PT1.setSymbolic("ω");
		System.out.println(PT1);
		
		RationalPolynomial PT2 = new RationalPolynomial("1; 6 1");
		PT2.setSymbolic("ω");
		System.out.println(PT2);
		
		RationalPolynomial I = new RationalPolynomial(5,"24 0");
		I.setSymbolic("ω");
		System.out.println(I);
		
		RationalPolynomial sys = PT1.times(PT2).times(I);
		sys.setSymbolic("ω");
		System.out.println(sys);

		System.out.println("|G(1)| = "+sys.mod(1)+"\n");
		
		System.out.println("phi(1) = "+sys.argd(1));
		
	}
}
