Author: luc
Date: Sat Dec 12 23:15:32 2009
New Revision: 890002

URL: http://svn.apache.org/viewvc?rev=890002&view=rev
Log:
added composition features for real functions
JIRA: MATH-313

Added:
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BinaryFunction.java
   (with props)
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BivariateRealFunction.java
   (with props)
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/ComposableFunction.java
      - copied, changed from r889944, 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/UnivariateRealFunctions.java
    
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/BinaryFunctionTest.java
   (with props)
    
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/ComposableFunctionTest.java
   (with props)
Removed:
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/UnivariateRealFunctions.java
Modified:
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml

Added: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BinaryFunction.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BinaryFunction.java?rev=890002&view=auto
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BinaryFunction.java
 (added)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BinaryFunction.java
 Sat Dec 12 23:15:32 2009
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+
+
+/**
+ * Base class for {...@link BivariateRealFunction} that can be composed with 
other functions.
+ *
+ * @version $Revision$ $Date$
+ */
+public abstract class BinaryFunction implements BivariateRealFunction {
+
+    /** The + operator method wrapped as a {...@link BinaryFunction}. */
+    public static final BinaryFunction ADD = new BinaryFunction() {
+        /** {...@inheritdoc} */
+        public double value(double x, double y) {
+            return x + y;
+        }
+    };
+
+    /** The - operator method wrapped as a {...@link BinaryFunction}. */
+    public static final BinaryFunction SUBTRACT = new BinaryFunction() {
+        /** {...@inheritdoc} */
+        public double value(double x, double y) {
+            return x - y;
+        }
+    };
+
+    /** The * operator method wrapped as a {...@link BinaryFunction}. */
+    public static final BinaryFunction MULTIPLY = new BinaryFunction() {
+        /** {...@inheritdoc} */
+        public double value(double x, double y) {
+            return x * y;
+        }
+    };
+
+    /** The / operator method wrapped as a {...@link BinaryFunction}. */
+    public static final BinaryFunction DIVIDE = new BinaryFunction() {
+        /** {...@inheritdoc} */
+        public double value(double x, double y) {
+            return x / y;
+        }
+    };
+
+    /** The {...@code Math.pow} method wrapped as a {...@link BinaryFunction}. 
*/
+    public static final BinaryFunction POW = new BinaryFunction() {
+        /** {...@inheritdoc} */
+        public double value(double x, double y) {
+            return Math.pow(x, y);
+        }
+    };
+
+    /** The {...@code Math.atan2} method wrapped as a {...@link 
BinaryFunction}. */
+    public static final BinaryFunction ATAN2 = new BinaryFunction() {
+        /** {...@inheritdoc} */
+        public double value(double x, double y) {
+            return Math.atan2(x, y);
+        }
+    };
+
+    /** {...@inheritdoc} */
+    public abstract double value(double x, double y) throws 
FunctionEvaluationException;
+
+    /** Get a composable function by fixing the first argument of the instance.
+     * @param fixedX fixed value of the first argument
+     * @return a function such that {...@code f.value(y) == value(fixedX, y)}
+     */
+    public ComposableFunction fix1stArgument(final double fixedX) {
+        return new ComposableFunction() {
+            @Override
+            /** {...@inheritdoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return BinaryFunction.this.value(fixedX, x);
+            }
+        };
+    }
+
+    /** Get a composable function by fixing the second argument of the 
instance.
+     * @param fixedY fixed value of the second argument
+     * @return a function such that {...@code f.value(x) == value(x, fixedY)}
+     */
+    public ComposableFunction fix2ndArgument(final double fixedY) {
+        return new ComposableFunction() {
+            @Override
+            /** {...@inheritdoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return BinaryFunction.this.value(x, fixedY);
+            }
+        };
+    }
+
+}

Propchange: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BinaryFunction.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BinaryFunction.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BivariateRealFunction.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BivariateRealFunction.java?rev=890002&view=auto
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BivariateRealFunction.java
 (added)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BivariateRealFunction.java
 Sat Dec 12 23:15:32 2009
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+
+
+
+/**
+ * An interface representing a bivariate real function.
+ *
+ * @version $Revision$ $Date$
+ */
+public interface BivariateRealFunction {
+
+    /**
+     * Compute the value for the function.
+     * @param x abscissa for which the function value should be computed
+     * @param y ordinate for which the function value should be computed
+     * @return the value
+     * @throws FunctionEvaluationException if the function evaluation fails
+     */
+    double value(double x, double y) throws FunctionEvaluationException;
+
+}

Propchange: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BivariateRealFunction.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/BivariateRealFunction.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Copied: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/ComposableFunction.java
 (from r889944, 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/UnivariateRealFunctions.java)
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/ComposableFunction.java?p2=commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/ComposableFunction.java&p1=commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/UnivariateRealFunctions.java&r1=889944&r2=890002&rev=890002&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/UnivariateRealFunctions.java
 (original)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/ComposableFunction.java
 Sat Dec 12 23:15:32 2009
@@ -17,209 +17,446 @@
 
 package org.apache.commons.math.analysis;
 
+import org.apache.commons.math.FunctionEvaluationException;
+
 
 /**
- * Set of {...@link UnivariateRealFunction} classes wrapping methods from
- * the standard Math class.
+ * Base class for {...@link UnivariateRealFunction} that can be composed with 
other functions.
  *
  * @version $Revision$ $Date$
  */
-public class UnivariateRealFunctions {
+public abstract class ComposableFunction implements UnivariateRealFunction {
+
+    /** The constant function always returning 0. */
+    public static final ComposableFunction ZERO = new ComposableFunction() {
+        /** {...@inheritdoc} */
+        public double value(double d) {
+            return 0;
+        }
+    };
+
+    /** The constant function always returning 1. */
+    public static final ComposableFunction ONE = new ComposableFunction() {
+        /** {...@inheritdoc} */
+        public double value(double d) {
+            return 1;
+        }
+    };
+
+    /** The identity function. */
+    public static final ComposableFunction IDENTITY = new ComposableFunction() 
{
+        /** {...@inheritdoc} */
+        public double value(double d) {
+            return d;
+        }
+    };
 
-    /** The {...@code Math.abs} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction ABS = new 
UnivariateRealFunction() {
+    /** The {...@code Math.abs} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction ABS = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.abs(d);
         }
     };
 
-    /** The - operator wrapped as a {...@link UnivariateRealFunction}. */
-    public static final UnivariateRealFunction NEGATE = new 
UnivariateRealFunction() {
+    /** The - operator wrapped as a {...@link ComposableFunction}. */
+    public static final ComposableFunction NEGATE = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return -d;
         }
     };
 
-    /** The {...@code Math.sin} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction SIN = new 
UnivariateRealFunction() {
+    /** The {...@code Math.sin} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction SIN = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.sin(d);
         }
     };
 
-    /** The {...@code Math.sqrt} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction SQRT = new 
UnivariateRealFunction() {
+    /** The {...@code Math.sqrt} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction SQRT = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.sqrt(d);
         }
     };
 
-    /** The {...@code Math.sinh} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction SINH = new 
UnivariateRealFunction() {
+    /** The {...@code Math.sinh} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction SINH = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.sinh(d);
         }
     };
 
-    /** The {...@code Math.exp} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction EXP = new 
UnivariateRealFunction() {
+    /** The {...@code Math.exp} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction EXP = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.exp(d);
         }
     };
 
-    /** The {...@code Math.expm1} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction EXP1M = new 
UnivariateRealFunction() {
+    /** The {...@code Math.expm1} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction EXPM1 = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.expm1(d);
         }
     };
 
-    /** The {...@code Math.asin} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction ASIN = new 
UnivariateRealFunction() {
+    /** The {...@code Math.asin} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction ASIN = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.asin(d);
         }
     };
 
-    /** The {...@code Math.atan} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction ATAN = new 
UnivariateRealFunction() {
+    /** The {...@code Math.atan} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction ATAN = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.atan(d);
         }
     };
 
-    /** The {...@code Math.tan} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction TAN = new 
UnivariateRealFunction() {
+    /** The {...@code Math.tan} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction TAN = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.tan(d);
         }
     };
 
-    /** The {...@code Math.tanh} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction TANH = new 
UnivariateRealFunction() {
+    /** The {...@code Math.tanh} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction TANH = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.tanh(d);
         }
     };
 
-    /** The {...@code Math.cbrt} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction CBRT = new 
UnivariateRealFunction() {
+    /** The {...@code Math.cbrt} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction CBRT = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.cbrt(d);
         }
     };
 
-    /** The {...@code Math.ceil} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction CEIL = new 
UnivariateRealFunction() {
+    /** The {...@code Math.ceil} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction CEIL = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.ceil(d);
         }
     };
 
-    /** The {...@code Math.floor} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction FLOOR = new 
UnivariateRealFunction() {
+    /** The {...@code Math.floor} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction FLOOR = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.floor(d);
         }
     };
 
-    /** The {...@code Math.log} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction LOG = new 
UnivariateRealFunction() {
+    /** The {...@code Math.log} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction LOG = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.log(d);
         }
     };
 
-    /** The {...@code Math.log10} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction LOG10 = new 
UnivariateRealFunction() {
+    /** The {...@code Math.log10} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction LOG10 = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.log10(d);
         }
     };
 
-    /** The {...@code Math.cos} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction COS = new 
UnivariateRealFunction() {
+    /** The {...@code Math.cos} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction COS = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.cos(d);
         }
     };
 
-    /** The {...@code Math.abs} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction ACOS = new 
UnivariateRealFunction() {
+    /** The {...@code Math.abs} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction ACOS = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.acos(d);
         }
     };
 
-    /** The {...@code Math.cosh} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction COSH = new 
UnivariateRealFunction() {
+    /** The {...@code Math.cosh} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction COSH = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.cosh(d);
         }
     };
 
-    /** The {...@code Math.rint} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction RINT = new 
UnivariateRealFunction() {
+    /** The {...@code Math.rint} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction RINT = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.rint(d);
         }
     };
 
-    /** The {...@code Math.signum} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction SIGNUM = new 
UnivariateRealFunction() {
+    /** The {...@code Math.signum} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction SIGNUM = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.signum(d);
         }
     };
 
-    /** The {...@code Math.ulp} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static final UnivariateRealFunction ULP = new 
UnivariateRealFunction() {
+    /** The {...@code Math.ulp} method wrapped as a {...@link 
ComposableFunction}. */
+    public static final ComposableFunction ULP = new ComposableFunction() {
         /** {...@inheritdoc} */
         public double value(double d) {
             return Math.ulp(d);
         }
     };
 
-    /** The {...@code Math.pow} method wrapped as a {...@link 
UnivariateRealFunction}. */
-    public static class Pow implements UnivariateRealFunction {
+    /** Precompose the instance with another function.
+     * <p>
+     * The composed function h created by {...@code h = g.of(f)} is such
+     * that {...@code h.value(x) == g.value(f.value(x))} for all x.
+     * </p>
+     * @param f function to compose with
+     * @return a new function which computes {...@code this.value(f.value(x))}
+     * @see #postCompose(UnivariateRealFunction)
+     */
+    public ComposableFunction of(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {...@inheritdoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(f.value(x));
+            }
+        };
+    }
 
-        /** The power to which the value should be raised. */
-        private final double pow;
+    /** Postcompose the instance with another function.
+     * <p>
+     * The composed function h created by {...@code h = g.postCompose(f)} is 
such
+     * that {...@code h.value(x) == f.value(g.value(x))} for all x.
+     * </p>
+     * @param f function to compose with
+     * @return a new function which computes {...@code f.value(this.value(x))}
+     * @see #of(UnivariateRealFunction)
+     */
+    public ComposableFunction postCompose(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {...@inheritdoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return f.value(ComposableFunction.this.value(x));
+            }
+        };
+    }
 
-        /** Simple constructor.
-         * @param pow the power to which the value should be raised
-         */
-        public Pow(double pow) {
-            this.pow = pow;
-        }
+    /**
+     * Return a function combining the instance and another function.
+     * <p>
+     * The function h created by {...@code h = g.combine(f, combiner)} is such 
that
+     * {...@code h.value(x) == combiner.value(g.value(x), f.value(x))} for all 
x.
+     * </p>
+     * @param f function to combine with the instance
+     * @param combiner bivariate function used for combining
+     * @return a new function which computes {...@code 
combine.value(this.value(x), f.value(x))}
+     */
+    public ComposableFunction combine(final UnivariateRealFunction f,
+                                      final BivariateRealFunction combiner) {
+        return new ComposableFunction() {
+            @Override
+            /** {...@inheritdoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return combiner.value(ComposableFunction.this.value(x), 
f.value(x));
+            }
+        };
+    }
 
-        /** {...@inheritdoc} */
-        public double value(double d) {
-            return Math.pow(d, pow);
-        }
+    /**
+     * Return a function adding the instance and another function.
+     * @param f function to combine with the instance
+     * @return a new function which computes {...@code this.value(x) + 
f.value(x)}
+     */
+    public ComposableFunction add(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {...@inheritdoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) + f.value(x);
+            }
+        };
+    }
+
+    /**
+     * Return a function adding a constant term to the instance.
+     * @param a term to add
+     * @return a new function which computes {...@code this.value(x) + a}
+     */
+    public ComposableFunction add(final double a) {
+        return new ComposableFunction() {
+            @Override
+            /** {...@inheritdoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) + a;
+            }
+        };
+    }
+
+    /**
+     * Return a function subtracting another function from the instance.
+     * @param f function to combine with the instance
+     * @return a new function which computes {...@code this.value(x) - 
f.value(x)}
+     */
+    public ComposableFunction subtract(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {...@inheritdoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) - f.value(x);
+            }
+        };
+    }
+
+    /**
+     * Return a function multiplying the instance and another function.
+     * @param f function to combine with the instance
+     * @return a new function which computes {...@code this.value(x) * 
f.value(x)}
+     */
+    public ComposableFunction multiply(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {...@inheritdoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) * f.value(x);
+            }
+        };
+    }
 
+    /**
+     * Return a function scaling the instance by a constant factor.
+     * @param scaleFactor constant scaling factor
+     * @return a new function which computes {...@code this.value(x) * 
scaleFactor}
+     */
+    public ComposableFunction multiply(final double scaleFactor) {
+        return new ComposableFunction() {
+            @Override
+            /** {...@inheritdoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) * scaleFactor;
+            }
+        };
     }
+    /**
+     * Return a function dividing the instance by another function.
+     * @param f function to combine with the instance
+     * @return a new function which computes {...@code this.value(x) / 
f.value(x)}
+     */
+    public ComposableFunction divide(final UnivariateRealFunction f) {
+        return new ComposableFunction() {
+            @Override
+            /** {...@inheritdoc} */
+            public double value(double x) throws FunctionEvaluationException {
+                return ComposableFunction.this.value(x) / f.value(x);
+            }
+        };
+    }
+
+    /**
+     * Generates a function that iteratively apply instance function on all
+     * elements of an array.
+     * <p>
+     * The generated function behaves as follows:
+     * <ul>
+     *   <li>initialize result = initialValue</li>
+     *   <li>iterate: {...@code result = combiner.value(result,
+     *   this.value(nextMultivariateEntry));}</li>
+     *   <li>return result</li>
+     * </ul>
+     * </p>
+     * @param combiner combiner to use between entries
+     * @param initialValue initial value to use before first entry
+     * @return a new function that iteratively applie instance function on all
+     * elements of an array.
+     */
+    public MultivariateRealFunction asCollector(final BivariateRealFunction 
combiner,
+                                                final double initialValue) {
+        return new MultivariateRealFunction() {
+            /** {...@inheritdoc} */
+            public double value(double[] point)
+                throws FunctionEvaluationException, IllegalArgumentException {
+                double result = initialValue;
+                for (final double entry : point) {
+                    result = combiner.value(result, 
ComposableFunction.this.value(entry));
+                }
+                return result;
+            }
+        };
+    }
+
+    /**
+     * Generates a function that iteratively apply instance function on all
+     * elements of an array.
+     * <p>
+     * Calling this method is equivalent to call {...@link
+     * #asCollector(BivariateRealFunction, double) 
asCollector(BivariateRealFunction, 0.0)}.
+     * </p>
+     * @param combiner combiner to use between entries
+     * @return a new function that iteratively applie instance function on all
+     * elements of an array.
+     * @see #asCollector(BivariateRealFunction, double)
+     */
+    public  MultivariateRealFunction asCollector(final BivariateRealFunction 
combiner) {
+        return asCollector(combiner, 0.0);
+    }
+
+    /**
+     * Generates a function that iteratively apply instance function on all
+     * elements of an array.
+     * <p>
+     * Calling this method is equivalent to call {...@link
+     * #asCollector(BivariateRealFunction, double) 
asCollector(BinaryFunction.ADD, initialValue)}.
+     * </p>
+     * @param initialValue initial value to use before first entry
+     * @return a new function that iteratively applie instance function on all
+     * elements of an array.
+     * @see #asCollector(BivariateRealFunction, double)
+     * @see BinaryFunction#ADD
+     */
+    public  MultivariateRealFunction asCollector(final double initialValue) {
+        return asCollector(BinaryFunction.ADD, initialValue);
+    }
+
+    /**
+     * Generates a function that iteratively apply instance function on all
+     * elements of an array.
+     * <p>
+     * Calling this method is equivalent to call {...@link
+     * #asCollector(BivariateRealFunction, double) 
asCollector(BinaryFunction.ADD, 0.0)}.
+     * </p>
+     * @return a new function that iteratively applie instance function on all
+     * elements of an array.
+     * @see #asCollector(BivariateRealFunction, double)
+     * @see BinaryFunction#ADD
+     */
+    public  MultivariateRealFunction asCollector() {
+        return asCollector(BinaryFunction.ADD, 0.0);
+    }
+
+    /** {...@inheritdoc} */
+    public abstract double value(double x) throws FunctionEvaluationException;
 
 }

Modified: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java?rev=890002&r1=890001&r2=890002&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java
 (original)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java
 Sat Dec 12 23:15:32 2009
@@ -22,7 +22,7 @@
 import org.apache.commons.math.FunctionEvaluationException;
 import org.apache.commons.math.MathRuntimeException;
 import org.apache.commons.math.analysis.UnivariateRealFunction;
-import org.apache.commons.math.analysis.UnivariateRealFunctions;
+import org.apache.commons.math.analysis.ComposableFunction;
 
 /**
  * This class provides default basic implementations for many methods in the
@@ -273,7 +273,7 @@
     /** {...@inheritdoc} */
     public RealVector mapAbsToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.ABS);
+            return mapToSelf(ComposableFunction.ABS);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -287,7 +287,7 @@
     /** {...@inheritdoc} */
     public RealVector mapAcosToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.ACOS);
+            return mapToSelf(ComposableFunction.ACOS);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -301,7 +301,7 @@
     /** {...@inheritdoc} */
     public RealVector mapAsinToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.ASIN);
+            return mapToSelf(ComposableFunction.ASIN);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -315,7 +315,7 @@
     /** {...@inheritdoc} */
     public RealVector mapAtanToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.ATAN);
+            return mapToSelf(ComposableFunction.ATAN);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -329,7 +329,7 @@
     /** {...@inheritdoc} */
     public RealVector mapCbrtToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.CBRT);
+            return mapToSelf(ComposableFunction.CBRT);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -343,7 +343,7 @@
     /** {...@inheritdoc} */
     public RealVector mapCeilToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.CEIL);
+            return mapToSelf(ComposableFunction.CEIL);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -357,7 +357,7 @@
     /** {...@inheritdoc} */
     public RealVector mapCosToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.COS);
+            return mapToSelf(ComposableFunction.COS);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -371,7 +371,7 @@
     /** {...@inheritdoc} */
     public RealVector mapCoshToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.COSH);
+            return mapToSelf(ComposableFunction.COSH);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -390,7 +390,7 @@
     /** {...@inheritdoc} */
     public RealVector mapExpToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.EXP);
+            return mapToSelf(ComposableFunction.EXP);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -404,7 +404,7 @@
     /** {...@inheritdoc} */
     public RealVector mapExpm1ToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.EXP1M);
+            return mapToSelf(ComposableFunction.EXPM1);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -418,7 +418,7 @@
     /** {...@inheritdoc} */
     public RealVector mapFloorToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.FLOOR);
+            return mapToSelf(ComposableFunction.FLOOR);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -437,7 +437,7 @@
     /** {...@inheritdoc} */
     public RealVector mapLogToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.LOG);
+            return mapToSelf(ComposableFunction.LOG);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -451,7 +451,7 @@
     /** {...@inheritdoc} */
     public RealVector mapLog10ToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.LOG10);
+            return mapToSelf(ComposableFunction.LOG10);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -465,7 +465,7 @@
     /** {...@inheritdoc} */
     public RealVector mapLog1pToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.ASIN);
+            return mapToSelf(ComposableFunction.ASIN);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -489,7 +489,7 @@
     /** {...@inheritdoc} */
     public RealVector mapRintToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.RINT);
+            return mapToSelf(ComposableFunction.RINT);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -503,7 +503,7 @@
     /** {...@inheritdoc} */
     public RealVector mapSignumToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.SIGNUM);
+            return mapToSelf(ComposableFunction.SIGNUM);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -517,7 +517,7 @@
     /** {...@inheritdoc} */
     public RealVector mapSinToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.SIN);
+            return mapToSelf(ComposableFunction.SIN);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -531,7 +531,7 @@
     /** {...@inheritdoc} */
     public RealVector mapSinhToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.SINH);
+            return mapToSelf(ComposableFunction.SINH);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -545,7 +545,7 @@
     /** {...@inheritdoc} */
     public RealVector mapSqrtToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.SQRT);
+            return mapToSelf(ComposableFunction.SQRT);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -564,7 +564,7 @@
     /** {...@inheritdoc} */
     public RealVector mapTanToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.TAN);
+            return mapToSelf(ComposableFunction.TAN);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -578,7 +578,7 @@
     /** {...@inheritdoc} */
     public RealVector mapTanhToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.TANH);
+            return mapToSelf(ComposableFunction.TANH);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }
@@ -592,7 +592,7 @@
     /** {...@inheritdoc} */
     public RealVector mapUlpToSelf() {
         try {
-            return mapToSelf(UnivariateRealFunctions.ULP);
+            return mapToSelf(ComposableFunction.ULP);
         } catch (FunctionEvaluationException e) {
             throw new IllegalArgumentException(e);
         }

Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=890002&r1=890001&r2=890002&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Sat Dec 12 23:15:32 2009
@@ -39,6 +39,9 @@
   </properties>
   <body>
     <release version="2.1" date="TBD" description="TBD">
+      <action dev="luc" type="fix" issue="MATH-313" due-to="Jake Mannix">
+        Added composition features for real functions.
+      </action>
       <action dev="luc" type="fix" issue="MATH-312" due-to="Jake Mannix">
         Added mapping and iteration methods to vectors. Provided a default 
implementation
         for the numerous simple methods in the RealVectorInterface.

Added: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/BinaryFunctionTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/BinaryFunctionTest.java?rev=890002&view=auto
==============================================================================
--- 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/BinaryFunctionTest.java
 (added)
+++ 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/BinaryFunctionTest.java
 Sat Dec 12 23:15:32 2009
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class BinaryFunctionTest {
+
+    @Test
+    public void testAdd() throws FunctionEvaluationException {
+        Assert.assertEquals(5.0, BinaryFunction.ADD.value(2, 3), 1.0e-15);
+        Assert.assertEquals(0.0, BinaryFunction.ADD.value(-1, 1), 1.0e-15);
+    }
+
+    @Test
+    public void testSubtract() throws FunctionEvaluationException {
+        Assert.assertEquals(-1.0, BinaryFunction.SUBTRACT.value(2, 3), 
1.0e-15);
+        Assert.assertEquals(-2.0, BinaryFunction.SUBTRACT.value(-1, 1), 
1.0e-15);
+    }
+
+    @Test
+    public void testMultiply() throws FunctionEvaluationException {
+        Assert.assertEquals(6.0, BinaryFunction.MULTIPLY.value(2, 3), 1.0e-15);
+        Assert.assertEquals(-1.0, BinaryFunction.MULTIPLY.value(-1, 1), 
1.0e-15);
+    }
+
+    @Test
+    public void testDivide() throws FunctionEvaluationException {
+        Assert.assertEquals(1.5, BinaryFunction.DIVIDE.value(3, 2), 1.0e-15);
+        Assert.assertEquals(-1.0, BinaryFunction.DIVIDE.value(-1, 1), 1.0e-15);
+    }
+
+    @Test
+    public void testPow() throws FunctionEvaluationException {
+        Assert.assertEquals(9.0, BinaryFunction.POW.value(3, 2), 1.0e-15);
+        Assert.assertEquals(-1.0, BinaryFunction.POW.value(-1, 1), 1.0e-15);
+    }
+
+    @Test
+    public void testAtan2() throws FunctionEvaluationException {
+        Assert.assertEquals(Math.PI / 4, BinaryFunction.ATAN2.value(1, 1), 
1.0e-15);
+        Assert.assertEquals(-Math.PI / 4, BinaryFunction.ATAN2.value(-1, 1), 
1.0e-15);
+    }
+
+    @Test
+    public void testFix1st() throws FunctionEvaluationException {
+        ComposableFunction f = BinaryFunction.POW.fix1stArgument(2);
+        for (double x = 0.0; x < 1.0; x += 0.01) {
+            Assert.assertEquals(Math.pow(2.0, x), f.value(x), 1.0e-15);
+        }
+    }
+
+    @Test
+    public void testFix2nd() throws FunctionEvaluationException {
+        ComposableFunction f = BinaryFunction.POW.fix2ndArgument(2);
+        for (double y = 0.0; y < 1.0; y += 0.01) {
+            Assert.assertEquals(y * y, f.value(y), 1.0e-15);
+        }
+    }
+
+}

Propchange: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/BinaryFunctionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/BinaryFunctionTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/ComposableFunctionTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/ComposableFunctionTest.java?rev=890002&view=auto
==============================================================================
--- 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/ComposableFunctionTest.java
 (added)
+++ 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/ComposableFunctionTest.java
 Sat Dec 12 23:15:32 2009
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.math.analysis;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ComposableFunctionTest {
+
+    @Test
+    public void testZero() throws FunctionEvaluationException {
+        Assert.assertEquals(0.0, ComposableFunction.ZERO.value(1), 1.0e-15);
+        Assert.assertEquals(0.0, ComposableFunction.ZERO.value(2), 1.0e-15);
+    }
+
+    @Test
+    public void testOne() throws FunctionEvaluationException {
+        Assert.assertEquals(1.0, ComposableFunction.ONE.value(1), 1.0e-15);
+        Assert.assertEquals(1.0, ComposableFunction.ONE.value(2), 1.0e-15);
+    }
+
+    @Test
+    public void testIdentity() throws FunctionEvaluationException {
+        Assert.assertEquals(1.0, ComposableFunction.IDENTITY.value(1), 
1.0e-15);
+        Assert.assertEquals(2.0, ComposableFunction.IDENTITY.value(2), 
1.0e-15);
+    }
+
+    @Test
+    public void testRint() throws FunctionEvaluationException {
+        Assert.assertEquals(1.0, ComposableFunction.RINT.value(0.9), 1.0e-15);
+        Assert.assertEquals(2.0, ComposableFunction.RINT.value(2.2), 1.0e-15);
+    }
+
+    @Test
+    public void testSignum() throws FunctionEvaluationException {
+        Assert.assertEquals(1.0, ComposableFunction.SIGNUM.value(12.3), 
1.0e-15);
+        Assert.assertEquals(-1.0, ComposableFunction.SIGNUM.value(-6), 
1.0e-15);
+    }
+
+    @Test
+    public void testComposition() throws FunctionEvaluationException {
+        ComposableFunction abs    = ComposableFunction.ABS;
+        ComposableFunction acos   = ComposableFunction.ACOS;
+        ComposableFunction asin   = ComposableFunction.ASIN;
+        ComposableFunction atan   = ComposableFunction.ATAN;
+        ComposableFunction cbrt   = ComposableFunction.CBRT;
+        ComposableFunction ceil   = ComposableFunction.CEIL;
+        ComposableFunction cos    = ComposableFunction.COS;
+        ComposableFunction cosh   = ComposableFunction.COSH;
+        ComposableFunction exp    = ComposableFunction.EXP;
+        ComposableFunction expm1  = ComposableFunction.EXPM1;
+        ComposableFunction floor  = ComposableFunction.FLOOR;
+        ComposableFunction id     = ComposableFunction.IDENTITY;
+        ComposableFunction log    = ComposableFunction.LOG;
+        ComposableFunction log10  = ComposableFunction.LOG10;
+        ComposableFunction negate = ComposableFunction.NEGATE;
+        ComposableFunction sin    = ComposableFunction.SIN;
+        ComposableFunction sinh   = ComposableFunction.SINH;
+        ComposableFunction sqrt   = ComposableFunction.SQRT;
+        ComposableFunction tan    = ComposableFunction.TAN;
+        ComposableFunction tanh   = ComposableFunction.TANH;
+        ComposableFunction ulp    = ComposableFunction.ULP;
+
+        ComposableFunction f1 = 
sqrt.of(abs.of(expm1.of(cbrt.of(tanh).of(id))));
+        for (double x = 0.1; x < 0.9; x += 0.01) {
+            
Assert.assertEquals(Math.sqrt(Math.abs(Math.expm1(Math.cbrt(Math.tanh(x))))),
+                                f1.value(x), 1.0e-15);
+        }
+
+        ComposableFunction f2 = 
cosh.of(sinh.of(tanh.of(ceil.postCompose(log.postCompose(cosh)))));
+        for (double x = 0.1; x < 12.9; x += 1.0) {
+            
Assert.assertEquals(Math.cosh(Math.sinh(Math.tanh(Math.cosh(Math.log(Math.ceil(x)))))),
+                                f2.value(x), 1.0e-15);
+        }
+
+        ComposableFunction f3 = 
cos.of(sin.of(tan.of(acos.of(asin.of(log10.of(log.of(ulp)))))));
+        for (double x = 1.0e16; x < 1.0e17; x += 1.0e16) {
+            
Assert.assertEquals(Math.cos(Math.sin(Math.tan(Math.acos(Math.asin(Math.log10(Math.log(Math.ulp(x)))))))),
+                                f3.value(x), 1.0e-15);
+        }
+
+        ComposableFunction f4 = atan.of(exp.of(negate.of(floor)));
+        for (double x = 1.1; x < 10.2; x += 1.0) {
+            Assert.assertEquals(Math.atan(Math.exp(-Math.floor(x))),
+                                f4.value(x), 1.0e-15);
+        }
+
+    }
+
+    @Test
+    public void testCombine() throws FunctionEvaluationException {
+
+        ComposableFunction f =
+            ComposableFunction.COS.combine(ComposableFunction.ASIN, 
BinaryFunction.POW);
+        for (double x = 0.1; x < 0.9; x += 0.01) {
+            Assert.assertEquals(Math.pow(Math.cos(x), Math.asin(x)), 
f.value(x), 1.0e-15);
+        }
+
+    }
+
+    @Test
+    public void testSimpleCombination() throws FunctionEvaluationException {
+
+        ComposableFunction f1 = ComposableFunction.COS.add(3);
+        ComposableFunction f2 = 
ComposableFunction.COS.add(ComposableFunction.SIN);
+        ComposableFunction f3 = 
ComposableFunction.COS.subtract(ComposableFunction.SIN);
+        ComposableFunction f4 = 
ComposableFunction.COS.multiply(ComposableFunction.SIN);
+        ComposableFunction f5 = ComposableFunction.COS.multiply(5);
+        ComposableFunction f6 = 
ComposableFunction.COS.divide(ComposableFunction.SIN);
+        for (double x = 0.1; x < 0.9; x += 0.01) {
+            Assert.assertEquals(Math.cos(x) + 3, f1.value(x), 1.0e-15);
+            Assert.assertEquals(Math.cos(x) + Math.sin(x), f2.value(x), 
1.0e-15);
+            Assert.assertEquals(Math.cos(x) - Math.sin(x), f3.value(x), 
1.0e-15);
+            Assert.assertEquals(Math.cos(x) * Math.sin(x), f4.value(x), 
1.0e-15);
+            Assert.assertEquals(Math.cos(x) * 5, f5.value(x), 1.0e-15);
+            Assert.assertEquals(Math.cos(x) / Math.sin(x), f6.value(x), 
1.0e-15);
+        }
+
+    }
+
+    @Test
+    public void testCollector() throws FunctionEvaluationException {
+
+        ComposableFunction f = BinaryFunction.POW.fix2ndArgument(2);
+        Assert.assertEquals(30, f.asCollector().value(new double[] { 1, 2, 3, 
4 }), 1.0e-15);
+        Assert.assertEquals(33, f.asCollector(3).value(new double[] { 1, 2, 3, 
4 }), 1.0e-15);
+        Assert.assertEquals(-30, 
f.asCollector(BinaryFunction.SUBTRACT).value(new double[] { 1, 2, 3, 4 }), 
1.0e-15);
+        Assert.assertEquals(1152, f.asCollector(BinaryFunction.MULTIPLY, 
2).value(new double[] { 1, 2, 3, 4 }), 1.0e-15);
+    }
+
+}

Propchange: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/ComposableFunctionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/ComposableFunctionTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision


Reply via email to