001/* 002 * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences. 003 * Copyright (C) 2006 - JScience (http://jscience.org/) 004 * All rights reserved. 005 * 006 * Permission to use, copy, modify, and distribute this software is 007 * freely granted, provided that this notice is preserved. 008 */ 009package org.jscience.mathematics.function; 010 011import java.util.List; 012import org.jscience.mathematics.structure.Field; 013 014import javolution.context.ObjectFactory; 015import javolution.text.Text; 016import javolution.text.TextBuilder; 017 018/** 019 * This class represents the quotient of two {@link Polynomial}, 020 * it is also a {@link Field field} (invertible). 021 * 022 * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a> 023 * @version 3.1, April 1, 2006 024 */ 025public class RationalFunction<F extends Field<F>> extends Function<F, F> 026 implements Field<RationalFunction<F>> { 027 028 /** 029 * Holds the factory for rational functions. 030 */ 031 /** 032 * Holds the dividend. 033 */ 034 private Polynomial<F> _dividend; 035 036 /** 037 * Holds the divisor. 038 */ 039 private Polynomial<F> _divisor; 040 041 /** 042 * Default constructor. 043 */ 044 private RationalFunction() { 045 } 046 047 /** 048 * Returns the dividend of this rational function. 049 * 050 * @return this rational function dividend. 051 */ 052 public Polynomial<F> getDividend() { 053 return _dividend; 054 } 055 056 /** 057 * Returns the divisor of this rational function. 058 * 059 * @return this rational function divisor. 060 */ 061 public Polynomial<F> getDivisor() { 062 return _divisor; 063 } 064 065 /** 066 * Returns the rational function from the specified dividend and divisor. 067 * 068 * @param dividend the dividend value. 069 * @param divisor the divisor value. 070 * @return <code>dividend / divisor</code> 071 */ 072 @SuppressWarnings("unchecked") 073 public static <F extends Field<F>> RationalFunction<F> valueOf( 074 Polynomial<F> dividend, Polynomial<F> divisor) { 075 RationalFunction<F> rf = FACTORY.object(); 076 rf._dividend = dividend; 077 rf._divisor = divisor; 078 return rf; 079 } 080 081 @SuppressWarnings("unchecked") 082 private static final ObjectFactory<RationalFunction> FACTORY = new ObjectFactory<RationalFunction>() { 083 084 protected RationalFunction create() { 085 return new RationalFunction(); 086 } 087 088 @SuppressWarnings("unchecked") 089 protected void cleanup(RationalFunction rf) { 090 rf._dividend = null; 091 rf._divisor = null; 092 } 093 }; 094 095 /** 096 * Returns the sum of two rational functions. 097 * 098 * @param that the rational function being added. 099 * @return <code>this + that</code> 100 */ 101 public RationalFunction<F> plus(RationalFunction<F> that) { 102 return valueOf(this._dividend.times(that._divisor).plus( 103 this._divisor.times(that._dividend)), this._divisor 104 .times(that._divisor)); 105 } 106 107 /** 108 * Returns the opposite of this rational function. 109 * 110 * @return <code>- this</code> 111 */ 112 public RationalFunction<F> opposite() { 113 return valueOf(_dividend.opposite(), _divisor); 114 } 115 116 /** 117 * Returns the difference of two rational functions. 118 * 119 * @param that the rational function being subtracted. 120 * @return <code>this - that</code> 121 */ 122 public RationalFunction<F> minus(RationalFunction<F> that) { 123 return this.plus(that.opposite()); 124 } 125 126 /** 127 * Returns the product of two rational functions. 128 * 129 * @param that the rational function multiplier. 130 * @return <code>this ยท that</code> 131 */ 132 public RationalFunction<F> times(RationalFunction<F> that) { 133 return valueOf(this._dividend.times(that._dividend), this._divisor 134 .times(that._divisor)); 135 } 136 137 /** 138 * Returns the inverse of this rational function. 139 * 140 * @return <code>1 / this</code> 141 */ 142 public RationalFunction<F> inverse() { 143 return valueOf(_divisor, _dividend); 144 } 145 146 /** 147 * Returns the quotient of two rational functions. 148 * 149 * @param that the rational function divisor. 150 * @return <code>this / that</code> 151 */ 152 public RationalFunction<F> divide(RationalFunction<F> that) { 153 return this.times(that.inverse()); 154 } 155 156 @SuppressWarnings("unchecked") 157 @Override 158 public List<Variable<F>> getVariables() { 159 return merge(_dividend.getVariables(), _divisor.getVariables()); 160 } 161 162 @SuppressWarnings("unchecked") 163 @Override 164 public F evaluate() { 165 return _dividend.evaluate().times(_divisor.evaluate().inverse()); 166 } 167 168 @Override 169 public Text toText() { 170 TextBuilder tb = TextBuilder.newInstance(); 171 tb.append('('); 172 tb.append(_dividend); 173 tb.append(")/("); 174 tb.append(_divisor); 175 tb.append(')'); 176 return tb.toText(); 177 } 178 179 @Override 180 public boolean equals(Object obj) { 181 if (obj instanceof RationalFunction) { 182 RationalFunction<?> that = (RationalFunction<?>) obj; 183 return this._dividend.equals(this._dividend) 184 && this._divisor.equals(that._divisor); 185 } else { 186 return false; 187 } 188 } 189 190 @Override 191 public int hashCode() { 192 return _dividend.hashCode() - _divisor.hashCode(); 193 } 194 195 ////////////////////////////////////////////////////////////////////// 196 // Overrides parent method potentially returning rational functions // 197 ////////////////////////////////////////////////////////////////////// 198 199 @Override 200 public RationalFunction<F> differentiate(Variable<F> v) { 201 return valueOf(_divisor.times(_dividend.differentiate(v)).plus( 202 _dividend.times(_divisor.differentiate(v)).opposite()), 203 _dividend.pow(2)); 204 } 205 206 @SuppressWarnings("unchecked") 207 @Override 208 public Function<F, F> plus(Function<F, F> that) { 209 return (that instanceof RationalFunction) ? 210 this.plus((RationalFunction<F>)that) : super.plus(that); 211 } 212 213 @SuppressWarnings("unchecked") 214 @Override 215 public Function<F, F> minus(Function<F, F> that) { 216 return (that instanceof RationalFunction) ? 217 this.minus((RationalFunction<F>)that) : super.minus(that); 218 } 219 220 @SuppressWarnings("unchecked") 221 @Override 222 public Function<F, F> times(Function<F, F> that) { 223 return (that instanceof RationalFunction) ? 224 this.times((RationalFunction<F>)that) : super.times(that); 225 } 226 227 @SuppressWarnings("unchecked") 228 @Override 229 public Function<F, F> divide(Function<F, F> that) { 230 return (that instanceof RationalFunction) ? 231 this.divide((RationalFunction<F>)that) : super.divide(that); 232 } 233 234 @SuppressWarnings("unchecked") 235 @Override 236 public RationalFunction<F> pow(int n) { 237 return (RationalFunction<F>) super.pow(n); 238 } 239 240 241 /** 242 * Returns a copy of this rational function. 243 * {@link javolution.context.AllocatorContext allocated} 244 * by the calling thread (possibly on the stack). 245 * 246 * @return an identical and independant copy of this rational function. 247 */ 248 public RationalFunction<F> copy() { 249 return RationalFunction.valueOf(_dividend.copy(), _divisor.copy()); 250 } 251 252 private static final long serialVersionUID = 1L; 253 254}