/*
 * 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.function;

import java.util.Arrays;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.exception.NullArgumentException;
import org.apache.commons.math.exception.NoDataException;
import org.apache.commons.math.util.MathArrays;

/**
 * <a href="http://en.wikipedia.org/wiki/Step_function">
 *  Step function</a>.
 *
 * @version $Id$
 * @since 3.0
 */
public class StepFunction implements UnivariateRealFunction {
    /** Abscissae. */
    private final double[] abscissa;
    /** Ordinates. */
    private final double[] ordinate;

    /**
     * Builds a step function from a list of arguments and the corresponding
     * values. Specifically, returns the function h(x) defined by <pre><code>
     * h(x) = y[0] for all x < x[1]
     *        y[1] for x[1] <= x < x[2]
     *        ...
     *        y[y.length] for x >= x[x.length]
     * </code></pre>
     * The value of x[0] is ignored, but it must be strictly less than x[1].
     *
     * @param x domain values where the function changes value.
     * @param y values of the function.
     * @throws org.apache.commons.math.exception.NonMonotonicSequenceException
     * if the {@code x} array is not sorted in strictly increasing order.
     * @throws NullArgumentException if {@code x} or {@code y} are {@code null}.
     * @throws NoDataException if {@code x} or {@code y} are zero-length.
     * @throws DimensionMismatchException if x and y do not have the same length
     */
    public StepFunction(double[] x,
                        double[] y) {
        if (x == null ||
            y == null) {
            throw new NullArgumentException();
        }
        if (x.length == 0 ||
            y.length == 0) {
            throw new NoDataException();
        }
        if (y.length != x.length) {
            throw new DimensionMismatchException(y.length, x.length);
        }
        MathArrays.checkOrder(x);

        abscissa = MathArrays.copyOf(x);
        ordinate = MathArrays.copyOf(y);
    }

    /** {@inheritDoc} */
    public double value(double x) {
        int index = Arrays.binarySearch(abscissa, x);
        double fx = 0;

        if (index < -1) {
            // "x" is between "abscissa[-index-2]" and "abscissa[-index-1]".
            fx = ordinate[-index-2];
        } else if (index >= 0) {
            // "x" is exactly "abscissa[index]".
            fx = ordinate[index];
        } else {
            // Otherwise, "x" is smaller than the first value in "abscissa"
            // (hence the returned value should be "ordinate[0]").
            fx = ordinate[0];
        }

        return fx;
    }
}

@@ -1762,16 +1762,20 @@
 y.length
+ - 1
 %5D for x 
@@ -1787,16 +1787,20 @@
 x.length
+ - 1
 %5D%0A     *
@@ -1838,12 +1838,20 @@
  of 
+%7B@code 
 x%5B0%5D
+%7D
  is 
@@ -1892,21 +1892,36 @@
 ess than
+%0A     * %7B@code
  x%5B1%5D
+%7D
 .%0A     *
@@ -1937,17 +1937,17 @@
 param x 
-d
+D
 omain va
@@ -2001,17 +2001,17 @@
 param y 
-v
+V
 alues of
@@ -2382,22 +2382,45 @@
  if 
-x and y do not
+%7B@code x%7D and %7B@code y%7D do not%0A     *
  hav
@@ -2436,16 +2436,17 @@
 e length
+.
 %0A     */

Javadoc.