commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From l..@apache.org
Subject svn commit: r821626 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/ main/java/org/apache/commons/math/analysis/interpolation/ main/java/org/apache/commons/math/random/ site/xdoc/ site/xdoc/userguide/ test/java/org/apache/commons...
Date Sun, 04 Oct 2009 21:57:30 GMT
Author: luc
Date: Sun Oct  4 21:57:30 2009
New Revision: 821626

URL: http://svn.apache.org/viewvc?rev=821626&view=rev
Log:
added multidimensional interpolation using the microsphere algorithm.
JIRA: MATH-300

Added:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java
  (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java
  (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MultivariateRealInterpolator.java
  (with props)
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.java
  (with props)
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatorTest.java
  (with props)
Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/MessagesResources_fr.java
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/UnivariateRealInterpolator.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml
    commons/proper/math/trunk/src/site/xdoc/userguide/analysis.xml

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/MessagesResources_fr.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/MessagesResources_fr.java?rev=821626&r1=821625&r2=821626&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/MessagesResources_fr.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/MessagesResources_fr.java
Sun Oct  4 21:57:30 2009
@@ -88,10 +88,21 @@
     // org.apache.commons.math.random.UncorrelatedRandomVectorGenerator
     // org.apache.commons.math.stat.regression.AbstractMultipleLinearRegression
     // org.apache.commons.math.stat.inference.ChiSquareTestImpl
+    // org.apache.commons.math.analysis.interpolation.MicrosphereInterpolatingFunction
     { "dimension mismatch {0} != {1}",
       "dimensions incompatibles {0} != {1}" },
 
-    // org.apache.commons.math.linear.decomposition.NotPositiveDefiniteMatrixException
+    // org.apache.commons.math.analysis.interpolation.MicrosphereInterpolatingFunction
+    { "no data",
+      "aucune donn\u00e9e" },
+
+    // org.apache.commons.math.analysis.interpolation.MicrosphereInterpolator
+    { "brightness exponent should be positive or null, but got {0}",
+      "l''exposant de brillance devrait \u00eatre positif ou null, or e = {0}" },
+    { "number of microsphere elements must be positive, but got {0}",
+      "le nombre d''\u00e9l\u00e9ments de la microsph\u00e8re devrait \u00eatre positif,
or n = {0}" },
+
+   // org.apache.commons.math.linear.decomposition.NotPositiveDefiniteMatrixException
     { "not positive definite matrix",
       "matrice non d\u00e9finie positive" },
 

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java?rev=821626&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java
(added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatingFunction.java
Sun Oct  4 21:57:30 2009
@@ -0,0 +1,243 @@
+/*
+ * 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.interpolation;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.commons.math.DimensionMismatchException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+import org.apache.commons.math.linear.RealVector;
+import org.apache.commons.math.linear.ArrayRealVector;
+import org.apache.commons.math.random.UnitSphereRandomVectorGenerator;
+
+/**
+ * Interpolating function that implements the
+ * <a href="http://www.dudziak.com/microsphere.php">Microsphere Projection</a>.
+ *
+ * @version $Revision$ $Date$
+ */
+public class MicrosphereInterpolatingFunction
+    implements MultivariateRealFunction {
+    /**
+     * Space dimension.
+     */
+    private final int dimension;
+    /**
+     * Internal accounting data for the interpolation algorithm.
+     * Each element of the list corresponds to one surface element of
+     * the microsphere.
+     */
+    private final List<MicrosphereSurfaceElement> microsphere;
+    /**
+     * Exponent used in the power law that computes the weights of the
+     * sample data.
+     */
+    private final double brightnessExponent;
+    /**
+     * Sample data.
+     */
+    private final Map<RealVector, Double> samples;
+
+    /**
+     * Class for storing the accounting data needed to perform the
+     * microsphere projection.
+     */
+    private static class MicrosphereSurfaceElement {
+
+        /** Normal vector characterizing a surface element. */
+        private final RealVector normal;
+
+        /** Illumination received from the brightest sample. */
+        private double brightestIllumination;
+
+        /** Brightest sample. */
+        private Map.Entry<RealVector, Double> brightestSample;
+
+        /**
+         * @param n Normal vector characterizing a surface element
+         * of the microsphere.
+         */
+        MicrosphereSurfaceElement(double[] n) {
+            normal = new ArrayRealVector(n);
+        }
+
+        /**
+         * Return the normal vector.
+         * @return the normal vector
+         */
+        RealVector normal() {
+            return normal;
+        }
+
+        /**
+         * Reset "illumination" and "sampleIndex".
+         */
+        void reset() {
+            brightestIllumination = 0;
+            brightestSample = null;
+        }
+
+        /**
+         * Store the illumination and index of the brightest sample.
+         * @param illuminationFromSample illumination received from sample
+         * @param sample current sample illuminating the element
+         */
+        void store(final double illuminationFromSample,
+                   final Map.Entry<RealVector, Double> sample) {
+            if (illuminationFromSample > this.brightestIllumination) {
+                this.brightestIllumination = illuminationFromSample;
+                this.brightestSample = sample;
+            }
+        }
+
+        /**
+         * Get the illumination of the element.
+         * @return the illumination.
+         */
+        double illumination() {
+            return brightestIllumination;
+        }
+
+        /**
+         * Get the sample illuminating the element the most.
+         * @return the sample.
+         */
+        Map.Entry<RealVector, Double> sample() {
+            return brightestSample;
+        }
+    }
+
+    /**
+     * @param xval the arguments for the interpolation points.
+     * {@code xval[i][0]} is the first component of interpolation point
+     * {@code i}, {@code xval[i][1]} is the second component, and so on
+     * until {@code xval[i][d-1]}, the last component of that interpolation
+     * point (where {@code dimension} is thus the dimension of the sampled
+     * space).
+     * @param yval the values for the interpolation points
+     * @param brightnessExponent Brightness dimming factor.
+     * @param microsphereElements Number of surface elements of the
+     * microsphere.
+     * @param rand Unit vector generator for creating the microsphere.
+     * @throws DimensionMismatchException if the lengths of {@code yval} and
+     * {@code xval} (equal to {@code n}, the number of interpolation points)
+     * do not match, or the the arrays {@code xval[0]} ... {@code xval[n]},
+     * have lengths different from {@code dimension}.
+     * @throws IllegalArgumentException if there are no data (xval null or zero length)
+     */
+    public MicrosphereInterpolatingFunction(double[][] xval,
+                                            double[] yval,
+                                            int brightnessExponent,
+                                            int microsphereElements,
+                                            UnitSphereRandomVectorGenerator rand)
+        throws DimensionMismatchException, IllegalArgumentException {
+        if (xval.length == 0 || xval[0] == null) {
+            MathRuntimeException.createIllegalArgumentException("no data");
+        }
+
+        if (xval.length != yval.length) {
+            throw new DimensionMismatchException(xval.length, yval.length);
+        }
+
+        dimension = xval[0].length;
+        this.brightnessExponent = brightnessExponent;
+
+        // Copy data samples.
+        samples = new HashMap<RealVector, Double>(yval.length);
+        for (int i = 0, max = xval.length; i < max; i++) {
+            if (xval[i].length != dimension) {
+                throw new DimensionMismatchException(xval.length, yval.length);
+            }
+
+            samples.put(new ArrayRealVector(xval[i]), yval[i]);
+        }
+
+        microsphere = new ArrayList<MicrosphereSurfaceElement>(microsphereElements);
+        // Generate the microsphere, assuming that a fairly large number of
+        // randomly generated normals will represent a sphere.
+        for (int i = 0; i < microsphereElements; i++) {
+            microsphere.add(new MicrosphereSurfaceElement(rand.nextVector()));
+        }
+
+    }
+
+    /**
+     * @param point Interpolation point.
+     * @return the interpolated value.
+     */
+    public double value(double[] point)
+        throws FunctionEvaluationException {
+
+        final RealVector p = new ArrayRealVector(point);
+
+        // Reset.
+        for (MicrosphereSurfaceElement md : microsphere) {
+            md.reset();
+        }
+
+        // Compute contribution of each sample points to the microsphere elements illumination
+        for (Map.Entry<RealVector, Double> sd : samples.entrySet()) {
+
+            // Vector between interpolation point and current sample point.
+            final RealVector diff = sd.getKey().subtract(p);
+            final double diffNorm = diff.getNorm();
+
+            if (Math.abs(diffNorm) < Math.ulp(1d)) {
+                // No need to interpolate, as the interpolation point is
+                // actually (very close to) one of the sampled points.
+                return sd.getValue();
+            }
+
+            for (MicrosphereSurfaceElement md : microsphere) {
+                final double w = Math.pow(diffNorm, -brightnessExponent);
+                md.store(cosAngle(diff, md.normal()) * w, sd);
+            }
+
+        }
+
+        // Interpolation calculation.
+        double value = 0;
+        double totalWeight = 0;
+        for (MicrosphereSurfaceElement md : microsphere) {
+            final double iV = md.illumination();
+            final Map.Entry<RealVector, Double> sd = md.sample();
+            if (sd != null) {
+                value += iV * sd.getValue();
+                totalWeight += iV;
+            }
+        }
+
+        return value / totalWeight;
+
+    }
+
+    /**
+     * Compute the cosine of the angle between 2 vectors.
+     *
+     * @param v Vector.
+     * @param w Vector.
+     */
+    private double cosAngle(final RealVector v, final RealVector w) {
+        return v.dotProduct(w) / (v.getNorm() * w.getNorm());
+    }
+
+}

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

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

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java?rev=821626&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java
(added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolator.java
Sun Oct  4 21:57:30 2009
@@ -0,0 +1,122 @@
+/*
+ * 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.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.MathRuntimeException;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+import org.apache.commons.math.random.UnitSphereRandomVectorGenerator;
+
+/**
+ * Interpolator that implements the algorithm described in
+ * <em>William Dudziak</em>'s
+ * <a href="http://www.dudziak.com/microsphere.pdf">MS thesis</a>
+ *
+ * @version $Revision$ $Date$
+ */
+public class MicrosphereInterpolator
+    implements MultivariateRealInterpolator {
+
+    /**
+     * Default number of surface elements that composes the microsphere.
+     */
+    public static final int DEFAULT_MICROSPHERE_ELEMENTS = 2000;
+
+    /**
+     * Default exponent used the weights calculation.
+     */
+    public static final int DEFAULT_BRIGHTNESS_EXPONENT = 2;
+
+    /**
+     * Number of surface elements of the microsphere.
+     */
+    private int microsphereElements;
+
+    /**
+     * Exponent used in the power law that computes the weights of the
+     * sample data.
+     */
+    private int brightnessExponent;
+
+    /** Create a microsphere interpolator with default settings.
+     * <p>Calling this constructor is equivalent to call {@link
+     * #MicrosphereInterpolator(int, int)
+     * MicrosphereInterpolator(MicrosphereInterpolator.DEFAULT_MICROSPHERE_ELEMENTS,
+     * MicrosphereInterpolator.DEFAULT_BRIGHTNESS_EXPONENT)}.</p>
+     * weights of the sample data
+     */
+    public MicrosphereInterpolator() {
+        this(DEFAULT_MICROSPHERE_ELEMENTS, DEFAULT_BRIGHTNESS_EXPONENT);
+    }
+
+    /** Create a microsphere interpolator.
+     * @param microsphereElements number of surface elements of the microsphere
+     * @param brightnessExponent exponent used in the power law that computes the
+     * weights of the sample data
+     * @throws IllegalArgumentException if {@code microsphereElements <= 0}
+     * or {@code brightnessExponent < 0}
+     */
+    public MicrosphereInterpolator(final int microsphereElements,
+                                   final int brightnessExponent) {
+        setMicropshereElements(microsphereElements);
+        setBrightnessExponent(brightnessExponent);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public MultivariateRealFunction interpolate(final double[][] xval,
+                                                final double[] yval)
+        throws MathException, IllegalArgumentException {
+        final UnitSphereRandomVectorGenerator rand
+            = new UnitSphereRandomVectorGenerator(xval[0].length);
+        return new MicrosphereInterpolatingFunction(xval, yval,
+                                                    brightnessExponent,
+                                                    microsphereElements,
+                                                    rand);
+    }
+
+    /**
+     * Set the brightness exponent.
+     * @param brightnessExponent Exponent for computing the distance dimming
+     * factor.
+     * @throws IllegalArgumentException if {@code brightnessExponent < 0}.
+     */
+    public void setBrightnessExponent(final int brightnessExponent) {
+        if (brightnessExponent < 0) {
+            MathRuntimeException.createIllegalArgumentException(
+                "brightness exponent should be positive or null, but got {0}",
+                brightnessExponent);
+        }
+        this.brightnessExponent = brightnessExponent;
+    }
+
+    /**
+     * Set the number of microsphere elements.
+     * @param microsphereElements Number of surface elements of the microsphere.
+     * @throws IllegalArgumentException if {@code microsphereElements <= 0}.
+     */
+    public void setMicropshereElements(final int microsphereElements) {
+        if (microsphereElements < 0) {
+            MathRuntimeException.createIllegalArgumentException(
+                "number of microsphere elements must be positive, but got {0}",
+                microsphereElements);
+        }
+        this.microsphereElements = microsphereElements;
+    }
+
+}

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

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

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MultivariateRealInterpolator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MultivariateRealInterpolator.java?rev=821626&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MultivariateRealInterpolator.java
(added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/MultivariateRealInterpolator.java
Sun Oct  4 21:57:30 2009
@@ -0,0 +1,46 @@
+/*
+ * 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.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+
+/**
+ * Interface representing a univariate real interpolating function.
+ *  
+ * @version $Revision$ $Date$
+ */
+public interface MultivariateRealInterpolator {
+
+    /**
+     * Computes an interpolating function for the data set.
+     *
+     * @param xval the arguments for the interpolation points.
+     * {@code xval[i][0]} is the first component of interpolation point
+     * {@code i}, {@code xval[i][1]} is the second component, and so on
+     * until {@code xval[i][d-1]}, the last component of that interpolation
+     * point (where {@code d} is thus the dimension of the space).
+     * @param yval the values for the interpolation points
+     * @return a function which interpolates the data set
+     * @throws MathException if arguments violate assumptions made by the
+     *         interpolation algorithm or some dimension mismatch occurs
+     * @throws IllegalArgumentException if there are no data (xval null or zero length)
+     */
+    public MultivariateRealFunction interpolate(double[][] xval,
+                                                double[] yval)
+        throws MathException, IllegalArgumentException;
+}

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

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

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/UnivariateRealInterpolator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/UnivariateRealInterpolator.java?rev=821626&r1=821625&r2=821626&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/UnivariateRealInterpolator.java
(original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/analysis/interpolation/UnivariateRealInterpolator.java
Sun Oct  4 21:57:30 2009
@@ -32,7 +32,7 @@
      * @param yval the values for the interpolation points
      * @return a function which interpolates the data set
      * @throws MathException if arguments violate assumptions made by the
-     *         interpolationg algorithm
+     *         interpolation algorithm
      */
     UnivariateRealFunction interpolate(double xval[], double yval[])
         throws MathException;

Added: commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.java?rev=821626&view=auto
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.java
(added)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/UnitSphereRandomVectorGenerator.java
Sun Oct  4 21:57:30 2009
@@ -0,0 +1,81 @@
+/*
+ * 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.random;
+
+
+/**
+ * Generate random vectors isotropically located on the surface of a sphere.
+ *
+ * @version $Revision$ $Date$
+ */
+
+public class UnitSphereRandomVectorGenerator
+    implements RandomVectorGenerator {
+    /**
+     * RNG used for generating the individual components of the vectors.
+     */
+    private final RandomGenerator rand;
+    /**
+     * Space dimension.
+     */
+    private final int dimension;
+
+    /**
+     * @param dimension Space dimension.
+     * @param rand RNG for the individual components of the vectors.
+     */
+    public UnitSphereRandomVectorGenerator(final int dimension,
+                                           final RandomGenerator rand) {
+        this.dimension = dimension;
+        this.rand = rand;
+    }
+    /**
+     * Create an object that will use a default RNG ({@link MersenneTwister}),
+     * in order to generate the individual components.
+     *
+     * @param dimension Space dimension.
+     */
+    public UnitSphereRandomVectorGenerator(final int dimension) {
+        this(dimension, new MersenneTwister());
+    }
+
+    /** {@inheritDoc} */
+    public double[] nextVector() {
+
+        final double[] v = new double[dimension];
+
+        double normSq;
+        do {
+            normSq = 0;
+            for (int i = 0; i < dimension; i++) {
+                final double comp = 2 * rand.nextDouble() - 1;
+                v[i] = comp;
+                normSq += comp * comp;
+            }
+        } while (normSq > 1);
+
+        final double f = 1 / Math.sqrt(normSq);
+        for (int i = 0; i < dimension; i++) {
+            v[i] *= f;
+        }
+
+        return v;
+
+    }
+
+}

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

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

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=821626&r1=821625&r2=821626&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Sun Oct  4 21:57:30 2009
@@ -39,6 +39,9 @@
   </properties>
   <body>
     <release version="2.1" date="TBD" description="TBD">
+      <action dev="psteitz" tyoe="add" issue="MATH-300" due-to="Gilles Sadowski">
+        Added support for multidimensional interpolation using the robust microsphere algorithm.
+      </action>
       <action dev="psteitz" tyoe="fix" issue="MATH-298">
         Fixed implementation of EmpiricalDistributionImpl#getUpperBounds to match
         interface contract.  Added getGeneratorUpperBounds method to

Modified: commons/proper/math/trunk/src/site/xdoc/userguide/analysis.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/userguide/analysis.xml?rev=821626&r1=821625&r2=821626&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/userguide/analysis.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/userguide/analysis.xml Sun Oct  4 21:57:30 2009
@@ -302,6 +302,11 @@
           Locally Weighted Regression and Smoothing Scatterplots</a>. This kind of
           interpolation is computationally intensive but robust.
         </p>
+        <p>
+          Microsphere interpolation is a robust multidimensional interpolation algorithm.
+          It has been described in William Dudziak's <a
+          href="http://www.dudziak.com/microsphere.pdf">MS thesis</a>.
+        </p>
       </subsection>
       <subsection name="4.4 Integration" href="integration">
         <p>

Added: commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatorTest.java?rev=821626&view=auto
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatorTest.java
(added)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/analysis/interpolation/MicrosphereInterpolatorTest.java
Sun Oct  4 21:57:30 2009
@@ -0,0 +1,132 @@
+/*
+ * 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.interpolation;
+
+import org.apache.commons.math.MathException;
+import org.apache.commons.math.analysis.MultivariateRealFunction;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Testcase for the "microsphere projection" interpolator.
+ * 
+ * @version $Revision$ $Date$ 
+ */
+public final class MicrosphereInterpolatorTest {
+    /**
+     * Test of interpolator for a plane.
+     * <p>
+     * y = 2 x<sub>1</sub> - 3 x<sub>2</sub> + 5
+     */
+    @Test
+    public void testLinearFunction2D() throws MathException {
+        MultivariateRealFunction f = new MultivariateRealFunction() {
+                public double value(double[] x) {
+                    if (x.length != 2) {
+                        throw new IllegalArgumentException();
+                    }
+                    return 2 * x[0] - 3 * x[1] + 5;
+                }
+            };
+
+        MultivariateRealInterpolator interpolator = new MicrosphereInterpolator();
+
+        // Interpolating points in [-1, 1][-1, 1] by steps of 1.
+        final int n = 9;
+        final int dim = 2;
+        double[][] x = new double[n][dim];
+        double[] y = new double[n];
+        int index = 0;
+        for (int i = -1; i <= 1; i++) {
+            for (int j = -1; j <= 1; j++) {
+                x[index][0] = i;
+                x[index][1] = j;
+                y[index] = f.value(x[index]);
+                ++index;
+            }
+        }
+
+        MultivariateRealFunction p = interpolator.interpolate(x, y);
+
+        double[] c = new double[dim];
+        double expected, result;
+
+        c[0] = 0;
+        c[1] = 0;
+        expected = f.value(c);
+        result = p.value(c);
+        Assert.assertEquals("On sample point", expected, result, Math.ulp(1d));
+
+        c[0] = 0 + 1e-5;
+        c[1] = 1 - 1e-5;
+        expected = f.value(c);
+        result = p.value(c);
+        Assert.assertEquals("1e-5 away from sample point", expected, result, 1e-4);
+    }
+
+    /**
+     * Test of interpolator for a quadratic function.
+     * <p>
+     * y = 2 x<sub>1</sub><sup>2</sup> - 3 x<sub>2</sub><sup>2</sup>
+     *     + 4 x<sub>1</sub> x<sub>2</sub> - 5
+     */
+    @Test
+    public void testParaboloid2D() throws MathException {
+        MultivariateRealFunction f = new MultivariateRealFunction() {
+                public double value(double[] x) {
+                    if (x.length != 2) {
+                        throw new IllegalArgumentException();
+                    }
+                    return 2 * x[0] * x[0] - 3 * x[1] * x[1] + 4 * x[0] * x[1] - 5;
+                }
+            };
+
+        MultivariateRealInterpolator interpolator = new MicrosphereInterpolator();
+
+        // Interpolating points in [-10, 10][-10, 10] by steps of 2.
+        final int n = 121;
+        final int dim = 2;
+        double[][] x = new double[n][dim];
+        double[] y = new double[n];
+        int index = 0;
+        for (int i = -10; i <= 10; i += 2) {
+            for (int j = -10; j <= 10; j += 2) {
+                x[index][0] = i;
+                x[index][1] = j;
+                y[index] = f.value(x[index]);
+                ++index;
+            }
+        }
+
+        MultivariateRealFunction p = interpolator.interpolate(x, y);
+
+        double[] c = new double[dim];
+        double expected, result;
+
+        c[0] = 0;
+        c[1] = 0;
+        expected = f.value(c);
+        result = p.value(c);
+        Assert.assertEquals("On sample point", expected, result, Math.ulp(1d));
+
+        c[0] = 2 + 1e-5;
+        c[1] = 2 - 1e-5;
+        expected = f.value(c);
+        result = p.value(c);
+        Assert.assertEquals("1e-5 away from sample point", expected, result, 1e-3);
+    }
+}

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

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



Mime
View raw message