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 }