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 }