1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.commons.math.analysis; 19 20 import org.apache.commons.math.FunctionEvaluationException; 21 import org.apache.commons.math.util.FastMath; 22 23 24 /** 25 * Base class for {@link UnivariateRealFunction} that can be composed with other functions. 26 * 27 * @since 2.1 28 * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $ 29 */ 30 public abstract class ComposableFunction implements UnivariateRealFunction { 31 32 /** The constant function always returning 0. */ 33 public static final ComposableFunction ZERO = new ComposableFunction() { 34 /** {@inheritDoc} */ 35 @Override 36 public double value(double d) { 37 return 0; 38 } 39 }; 40 41 /** The constant function always returning 1. */ 42 public static final ComposableFunction ONE = new ComposableFunction() { 43 /** {@inheritDoc} */ 44 @Override 45 public double value(double d) { 46 return 1; 47 } 48 }; 49 50 /** The identity function. */ 51 public static final ComposableFunction IDENTITY = new ComposableFunction() { 52 /** {@inheritDoc} */ 53 @Override 54 public double value(double d) { 55 return d; 56 } 57 }; 58 59 /** The {@code FastMath.abs} method wrapped as a {@link ComposableFunction}. */ 60 public static final ComposableFunction ABS = new ComposableFunction() { 61 /** {@inheritDoc} */ 62 @Override 63 public double value(double d) { 64 return FastMath.abs(d); 65 } 66 }; 67 68 /** The - operator wrapped as a {@link ComposableFunction}. */ 69 public static final ComposableFunction NEGATE = new ComposableFunction() { 70 /** {@inheritDoc} */ 71 @Override 72 public double value(double d) { 73 return -d; 74 } 75 }; 76 77 /** The invert operator wrapped as a {@link ComposableFunction}. */ 78 public static final ComposableFunction INVERT = new ComposableFunction () { 79 /** {@inheritDoc} */ 80 @Override 81 public double value(double d){ 82 return 1/d; 83 } 84 }; 85 86 /** The {@code FastMath.sin} method wrapped as a {@link ComposableFunction}. */ 87 public static final ComposableFunction SIN = new ComposableFunction() { 88 /** {@inheritDoc} */ 89 @Override 90 public double value(double d) { 91 return FastMath.sin(d); 92 } 93 }; 94 95 /** The {@code FastMath.sqrt} method wrapped as a {@link ComposableFunction}. */ 96 public static final ComposableFunction SQRT = new ComposableFunction() { 97 /** {@inheritDoc} */ 98 @Override 99 public double value(double d) { 100 return FastMath.sqrt(d); 101 } 102 }; 103 104 /** The {@code FastMath.sinh} method wrapped as a {@link ComposableFunction}. */ 105 public static final ComposableFunction SINH = new ComposableFunction() { 106 /** {@inheritDoc} */ 107 @Override 108 public double value(double d) { 109 return FastMath.sinh(d); 110 } 111 }; 112 113 /** The {@code FastMath.exp} method wrapped as a {@link ComposableFunction}. */ 114 public static final ComposableFunction EXP = new ComposableFunction() { 115 /** {@inheritDoc} */ 116 @Override 117 public double value(double d) { 118 return FastMath.exp(d); 119 } 120 }; 121 122 /** The {@code FastMath.expm1} method wrapped as a {@link ComposableFunction}. */ 123 public static final ComposableFunction EXPM1 = new ComposableFunction() { 124 /** {@inheritDoc} */ 125 @Override 126 public double value(double d) { 127 return FastMath.expm1(d); 128 } 129 }; 130 131 /** The {@code FastMath.asin} method wrapped as a {@link ComposableFunction}. */ 132 public static final ComposableFunction ASIN = new ComposableFunction() { 133 /** {@inheritDoc} */ 134 @Override 135 public double value(double d) { 136 return FastMath.asin(d); 137 } 138 }; 139 140 /** The {@code FastMath.atan} method wrapped as a {@link ComposableFunction}. */ 141 public static final ComposableFunction ATAN = new ComposableFunction() { 142 /** {@inheritDoc} */ 143 @Override 144 public double value(double d) { 145 return FastMath.atan(d); 146 } 147 }; 148 149 /** The {@code FastMath.tan} method wrapped as a {@link ComposableFunction}. */ 150 public static final ComposableFunction TAN = new ComposableFunction() { 151 /** {@inheritDoc} */ 152 @Override 153 public double value(double d) { 154 return FastMath.tan(d); 155 } 156 }; 157 158 /** The {@code FastMath.tanh} method wrapped as a {@link ComposableFunction}. */ 159 public static final ComposableFunction TANH = new ComposableFunction() { 160 /** {@inheritDoc} */ 161 @Override 162 public double value(double d) { 163 return FastMath.tanh(d); 164 } 165 }; 166 167 /** The {@code FastMath.cbrt} method wrapped as a {@link ComposableFunction}. */ 168 public static final ComposableFunction CBRT = new ComposableFunction() { 169 /** {@inheritDoc} */ 170 @Override 171 public double value(double d) { 172 return FastMath.cbrt(d); 173 } 174 }; 175 176 /** The {@code FastMath.ceil} method wrapped as a {@link ComposableFunction}. */ 177 public static final ComposableFunction CEIL = new ComposableFunction() { 178 /** {@inheritDoc} */ 179 @Override 180 public double value(double d) { 181 return FastMath.ceil(d); 182 } 183 }; 184 185 /** The {@code FastMath.floor} method wrapped as a {@link ComposableFunction}. */ 186 public static final ComposableFunction FLOOR = new ComposableFunction() { 187 /** {@inheritDoc} */ 188 @Override 189 public double value(double d) { 190 return FastMath.floor(d); 191 } 192 }; 193 194 /** The {@code FastMath.log} method wrapped as a {@link ComposableFunction}. */ 195 public static final ComposableFunction LOG = new ComposableFunction() { 196 /** {@inheritDoc} */ 197 @Override 198 public double value(double d) { 199 return FastMath.log(d); 200 } 201 }; 202 203 /** The {@code FastMath.log10} method wrapped as a {@link ComposableFunction}. */ 204 public static final ComposableFunction LOG10 = new ComposableFunction() { 205 /** {@inheritDoc} */ 206 @Override 207 public double value(double d) { 208 return FastMath.log10(d); 209 } 210 }; 211 212 /** The {@code FastMath.log1p} method wrapped as a {@link ComposableFunction}. */ 213 public static final ComposableFunction LOG1P = new ComposableFunction () { 214 @Override 215 public double value(double d){ 216 return FastMath.log1p(d); 217 } 218 }; 219 220 /** The {@code FastMath.cos} method wrapped as a {@link ComposableFunction}. */ 221 public static final ComposableFunction COS = new ComposableFunction() { 222 /** {@inheritDoc} */ 223 @Override 224 public double value(double d) { 225 return FastMath.cos(d); 226 } 227 }; 228 229 /** The {@code FastMath.abs} method wrapped as a {@link ComposableFunction}. */ 230 public static final ComposableFunction ACOS = new ComposableFunction() { 231 /** {@inheritDoc} */ 232 @Override 233 public double value(double d) { 234 return FastMath.acos(d); 235 } 236 }; 237 238 /** The {@code FastMath.cosh} method wrapped as a {@link ComposableFunction}. */ 239 public static final ComposableFunction COSH = new ComposableFunction() { 240 /** {@inheritDoc} */ 241 @Override 242 public double value(double d) { 243 return FastMath.cosh(d); 244 } 245 }; 246 247 /** The {@code FastMath.rint} method wrapped as a {@link ComposableFunction}. */ 248 public static final ComposableFunction RINT = new ComposableFunction() { 249 /** {@inheritDoc} */ 250 @Override 251 public double value(double d) { 252 return FastMath.rint(d); 253 } 254 }; 255 256 /** The {@code FastMath.signum} method wrapped as a {@link ComposableFunction}. */ 257 public static final ComposableFunction SIGNUM = new ComposableFunction() { 258 /** {@inheritDoc} */ 259 @Override 260 public double value(double d) { 261 return FastMath.signum(d); 262 } 263 }; 264 265 /** The {@code FastMath.ulp} method wrapped as a {@link ComposableFunction}. */ 266 public static final ComposableFunction ULP = new ComposableFunction() { 267 /** {@inheritDoc} */ 268 @Override 269 public double value(double d) { 270 return FastMath.ulp(d); 271 } 272 }; 273 274 /** Precompose the instance with another function. 275 * <p> 276 * The composed function h created by {@code h = g.of(f)} is such 277 * that {@code h.value(x) == g.value(f.value(x))} for all x. 278 * </p> 279 * @param f function to compose with 280 * @return a new function which computes {@code this.value(f.value(x))} 281 * @see #postCompose(UnivariateRealFunction) 282 */ of(final UnivariateRealFunction f)283 public ComposableFunction of(final UnivariateRealFunction f) { 284 return new ComposableFunction() { 285 @Override 286 /** {@inheritDoc} */ 287 public double value(double x) throws FunctionEvaluationException { 288 return ComposableFunction.this.value(f.value(x)); 289 } 290 }; 291 } 292 293 /** Postcompose the instance with another function. 294 * <p> 295 * The composed function h created by {@code h = g.postCompose(f)} is such 296 * that {@code h.value(x) == f.value(g.value(x))} for all x. 297 * </p> 298 * @param f function to compose with 299 * @return a new function which computes {@code f.value(this.value(x))} 300 * @see #of(UnivariateRealFunction) 301 */ 302 public ComposableFunction postCompose(final UnivariateRealFunction f) { 303 return new ComposableFunction() { 304 @Override 305 /** {@inheritDoc} */ 306 public double value(double x) throws FunctionEvaluationException { 307 return f.value(ComposableFunction.this.value(x)); 308 } 309 }; 310 } 311 312 /** 313 * Return a function combining the instance and another function. 314 * <p> 315 * The function h created by {@code h = g.combine(f, combiner)} is such that 316 * {@code h.value(x) == combiner.value(g.value(x), f.value(x))} for all x. 317 * </p> 318 * @param f function to combine with the instance 319 * @param combiner bivariate function used for combining 320 * @return a new function which computes {@code combine.value(this.value(x), f.value(x))} 321 */ 322 public ComposableFunction combine(final UnivariateRealFunction f, 323 final BivariateRealFunction combiner) { 324 return new ComposableFunction() { 325 @Override 326 /** {@inheritDoc} */ 327 public double value(double x) throws FunctionEvaluationException { 328 return combiner.value(ComposableFunction.this.value(x), f.value(x)); 329 } 330 }; 331 } 332 333 /** 334 * Return a function adding the instance and another function. 335 * @param f function to combine with the instance 336 * @return a new function which computes {@code this.value(x) + f.value(x)} 337 */ 338 public ComposableFunction add(final UnivariateRealFunction f) { 339 return new ComposableFunction() { 340 @Override 341 /** {@inheritDoc} */ 342 public double value(double x) throws FunctionEvaluationException { 343 return ComposableFunction.this.value(x) + f.value(x); 344 } 345 }; 346 } 347 348 /** 349 * Return a function adding a constant term to the instance. 350 * @param a term to add 351 * @return a new function which computes {@code this.value(x) + a} 352 */ 353 public ComposableFunction add(final double a) { 354 return new ComposableFunction() { 355 @Override 356 /** {@inheritDoc} */ 357 public double value(double x) throws FunctionEvaluationException { 358 return ComposableFunction.this.value(x) + a; 359 } 360 }; 361 } 362 363 /** 364 * Return a function subtracting another function from the instance. 365 * @param f function to combine with the instance 366 * @return a new function which computes {@code this.value(x) - f.value(x)} 367 */ 368 public ComposableFunction subtract(final UnivariateRealFunction f) { 369 return new ComposableFunction() { 370 @Override 371 /** {@inheritDoc} */ 372 public double value(double x) throws FunctionEvaluationException { 373 return ComposableFunction.this.value(x) - f.value(x); 374 } 375 }; 376 } 377 378 /** 379 * Return a function multiplying the instance and another function. 380 * @param f function to combine with the instance 381 * @return a new function which computes {@code this.value(x) * f.value(x)} 382 */ 383 public ComposableFunction multiply(final UnivariateRealFunction f) { 384 return new ComposableFunction() { 385 @Override 386 /** {@inheritDoc} */ 387 public double value(double x) throws FunctionEvaluationException { 388 return ComposableFunction.this.value(x) * f.value(x); 389 } 390 }; 391 } 392 393 /** 394 * Return a function scaling the instance by a constant factor. 395 * @param scaleFactor constant scaling factor 396 * @return a new function which computes {@code this.value(x) * scaleFactor} 397 */ 398 public ComposableFunction multiply(final double scaleFactor) { 399 return new ComposableFunction() { 400 @Override 401 /** {@inheritDoc} */ 402 public double value(double x) throws FunctionEvaluationException { 403 return ComposableFunction.this.value(x) * scaleFactor; 404 } 405 }; 406 } 407 /** 408 * Return a function dividing the instance by another function. 409 * @param f function to combine with the instance 410 * @return a new function which computes {@code this.value(x) / f.value(x)} 411 */ 412 public ComposableFunction divide(final UnivariateRealFunction f) { 413 return new ComposableFunction() { 414 @Override 415 /** {@inheritDoc} */ 416 public double value(double x) throws FunctionEvaluationException { 417 return ComposableFunction.this.value(x) / f.value(x); 418 } 419 }; 420 } 421 422 /** 423 * Generates a function that iteratively apply instance function on all 424 * elements of an array. 425 * <p> 426 * The generated function behaves as follows: 427 * <ul> 428 * <li>initialize result = initialValue</li> 429 * <li>iterate: {@code result = combiner.value(result, 430 * this.value(nextMultivariateEntry));}</li> 431 * <li>return result</li> 432 * </ul> 433 * </p> 434 * @param combiner combiner to use between entries 435 * @param initialValue initial value to use before first entry 436 * @return a new function that iteratively apply instance function on all 437 * elements of an array. 438 */ 439 public MultivariateRealFunction asCollector(final BivariateRealFunction combiner, 440 final double initialValue) { 441 return new MultivariateRealFunction() { 442 /** {@inheritDoc} */ 443 public double value(double[] point) 444 throws FunctionEvaluationException, IllegalArgumentException { 445 double result = initialValue; 446 for (final double entry : point) { 447 result = combiner.value(result, ComposableFunction.this.value(entry)); 448 } 449 return result; 450 } 451 }; 452 } 453 454 /** 455 * Generates a function that iteratively apply instance function on all 456 * elements of an array. 457 * <p> 458 * Calling this method is equivalent to call {@link 459 * #asCollector(BivariateRealFunction, double) asCollector(BivariateRealFunction, 0.0)}. 460 * </p> 461 * @param combiner combiner to use between entries 462 * @return a new function that iteratively apply instance function on all 463 * elements of an array. 464 * @see #asCollector(BivariateRealFunction, double) 465 */ 466 public MultivariateRealFunction asCollector(final BivariateRealFunction combiner) { 467 return asCollector(combiner, 0.0); 468 } 469 470 /** 471 * Generates a function that iteratively apply instance function on all 472 * elements of an array. 473 * <p> 474 * Calling this method is equivalent to call {@link 475 * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, initialValue)}. 476 * </p> 477 * @param initialValue initial value to use before first entry 478 * @return a new function that iteratively apply instance function on all 479 * elements of an array. 480 * @see #asCollector(BivariateRealFunction, double) 481 * @see BinaryFunction#ADD 482 */ 483 public MultivariateRealFunction asCollector(final double initialValue) { 484 return asCollector(BinaryFunction.ADD, initialValue); 485 } 486 487 /** 488 * Generates a function that iteratively apply instance function on all 489 * elements of an array. 490 * <p> 491 * Calling this method is equivalent to call {@link 492 * #asCollector(BivariateRealFunction, double) asCollector(BinaryFunction.ADD, 0.0)}. 493 * </p> 494 * @return a new function that iteratively apply instance function on all 495 * elements of an array. 496 * @see #asCollector(BivariateRealFunction, double) 497 * @see BinaryFunction#ADD 498 */ 499 public MultivariateRealFunction asCollector() { 500 return asCollector(BinaryFunction.ADD, 0.0); 501 } 502 503 /** {@inheritDoc} */ 504 public abstract double value(double x) throws FunctionEvaluationException; 505 506 } 507