001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.math4.legacy.core;
018
019import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
020
021/**
022 * Interface representing a <a href="http://mathworld.wolfram.com/RealNumber.html">real</a>
023 * <a href="http://mathworld.wolfram.com/Field.html">field</a>.
024 * @param <T> the type of the field elements
025 * @see FieldElement
026 * @since 3.2
027 */
028public interface RealFieldElement<T> extends FieldElement<T> {
029
030    /** Get the real value of the number.
031     * @return real value
032     */
033    double getReal();
034
035    /** '+' operator.
036     * @param a right hand side parameter of the operator
037     * @return this+a
038     */
039    T add(double a);
040
041    /** '-' operator.
042     * @param a right hand side parameter of the operator
043     * @return this-a
044     */
045    T subtract(double a);
046
047    /** '&times;' operator.
048     * @param a right hand side parameter of the operator
049     * @return this&times;a
050     */
051    T multiply(double a);
052
053    /** '&divide;' operator.
054     * @param a right hand side parameter of the operator
055     * @return this&divide;a
056     */
057    T divide(double a);
058
059    /** IEEE remainder operator.
060     * @param a right hand side parameter of the operator
061     * @return this - n &times; a where n is the closest integer to this/a
062     * (the even integer is chosen for n if this/a is halfway between two integers)
063     */
064    T remainder(double a);
065
066    /** IEEE remainder operator.
067     * @param a right hand side parameter of the operator
068     * @return this - n &times; a where n is the closest integer to this/a
069     * (the even integer is chosen for n if this/a is halfway between two integers)
070     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
071     */
072    T remainder(T a)
073        throws DimensionMismatchException;
074
075    /** absolute value.
076     * @return abs(this)
077     */
078    T abs();
079
080    /** Get the smallest whole number larger than instance.
081     * @return ceil(this)
082     */
083    T ceil();
084
085    /** Get the largest whole number smaller than instance.
086     * @return floor(this)
087     */
088    T floor();
089
090    /** Get the whole number that is the nearest to the instance, or the even one if x is exactly
091     * half way between two integers.
092     * @return a double number r such that r is an integer r - 0.5 &le; this &le; r + 0.5
093     */
094    T rint();
095
096    /** Get the closest long to instance value.
097     * @return closest long to {@link #getReal()}
098     */
099    long round();
100
101    /** Compute the signum of the instance.
102     * The signum is -1 for negative numbers, +1 for positive numbers and 0 otherwise
103     * @return -1.0, -0.0, +0.0, +1.0 or NaN depending on sign of a
104     */
105    T signum();
106
107    /**
108     * Returns the instance with the sign of the argument.
109     * A NaN {@code sign} argument is treated as positive.
110     *
111     * @param sign the sign for the returned value
112     * @return the instance with the same sign as the {@code sign} argument
113     */
114    T copySign(T sign);
115
116    /**
117     * Returns the instance with the sign of the argument.
118     * A NaN {@code sign} argument is treated as positive.
119     *
120     * @param sign the sign for the returned value
121     * @return the instance with the same sign as the {@code sign} argument
122     */
123    T copySign(double sign);
124
125    /**
126     * Multiply the instance by a power of 2.
127     * @param n power of 2
128     * @return this &times; 2<sup>n</sup>
129     */
130    T scalb(int n);
131
132    /**
133     * Returns the hypotenuse of a triangle with sides {@code this} and {@code y}
134     * - sqrt(<i>this</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
135     * avoiding intermediate overflow or underflow.
136     *
137     * <ul>
138     * <li> If either argument is infinite, then the result is positive infinity.</li>
139     * <li> else, if either argument is NaN then the result is NaN.</li>
140     * </ul>
141     *
142     * @param y a value
143     * @return sqrt(<i>this</i><sup>2</sup>&nbsp;+<i>y</i><sup>2</sup>)
144     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
145     */
146    T hypot(T y)
147        throws DimensionMismatchException;
148
149    /** {@inheritDoc} */
150    @Override
151    T reciprocal();
152
153    /** Square root.
154     * @return square root of the instance
155     */
156    T sqrt();
157
158    /** Cubic root.
159     * @return cubic root of the instance
160     */
161    T cbrt();
162
163    /** N<sup>th</sup> root.
164     * @param n order of the root
165     * @return n<sup>th</sup> root of the instance
166     */
167    T rootN(int n);
168
169    /** Power operation.
170     * @param p power to apply
171     * @return this<sup>p</sup>
172     */
173    T pow(double p);
174
175    /** Integer power operation.
176     * @param n power to apply
177     * @return this<sup>n</sup>
178     */
179    T pow(int n);
180
181    /** Power operation.
182     * @param e exponent
183     * @return this<sup>e</sup>
184     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
185     */
186    T pow(T e)
187        throws DimensionMismatchException;
188
189    /** Exponential.
190     * @return exponential of the instance
191     */
192    T exp();
193
194    /** Exponential minus 1.
195     * @return exponential minus one of the instance
196     */
197    T expm1();
198
199    /** Natural logarithm.
200     * @return logarithm of the instance
201     */
202    T log();
203
204    /** Shifted natural logarithm.
205     * @return logarithm of one plus the instance
206     */
207    T log1p();
208
209    /** Base 10 logarithm.
210     * @return base 10 logarithm of the instance
211     * @since 4.0
212     */
213    T log10();
214
215    /** Cosine operation.
216     * @return cos(this)
217     */
218    T cos();
219
220    /** Sine operation.
221     * @return sin(this)
222     */
223    T sin();
224
225    /** Tangent operation.
226     * @return tan(this)
227     */
228    T tan();
229
230    /** Arc cosine operation.
231     * @return acos(this)
232     */
233    T acos();
234
235    /** Arc sine operation.
236     * @return asin(this)
237     */
238    T asin();
239
240    /** Arc tangent operation.
241     * @return atan(this)
242     */
243    T atan();
244
245    /** Two arguments arc tangent operation.
246     * @param x second argument of the arc tangent
247     * @return atan2(this, x)
248     * @exception DimensionMismatchException if number of free parameters or orders are inconsistent
249     */
250    T atan2(T x)
251        throws DimensionMismatchException;
252
253    /** Hyperbolic cosine operation.
254     * @return cosh(this)
255     */
256    T cosh();
257
258    /** Hyperbolic sine operation.
259     * @return sinh(this)
260     */
261    T sinh();
262
263    /** Hyperbolic tangent operation.
264     * @return tanh(this)
265     */
266    T tanh();
267
268    /** Inverse hyperbolic cosine operation.
269     * @return acosh(this)
270     */
271    T acosh();
272
273    /** Inverse hyperbolic sine operation.
274     * @return asin(this)
275     */
276    T asinh();
277
278    /** Inverse hyperbolic  tangent operation.
279     * @return atanh(this)
280     */
281    T atanh();
282
283    /**
284     * Compute a linear combination.
285     * @param a Factors.
286     * @param b Factors.
287     * @return <code>&Sigma;<sub>i</sub> a<sub>i</sub> b<sub>i</sub></code>.
288     * @throws DimensionMismatchException if arrays dimensions don't match
289     * @since 3.2
290     */
291    T linearCombination(T[] a, T[] b)
292        throws DimensionMismatchException;
293
294    /**
295     * Compute a linear combination.
296     * @param a Factors.
297     * @param b Factors.
298     * @return <code>&Sigma;<sub>i</sub> a<sub>i</sub> b<sub>i</sub></code>.
299     * @throws DimensionMismatchException if arrays dimensions don't match
300     * @since 3.2
301     */
302    T linearCombination(double[] a, T[] b)
303        throws DimensionMismatchException;
304
305    /**
306     * Compute a linear combination.
307     * @param a1 first factor of the first term
308     * @param b1 second factor of the first term
309     * @param a2 first factor of the second term
310     * @param b2 second factor of the second term
311     * @return a<sub>1</sub>&times;b<sub>1</sub> +
312     * a<sub>2</sub>&times;b<sub>2</sub>
313     * @see #linearCombination(Object, Object, Object, Object, Object, Object)
314     * @see #linearCombination(Object, Object, Object, Object, Object, Object, Object, Object)
315     * @since 3.2
316     */
317    T linearCombination(T a1, T b1, T a2, T b2);
318
319    /**
320     * Compute a linear combination.
321     * @param a1 first factor of the first term
322     * @param b1 second factor of the first term
323     * @param a2 first factor of the second term
324     * @param b2 second factor of the second term
325     * @return a<sub>1</sub>&times;b<sub>1</sub> +
326     * a<sub>2</sub>&times;b<sub>2</sub>
327     * @see #linearCombination(double, Object, double, Object, double, Object)
328     * @see #linearCombination(double, Object, double, Object, double, Object, double, Object)
329     * @since 3.2
330     */
331    T linearCombination(double a1, T b1, double a2, T b2);
332
333    /**
334     * Compute a linear combination.
335     * @param a1 first factor of the first term
336     * @param b1 second factor of the first term
337     * @param a2 first factor of the second term
338     * @param b2 second factor of the second term
339     * @param a3 first factor of the third term
340     * @param b3 second factor of the third term
341     * @return a<sub>1</sub>&times;b<sub>1</sub> +
342     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
343     * @see #linearCombination(Object, Object, Object, Object)
344     * @see #linearCombination(Object, Object, Object, Object, Object, Object, Object, Object)
345     * @since 3.2
346     */
347    T linearCombination(T a1, T b1, T a2, T b2, T a3, T b3);
348
349    /**
350     * Compute a linear combination.
351     * @param a1 first factor of the first term
352     * @param b1 second factor of the first term
353     * @param a2 first factor of the second term
354     * @param b2 second factor of the second term
355     * @param a3 first factor of the third term
356     * @param b3 second factor of the third term
357     * @return a<sub>1</sub>&times;b<sub>1</sub> +
358     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
359     * @see #linearCombination(double, Object, double, Object)
360     * @see #linearCombination(double, Object, double, Object, double, Object, double, Object)
361     * @since 3.2
362     */
363    T linearCombination(double a1, T b1,  double a2, T b2, double a3, T b3);
364
365    /**
366     * Compute a linear combination.
367     * @param a1 first factor of the first term
368     * @param b1 second factor of the first term
369     * @param a2 first factor of the second term
370     * @param b2 second factor of the second term
371     * @param a3 first factor of the third term
372     * @param b3 second factor of the third term
373     * @param a4 first factor of the third term
374     * @param b4 second factor of the third term
375     * @return a<sub>1</sub>&times;b<sub>1</sub> +
376     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
377     * a<sub>4</sub>&times;b<sub>4</sub>
378     * @see #linearCombination(Object, Object, Object, Object)
379     * @see #linearCombination(Object, Object, Object, Object, Object, Object)
380     * @since 3.2
381     */
382    T linearCombination(T a1, T b1, T a2, T b2, T a3, T b3, T a4, T b4);
383
384    /**
385     * Compute a linear combination.
386     * @param a1 first factor of the first term
387     * @param b1 second factor of the first term
388     * @param a2 first factor of the second term
389     * @param b2 second factor of the second term
390     * @param a3 first factor of the third term
391     * @param b3 second factor of the third term
392     * @param a4 first factor of the third term
393     * @param b4 second factor of the third term
394     * @return a<sub>1</sub>&times;b<sub>1</sub> +
395     * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
396     * a<sub>4</sub>&times;b<sub>4</sub>
397     * @see #linearCombination(double, Object, double, Object)
398     * @see #linearCombination(double, Object, double, Object, double, Object)
399     * @since 3.2
400     */
401    T linearCombination(double a1, T b1, double a2, T b2, double a3, T b3, double a4, T b4);
402
403    /** Find the maximum of two field elements.
404     * @param <T> the type of the field elements
405     * @param e1 first element
406     * @param e2 second element
407     * @return max(a1, e2)
408     */
409    static <T extends RealFieldElement<T>> T max(final T e1, final T e2) {
410        return e1.subtract(e2).getReal() >= 0 ? e1 : e2;
411    }
412
413    /** Find the minimum of two field elements.
414     * @param <T> the type of the field elements
415     * @param e1 first element
416     * @param e2 second element
417     * @return min(a1, e2)
418     */
419    static <T extends RealFieldElement<T>> T min(final T e1, final T e2) {
420        return e1.subtract(e2).getReal() >= 0 ? e2 : e1;
421    }
422}