001/* 002 * $Id: IdealWithRealAlgebraicRoots.java 5825 2018-05-13 15:19:54Z kredel $ 003 */ 004 005package edu.jas.application; 006 007 008import java.util.ArrayList; 009import java.util.List; 010 011import edu.jas.arith.BigDecimal; 012import edu.jas.arith.Rational; 013import edu.jas.poly.GenPolynomial; 014import edu.jas.poly.GenPolynomialRing; 015import edu.jas.poly.PolyUtil; 016import edu.jas.root.RealAlgebraicNumber; 017import edu.jas.structure.GcdRingElem; 018 019 020/** 021 * Container for Ideals together with univariate polynomials and real algebraic 022 * roots. 023 * @author Heinz Kredel 024 */ 025public class IdealWithRealAlgebraicRoots<D extends GcdRingElem<D> & Rational> extends IdealWithUniv<D> { 026 027 028 /** 029 * The list of real algebraic roots. 030 */ 031 public final List<List<RealAlgebraicNumber<D>>> ran; 032 033 034 /** 035 * The list of decimal approximations of the real algebraic roots. 036 */ 037 protected List<List<BigDecimal>> droots = null; 038 039 040 /** 041 * Constructor not for use. 042 */ 043 protected IdealWithRealAlgebraicRoots() { 044 throw new IllegalArgumentException("do not use this constructor"); 045 } 046 047 048 /** 049 * Constructor. 050 * @param id the ideal 051 * @param up the list of univaraite polynomials 052 * @param rr the list of real algebraic roots 053 */ 054 public IdealWithRealAlgebraicRoots(Ideal<D> id, List<GenPolynomial<D>> up, 055 List<List<RealAlgebraicNumber<D>>> rr) { 056 super(id, up); 057 ran = rr; 058 } 059 060 061 /** 062 * Constructor. 063 * @param iu the ideal with univariate polynomials 064 * @param rr the list of real algebraic roots 065 */ 066 public IdealWithRealAlgebraicRoots(IdealWithUniv<D> iu, List<List<RealAlgebraicNumber<D>>> rr) { 067 super(iu.ideal, iu.upolys); 068 ran = rr; 069 } 070 071 072 /** 073 * String representation of the ideal. 074 * @see java.lang.Object#toString() 075 */ 076 @Override 077 public String toString() { 078 StringBuffer sb = new StringBuffer(super.toString() + "\nreal roots:\n"); 079 sb.append("["); 080 boolean f1 = true; 081 for (List<RealAlgebraicNumber<D>> lr : ran) { 082 if (!f1) { 083 sb.append(", "); 084 } else { 085 f1 = false; 086 } 087 sb.append("["); 088 boolean f2 = true; 089 for (RealAlgebraicNumber<D> rr : lr) { 090 if (!f2) { 091 sb.append(", "); 092 } else { 093 f2 = false; 094 } 095 sb.append(rr.ring.toScript()); 096 } 097 sb.append("]"); 098 } 099 sb.append("]"); 100 if (droots != null) { 101 sb.append("\ndecimal real root approximation:\n"); 102 for (List<BigDecimal> d : droots) { 103 sb.append(d.toString()); 104 sb.append("\n"); 105 } 106 } 107 return sb.toString(); 108 } 109 110 111 /** 112 * Get a scripting compatible string representation. 113 * @return script compatible representation for this Element. 114 * @see edu.jas.structure.Element#toScript() 115 */ 116 @Override 117 public String toScript() { 118 // Python case 119 return super.toScript() + ", " + ran.toString(); 120 } 121 122 123 /** 124 * Get decimal approximation of the real root tuples. 125 */ 126 public synchronized List<List<BigDecimal>> decimalApproximation() { 127 if (this.droots != null) { 128 return droots; 129 } 130 List<List<BigDecimal>> rroots = new ArrayList<List<BigDecimal>>(); 131 for (List<RealAlgebraicNumber<D>> rri : this.ran) { 132 List<BigDecimal> r = new ArrayList<BigDecimal>(); 133 for (RealAlgebraicNumber<D> rr : rri) { 134 BigDecimal d = new BigDecimal(rr.magnitude()); 135 r.add(d); 136 } 137 rroots.add(r); 138 } 139 droots = rroots; 140 return rroots; 141 } 142 143 144 /** 145 * compute decimal approximation of the real root tuples. 146 */ 147 public void doDecimalApproximation() { 148 List<List<BigDecimal>> unused = decimalApproximation(); 149 if (unused.isEmpty()) { // use for findbugs 150 System.out.println("unused is empty"); 151 } 152 return; 153 } 154 155 156 /** 157 * Is decimal approximation of the real roots. 158 * @return true, if the decimal real roots approximate the real roots. 159 */ 160 public synchronized boolean isDecimalApproximation() { 161 doDecimalApproximation(); 162 if (droots == null || droots.size() == 0) { 163 return true; 164 } 165 if (upolys == null || upolys.size() == 0) { 166 return true; 167 } 168 BigDecimal dr = droots.get(0).get(0); 169 BigDecimal c = new BigDecimal("0.15").power(BigDecimal.DEFAULT_PRECISION / 2); 170 //System.out.println("eps: c = " + c); 171 List<GenPolynomial<BigDecimal>> upds = new ArrayList<GenPolynomial<BigDecimal>>(upolys.size()); 172 for (GenPolynomial<D> up : upolys) { 173 GenPolynomialRing<D> pfac = up.ring; 174 GenPolynomialRing<BigDecimal> dpfac = new GenPolynomialRing<BigDecimal>(dr, pfac); 175 GenPolynomial<BigDecimal> upd = PolyUtil.<D> decimalFromRational(dpfac, up); 176 //System.out.println("upd = " + upd); 177 upds.add(upd); 178 } 179 for (List<BigDecimal> rr : droots) { 180 int i = 0; 181 for (GenPolynomial<BigDecimal> upd : upds) { 182 BigDecimal d = rr.get(i++); 183 BigDecimal z = PolyUtil.<BigDecimal> evaluateMain(dr, upd, d); 184 z = z.abs(); 185 //System.out.println("z = " + z + ", d = " + d); 186 if (z.compareTo(c) >= 0) { 187 //System.out.println("no root: z = " + z); 188 BigDecimal cc = new BigDecimal("0.1").power(BigDecimal.DEFAULT_PRECISION / 3); 189 if (z.compareTo(cc) >= 0) { 190 System.out.println("no root: z = " + z + ", cc = " + cc); 191 return false; 192 } 193 } 194 } 195 } 196 GenPolynomialRing<D> pfac = ideal.list.ring; 197 GenPolynomialRing<BigDecimal> dpfac = new GenPolynomialRing<BigDecimal>(dr, pfac); 198 List<GenPolynomial<D>> ips = ideal.list.list; 199 //List<GenPolynomial<BigDecimal>> ipds = new ArrayList<GenPolynomial<BigDecimal>>(ips.size()); 200 c = new BigDecimal("0.15").power(BigDecimal.DEFAULT_PRECISION / 2 - 1); 201 for (GenPolynomial<D> ip : ips) { 202 GenPolynomial<BigDecimal> ipd = PolyUtil.<D> decimalFromRational(dpfac, ip); 203 //System.out.println("ipd = " + ipd); 204 //ipds.add(ipd); 205 for (List<BigDecimal> rr : droots) { 206 BigDecimal z = PolyUtil.<BigDecimal> evaluateAll(dr, ipd, rr); 207 z = z.abs(); 208 //System.out.println("z = " + z + ", rr = " + rr); 209 if (z.compareTo(c) >= 0) { 210 //System.out.println("no root: z = " + z + ", c = " + c); 211 BigDecimal cc = new BigDecimal("0.1").power(BigDecimal.DEFAULT_PRECISION / 3); 212 if (z.compareTo(cc) >= 0) { 213 System.out.println("no root: z = " + z + ", cc = " + cc); 214 System.out.println("ipd = " + ipd + ", rr = " + rr); 215 return false; 216 } 217 } 218 } 219 } 220 return true; 221 } 222 223}