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.MathRuntimeException;
021 import org.apache.commons.math.analysis.MultivariateRealFunction;
022 import org.apache.commons.math.random.UnitSphereRandomVectorGenerator;
023
024 /**
025 * Interpolator that implements the algorithm described in
026 * <em>William Dudziak</em>'s
027 * <a href="http://www.dudziak.com/microsphere.pdf">MS thesis</a>
028 * @since 2.1
029 *
030 * @version $Revision: 924794 $ $Date: 2010-03-18 10:15:50 -0400 (Thu, 18 Mar 2010) $
031 */
032 public class MicrosphereInterpolator
033 implements MultivariateRealInterpolator {
034
035 /**
036 * Default number of surface elements that composes the microsphere.
037 */
038 public static final int DEFAULT_MICROSPHERE_ELEMENTS = 2000;
039
040 /**
041 * Default exponent used the weights calculation.
042 */
043 public static final int DEFAULT_BRIGHTNESS_EXPONENT = 2;
044
045 /**
046 * Number of surface elements of the microsphere.
047 */
048 private int microsphereElements;
049
050 /**
051 * Exponent used in the power law that computes the weights of the
052 * sample data.
053 */
054 private int brightnessExponent;
055
056 /** Create a microsphere interpolator with default settings.
057 * <p>Calling this constructor is equivalent to call {@link
058 * #MicrosphereInterpolator(int, int)
059 * MicrosphereInterpolator(MicrosphereInterpolator.DEFAULT_MICROSPHERE_ELEMENTS,
060 * MicrosphereInterpolator.DEFAULT_BRIGHTNESS_EXPONENT)}.</p>
061 * weights of the sample data
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 IllegalArgumentException 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 brightnessExponent Exponent for computing the distance dimming
097 * factor.
098 * @throws IllegalArgumentException if {@code brightnessExponent < 0}.
099 */
100 public void setBrightnessExponent(final int brightnessExponent) {
101 if (brightnessExponent < 0) {
102 throw MathRuntimeException.createIllegalArgumentException(
103 "brightness exponent should be positive or null, but got {0}",
104 brightnessExponent);
105 }
106 this.brightnessExponent = brightnessExponent;
107 }
108
109 /**
110 * Set the number of microsphere elements.
111 * @param elements Number of surface elements of the microsphere.
112 * @throws IllegalArgumentException if {@code microsphereElements <= 0}.
113 */
114 public void setMicropshereElements(final int elements) {
115 if (microsphereElements < 0) {
116 throw MathRuntimeException.createIllegalArgumentException(
117 "number of microsphere elements must be positive, but got {0}",
118 microsphereElements);
119 }
120 this.microsphereElements = elements;
121 }
122
123 }