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 */
017
018 package org.apache.commons.math.analysis;
019
020 import org.apache.commons.math.FunctionEvaluationException;
021
022
023 /**
024 * Base class for {@link UnivariateRealFunction} that can be composed with other functions.
025 *
026 * @since 2.1
027 * @version $Revision: 924453 $ $Date: 2010-03-17 16:05:20 -0400 (Wed, 17 Mar 2010) $
028 */
029 public abstract class ComposableFunction implements UnivariateRealFunction {
030
031 /** The constant function always returning 0. */
032 public static final ComposableFunction ZERO = new ComposableFunction() {
033 /** {@inheritDoc} */
034 @Override
035 public double value(double d) {
036 return 0;
037 }
038 };
039
040 /** The constant function always returning 1. */
041 public static final ComposableFunction ONE = new ComposableFunction() {
042 /** {@inheritDoc} */
043 @Override
044 public double value(double d) {
045 return 1;
046 }
047 };
048
049 /** The identity function. */
050 public static final ComposableFunction IDENTITY = new ComposableFunction() {
051 /** {@inheritDoc} */
052 @Override
053 public double value(double d) {
054 return d;
055 }
056 };
057
058 /** The {@code Math.abs} method wrapped as a {@link ComposableFunction}. */
059 public static final ComposableFunction ABS = new ComposableFunction() {
060 /** {@inheritDoc} */
061 @Override
062 public double value(double d) {
063 return Math.abs(d);
064 }
065 };
066
067 /** The - operator wrapped as a {@link ComposableFunction}. */
068 public static final ComposableFunction NEGATE = new ComposableFunction() {
069 /** {@inheritDoc} */
070 @Override
071 public double value(double d) {
072 return -d;
073 }
074 };
075
076 /** The invert operator wrapped as a {@link ComposableFunction}. */
077 public static final ComposableFunction INVERT = new ComposableFunction () {
078 /** {@inheritDoc} */
079 @Override
080 public double value(double d){
081 return 1/d;
082 }
083 };
084
085 /** The {@code Math.sin} method wrapped as a {@link ComposableFunction}. */
086 public static final ComposableFunction SIN = new ComposableFunction() {
087 /** {@inheritDoc} */
088 @Override
089 public double value(double d) {
090 return Math.sin(d);
091 }
092 };
093
094 /** The {@code Math.sqrt} method wrapped as a {@link ComposableFunction}. */
095 public static final ComposableFunction SQRT = new ComposableFunction() {
096 /** {@inheritDoc} */
097 @Override
098 public double value(double d) {
099 return Math.sqrt(d);
100 }
101 };
102
103 /** The {@code Math.sinh} method wrapped as a {@link ComposableFunction}. */
104 public static final ComposableFunction SINH = new ComposableFunction() {
105 /** {@inheritDoc} */
106 @Override
107 public double value(double d) {
108 return Math.sinh(d);
109 }
110 };
111
112 /** The {@code Math.exp} method wrapped as a {@link ComposableFunction}. */
113 public static final ComposableFunction EXP = new ComposableFunction() {
114 /** {@inheritDoc} */
115 @Override
116 public double value(double d) {
117 return Math.exp(d);
118 }
119 };
120
121 /** The {@code Math.expm1} method wrapped as a {@link ComposableFunction}. */
122 public static final ComposableFunction EXPM1 = new ComposableFunction() {
123 /** {@inheritDoc} */
124 @Override
125 public double value(double d) {
126 return Math.expm1(d);
127 }
128 };
129
130 /** The {@code Math.asin} method wrapped as a {@link ComposableFunction}. */
131 public static final ComposableFunction ASIN = new ComposableFunction() {
132 /** {@inheritDoc} */
133 @Override
134 public double value(double d) {
135 return Math.asin(d);
136 }
137 };
138
139 /** The {@code Math.atan} method wrapped as a {@link ComposableFunction}. */
140 public static final ComposableFunction ATAN = new ComposableFunction() {
141 /** {@inheritDoc} */
142 @Override
143 public double value(double d) {
144 return Math.atan(d);
145 }
146 };
147
148 /** The {@code Math.tan} method wrapped as a {@link ComposableFunction}. */
149 public static final ComposableFunction TAN = new ComposableFunction() {
150 /** {@inheritDoc} */
151 @Override
152 public double value(double d) {
153 return Math.tan(d);
154 }
155 };
156
157 /** The {@code Math.tanh} method wrapped as a {@link ComposableFunction}. */
158 public static final ComposableFunction TANH = new ComposableFunction() {
159 /** {@inheritDoc} */
160 @Override
161 public double value(double d) {
162 return Math.tanh(d);
163 }
164 };
165
166 /** The {@code Math.cbrt} method wrapped as a {@link ComposableFunction}. */
167 public static final ComposableFunction CBRT = new ComposableFunction() {
168 /** {@inheritDoc} */
169 @Override
170 public double value(double d) {
171 return Math.cbrt(d);
172 }
173 };
174
175 /** The {@code Math.ceil} method wrapped as a {@link ComposableFunction}. */
176 public static final ComposableFunction CEIL = new ComposableFunction() {
177 /** {@inheritDoc} */
178 @Override
179 public double value(double d) {
180 return Math.ceil(d);
181 }
182 };
183
184 /** The {@code Math.floor} method wrapped as a {@link ComposableFunction}. */
185 public static final ComposableFunction FLOOR = new ComposableFunction() {
186 /** {@inheritDoc} */
187 @Override
188 public double value(double d) {
189 return Math.floor(d);
190 }
191 };
192
193 /** The {@code Math.log} method wrapped as a {@link ComposableFunction}. */
194 public static final ComposableFunction LOG = new ComposableFunction() {
195 /** {@inheritDoc} */
196 @Override
197 public double value(double d) {
198 return Math.log(d);
199 }
200 };
201
202 /** The {@code Math.log10} method wrapped as a {@link ComposableFunction}. */
203 public static final ComposableFunction LOG10 = new ComposableFunction() {
204 /** {@inheritDoc} */
205 @Override
206 public double value(double d) {
207 return Math.log10(d);
208 }
209 };
210
211 /** The {@code Math.log1p} method wrapped as a {@link ComposableFunction}. */
212 public static final ComposableFunction LOG1P = new ComposableFunction () {
213 @Override
214 public double value(double d){
215 return Math.log1p(d);
216 }
217 };
218
219 /** The {@code Math.cos} method wrapped as a {@link ComposableFunction}. */
220 public static final ComposableFunction COS = new ComposableFunction() {
221 /** {@inheritDoc} */
222 @Override
223 public double value(double d) {
224 return Math.cos(d);
225 }
226 };
227
228 /** The {@code Math.abs} method wrapped as a {@link ComposableFunction}. */
229 public static final ComposableFunction ACOS = new ComposableFunction() {
230 /** {@inheritDoc} */
231 @Override
232 public double value(double d) {
233 return Math.acos(d);
234 }
235 };
236
237 /** The {@code Math.cosh} method wrapped as a {@link ComposableFunction}. */
238 public static final ComposableFunction COSH = new ComposableFunction() {
239 /** {@inheritDoc} */
240 @Override
241 public double value(double d) {
242 return Math.cosh(d);
243 }
244 };
245
246 /** The {@code Math.rint} method wrapped as a {@link ComposableFunction}. */
247 public static final ComposableFunction RINT = new ComposableFunction() {
248 /** {@inheritDoc} */
249 @Override
250 public double value(double d) {
251 return Math.rint(d);
252 }
253 };
254
255 /** The {@code Math.signum} method wrapped as a {@link ComposableFunction}. */
256 public static final ComposableFunction SIGNUM = new ComposableFunction() {
257 /** {@inheritDoc} */
258 @Override
259 public double value(double d) {
260 return Math.signum(d);
261 }
262 };
263
264 /** The {@code Math.ulp} method wrapped as a {@link ComposableFunction}. */
265 public static final ComposableFunction ULP = new ComposableFunction() {
266 /** {@inheritDoc} */
267 @Override
268 public double value(double d) {
269 return Math.ulp(d);
270 }
271 };
272
273 /** Precompose the instance with another function.
274 * <p>
275 * The composed function h created by {@code h = g.of(f)} is such
276 * that {@code h.value(x) == g.value(f.value(x))} for all x.
277 * </p>
278 * @param f function to compose with
279 * @return a new function which computes {@code this.value(f.value(x))}
280 * @see #postCompose(UnivariateRealFunction)
281 */
282 public ComposableFunction of(final UnivariateRealFunction f) {
283 return new ComposableFunction() {
284 @Override
285 /** {@inheritDoc} */
286 public double value(double x) throws FunctionEvaluationException {
287 return ComposableFunction.this.value(f.value(x));
288 }
289 };
290 }
291
292 /** Postcompose the instance with another function.
293 * <p>
294 * The composed function h created by {@code h = g.postCompose(f)} is such
295 * that {@code h.value(x) == f.value(g.value(x))} for all x.
296 * </p>
297 * @param f function to compose with
298 * @return a new function which computes {@code f.value(this.value(x))}
299 * @see #of(UnivariateRealFunction)
300 */
301 public ComposableFunction postCompose(final UnivariateRealFunction f) {
302 return new ComposableFunction() {
303 @Override
304 /** {@inheritDoc} */
305 public double value(double x) throws FunctionEvaluationException {
306 return f.value(ComposableFunction.this.value(x));
307 }
308 };
309 }
310
311 /**
312 * Return a function combining the instance and another function.
313 * <p>
314 * The function h created by {@code h = g.combine(f, combiner)} is such that
315 * {@code h.value(x) == combiner.value(g.value(x), f.value(x))} for all x.
316 * </p>
317 * @param f function to combine with the instance
318 * @param combiner bivariate function used for combining
319 * @return a new function which computes {@code combine.value(this.value(x), f.value(x))}
320 */
321 public ComposableFunction combine(final UnivariateRealFunction f,
322 final BivariateRealFunction combiner) {
323 return new ComposableFunction() {
324 @Override
325 /** {@inheritDoc} */
326 public double value(double x) throws FunctionEvaluationException {
327 return combiner.value(ComposableFunction.this.value(x), f.value(x));
328 }
329 };
330 }
331
332 /**
333 * Return a function adding the instance and another function.
334 * @param f function to combine with the instance
335 * @return a new function which computes {@code this.value(x) + f.value(x)}
336 */
337 public ComposableFunction add(final UnivariateRealFunction f) {
338 return new ComposableFunction() {
339 @Override
340 /** {@inheritDoc} */
341 public double value(double x) throws FunctionEvaluationException {
342 return ComposableFunction.this.value(x) + f.value(x);
343 }
344 };
345 }
346
347 /**
348 * Return a function adding a constant term to the instance.
349 * @param a term to add
350 * @return a new function which computes {@code this.value(x) + a}
351 */
352 public ComposableFunction add(final double a) {
353 return new ComposableFunction() {
354 @Override
355 /** {@inheritDoc} */
356 public double value(double x) throws FunctionEvaluationException {
357 return ComposableFunction.this.value(x) + a;
358 }
359 };
360 }
361
362 /**
363 * Return a function subtracting another function from the instance.
364 * @param f function to combine with the instance
365 * @return a new function which computes {@code this.value(x) - f.value(x)}
366 */
367 public ComposableFunction subtract(final UnivariateRealFunction f) {
368 return new ComposableFunction() {
369 @Override
370 /** {@inheritDoc} */
371 public double value(double x) throws FunctionEvaluationException {
372 return ComposableFunction.this.value(x) - f.value(x);
373 }
374 };
375 }
376
377 /**
378 * Return a function multiplying the instance and another function.
379 * @param f function to combine with the instance
380 * @return a new function which computes {@code this.value(x) * f.value(x)}
381 */
382 public ComposableFunction multiply(final UnivariateRealFunction f) {
383 return new ComposableFunction() {
384 @Override
385 /** {@inheritDoc} */
386 public double value(double x) throws FunctionEvaluationException {
387 return ComposableFunction.this.value(x) * f.value(x);
388 }
389 };
390 }
391
392 /**
393 * Return a function scaling the instance by a constant factor.
394 * @param scaleFactor constant scaling factor
395 * @return a new function which computes {@code this.value(x) * scaleFactor}
396 */
397 public ComposableFunction multiply(final double scaleFactor) {
398 return new ComposableFunction() {
399 @Override
400 /** {@inheritDoc} */
401 public double value(double x) throws FunctionEvaluationException {
402 return ComposableFunction.this.value(x) * scaleFactor;
403 }
404 };
405 }
406 /**
407 * Return a function dividing the instance by another function.
408 * @param f function to combine with the instance
409 * @return a new function which computes {@code this.value(x) / f.value(x)}
410 */
411 public ComposableFunction divide(final UnivariateRealFunction f) {
412 return new ComposableFunction() {
413 @Override
414 /** {@inheritDoc} */
415 public double value(double x) throws FunctionEvaluationException {
416 return ComposableFunction.this.value(x) / f.value(x);
417 }
418 };
419 }
420
421 /**
422 * Generates a function that iteratively apply instance function on all
423 * elements of an array.
424 * <p>
425 * The generated function behaves as follows:
426 * <ul>
427 * <li>initialize result = initialValue</li>
428 * <li>iterate: {@code result = combiner.value(result,
429 * this.value(nextMultivariateEntry));}</li>
430 * <li>return result</li>
431 * </ul>
432 * </p>
433 * @param combiner combiner to use between entries
434 * @param initialValue initial value to use before first entry
435 * @return a new function that iteratively applie instance function on all
436 * elements of an array.
437 */
438 public MultivariateRealFunction asCollector(final BivariateRealFunction combiner,
439 final double initialValue) {
440 return new MultivariateRealFunction() {
441 /** {@inheritDoc} */
442 public double value(double[] point)
443 throws FunctionEvaluationException, IllegalArgumentException {
444 double result = initialValue;
445 for (final double entry : point) {
446 result = combiner.value(result, ComposableFunction.this.value(entry));
447 }
448 return result;
449 }
450 };
451 }
452
453 /**
454 * Generates a function that iteratively apply instance function on all
455 * elements of an array.
456 * <p>
457 * Calling this method is equivalent to call {@link
458 * #asCollector(BivariateRealFunction, double) asCollector(BivariateRealFunction, 0.0)}.
459 * </p>
460 * @param combiner combiner to use between entries
461 * @return a new function that iteratively applie instance function on all
462 * elements of an array.
463 * @see #asCollector(BivariateRealFunction, double)
464 */
465 public MultivariateRealFunction asCollector(final BivariateRealFunction combiner) {
466 return asCollector(combiner, 0.0);
467 }
468
469 /**
470 * Generates a function that iteratively apply instance function on all
471 * elements of an array.
472 * <p>
473 * Calling this method is equivalent to call {@link
474 * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, initialValue)}.
475 * </p>
476 * @param initialValue initial value to use before first entry
477 * @return a new function that iteratively applie instance function on all
478 * elements of an array.
479 * @see #asCollector(BivariateRealFunction, double)
480 * @see BinaryFunction#ADD
481 */
482 public MultivariateRealFunction asCollector(final double initialValue) {
483 return asCollector(BinaryFunction.ADD, initialValue);
484 }
485
486 /**
487 * Generates a function that iteratively apply instance function on all
488 * elements of an array.
489 * <p>
490 * Calling this method is equivalent to call {@link
491 * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, 0.0)}.
492 * </p>
493 * @return a new function that iteratively applie instance function on all
494 * elements of an array.
495 * @see #asCollector(BivariateRealFunction, double)
496 * @see BinaryFunction#ADD
497 */
498 public MultivariateRealFunction asCollector() {
499 return asCollector(BinaryFunction.ADD, 0.0);
500 }
501
502 /** {@inheritDoc} */
503 public abstract double value(double x) throws FunctionEvaluationException;
504
505 }