001 /* 002 * $Id: Boundary.java 3677 2011-07-04 20:29:49Z kredel $ 003 */ 004 005 package edu.jas.root; 006 007 008 import edu.jas.arith.Rational; 009 import edu.jas.poly.Complex; 010 import edu.jas.poly.ComplexRing; 011 import edu.jas.poly.GenPolynomial; 012 import edu.jas.poly.GenPolynomialRing; 013 import edu.jas.poly.PolyUtil; 014 import edu.jas.structure.RingElem; 015 import edu.jas.structure.RingFactory; 016 import edu.jas.ufd.GCDFactory; 017 import edu.jas.ufd.GreatestCommonDivisor; 018 019 020 /** 021 * Boundary determined by a rectangle and a polynomial. 022 * 023 * For a given complex polynomial A a closed path throught the corners 024 * of the given rectangle is constructed. The path is represented by 025 * four polynomials, one for each side of the rectangle. For a real t 026 * in [0,1] the i-th polynomial describes the path of A from corner[i] 027 * to corner[i+1]. In particular polys[i](0) = A(corner[i]) and 028 * polys[i](1) = A(corner[i+1]), with corner[4] = corner[0]. If A 029 * would be zero on a point of the path, an InvalidBoundaryException 030 * is thrown. 031 * @param <C> coefficient type. 032 * @author Heinz Kredel 033 */ 034 public class Boundary<C extends RingElem<C> & Rational> { 035 036 037 /** 038 * Rectangle. 039 */ 040 public final Rectangle<C> rect; 041 042 043 /** 044 * Polynomial. 045 */ 046 public final GenPolynomial<Complex<C>> A; 047 048 049 /** 050 * Boundary polynomials. 051 */ 052 public final GenPolynomial<Complex<C>>[] polys; 053 054 055 /** 056 * Factory for real polynomials. 057 */ 058 GenPolynomialRing<C> rfac; 059 060 061 /** 062 * Constructor. 063 * @param r rectangle of of corners. 064 * @param p non constant polynomial. 065 */ 066 @SuppressWarnings("unchecked") 067 public Boundary(Rectangle<C> r, GenPolynomial<Complex<C>> p) throws InvalidBoundaryException { 068 if ( p.isConstant() || p.isZERO() ) { 069 throw new InvalidBoundaryException("p is constant or 0 " + p); 070 } 071 rect = r; 072 A = p; 073 GreatestCommonDivisor<Complex<C>> ufd = GCDFactory.<Complex<C>> getImplementation(A.ring.coFac); 074 polys = (GenPolynomial<Complex<C>>[]) new GenPolynomial[5]; 075 076 Complex<C>[] corner = rect.corners; 077 for (int i = 0; i < 4; i++) { 078 Complex<C> t = corner[i + 1].subtract(corner[i]); 079 GenPolynomial<Complex<C>> tp = A.ring.univariate(0, 1L).multiply(t); 080 //System.out.println("t = " + t); 081 GenPolynomial<Complex<C>> pc = PolyUtil.<Complex<C>> seriesOfTaylor(A, corner[i]); 082 pc = PolyUtil.<Complex<C>> substituteUnivariate(pc, tp); 083 GenPolynomial<Complex<C>> gcd = ufd.gcd(A, pc); 084 if (!gcd.isONE()) { 085 //System.out.println("A = " + A); 086 //System.out.println("PC["+i+"] = " + pc); 087 //System.out.println("gcd = " + gcd); 088 throw new InvalidBoundaryException("A has a zero on rectangle " + rect + ", A = " + A); 089 } 090 polys[i] = pc; 091 } 092 polys[4] = polys[0]; 093 094 // setup factory for real and imaginary parts 095 ComplexRing<C> cr = (ComplexRing<C>) A.ring.coFac; 096 RingFactory<C> cf = cr.ring; 097 rfac = new GenPolynomialRing<C>(cf, A.ring); 098 } 099 100 101 /** 102 * Constructor. 103 * @param r rectangle of of corners. 104 * @param p polynomial. 105 * @param b boundary polynomials. 106 */ 107 protected Boundary(Rectangle<C> r, GenPolynomial<Complex<C>> p, GenPolynomial<Complex<C>>[] b) { 108 rect = r; 109 A = p; 110 polys = b; 111 //ufd = GCDFactory.<Complex<C>> getImplementation(A.ring.coFac); 112 } 113 114 115 /** 116 * String representation of Boundary. 117 * @see java.lang.Object#toString() 118 */ 119 @Override 120 public String toString() { 121 return rect.toString(); 122 } 123 124 125 /** 126 * Get a scripting compatible string representation. 127 * @return script compatible representation for this Boundary. 128 */ 129 public String toScript() { 130 // Python case 131 return rect.toScript(); 132 } 133 134 135 /** 136 * Get real part for polynomial i. 137 * @param i index of polynomial. 138 * @return real part for polynomial i. 139 */ 140 public GenPolynomial<C> getRealPart(int i) { 141 GenPolynomial<C> f = PolyUtil.<C> realPartFromComplex(rfac, polys[i]); 142 return f; 143 } 144 145 146 /** 147 * Get imaginary part for polynomial i. 148 * @param i index of polynomial. 149 * @return imaginary part for polynomial i. 150 */ 151 public GenPolynomial<C> getImagPart(int i) { 152 GenPolynomial<C> g = PolyUtil.<C> imaginaryPartFromComplex(rfac, polys[i]); 153 return g; 154 } 155 156 157 /** 158 * Clone this. 159 * @see java.lang.Object#clone() 160 */ 161 @Override 162 public Boundary<C> clone() { 163 return new Boundary<C>(rect, A, polys); 164 } 165 166 167 /** 168 * Comparison with any other object. 169 * @see java.lang.Object#equals(java.lang.Object) 170 */ 171 @Override 172 @SuppressWarnings("unchecked") 173 public boolean equals(Object b) { 174 if (!(b instanceof Boundary)) { 175 return false; 176 } 177 Boundary<C> a = null; 178 try { 179 a = (Boundary<C>) b; 180 } catch (ClassCastException e) { 181 } 182 return rect.equals(a.rect) && A.equals(a.A); 183 } 184 185 186 /** 187 * Hash code for this Rectangle. 188 * @see java.lang.Object#hashCode() 189 */ 190 @Override 191 public int hashCode() { 192 int hc = 0; 193 hc += 37 * rect.hashCode(); 194 return 37 * hc + A.hashCode(); 195 } 196 197 }