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