    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    package org.apache.commons.math.analysis.interpolation;
    018
    019    import org.apache.commons.math.MathException;
    020    import org.apache.commons.math.analysis.MultivariateRealFunction;
    021    import org.apache.commons.math.exception.NotPositiveException;
    022    import org.apache.commons.math.exception.NotStrictlyPositiveException;
    023    import org.apache.commons.math.random.UnitSphereRandomVectorGenerator;
    024
    025    /**
    026     * Interpolator that implements the algorithm described in
    027     * <em>William Dudziak</em>'s
    028     * <a href="http://www.dudziak.com/microsphere.pdf">MS thesis</a>.
    029     * @since 2.1
    030     *
    031     * @version $Revision: 980944 $ $Date: 2010-07-30 22:31:11 +0200 (ven. 30 juil. 2010) $
    032     */
    033    public class MicrosphereInterpolator
    034        implements MultivariateRealInterpolator {
    035
    036        /**
    037         * Default number of surface elements that composes the microsphere.
    038         */
    039        public static final int DEFAULT_MICROSPHERE_ELEMENTS = 2000;
    040
    041        /**
    042         * Default exponent used the weights calculation.
    043         */
    044        public static final int DEFAULT_BRIGHTNESS_EXPONENT = 2;
    045
    046        /**
    047         * Number of surface elements of the microsphere.
    048         */
    049        private int microsphereElements;
    050
    051        /**
    052         * Exponent used in the power law that computes the weights of the
    053         * sample data.
    054         */
    055        private int brightnessExponent;
    056
    057        /** Create a microsphere interpolator with default settings.
    058         * <p>Calling this constructor is equivalent to call {@link
    059         * #MicrosphereInterpolator(int, int)
    060         * MicrosphereInterpolator(MicrosphereInterpolator.DEFAULT_MICROSPHERE_ELEMENTS,
    061         * MicrosphereInterpolator.DEFAULT_BRIGHTNESS_EXPONENT)}.</p>
    062         */
    063        public MicrosphereInterpolator() {
    064            this(DEFAULT_MICROSPHERE_ELEMENTS, DEFAULT_BRIGHTNESS_EXPONENT);
    065        }
    066
    067        /** Create a microsphere interpolator.
    068         * @param microsphereElements number of surface elements of the microsphere.
    069         * @param brightnessExponent exponent used in the power law that computes the
    070         * weights of the sample data.
    071         * @throws NotPositiveException if {@code microsphereElements <= 0}
    072         * or {@code brightnessExponent < 0}.
    073         */
    074        public MicrosphereInterpolator(final int microsphereElements,
    075                                       final int brightnessExponent) {
    076            setMicropshereElements(microsphereElements);
    077            setBrightnessExponent(brightnessExponent);
    078        }
    079
    080        /**
    081         * {@inheritDoc}
    082         */
    083        public MultivariateRealFunction interpolate(final double[][] xval,
    084                                                    final double[] yval)
    085            throws MathException, IllegalArgumentException {
    086            final UnitSphereRandomVectorGenerator rand
    087                = new UnitSphereRandomVectorGenerator(xval[0].length);
    088            return new MicrosphereInterpolatingFunction(xval, yval,
    089                                                        brightnessExponent,
    090                                                        microsphereElements,
    091                                                        rand);
    092        }
    093
    094        /**
    095         * Set the brightness exponent.
    096         * @param exponent Exponent for computing the distance dimming
    097         * factor.
    098         * @throws NotPositiveException if {@code exponent < 0}.
    099         */
    100        public void setBrightnessExponent(final int exponent) {
    101            if (exponent < 0) {
    102                throw new NotPositiveException(exponent);
    103            }
    104            brightnessExponent = exponent;
    105        }
    106
    107        /**
    108         * Set the number of microsphere elements.
    109         * @param elements Number of surface elements of the microsphere.
    110         * @throws NotStrictlyPositiveException if {@code elements <= 0}.
    111         */
    112        public void setMicropshereElements(final int elements) {
    113            if (elements <= 0) {
    114                throw new NotStrictlyPositiveException(elements);
    115            }
    116            microsphereElements = elements;
    117        }
    118    }