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