001/* 002 * $Id$ 003 */ 004 005package edu.jas.root; 006 007 008import java.io.Serializable; 009import java.util.List; 010 011import edu.jas.arith.Rational; 012import edu.jas.poly.AlgebraicNumberRing; 013import edu.jas.poly.GenPolynomial; 014import edu.jas.poly.Complex; 015import edu.jas.structure.GcdRingElem; 016 017 018/** 019 * Container for the real and complex algebraic roots of a univariate 020 * polynomial. 021 * @param <C> coefficient type. 022 * @author Heinz Kredel 023 */ 024public class AlgebraicRoots<C extends GcdRingElem<C> & Rational> implements Serializable { 025 026 027 /** 028 * Univariate polynomial. 029 */ 030 public final GenPolynomial<C> p; 031 032 033 /** 034 * Real algebraic roots. 035 */ 036 public final List<RealAlgebraicNumber<C>> real; 037 038 039 /** 040 * Univariate polynomial with complex coefficients equivalent to p. 041 */ 042 public final GenPolynomial<Complex<C>> cp; 043 044 045 /** 046 * Complex algebraic roots. 047 */ 048 public final List<ComplexAlgebraicNumber<C>> complex; 049 050 051 /** 052 * Constructor not for use. 053 */ 054 protected AlgebraicRoots() { 055 throw new IllegalArgumentException("do not use this constructor"); 056 } 057 058 059 /** 060 * Constructor. 061 * @param p univariate polynomial 062 * @param cp univariate polynomial with compelx coefficients 063 * @param r list of real algebraic roots 064 * @param c list of complex algebraic roots 065 */ 066 public AlgebraicRoots(GenPolynomial<C> p, GenPolynomial<Complex<C>> cp, List<RealAlgebraicNumber<C>> r, 067 List<ComplexAlgebraicNumber<C>> c) { 068 this.p = p; 069 this.cp = cp; 070 this.real = r; 071 this.complex = c; 072 } 073 074 075 /** 076 * String representation of AlgebraicRoots. 077 * @see java.lang.Object#toString() 078 */ 079 @Override 080 public String toString() { 081 return "[" + p + ", real=" + real + ", complex=" + complex + "]"; 082 } 083 084 085 /** 086 * Get a scripting compatible string representation. 087 * @return script compatible representation for this roots. 088 */ 089 public String toScript() { 090 // Python case 091 StringBuffer sb = new StringBuffer("["); 092 sb.append(p.toScript()); 093 //sb.append(", "); 094 //sb.append(cp.toScript()); 095 if (!real.isEmpty()) { 096 sb.append(", real=["); 097 boolean first = true; 098 for (RealAlgebraicNumber<C> r : real) { 099 if (first) { 100 first = false; 101 } else { 102 sb.append(", "); 103 } 104 sb.append(r.ring.root.toScript()); 105 } 106 sb.append("]"); 107 } 108 if (!complex.isEmpty()) { 109 sb.append(", complex=["); 110 boolean first = true; 111 for (ComplexAlgebraicNumber<C> c : complex) { 112 if (first) { 113 first = false; 114 } else { 115 sb.append(", "); 116 } 117 sb.append(c.ring.root.toScript()); 118 } 119 sb.append("]"); 120 } 121 sb.append("]"); 122 return sb.toString(); 123 } 124 125 126 /** 127 * Get a decimal number scripting compatible string representation. 128 * @return decimal number script compatible representation for this roots. 129 */ 130 public String toDecimalScript() { 131 // Python case 132 StringBuffer sb = new StringBuffer("["); 133 sb.append(p.toScript()); 134 //sb.append(", "); 135 //sb.append(cp.toScript()); 136 if (!real.isEmpty()) { 137 sb.append(", real=["); 138 boolean first = true; 139 for (RealAlgebraicNumber<C> r : real) { 140 if (first) { 141 first = false; 142 } else { 143 sb.append(", "); 144 } 145 r.ring.refineRoot(); 146 sb.append(r.ring.root.toDecimal().toScript()); 147 } 148 sb.append("]"); 149 } 150 if (!complex.isEmpty()) { 151 sb.append(", complex=["); 152 boolean first = true; 153 for (ComplexAlgebraicNumber<C> c : complex) { 154 if (first) { 155 first = false; 156 } else { 157 sb.append(", "); 158 } 159 c.ring.refineRoot(); 160 sb.append(c.ring.root.getDecimalCenter().toScript()); 161 } 162 sb.append("]"); 163 } 164 sb.append("]"); 165 return sb.toString(); 166 } 167 168 169 /** 170 * Copy this. 171 * @return a copy of this. 172 */ 173 public AlgebraicRoots<C> copy() { 174 return new AlgebraicRoots<C>(p, cp, real, complex); 175 } 176 177 178 /** 179 * Comparison with any other object. 180 * @see java.lang.Object#equals(java.lang.Object) 181 */ 182 @Override 183 @SuppressWarnings("unchecked") 184 public boolean equals(Object b) { 185 if (!(b instanceof AlgebraicRoots)) { 186 return false; 187 } 188 AlgebraicRoots<C> a = null; 189 try { 190 a = (AlgebraicRoots<C>) b; 191 } catch (ClassCastException e) { 192 return false; 193 } 194 return p.equals(a.p) && real.equals(a.real) && complex.equals(a.complex); 195 } 196 197 198 /** 199 * Hash code for this AlgebraicRoots. 200 * @see java.lang.Object#hashCode() 201 */ 202 @Override 203 public int hashCode() { 204 return (161 * p.hashCode() + 37) * real.hashCode() + complex.hashCode(); 205 } 206 207 208 /** 209 * Algebraic number ring. 210 * @return algebraic ring of roots. 211 */ 212 public AlgebraicNumberRing<C> getAlgebraicRing() { 213 AlgebraicNumberRing<C> anr = new AlgebraicNumberRing<C>(p); 214 return anr; 215 } 216}