001 /* 002 * $Id: RootUtil.java 3652 2011-06-02 18:17:04Z kredel $ 003 */ 004 005 package edu.jas.root; 006 007 008 import java.util.List; 009 010 import org.apache.log4j.Logger; 011 012 import edu.jas.structure.RingElem; 013 import edu.jas.structure.RingFactory; 014 import edu.jas.arith.Rational; 015 import edu.jas.poly.Complex; 016 017 018 /** 019 * Real root utilities. For example real root count. 020 * @author Heinz Kredel 021 */ 022 public class RootUtil { 023 024 025 private static final Logger logger = Logger.getLogger(RootUtil.class); 026 027 028 private static boolean debug = logger.isDebugEnabled(); 029 030 031 /** 032 * Count changes in sign. 033 * @param <C> coefficient type. 034 * @param L list of coefficients. 035 * @return number of sign changes in L. 036 */ 037 public static <C extends RingElem<C>> long signVar(List<C> L) { 038 long v = 0; 039 if (L == null || L.isEmpty()) { 040 return v; 041 } 042 C A = L.get(0); 043 for (int i = 1; i < L.size(); i++) { 044 C B = L.get(i); 045 while (B == null || B.signum() == 0) { 046 i++; 047 if (i >= L.size()) { 048 return v; 049 } 050 B = L.get(i); 051 } 052 if (A.signum() * B.signum() < 0) { 053 v++; 054 } 055 A = B; 056 } 057 return v; 058 } 059 060 061 /** 062 * Parse interval for a real root from String. 063 * @param s String, syntax: [left, right] or [mid]. 064 * @return Interval from s. 065 */ 066 public static <C extends RingElem<C> & Rational> 067 Interval<C> parseInterval(RingFactory<C> fac, String s) { 068 int r = s.length(); 069 int el = s.indexOf("["); 070 if ( el >= 0 ) { 071 int ri = s.indexOf("]"); 072 if ( ri > 0 ) { 073 r = ri; 074 } 075 } else { 076 el = -1; 077 } 078 //System.out.println("s = " + s); 079 String iv = s.substring(el+1,r).trim(); 080 //System.out.println("iv = " + iv); 081 int k = iv.indexOf(","); 082 if ( k < 0 ) { 083 k = s.indexOf(" "); 084 } 085 if ( k < 0 ) { 086 C mid = fac.parse(iv); 087 return new Interval<C>(mid); 088 } 089 //System.out.println("k = " + k + ", len = " + iv.length()); 090 String ls = iv.substring(0,k).trim(); 091 String rs = iv.substring(k+1,iv.length()).trim(); 092 //System.out.println("ls = " + ls + ", rs = " + rs); 093 C left = fac.parse(ls);; 094 C right = fac.parse(rs);; 095 //System.out.println("left = " + left + ", right = " + right); 096 return new Interval<C>(left,right); 097 } 098 099 100 /** 101 * Parse rectangle for a complex root from String. 102 * @param s String, syntax: [south-west, north-east] or [mid]. 103 * @return Interval from s. 104 */ 105 public static <C extends RingElem<C> & Rational> 106 Rectangle<C> parseRectangle(RingFactory<Complex<C>> fac, String s) { 107 int r = s.length(); 108 int el = s.indexOf("["); 109 if ( el >= 0 ) { 110 int ri = s.indexOf("]"); 111 if ( ri > 0 ) { 112 r = ri; 113 } 114 } else { 115 el = -1; 116 } 117 //System.out.println("s = " + s); 118 String iv = s.substring(el+1,r).trim(); 119 //System.out.println("iv = " + iv); 120 int k = iv.indexOf(","); 121 if ( k < 0 ) { 122 k = s.indexOf(" "); 123 } 124 if ( k < 0 ) { 125 Complex mid = fac.parse(iv); 126 return new Rectangle<C>(mid); 127 } 128 //System.out.println("k = " + k + ", len = " + iv.length()); 129 String ls = iv.substring(0,k).trim(); 130 String rs = iv.substring(k+1,iv.length()).trim(); 131 //System.out.println("ls = " + ls + ", rs = " + rs); 132 Complex sw = fac.parse(ls);; 133 Complex ne = fac.parse(rs);; 134 //System.out.println("left = " + left + ", right = " + right); 135 return new Rectangle<C>(sw,ne); 136 } 137 138 }