You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ra...@apache.org on 2017/05/12 21:32:40 UTC
[31/31] [math] MATH-1284: Merge branch 'feature-MATH-1284'
MATH-1284: Merge branch 'feature-MATH-1284'
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/7a59c0af
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/7a59c0af
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/7a59c0af
Branch: refs/heads/master
Commit: 7a59c0af26177cf69e702eaac85471e54762f664
Parents: bf91584 c9e49fa
Author: Ray DeCampo <ra...@decampo.org>
Authored: Fri May 12 17:30:53 2017 -0400
Committer: Ray DeCampo <ra...@decampo.org>
Committed: Fri May 12 17:30:53 2017 -0400
----------------------------------------------------------------------
findbugs-exclude-filter.xml | 6 +-
.../apache/commons/math4/geometry/Vector.java | 19 +-
.../geometry/euclidean/oned/Cartesian1D.java | 387 ++++++
.../geometry/euclidean/oned/IntervalsSet.java | 18 +-
.../geometry/euclidean/oned/OrientedPoint.java | 8 +-
.../math4/geometry/euclidean/oned/Vector1D.java | 344 +----
.../geometry/euclidean/oned/Vector1DFormat.java | 2 +-
.../geometry/euclidean/threed/Cartesian3D.java | 621 +++++++++
.../euclidean/threed/FieldRotation.java | 100 +-
.../euclidean/threed/FieldVector3D.java | 92 +-
.../math4/geometry/euclidean/threed/Line.java | 80 +-
.../euclidean/threed/OutlineExtractor.java | 46 +-
.../math4/geometry/euclidean/threed/Plane.java | 132 +-
.../euclidean/threed/PolyhedronsSet.java | 96 +-
.../geometry/euclidean/threed/Rotation.java | 246 ++--
.../euclidean/threed/RotationConvention.java | 16 +-
.../euclidean/threed/RotationOrder.java | 38 +-
.../geometry/euclidean/threed/Segment.java | 10 +-
.../euclidean/threed/SphereGenerator.java | 22 +-
.../euclidean/threed/SphericalCoordinates.java | 10 +-
.../geometry/euclidean/threed/SubLine.java | 14 +-
.../geometry/euclidean/threed/SubPlane.java | 14 +-
.../geometry/euclidean/threed/Vector3D.java | 572 +-------
.../euclidean/threed/Vector3DFormat.java | 2 +-
.../geometry/euclidean/twod/Cartesian2D.java | 492 +++++++
.../geometry/euclidean/twod/DiskGenerator.java | 16 +-
.../math4/geometry/euclidean/twod/Line.java | 88 +-
.../geometry/euclidean/twod/NestedLoops.java | 14 +-
.../geometry/euclidean/twod/PolygonsSet.java | 78 +-
.../math4/geometry/euclidean/twod/Segment.java | 14 +-
.../math4/geometry/euclidean/twod/SubLine.java | 22 +-
.../math4/geometry/euclidean/twod/Vector2D.java | 447 +------
.../geometry/euclidean/twod/Vector2DFormat.java | 2 +-
.../hull/AbstractConvexHullGenerator2D.java | 10 +-
.../twod/hull/AklToussaintHeuristic.java | 34 +-
.../euclidean/twod/hull/ConvexHull2D.java | 32 +-
.../twod/hull/ConvexHullGenerator2D.java | 6 +-
.../euclidean/twod/hull/MonotoneChain.java | 28 +-
.../geometry/partitioning/AbstractRegion.java | 6 +-
.../math4/geometry/partitioning/Embedding.java | 4 +-
.../math4/geometry/spherical/oned/S1Point.java | 14 +-
.../math4/geometry/spherical/twod/Circle.java | 38 +-
.../math4/geometry/spherical/twod/Edge.java | 4 +-
.../geometry/spherical/twod/EdgesBuilder.java | 10 +-
.../spherical/twod/PropertiesComputer.java | 30 +-
.../math4/geometry/spherical/twod/S2Point.java | 32 +-
.../spherical/twod/SphericalPolygonsSet.java | 28 +-
.../geometry/spherical/twod/SubCircle.java | 4 +-
src/site/design/threeD.puml | 4 +-
src/site/design/twoD.puml | 4 +-
src/site/xdoc/userguide/geometry.xml | 16 +-
src/site/xdoc/userguide/leastsquares.xml | 20 +-
.../commons/math4/complex/QuaternionTest.java | 30 +-
...stractLeastSquaresOptimizerAbstractTest.java | 6 +-
.../fitting/leastsquares/CircleVectorial.java | 18 +-
.../GaussNewtonOptimizerWithSVDTest.java | 6 +-
.../LevenbergMarquardtOptimizerTest.java | 6 +-
.../RandomCirclePointGenerator.java | 10 +-
.../geometry/enclosing/WelzlEncloser2DTest.java | 56 +-
.../geometry/enclosing/WelzlEncloser3DTest.java | 110 +-
.../euclidean/oned/Cartesian1DTest.java | 219 +++
.../euclidean/oned/IntervalsSetTest.java | 44 +-
.../oned/Vector1DFormatAbstractTest.java | 45 +-
.../geometry/euclidean/oned/Vector1DTest.java | 220 ---
.../euclidean/threed/FieldRotationDSTest.java | 20 +-
.../euclidean/threed/FieldRotationDfpTest.java | 6 +-
.../euclidean/threed/FieldVector3DTest.java | 70 +-
.../geometry/euclidean/threed/LineTest.java | 76 +-
.../geometry/euclidean/threed/PLYParser.java | 8 +-
.../geometry/euclidean/threed/PlaneTest.java | 88 +-
.../euclidean/threed/PolyhedronsSetTest.java | 146 +-
.../geometry/euclidean/threed/RotationTest.java | 250 ++--
.../euclidean/threed/SphereGeneratorTest.java | 114 +-
.../threed/SphericalCoordinatesTest.java | 30 +-
.../geometry/euclidean/threed/SubLineTest.java | 60 +-
.../threed/Vector3DFormatAbstractTest.java | 50 +-
.../geometry/euclidean/threed/Vector3DTest.java | 246 ++--
.../euclidean/twod/Cartesian2DTest.java | 235 ++++
.../euclidean/twod/DiskGeneratorTest.java | 58 +-
.../math4/geometry/euclidean/twod/LineTest.java | 67 +-
.../euclidean/twod/NestedLoopsTest.java | 16 +-
.../euclidean/twod/PolygonsSetTest.java | 1260 +++++++++---------
.../geometry/euclidean/twod/SegmentTest.java | 14 +-
.../geometry/euclidean/twod/SubLineTest.java | 60 +-
.../twod/Vector2DFormatAbstractTest.java | 50 +-
.../geometry/euclidean/twod/Vector2DTest.java | 235 ----
.../twod/hull/AklToussaintHeuristicTest.java | 4 +-
.../hull/ConvexHullGenerator2DAbstractTest.java | 226 ++--
.../euclidean/twod/hull/MonotoneChainTest.java | 22 +-
.../geometry/partitioning/RegionDumper.java | 10 +-
.../geometry/partitioning/RegionParser.java | 16 +-
.../geometry/spherical/twod/CircleTest.java | 80 +-
.../twod/SphericalPolygonsSetTest.java | 152 +--
.../geometry/spherical/twod/SubCircleTest.java | 34 +-
.../MultiStartMultivariateOptimizerTest.java | 4 +-
.../nonlinear/scalar/gradient/CircleScalar.java | 18 +-
...NonLinearConjugateGradientOptimizerTest.java | 4 +-
.../userguide/ClusterAlgorithmComparison.java | 40 +-
.../LowDiscrepancyGeneratorComparison.java | 43 +-
.../userguide/geometry/GeometryExample.java | 36 +-
.../math4/userguide/sofm/ChineseRings.java | 20 +-
.../userguide/sofm/ChineseRingsClassifier.java | 10 +-
102 files changed, 4634 insertions(+), 4406 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/main/java/org/apache/commons/math4/geometry/euclidean/oned/IntervalsSet.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldVector3D.java
----------------------------------------------------------------------
diff --cc src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldVector3D.java
index 4f04edf,6f93fdd..c49dd76
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldVector3D.java
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/FieldVector3D.java
@@@ -535,10 -535,10 +535,10 @@@ public class FieldVector3D<T extends Re
* following example shows how to build a frame having the k axis
* aligned with the known vector u :
* <pre><code>
- * Vector3D k = u.normalize();
- * Vector3D i = k.orthogonal();
- * Vector3D j = Vector3D.crossProduct(k, i);
+ * Cartesian3D k = u.normalize();
+ * Cartesian3D i = k.orthogonal();
+ * Cartesian3D j = Cartesian3D.crossProduct(k, i);
- * </code></pre></p>
+ * </code></pre>
* @return a new normalized vector orthogonal to the instance
* @exception MathArithmeticException if the norm of the instance is null
*/
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Line.java
----------------------------------------------------------------------
diff --cc src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Line.java
index 6b14f6e,4ec55a3..6b467fc
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Line.java
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Line.java
@@@ -22,10 -22,10 +22,10 @@@ import org.apache.commons.math4.geometr
import org.apache.commons.math4.geometry.Vector;
import org.apache.commons.math4.geometry.euclidean.oned.Euclidean1D;
import org.apache.commons.math4.geometry.euclidean.oned.IntervalsSet;
- import org.apache.commons.math4.geometry.euclidean.oned.Vector1D;
+ import org.apache.commons.math4.geometry.euclidean.oned.Cartesian1D;
import org.apache.commons.math4.geometry.partitioning.Embedding;
import org.apache.commons.math4.util.FastMath;
-import org.apache.commons.math4.util.Precision;
+import org.apache.commons.numbers.core.Precision;
/** The class represent lines in a three dimensional space.
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/PolygonsSet.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/hull/ConvexHull2D.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/hull/MonotoneChain.java
----------------------------------------------------------------------
diff --cc src/main/java/org/apache/commons/math4/geometry/euclidean/twod/hull/MonotoneChain.java
index d23a902,42cbc33..e77d4e3
--- a/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/hull/MonotoneChain.java
+++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/twod/hull/MonotoneChain.java
@@@ -23,9 -23,9 +23,9 @@@ import java.util.Comparator
import java.util.List;
import org.apache.commons.math4.geometry.euclidean.twod.Line;
- import org.apache.commons.math4.geometry.euclidean.twod.Vector2D;
+ import org.apache.commons.math4.geometry.euclidean.twod.Cartesian2D;
import org.apache.commons.math4.util.FastMath;
-import org.apache.commons.math4.util.Precision;
+import org.apache.commons.numbers.core.Precision;
/**
* Implements Andrew's monotone chain method to generate the convex hull of a finite set of
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/test/java/org/apache/commons/math4/fitting/leastsquares/AbstractLeastSquaresOptimizerAbstractTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/test/java/org/apache/commons/math4/fitting/leastsquares/LevenbergMarquardtOptimizerTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/test/java/org/apache/commons/math4/geometry/euclidean/oned/Cartesian1DTest.java
----------------------------------------------------------------------
diff --cc src/test/java/org/apache/commons/math4/geometry/euclidean/oned/Cartesian1DTest.java
index 0000000,2b60c3d..a01c9ef
mode 000000,100644..100644
--- a/src/test/java/org/apache/commons/math4/geometry/euclidean/oned/Cartesian1DTest.java
+++ b/src/test/java/org/apache/commons/math4/geometry/euclidean/oned/Cartesian1DTest.java
@@@ -1,0 -1,219 +1,219 @@@
+ /*
+ * 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.math4.geometry.euclidean.oned;
+
+ import java.text.DecimalFormat;
+ import java.text.DecimalFormatSymbols;
+ import java.text.NumberFormat;
+ import java.util.Locale;
+
+ import org.apache.commons.math4.exception.DimensionMismatchException;
+ import org.apache.commons.math4.exception.MathArithmeticException;
+ import org.apache.commons.math4.geometry.Space;
+ import org.apache.commons.math4.util.FastMath;
-import org.apache.commons.math4.util.Precision;
++import org.apache.commons.numbers.core.Precision;
+ import org.junit.Assert;
+ import org.junit.Test;
+
+ public class Cartesian1DTest {
+ @Test
+ public void testConstructors() throws DimensionMismatchException {
+ checkVector(new Cartesian1D(3, new Cartesian1D(FastMath.PI / 3)),
+ FastMath.PI);
+ checkVector(new Cartesian1D(2, Cartesian1D.ONE, -3, new Cartesian1D(2)),
+ -4);
+ checkVector(new Cartesian1D(2, Cartesian1D.ONE,
+ 5, new Cartesian1D(2),
+ -3, new Cartesian1D(3)),
+ 3);
+ checkVector(new Cartesian1D(2, Cartesian1D.ONE,
+ 5, new Cartesian1D(2),
+ 5, new Cartesian1D(-2),
+ -3, new Cartesian1D(-3)),
+ 11);
+ }
+
+ @Test
+ public void testSpace() {
+ Space space = new Cartesian1D(1).getSpace();
+ Assert.assertEquals(1, space.getDimension());
+ }
+
+ @Test
+ public void testZero() {
+ Assert.assertEquals(0, new Cartesian1D(1).getZero().getNorm(), 1.0e-15);
+ }
+
+ @Test
+ public void testEquals() {
+ Cartesian1D u1 = new Cartesian1D(1);
+ Cartesian1D u2 = new Cartesian1D(1);
+ Assert.assertTrue(u1.equals(u1));
+ Assert.assertTrue(u1.equals(u2));
+ Assert.assertFalse(u1.equals(new Cartesian1D(1 + 10 * Precision.EPSILON)));
+ Assert.assertTrue(new Cartesian1D(Double.NaN).equals(new Cartesian1D(Double.NaN)));
+ }
+
+ @Test
+ public void testHash() {
+ Assert.assertEquals(new Cartesian1D(Double.NaN).hashCode(), new Cartesian1D(Double.NaN).hashCode());
+ Cartesian1D u = new Cartesian1D(1);
+ Cartesian1D v = new Cartesian1D(1 + 10 * Precision.EPSILON);
+ Assert.assertTrue(u.hashCode() != v.hashCode());
+ }
+
+ @Test
+ public void testInfinite() {
+ Assert.assertTrue(new Cartesian1D(Double.NEGATIVE_INFINITY).isInfinite());
+ Assert.assertTrue(new Cartesian1D(Double.POSITIVE_INFINITY).isInfinite());
+ Assert.assertFalse(new Cartesian1D(1).isInfinite());
+ Assert.assertFalse(new Cartesian1D(Double.NaN).isInfinite());
+ }
+
+ @Test
+ public void testNaN() {
+ Assert.assertTrue(new Cartesian1D(Double.NaN).isNaN());
+ Assert.assertFalse(new Cartesian1D(1).isNaN());
+ Assert.assertFalse(new Cartesian1D(Double.NEGATIVE_INFINITY).isNaN());
+ }
+
+ @Test
+ public void testToString() {
+ Assert.assertEquals("{3}", new Cartesian1D(3).toString());
+ NumberFormat format = new DecimalFormat("0.000", new DecimalFormatSymbols(Locale.US));
+ Assert.assertEquals("{3.000}", new Cartesian1D(3).toString(format));
+ }
+
+ @Test
+ public void testCoordinates() {
+ Cartesian1D v = new Cartesian1D(1);
+ Assert.assertTrue(FastMath.abs(v.getX() - 1) < 1.0e-12);
+ }
+
+ @Test
+ public void testNorm1() {
+ Assert.assertEquals(0.0, Cartesian1D.ZERO.getNorm1(), 0);
+ Assert.assertEquals(6.0, new Cartesian1D(6).getNorm1(), 0);
+ }
+
+ @Test
+ public void testNorm() {
+ Assert.assertEquals(0.0, Cartesian1D.ZERO.getNorm(), 0);
+ Assert.assertEquals(3.0, new Cartesian1D(-3).getNorm(), 1.0e-12);
+ }
+
+ @Test
+ public void testNormSq() {
+ Assert.assertEquals(0.0, new Cartesian1D(0).getNormSq(), 0);
+ Assert.assertEquals(9.0, new Cartesian1D(-3).getNormSq(), 1.0e-12);
+ }
+
+ @Test
+ public void testNormInf() {
+ Assert.assertEquals(0.0, Cartesian1D.ZERO.getNormInf(), 0);
+ Assert.assertEquals(3.0, new Cartesian1D(-3).getNormInf(), 0);
+ }
+
+ @Test
+ public void testDistance1() {
+ Cartesian1D v1 = new Cartesian1D(1);
+ Cartesian1D v2 = new Cartesian1D(-4);
+ Assert.assertEquals(0.0, new Cartesian1D(-1).distance1(new Cartesian1D(-1)), 0);
+ Assert.assertEquals(5.0, v1.distance1(v2), 1.0e-12);
+ Assert.assertEquals(v1.subtract(v2).getNorm1(), v1.distance1(v2), 1.0e-12);
+ }
+
+ @Test
+ public void testDistance() {
+ Cartesian1D v1 = new Cartesian1D(1);
+ Cartesian1D v2 = new Cartesian1D(-4);
+ Assert.assertEquals(0.0, Cartesian1D.distance(new Cartesian1D(-1), new Cartesian1D(-1)), 0);
+ Assert.assertEquals(5.0, Cartesian1D.distance(v1, v2), 1.0e-12);
+ Assert.assertEquals(v1.subtract(v2).getNorm(), Cartesian1D.distance(v1, v2), 1.0e-12);
+ }
+
+ @Test
+ public void testDistanceSq() {
+ Cartesian1D v1 = new Cartesian1D(1);
+ Cartesian1D v2 = new Cartesian1D(-4);
+ Assert.assertEquals(0.0, Cartesian1D.distanceSq(new Cartesian1D(-1), new Cartesian1D(-1)), 0);
+ Assert.assertEquals(25.0, Cartesian1D.distanceSq(v1, v2), 1.0e-12);
+ Assert.assertEquals(Cartesian1D.distance(v1, v2) * Cartesian1D.distance(v1, v2),
+ Cartesian1D.distanceSq(v1, v2), 1.0e-12);
+ }
+
+ @Test
+ public void testDistanceInf() {
+ Cartesian1D v1 = new Cartesian1D(1);
+ Cartesian1D v2 = new Cartesian1D(-4);
+ Assert.assertEquals(0.0, Cartesian1D.distanceInf(new Cartesian1D(-1), new Cartesian1D(-1)), 0);
+ Assert.assertEquals(5.0, Cartesian1D.distanceInf(v1, v2), 1.0e-12);
+ Assert.assertEquals(v1.subtract(v2).getNormInf(), Cartesian1D.distanceInf(v1, v2), 1.0e-12);
+ }
+
+ @Test
+ public void testSubtract() {
+ Cartesian1D v1 = new Cartesian1D(1);
+ Cartesian1D v2 = new Cartesian1D(-3);
+ v1 = v1.subtract(v2);
+ checkVector(v1, 4);
+
+ checkVector(v2.subtract(v1), -7);
+ checkVector(v2.subtract(3, v1), -15);
+ }
+
+ @Test
+ public void testAdd() {
+ Cartesian1D v1 = new Cartesian1D(1);
+ Cartesian1D v2 = new Cartesian1D(-3);
+ v1 = v1.add(v2);
+ checkVector(v1, -2);
+
+ checkVector(v2.add(v1), -5);
+ checkVector(v2.add(3, v1), -9);
+ }
+
+ @Test
+ public void testScalarProduct() {
+ Cartesian1D v = new Cartesian1D(1);
+ v = v.scalarMultiply(3);
+ checkVector(v, 3);
+
+ checkVector(v.scalarMultiply(0.5), 1.5);
+ }
+
+ @Test
+ public void testNormalize() throws MathArithmeticException {
+ Assert.assertEquals(1.0, new Cartesian1D(5).normalize().getNorm(), 1.0e-12);
+ try {
+ Cartesian1D.ZERO.normalize();
+ Assert.fail("an exception should have been thrown");
+ } catch (MathArithmeticException ae) {
+ // expected behavior
+ }
+ }
+
+ @Test
+ public void testNegate() {
+ checkVector(new Cartesian1D(0.1).negate(), -0.1);
+ }
+
+ private void checkVector(Cartesian1D v, double x) {
+ Assert.assertEquals(x, v.getX(), 1.0e-12);
+ }
+ }
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/test/java/org/apache/commons/math4/geometry/euclidean/oned/IntervalsSetTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/test/java/org/apache/commons/math4/geometry/euclidean/threed/FieldVector3DTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/test/java/org/apache/commons/math4/geometry/euclidean/threed/PLYParser.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/test/java/org/apache/commons/math4/geometry/euclidean/threed/Vector3DTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/test/java/org/apache/commons/math4/geometry/euclidean/twod/hull/ConvexHullGenerator2DAbstractTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/test/java/org/apache/commons/math4/optim/nonlinear/scalar/MultiStartMultivariateOptimizerTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/test/java/org/apache/commons/math4/optim/nonlinear/scalar/gradient/NonLinearConjugateGradientOptimizerTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/7a59c0af/src/userguide/java/org/apache/commons/math4/userguide/sofm/ChineseRingsClassifier.java
----------------------------------------------------------------------