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 }