From 9ec53e16d65c7ec818424cd34bd32df1fbbf4303 Mon Sep 17 00:00:00 2001 From: Phil Steitz Date: Sat, 11 Apr 2015 13:45:50 -0700 Subject: [PATCH 1/7] Dropped vestigal methods from test distributions. --- .../AbstractRealDistributionTest.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/test/java/org/apache/commons/math4/distribution/AbstractRealDistributionTest.java b/src/test/java/org/apache/commons/math4/distribution/AbstractRealDistributionTest.java index d0b27611a..a13a12a90 100644 --- a/src/test/java/org/apache/commons/math4/distribution/AbstractRealDistributionTest.java +++ b/src/test/java/org/apache/commons/math4/distribution/AbstractRealDistributionTest.java @@ -91,14 +91,6 @@ public class AbstractRealDistributionTest { return false; } - public boolean isSupportLowerBoundInclusive() { - return true; - } - - public boolean isSupportUpperBoundInclusive() { - return true; - } - @Override public double probability(final double x) { throw new UnsupportedOperationException(); @@ -190,14 +182,6 @@ public class AbstractRealDistributionTest { return false; } - public boolean isSupportLowerBoundInclusive() { - return true; - } - - public boolean isSupportUpperBoundInclusive() { - return true; - } - @Override public double probability(final double x) { throw new UnsupportedOperationException(); From b6488f0869b79d3ba5a1ea1d3221e9ea191182d5 Mon Sep 17 00:00:00 2001 From: Phil Steitz Date: Sat, 11 Apr 2015 14:04:59 -0700 Subject: [PATCH 2/7] Added @Overrides. --- .../distribution/AbstractRealDistributionTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/java/org/apache/commons/math4/distribution/AbstractRealDistributionTest.java b/src/test/java/org/apache/commons/math4/distribution/AbstractRealDistributionTest.java index a13a12a90..cff0c0837 100644 --- a/src/test/java/org/apache/commons/math4/distribution/AbstractRealDistributionTest.java +++ b/src/test/java/org/apache/commons/math4/distribution/AbstractRealDistributionTest.java @@ -38,6 +38,7 @@ public class AbstractRealDistributionTest { distribution = new AbstractRealDistribution(null) { private static final long serialVersionUID = 1L; + @Override public double cumulativeProbability(final double x) { if ((x < x0) || (x > x3)) { throw new OutOfRangeException(x, x0, x3); @@ -52,6 +53,7 @@ public class AbstractRealDistributionTest { return 0.0; } + @Override public double density(final double x) { if ((x < x0) || (x > x3)) { throw new OutOfRangeException(x, x0, x3); @@ -66,10 +68,12 @@ public class AbstractRealDistributionTest { return 0.0; } + @Override public double getNumericalMean() { return ((x0 + x1) * p12 + (x2 + x3) * (1.0 - p12)) / 2.0; } + @Override public double getNumericalVariance() { final double meanX = getNumericalMean(); final double meanX2; @@ -79,14 +83,17 @@ public class AbstractRealDistributionTest { return meanX2 - meanX * meanX; } + @Override public double getSupportLowerBound() { return x0; } + @Override public double getSupportUpperBound() { return x3; } + @Override public boolean isSupportConnected() { return false; } @@ -115,6 +122,7 @@ public class AbstractRealDistributionTest { distribution = new AbstractRealDistribution(null) { private static final long serialVersionUID = 1L; + @Override public double cumulativeProbability(final double x) { if ((x < x0) || (x > x4)) { throw new OutOfRangeException(x, x0, x4); @@ -130,6 +138,7 @@ public class AbstractRealDistributionTest { } } + @Override public double density(final double x) { if ((x < x0) || (x > x4)) { throw new OutOfRangeException(x, x0, x4); @@ -145,6 +154,7 @@ public class AbstractRealDistributionTest { } } + @Override public double getNumericalMean() { final UnivariateFunction f = new UnivariateFunction() { @@ -156,6 +166,7 @@ public class AbstractRealDistributionTest { return integrator.integrate(Integer.MAX_VALUE, f, x0, x4); } + @Override public double getNumericalVariance() { final double meanX = getNumericalMean(); final UnivariateFunction f = new UnivariateFunction() { @@ -170,14 +181,17 @@ public class AbstractRealDistributionTest { return meanX2 - meanX * meanX; } + @Override public double getSupportLowerBound() { return x0; } + @Override public double getSupportUpperBound() { return x4; } + @Override public boolean isSupportConnected() { return false; } From 4aa1d98adf4520f62ac895a0aa76607300779348 Mon Sep 17 00:00:00 2001 From: Phil Steitz Date: Sat, 11 Apr 2015 14:34:08 -0700 Subject: [PATCH 3/7] Added missing serial version ids. --- .../apache/commons/math4/ml/neuralnet/oned/NeuronString.java | 2 ++ .../commons/math4/ml/neuralnet/twod/NeuronSquareMesh2D.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/org/apache/commons/math4/ml/neuralnet/oned/NeuronString.java b/src/main/java/org/apache/commons/math4/ml/neuralnet/oned/NeuronString.java index 94aff98d8..ba454caa1 100644 --- a/src/main/java/org/apache/commons/math4/ml/neuralnet/oned/NeuronString.java +++ b/src/main/java/org/apache/commons/math4/ml/neuralnet/oned/NeuronString.java @@ -32,6 +32,8 @@ import org.apache.commons.math4.ml.neuralnet.Network; * @since 3.3 */ public class NeuronString implements Serializable { + /** Serial version ID */ + private static final long serialVersionUID = 1L; /** Underlying network. */ private final Network network; /** Number of neurons. */ diff --git a/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2D.java b/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2D.java index a6f4315b0..3463b7552 100644 --- a/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2D.java +++ b/src/main/java/org/apache/commons/math4/ml/neuralnet/twod/NeuronSquareMesh2D.java @@ -42,6 +42,8 @@ import org.apache.commons.math4.ml.neuralnet.SquareNeighbourhood; * @since 3.3 */ public class NeuronSquareMesh2D implements Serializable { + /** Serial version ID */ + private static final long serialVersionUID = 1L; /** Underlying network. */ private final Network network; /** Number of rows. */ From fa6fcf2080a7d2a2202713035d887d80e8a9400d Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Sun, 12 Apr 2015 17:15:55 +0200 Subject: [PATCH 4/7] Added a way to build polyhedrons sets from vertices and facets. --- pom.xml | 8 +- src/changes/changes.xml | 4 + .../exception/util/LocalizedFormats.java | 4 + .../geometry/euclidean/threed/Plane.java | 8 +- .../euclidean/threed/PolyhedronsSet.java | 201 +++++++++++- .../util/LocalizedFormats_fr.properties | 4 + .../exception/util/LocalizedFormatsTest.java | 2 +- .../geometry/euclidean/threed/PLYParser.java | 290 ++++++++++++++++++ .../euclidean/threed/PolyhedronsSetTest.java | 91 +++++- .../threed/pentomino-N-bad-orientation.ply | 40 +++ .../euclidean/threed/pentomino-N-hole.ply | 39 +++ .../threed/pentomino-N-out-of-plane.ply | 40 +++ .../threed/pentomino-N-too-close.ply | 86 ++++++ .../geometry/euclidean/threed/pentomino-N.ply | 39 +++ 14 files changed, 835 insertions(+), 21 deletions(-) create mode 100644 src/test/java/org/apache/commons/math4/geometry/euclidean/threed/PLYParser.java create mode 100644 src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-bad-orientation.ply create mode 100644 src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-hole.ply create mode 100644 src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-out-of-plane.ply create mode 100644 src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-too-close.ply create mode 100644 src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N.ply diff --git a/pom.xml b/pom.xml index f9712b60d..ad8578d63 100644 --- a/pom.xml +++ b/pom.xml @@ -602,9 +602,15 @@ src/test/resources/org/apache/commons/math4/stat/data/NumAcc4.txt src/test/resources/org/apache/commons/math4/stat/data/Michelso.txt src/test/resources/org/apache/commons/math4/stat/data/Mavro.txt + src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/issue-1211.bsp + src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-bad-orientation.ply + src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-hole.ply + src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-out-of-plane.ply + src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-too-close.ply + src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-.ply + available under a BSD-style license (see LICENSE.txt) --> src/main/resources/assets/org/apache/commons/math4/random/new-joe-kuo-6.1000 diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 39fe6fedb..0bd49c497 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -54,6 +54,10 @@ If the output is not quite correct, check for invisible trailing spaces! + + Added a way to build polyhedrons sets from a list of vertices and + facets specified using vertices indices. + Fixed ignored method parameters in QRDecomposition protected methods. diff --git a/src/main/java/org/apache/commons/math4/exception/util/LocalizedFormats.java b/src/main/java/org/apache/commons/math4/exception/util/LocalizedFormats.java index 547bfe3f3..699a0cc5a 100644 --- a/src/main/java/org/apache/commons/math4/exception/util/LocalizedFormats.java +++ b/src/main/java/org/apache/commons/math4/exception/util/LocalizedFormats.java @@ -70,6 +70,7 @@ public enum LocalizedFormats implements Localizable { CANNOT_TRANSFORM_TO_DOUBLE("Conversion Exception in Transformation: {0}"), CARDAN_ANGLES_SINGULARITY("Cardan angles singularity"), CLASS_DOESNT_IMPLEMENT_COMPARABLE("class ({0}) does not implement Comparable"), + CLOSE_VERTICES("too close vertices near point ({0}, {1}, {2})"), CLOSEST_ORTHOGONAL_MATRIX_HAS_NEGATIVE_DETERMINANT("the closest orthogonal matrix has a negative determinant {0}"), COLUMN_INDEX_OUT_OF_RANGE("column index {0} out of allowed range [{1}, {2}]"), COLUMN_INDEX("column index ({0})"), /* keep */ @@ -91,6 +92,7 @@ public enum LocalizedFormats implements Localizable { DISCRETE_CUMULATIVE_PROBABILITY_RETURNED_NAN("Discrete cumulative probability function returned NaN for argument {0}"), DISTRIBUTION_NOT_LOADED("distribution not loaded"), DUPLICATED_ABSCISSA_DIVISION_BY_ZERO("duplicated abscissa {0} causes division by zero"), + EDGE_CONNECTED_TO_ONE_FACET("edge joining points ({0}, {1}, {2}) and ({3}, {4}, {5}) is connected to one facet only"), ELITISM_RATE("elitism rate ({0})"), EMPTY_CLUSTER_IN_K_MEANS("empty cluster in k-means"), EMPTY_INTERPOLATION_SAMPLE("sample for interpolation is empty"), @@ -103,6 +105,7 @@ public enum LocalizedFormats implements Localizable { EULER_ANGLES_SINGULARITY("Euler angles singularity"), EVALUATION("evaluation"), /* keep */ EXPANSION_FACTOR_SMALLER_THAN_ONE("expansion factor smaller than one ({0})"), + FACET_ORIENTATION_MISMATCH("facets orientation mismatch around edge joining points ({0}, {1}, {2}) and ({3}, {4}, {5})"), FACTORIAL_NEGATIVE_PARAMETER("must have n >= 0 for n!, got n = {0}"), FAILED_BRACKETING("number of iterations={4}, maximum iterations={5}, initial={6}, lower bound={7}, upper bound={8}, final a value={0}, final b value={1}, f(a)={2}, f(b)={3}"), FAILED_FRACTION_CONVERSION("Unable to convert {0} to fraction after {1} iterations"), @@ -284,6 +287,7 @@ public enum LocalizedFormats implements Localizable { OUT_OF_BOUND_SIGNIFICANCE_LEVEL("out of bounds significance level {0}, must be between {1} and {2}"), SIGNIFICANCE_LEVEL("significance level ({0})"), /* keep */ OUT_OF_ORDER_ABSCISSA_ARRAY("the abscissae array must be sorted in a strictly increasing order, but the {0}-th element is {1} whereas {2}-th is {3}"), + OUT_OF_PLANE("point ({0}, {1}, {2}) is out of plane"), OUT_OF_RANGE_ROOT_OF_UNITY_INDEX("out of range root of unity index {0} (must be in [{1};{2}])"), OUT_OF_RANGE("out of range"), /* keep */ OUT_OF_RANGE_SIMPLE("{0} out of [{1}, {2}] range"), /* keep */ diff --git a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Plane.java b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Plane.java index b8f2fa6fb..039f5f2e4 100644 --- a/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Plane.java +++ b/src/main/java/org/apache/commons/math4/geometry/euclidean/threed/Plane.java @@ -311,8 +311,8 @@ public class Plane implements Hyperplane, Embedding (FastMath.PI - 1.0e-10)) && (FastMath.abs(originOffset + plane.originOffset) < 1.0e-10)); + return ((angle < 1.0e-10) && (FastMath.abs(originOffset - plane.originOffset) < tolerance)) || + ((angle > (FastMath.PI - 1.0e-10)) && (FastMath.abs(originOffset + plane.originOffset) < tolerance)); } /** Rotate the plane around the specified point. @@ -375,7 +375,7 @@ public class Plane implements Hyperplane, Embedding, Embedding { super(tree, tolerance); } - /** Build a polyhedrons set from a Boundary REPresentation (B-rep). + /** Build a polyhedrons set from a Boundary REPresentation (B-rep) specified by sub-hyperplanes. *

The boundary is provided as a collection of {@link * SubHyperplane sub-hyperplanes}. Each sub-hyperplane has the * interior part of the region on its minus side and the exterior on @@ -99,6 +106,29 @@ public class PolyhedronsSet extends AbstractRegion { super(boundary, tolerance); } + /** Build a polyhedrons set from a Boundary REPresentation (B-rep) specified by connected vertices. + *

+ * The boundary is provided as a list of vertices and a list of facets. + * Each facet is specified as an integer array containing the arrays vertices + * indices in the vertices list. Each facet normal is oriented by right hand + * rule to the facet vertices list. + *

+ *

+ * Some basic sanity checks are performed but not everything is thoroughly + * assessed, so it remains under caller responsibility to ensure the vertices + * and facets are consistent and properly define a polyhedrons set. + *

+ * @param vertices list of polyhedrons set vertices + * @param facets list of facets, as vertices indices in the vertices list + * @param tolerance tolerance below which points are considered identical + * @exception MathIllegalArgumentException if some basic sanity checks fail + * @since 3.5 + */ + public PolyhedronsSet(final List vertices, final List facets, + final double tolerance) { + super(buildBoundary(vertices, facets, tolerance), tolerance); + } + /** Build a parallellepipedic box. * @param xMin low bound along the x direction * @param xMax high bound along the x direction @@ -147,6 +177,175 @@ public class PolyhedronsSet extends AbstractRegion { return boundary.getTree(false); } + /** Build boundary from vertices and facets. + * @param vertices list of polyhedrons set vertices + * @param facets list of facets, as vertices indices in the vertices list + * @param tolerance tolerance below which points are considered identical + * @return boundary as a list of sub-hyperplanes + * @exception MathIllegalArgumentException if some basic sanity checks fail + * @since 3.5 + */ + private static List> buildBoundary(final List vertices, + final List facets, + final double tolerance) { + + // check vertices distances + for (int i = 0; i < vertices.size() - 1; ++i) { + final Vector3D vi = vertices.get(i); + for (int j = i + 1; j < vertices.size(); ++j) { + if (Vector3D.distance(vi, vertices.get(j)) <= tolerance) { + throw new MathIllegalArgumentException(LocalizedFormats.CLOSE_VERTICES, + vi.getX(), vi.getY(), vi.getZ()); + } + } + } + + // find how vertices are referenced by facets + final int[][] references = findReferences(vertices, facets); + + // find how vertices are linked together by edges along the facets they belong to + final int[][] successors = successors(vertices, facets, references); + + // check edges orientations + for (int vA = 0; vA < vertices.size(); ++vA) { + for (final int vB : successors[vA]) { + + if (vB >= 0) { + // when facets are properly oriented, if vB is the successor of vA on facet f1, + // then there must be an adjacent facet f2 where vA is the successor of vB + boolean found = false; + for (final int v : successors[vB]) { + found = found || (v == vA); + } + if (!found) { + final Vector3D start = vertices.get(vA); + final Vector3D end = vertices.get(vB); + throw new MathIllegalArgumentException(LocalizedFormats.EDGE_CONNECTED_TO_ONE_FACET, + start.getX(), start.getY(), start.getZ(), + end.getX(), end.getY(), end.getZ()); + } + } + } + } + + final List> boundary = new ArrayList>(); + + for (final int[] facet : facets) { + + // define facet plane from the first 3 points + Plane plane = new Plane(vertices.get(facet[0]), vertices.get(facet[1]), vertices.get(facet[2]), + tolerance); + + // check all points are in the plane + final Vector2D[] two2Points = new Vector2D[facet.length]; + for (int i = 0 ; i < facet.length; ++i) { + final Vector3D v = vertices.get(facet[i]); + if (!plane.contains(v)) { + throw new MathIllegalArgumentException(LocalizedFormats.OUT_OF_PLANE, + v.getX(), v.getY(), v.getZ()); + } + two2Points[i] = plane.toSubSpace(v); + } + + // create the polygonal facet + boundary.add(new SubPlane(plane, new PolygonsSet(tolerance, two2Points))); + + } + + return boundary; + + } + + /** Find the facets that reference each edges. + * @param vertices list of polyhedrons set vertices + * @param facets list of facets, as vertices indices in the vertices list + * @return references array such that r[v][k] = f for some k if facet f contains vertex v + * @exception MathIllegalArgumentException if some facets have fewer than 3 vertices + * @since 3.5 + */ + private static int[][] findReferences(final List vertices, final List facets) { + + // find the maximum number of facets a vertex belongs to + final int[] nbFacets = new int[vertices.size()]; + int maxFacets = 0; + for (final int[] facet : facets) { + if (facet.length < 3) { + throw new NumberIsTooSmallException(LocalizedFormats.WRONG_NUMBER_OF_POINTS, + 3, facet.length, true); + } + for (final int index : facet) { + maxFacets = FastMath.max(maxFacets, ++nbFacets[index]); + } + } + + // set up the references array + final int[][] references = new int[vertices.size()][maxFacets]; + for (int[] r : references) { + Arrays.fill(r, -1); + } + for (int f = 0; f < facets.size(); ++f) { + for (final int v : facets.get(f)) { + // vertex v is referenced by facet f + int k = 0; + while (k < maxFacets && references[v][k] >= 0) { + ++k; + } + references[v][k] = f; + } + } + + return references; + + } + + /** Find the successors of all vertices among all facets they belong to. + * @param vertices list of polyhedrons set vertices + * @param facets list of facets, as vertices indices in the vertices list + * @param references facets references array + * @return indices of vertices that follow vertex v in some facet (the array + * may contain extra entries at the end, set to negative indices) + * @exception MathIllegalArgumentException if the same vertex appears more than + * once in the successors list (which means one facet orientation is wrong) + * @since 3.5 + */ + private static int[][] successors(final List vertices, final List facets, + final int[][] references) { + + // create an array large enough + final int[][] successors = new int[vertices.size()][references[0].length]; + for (final int[] s : successors) { + Arrays.fill(s, -1); + } + + for (int v = 0; v < vertices.size(); ++v) { + for (int k = 0; k < successors[v].length && references[v][k] >= 0; ++k) { + + // look for vertex v + final int[] facet = facets.get(references[v][k]); + int i = 0; + while (i < facet.length && facet[i] != v) { + ++i; + } + + // we have found vertex v, we deduce its successor on current facet + successors[v][k] = facet[(i + 1) % facet.length]; + for (int l = 0; l < k; ++l) { + if (successors[v][l] == successors[v][k]) { + final Vector3D start = vertices.get(v); + final Vector3D end = vertices.get(successors[v][k]); + throw new MathIllegalArgumentException(LocalizedFormats.FACET_ORIENTATION_MISMATCH, + start.getX(), start.getY(), start.getZ(), + end.getX(), end.getY(), end.getZ()); + } + } + + } + } + + return successors; + + } + /** {@inheritDoc} */ @Override public PolyhedronsSet buildNew(final BSPTree tree) { diff --git a/src/main/resources/assets/org/apache/commons/math4/exception/util/LocalizedFormats_fr.properties b/src/main/resources/assets/org/apache/commons/math4/exception/util/LocalizedFormats_fr.properties index 678546aa0..eba92a0a0 100644 --- a/src/main/resources/assets/org/apache/commons/math4/exception/util/LocalizedFormats_fr.properties +++ b/src/main/resources/assets/org/apache/commons/math4/exception/util/LocalizedFormats_fr.properties @@ -43,6 +43,7 @@ CANNOT_SUBSTITUTE_ELEMENT_FROM_EMPTY_ARRAY = impossible de substituer un \u00e9l CANNOT_TRANSFORM_TO_DOUBLE = Exception de conversion dans une transformation : {0} CARDAN_ANGLES_SINGULARITY = singularit\u00e9 d''angles de Cardan CLASS_DOESNT_IMPLEMENT_COMPARABLE = la classe ({0}) n''implante pas l''interface Comparable +CLOSE_VERTICES = sommets trop proches \u00e0 proximit\u00e9 du point ({0}, {1}, {2}) CLOSEST_ORTHOGONAL_MATRIX_HAS_NEGATIVE_DETERMINANT = la matrice orthogonale la plus proche a un d\u00e9terminant n\u00e9gatif {0} COLUMN_INDEX_OUT_OF_RANGE = l''index de colonne {0} est hors du domaine autoris\u00e9 [{1}, {2}] COLUMN_INDEX = index de colonne ({0}) @@ -64,6 +65,7 @@ DIMENSIONS_MISMATCH = dimensions incoh\u00e9rentes DISCRETE_CUMULATIVE_PROBABILITY_RETURNED_NAN = Discr\u00e8tes fonction de probabilit\u00e9 cumulative retourn\u00e9 NaN \u00e0 l''argument de {0} DISTRIBUTION_NOT_LOADED = aucune distribution n''a \u00e9t\u00e9 charg\u00e9e DUPLICATED_ABSCISSA_DIVISION_BY_ZERO = la duplication de l''abscisse {0} engendre une division par z\u00e9ro +EDGE_CONNECTED_TO_ONE_FACET = l''ar\u00eate joignant les points ({0}, {1}, {2}) et ({3}, {4}, {5}) n''est connect\u00e9e qu''\u00e0 une seule facette ELITISM_RATE = proportion d''\u00e9litisme ({0}) EMPTY_CLUSTER_IN_K_MEANS = groupe vide dans l''algorithme des k-moyennes EMPTY_INTERPOLATION_SAMPLE = \u00e9chantillon d''interpolation vide @@ -76,6 +78,7 @@ EQUAL_VERTICES_IN_SIMPLEX = sommets {0} et {1} \u00e9gaux dans la configuration EULER_ANGLES_SINGULARITY = singularit\u00e9 d''angles d''Euler EVALUATION = \u00e9valuation EXPANSION_FACTOR_SMALLER_THAN_ONE = facteur d''extension inf\u00e9rieur \u00e0 un ({0}) +FACET_ORIENTATION_MISMATCH = orientations incoh\u00e9rentes des facettes de part et d''autre de l''ar\u00eate joignant les points ({0}, {1}, {2}) et ({3}, {4}, {5}) FACTORIAL_NEGATIVE_PARAMETER = n doit \u00eatre positif pour le calcul de n!, or n = {0} FAILED_BRACKETING = nombre d''it\u00e9rations = {4}, it\u00e9rations maximum = {5}, valeur initiale = {6}, borne inf\u00e9rieure = {7}, borne sup\u00e9rieure = {8}, valeur a finale = {0}, valeur b finale = {1}, f(a) = {2}, f(b) = {3} FAILED_FRACTION_CONVERSION = Impossible de convertir {0} en fraction apr\u00e8s {1} it\u00e9rations @@ -257,6 +260,7 @@ OUT_OF_BOUNDS_QUANTILE_VALUE = valeur de quantile {0} hors bornes, doit \u00eatr OUT_OF_BOUND_SIGNIFICANCE_LEVEL = niveau de signification {0} hors domaine, doit \u00eatre entre {1} et {2} SIGNIFICANCE_LEVEL = niveau de signification ({0}) OUT_OF_ORDER_ABSCISSA_ARRAY = les abscisses doivent \u00eatre en ordre strictement croissant, mais l''\u00e9l\u00e9ment {0} vaut {1} alors que l''\u00e9l\u00e9ment {2} vaut {3} +OUT_OF_PLANE = le point ({0}, {1}, {2}) est hors du plan OUT_OF_RANGE_ROOT_OF_UNITY_INDEX = l''indice de racine de l''unit\u00e9 {0} est hors du domaine autoris\u00e9 [{1};{2}] OUT_OF_RANGE_SIMPLE = {0} hors du domaine [{1}, {2}] OUT_OF_RANGE_LEFT = {0} hors du domaine ({1}, {2}] diff --git a/src/test/java/org/apache/commons/math4/exception/util/LocalizedFormatsTest.java b/src/test/java/org/apache/commons/math4/exception/util/LocalizedFormatsTest.java index b497780cb..6912f5f93 100644 --- a/src/test/java/org/apache/commons/math4/exception/util/LocalizedFormatsTest.java +++ b/src/test/java/org/apache/commons/math4/exception/util/LocalizedFormatsTest.java @@ -29,7 +29,7 @@ public class LocalizedFormatsTest { @Test public void testMessageNumber() { - Assert.assertEquals(322, LocalizedFormats.values().length); + Assert.assertEquals(326, LocalizedFormats.values().length); } @Test diff --git a/src/test/java/org/apache/commons/math4/geometry/euclidean/threed/PLYParser.java b/src/test/java/org/apache/commons/math4/geometry/euclidean/threed/PLYParser.java new file mode 100644 index 000000000..f65663cc2 --- /dev/null +++ b/src/test/java/org/apache/commons/math4/geometry/euclidean/threed/PLYParser.java @@ -0,0 +1,290 @@ +/* + * 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.threed; + +import java.io.BufferedReader; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.StringTokenizer; + +import org.apache.commons.math4.util.Precision; + +/** This class is a small and incomplete parser for PLY files. + *

+ * This parser is only intended for test purposes, it does not + * parse the full header, it does not handle all properties, + * it has rudimentary error handling. + *

+ * @since 3.5 + */ +public class PLYParser { + + /** Parsed vertices. */ + private Vector3D[] vertices; + + /** Parsed faces. */ + private int[][] faces; + + /** Reader for PLY data. */ + private BufferedReader br; + + /** Last parsed line. */ + private String line; + + /** Simple constructor. + * @param stream stream to parse (closing it remains caller responsibility) + * @exception IOException if stream cannot be read + * @exception ParseException if stream content cannot be parsed + */ + public PLYParser(final InputStream stream) + throws IOException, ParseException { + + try { + br = new BufferedReader(new InputStreamReader(stream, "UTF-8")); + + // parse the header + List fields = parseNextLine(); + if (fields.size() != 1 || fields.get(0).getToken() != Token.PLY) { + complain(); + } + + boolean parsing = true; + int nbVertices = -1; + int nbFaces = -1; + int xIndex = -1; + int yIndex = -1; + int zIndex = -1; + int vPropertiesNumber = -1; + boolean inVertexElt = false; + boolean inFaceElt = false; + while (parsing) { + fields = parseNextLine(); + if (fields.size() < 1) { + complain(); + } + switch (fields.get(0).getToken()) { + case FORMAT: + if (fields.size() != 3 || + fields.get(1).getToken() != Token.ASCII || + fields.get(2).getToken() != Token.UNKNOWN || + !Precision.equals(Double.parseDouble(fields.get(2).getValue()), 1.0, 0.001)) { + complain(); + } + inVertexElt = false; + inFaceElt = false; + break; + case COMMENT: + // we just ignore this line + break; + case ELEMENT: + if (fields.size() != 3 || + (fields.get(1).getToken() != Token.VERTEX && fields.get(1).getToken() != Token.FACE) || + fields.get(2).getToken() != Token.UNKNOWN) { + complain(); + } + if (fields.get(1).getToken() == Token.VERTEX) { + nbVertices = Integer.parseInt(fields.get(2).getValue()); + inVertexElt = true; + inFaceElt = false; + } else { + nbFaces = Integer.parseInt(fields.get(2).getValue()); + inVertexElt = false; + inFaceElt = true; + } + break; + case PROPERTY: + if (inVertexElt) { + ++vPropertiesNumber; + if (fields.size() != 3 || + (fields.get(1).getToken() != Token.CHAR && + fields.get(1).getToken() != Token.UCHAR && + fields.get(1).getToken() != Token.SHORT && + fields.get(1).getToken() != Token.USHORT && + fields.get(1).getToken() != Token.INT && + fields.get(1).getToken() != Token.UINT && + fields.get(1).getToken() != Token.FLOAT && + fields.get(1).getToken() != Token.DOUBLE)) { + complain(); + } + if (fields.get(2).getToken() == Token.X) { + xIndex = vPropertiesNumber; + }else if (fields.get(2).getToken() == Token.Y) { + yIndex = vPropertiesNumber; + }else if (fields.get(2).getToken() == Token.Z) { + zIndex = vPropertiesNumber; + } + } else if (inFaceElt) { + if (fields.size() != 5 || + fields.get(1).getToken() != Token.LIST && + (fields.get(2).getToken() != Token.CHAR && + fields.get(2).getToken() != Token.UCHAR && + fields.get(2).getToken() != Token.SHORT && + fields.get(2).getToken() != Token.USHORT && + fields.get(2).getToken() != Token.INT && + fields.get(2).getToken() != Token.UINT) || + (fields.get(3).getToken() != Token.CHAR && + fields.get(3).getToken() != Token.UCHAR && + fields.get(3).getToken() != Token.SHORT && + fields.get(3).getToken() != Token.USHORT && + fields.get(3).getToken() != Token.INT && + fields.get(3).getToken() != Token.UINT) || + fields.get(4).getToken() != Token.VERTEX_INDICES) { + complain(); + } + } else { + complain(); + } + break; + case END_HEADER: + inVertexElt = false; + inFaceElt = false; + parsing = false; + break; + default: + throw new ParseException("unable to parse line: " + line, 0); + } + } + ++vPropertiesNumber; + + // parse vertices + vertices = new Vector3D[nbVertices]; + for (int i = 0; i < nbVertices; ++i) { + fields = parseNextLine(); + if (fields.size() != vPropertiesNumber || + fields.get(xIndex).getToken() != Token.UNKNOWN || + fields.get(yIndex).getToken() != Token.UNKNOWN || + fields.get(zIndex).getToken() != Token.UNKNOWN) { + complain(); + } + vertices[i] = new Vector3D(Double.parseDouble(fields.get(xIndex).getValue()), + Double.parseDouble(fields.get(yIndex).getValue()), + Double.parseDouble(fields.get(zIndex).getValue())); + } + + // parse faces + faces = new int[nbFaces][]; + for (int i = 0; i < nbFaces; ++i) { + fields = parseNextLine(); + if (fields.isEmpty() || + fields.size() != (Integer.parseInt(fields.get(0).getValue()) + 1)) { + complain(); + } + faces[i] = new int[fields.size() - 1]; + for (int j = 0; j < faces[i].length; ++j) { + faces[i][j] = Integer.parseInt(fields.get(j + 1).getValue()); + } + } + + } catch (NumberFormatException nfe) { + complain(); + } + } + + /** Complain about a bad line. + * @exception ParseException always thrown + */ + private void complain() throws ParseException { + throw new ParseException("unable to parse line: " + line, 0); + } + + /** Parse next line. + * @return parsed fields + * @exception IOException if stream cannot be read + * @exception ParseException if the line does not contain the expected number of fields + */ + private List parseNextLine() + throws IOException, ParseException { + final List fields = new ArrayList(); + line = br.readLine(); + if (line == null) { + throw new EOFException(); + } + final StringTokenizer tokenizer = new StringTokenizer(line); + while (tokenizer.hasMoreTokens()) { + fields.add(new Field(tokenizer.nextToken())); + } + return fields; + } + + /** Get the parsed vertices. + * @return parsed vertices + */ + public List getVertices() { + return Arrays.asList(vertices); + } + + /** Get the parsed faces. + * @return parsed faces + */ + public List getFaces() { + return Arrays.asList(faces); + } + + /** Tokens from PLY files. */ + private static enum Token { + PLY, FORMAT, ASCII, BINARY_BIG_ENDIAN, BINARY_LITTLE_ENDIAN, + COMMENT, ELEMENT, VERTEX, FACE, PROPERTY, LIST, OBJ_INFO, + CHAR, UCHAR, SHORT, USHORT, INT, UINT, FLOAT, DOUBLE, + X, Y, Z, VERTEX_INDICES, END_HEADER, UNKNOWN; + } + + /** Parsed line fields. */ + private static class Field { + + /** Token. */ + private final Token token; + + /** Value. */ + private final String value; + + /** Simple constructor. + * @param value field value + */ + public Field(final String value) { + Token parsedToken = null; + try { + parsedToken = Token.valueOf(value.toUpperCase()); + } catch (IllegalArgumentException iae) { + parsedToken = Token.UNKNOWN; + } + this.token = parsedToken; + this.value = value; + } + + /** Get the recognized token. + * @return recognized token + */ + public Token getToken() { + return token; + } + + /** Get the field value. + * @return field value + */ + public String getValue() { + return value; + } + + } + +} diff --git a/src/test/java/org/apache/commons/math4/geometry/euclidean/threed/PolyhedronsSetTest.java b/src/test/java/org/apache/commons/math4/geometry/euclidean/threed/PolyhedronsSetTest.java index b96c0454b..5c6f93c97 100644 --- a/src/test/java/org/apache/commons/math4/geometry/euclidean/threed/PolyhedronsSetTest.java +++ b/src/test/java/org/apache/commons/math4/geometry/euclidean/threed/PolyhedronsSetTest.java @@ -20,13 +20,17 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.lang.reflect.Field; import java.text.ParseException; import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; +import java.util.Arrays; +import java.util.List; import org.apache.commons.math4.exception.MathArithmeticException; import org.apache.commons.math4.exception.MathIllegalArgumentException; +import org.apache.commons.math4.exception.util.ExceptionContext; +import org.apache.commons.math4.exception.util.Localizable; +import org.apache.commons.math4.exception.util.LocalizedFormats; import org.apache.commons.math4.geometry.Vector; import org.apache.commons.math4.geometry.euclidean.threed.Euclidean3D; import org.apache.commons.math4.geometry.euclidean.threed.Plane; @@ -354,18 +358,7 @@ public class PolyhedronsSetTest { faces[9]=new int[]{1,4,0}; // front (-y) faces[10]=new int[]{3,6,2}; // back (+y) faces[11]=new int[]{6,3,7}; // back (+y) - // - Set> pset=new HashSet>(); - for (int f=0; f().difference(polyset, parsed).isEmpty()); } + @Test + public void testConnectedFacets() throws IOException, ParseException { + InputStream stream = getClass().getResourceAsStream("pentomino-N.ply"); + PLYParser parser = new PLYParser(stream); + stream.close(); + PolyhedronsSet polyhedron = new PolyhedronsSet(parser.getVertices(), parser.getFaces(), 1.0e-10); + Assert.assertEquals( 5.0, polyhedron.getSize(), 1.0e-10); + Assert.assertEquals(22.0, polyhedron.getBoundarySize(), 1.0e-10); + } + + @Test + public void testTooClose() throws IOException, ParseException { + checkError("pentomino-N-too-close.ply", LocalizedFormats.CLOSE_VERTICES); + } + + @Test + public void testHole() throws IOException, ParseException { + checkError("pentomino-N-hole.ply", LocalizedFormats.EDGE_CONNECTED_TO_ONE_FACET); + } + + @Test + public void testNonPlanar() throws IOException, ParseException { + checkError("pentomino-N-out-of-plane.ply", LocalizedFormats.OUT_OF_PLANE); + } + + @Test + public void testOrientation() throws IOException, ParseException { + checkError("pentomino-N-bad-orientation.ply", LocalizedFormats.FACET_ORIENTATION_MISMATCH); + } + + @Test + public void testFacet2Vertices() throws IOException, ParseException { + checkError(Arrays.asList(Vector3D.ZERO, Vector3D.PLUS_I, Vector3D.PLUS_J, Vector3D.PLUS_K), + Arrays.asList(new int[] { 0, 1, 2 }, new int[] {2, 3}), + LocalizedFormats.WRONG_NUMBER_OF_POINTS); + } + + private void checkError(final String resourceName, final LocalizedFormats expected) { + try { + InputStream stream = getClass().getResourceAsStream(resourceName); + PLYParser parser = new PLYParser(stream); + stream.close(); + checkError(parser.getVertices(), parser.getFaces(), expected); + } catch (IOException ioe) { + Assert.fail(ioe.getLocalizedMessage()); + } catch (ParseException pe) { + Assert.fail(pe.getLocalizedMessage()); + } + } + + private void checkError(final List vertices, final List facets, + final LocalizedFormats expected) { + try { + new PolyhedronsSet(vertices, facets, 1.0e-10); + Assert.fail("an exception should have been thrown"); + } catch (MathIllegalArgumentException miae) { + try { + Field msgPatterns = ExceptionContext.class.getDeclaredField("msgPatterns"); + msgPatterns.setAccessible(true); + @SuppressWarnings("unchecked") + List list = (List) msgPatterns.get(miae.getContext()); + Assert.assertEquals(expected, list.get(0)); + } catch (NoSuchFieldException nsfe) { + Assert.fail(nsfe.getLocalizedMessage()); + } catch (IllegalAccessException iae) { + Assert.fail(iae.getLocalizedMessage()); + } + } + } + @Test public void testIssue1211() throws IOException, ParseException { diff --git a/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-bad-orientation.ply b/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-bad-orientation.ply new file mode 100644 index 000000000..410957689 --- /dev/null +++ b/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-bad-orientation.ply @@ -0,0 +1,40 @@ +ply +format ascii 1.0 +comment this file represents the 'N' pentomino +comment it has been created manually +comment the shape has a reversed orientation for facet 3 +element vertex 16 +property double x +property double y +property double z +element face 12 +property list uchar uint vertex_indices +end_header +0.0 0.0 0.0 +1.0 0.0 0.0 +1.0 1.0 0.0 +2.0 1.0 0.0 +2.0 4.0 0.0 +1.0 4.0 0.0 +1.0 2.0 0.0 +0.0 2.0 0.0 +0.0 0.0 1.0 +1.0 0.0 1.0 +1.0 1.0 1.0 +2.0 1.0 1.0 +2.0 4.0 1.0 +1.0 4.0 1.0 +1.0 2.0 1.0 +0.0 2.0 1.0 +5 8 9 10 14 15 +5 10 11 12 13 14 +5 7 6 2 1 0 +5 2 3 4 5 6 +4 0 1 9 8 +4 1 2 10 9 +4 2 3 11 10 +4 3 4 12 11 +4 4 5 13 12 +4 5 6 14 13 +4 6 7 15 14 +4 7 0 8 15 \ No newline at end of file diff --git a/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-hole.ply b/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-hole.ply new file mode 100644 index 000000000..e40a025e8 --- /dev/null +++ b/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-hole.ply @@ -0,0 +1,39 @@ +ply +format ascii 1.0 +comment this file represents the 'N' pentomino +comment it has been created manually +comment the shape has a missing face between vertices 0, 1, 9, 8 +element vertex 16 +property double x +property double y +property double z +element face 11 +property list uchar uint vertex_indices +end_header +0.0 0.0 0.0 +1.0 0.0 0.0 +1.0 1.0 0.0 +2.0 1.0 0.0 +2.0 4.0 0.0 +1.0 4.0 0.0 +1.0 2.0 0.0 +0.0 2.0 0.0 +0.0 0.0 1.0 +1.0 0.0 1.0 +1.0 1.0 1.0 +2.0 1.0 1.0 +2.0 4.0 1.0 +1.0 4.0 1.0 +1.0 2.0 1.0 +0.0 2.0 1.0 +5 8 9 10 14 15 +5 10 11 12 13 14 +5 7 6 2 1 0 +5 6 5 4 3 2 +4 1 2 10 9 +4 2 3 11 10 +4 3 4 12 11 +4 4 5 13 12 +4 5 6 14 13 +4 6 7 15 14 +4 7 0 8 15 \ No newline at end of file diff --git a/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-out-of-plane.ply b/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-out-of-plane.ply new file mode 100644 index 000000000..c345eda20 --- /dev/null +++ b/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-out-of-plane.ply @@ -0,0 +1,40 @@ +ply +format ascii 1.0 +comment this file represents the 'N' pentomino +comment it has been created manually +comment the shape is distorted with edge 7 moved, so associated facets are not planar +element vertex 16 +property double x +property double y +property double z +element face 12 +property list uchar uint vertex_indices +end_header +0.0 0.0 0.0 +1.0 0.0 0.0 +1.0 1.0 0.0 +2.0 1.0 0.0 +2.0 4.0 0.0 +1.0 4.0 0.0 +1.0 2.0 0.0 +0.0 2.0 0.5 +0.0 0.0 1.0 +1.0 0.0 1.0 +1.0 1.0 1.0 +2.0 1.0 1.0 +2.0 4.0 1.0 +1.0 4.0 1.0 +1.0 2.0 1.0 +0.0 2.0 1.0 +5 8 9 10 14 15 +5 10 11 12 13 14 +5 7 6 2 1 0 +5 6 5 4 3 2 +4 0 1 9 8 +4 1 2 10 9 +4 2 3 11 10 +4 3 4 12 11 +4 4 5 13 12 +4 5 6 14 13 +4 6 7 15 14 +4 7 0 8 15 \ No newline at end of file diff --git a/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-too-close.ply b/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-too-close.ply new file mode 100644 index 000000000..17015404c --- /dev/null +++ b/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-too-close.ply @@ -0,0 +1,86 @@ +ply +format ascii 1.0 +comment this file should trigger an error as it contains several vertices at the same location +comment the file was originally created using blender http://www.blender.org +element vertex 52 +property float x +property float y +property float z +property float nx +property float ny +property float nz +element face 20 +property list uchar uint vertex_indices +end_header +0.000000 0.000000 0.000000 1.000000 0.000000 0.000000 +0.000000 1.000000 0.000000 1.000000 0.000000 0.000000 +0.000000 1.000000 1.000000 1.000000 0.000000 0.000000 +0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 +0.000000 1.000000 0.000000 0.000000 1.000000 0.000000 +-2.000000 1.000000 0.000000 0.000000 1.000000 0.000000 +-2.000000 1.000000 1.000000 0.000000 1.000000 0.000000 +0.000000 1.000000 1.000000 0.000000 1.000000 0.000000 +-2.000000 1.000000 1.000000 0.000000 0.000000 0.000000 +1.000000 1.000000 1.000000 0.000000 0.000000 0.000000 +0.000000 1.000000 1.000000 0.000000 0.000000 0.000000 +-2.000000 2.000000 1.000000 0.000000 0.000000 -1.000000 +1.000000 2.000000 1.000000 0.000000 0.000000 -1.000000 +1.000000 1.000000 1.000000 0.000000 0.000000 -1.000000 +-2.000000 1.000000 1.000000 -0.000000 -0.000000 -1.000000 +-2.000000 2.000000 0.000000 0.000000 -1.000000 -0.000000 +1.000000 2.000000 0.000000 0.000000 -1.000000 -0.000000 +1.000000 2.000000 1.000000 0.000000 -1.000000 -0.000000 +-2.000000 2.000000 1.000000 0.000000 -1.000000 -0.000000 +0.000000 0.000000 0.000000 -0.000000 0.000000 1.000000 +1.000000 1.000000 0.000000 -0.000000 0.000000 1.000000 +0.000000 1.000000 0.000000 -0.000000 0.000000 1.000000 +2.000000 0.000000 0.000000 -0.000000 0.000000 1.000000 +2.000000 1.000000 0.000000 -0.000000 0.000000 1.000000 +2.000000 1.000000 0.000000 -1.000000 0.000000 -0.000000 +2.000000 0.000000 0.000000 -1.000000 0.000000 -0.000000 +2.000000 0.000000 1.000000 -1.000000 0.000000 -0.000000 +2.000000 1.000000 1.000000 -1.000000 0.000000 -0.000000 +2.000000 0.000000 0.000000 0.000000 1.000000 0.000000 +0.000000 0.000000 0.000000 0.000000 1.000000 0.000000 +0.000000 0.000000 1.000000 0.000000 1.000000 0.000000 +2.000000 0.000000 1.000000 0.000000 1.000000 0.000000 +-2.000000 1.000000 0.000000 1.000000 0.000000 0.000000 +-2.000000 2.000000 0.000000 1.000000 0.000000 0.000000 +-2.000000 2.000000 1.000000 1.000000 0.000000 0.000000 +-2.000000 1.000000 1.000000 1.000000 0.000000 0.000000 +1.000000 1.000000 0.000000 0.000000 -1.000000 -0.000000 +2.000000 1.000000 0.000000 0.000000 -1.000000 -0.000000 +2.000000 1.000000 1.000000 0.000000 -1.000000 -0.000000 +1.000000 1.000000 1.000000 0.000000 -1.000000 -0.000000 +1.000000 2.000000 0.000000 -1.000000 0.000000 -0.000000 +1.000000 1.000000 0.000000 -1.000000 0.000000 -0.000000 +1.000000 1.000000 1.000000 -1.000000 0.000000 -0.000000 +1.000000 2.000000 1.000000 -1.000000 0.000000 -0.000000 +-2.000000 1.000000 0.000000 -0.000000 0.000000 1.000000 +1.000000 2.000000 0.000000 -0.000000 0.000000 1.000000 +-2.000000 2.000000 0.000000 -0.000000 0.000000 1.000000 +0.000000 0.000000 1.000000 -0.000000 0.000000 -1.000000 +2.000000 1.000000 1.000000 -0.000000 0.000000 -1.000000 +2.000000 0.000000 1.000000 -0.000000 0.000000 -1.000000 +2.000000 1.000000 1.000000 0.000000 0.000000 0.000000 +0.000000 1.000000 1.000000 -0.000000 -0.000000 -1.000000 +4 0 1 2 3 +4 4 5 6 7 +3 8 9 10 +3 11 12 13 +3 14 11 13 +4 15 16 17 18 +3 19 20 21 +3 22 23 20 +3 19 22 20 +4 24 25 26 27 +4 28 29 30 31 +4 32 33 34 35 +4 36 37 38 39 +4 40 41 42 43 +3 44 45 46 +3 21 20 45 +3 44 21 45 +3 47 48 49 +3 10 9 50 +3 47 51 48 diff --git a/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N.ply b/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N.ply new file mode 100644 index 000000000..4efbf200c --- /dev/null +++ b/src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N.ply @@ -0,0 +1,39 @@ +ply +format ascii 1.0 +comment this file represents the 'N' pentomino +comment it has been created manually +element vertex 16 +property double x +property double y +property double z +element face 12 +property list uchar uint vertex_indices +end_header +0.0 0.0 0.0 +1.0 0.0 0.0 +1.0 1.0 0.0 +2.0 1.0 0.0 +2.0 4.0 0.0 +1.0 4.0 0.0 +1.0 2.0 0.0 +0.0 2.0 0.0 +0.0 0.0 1.0 +1.0 0.0 1.0 +1.0 1.0 1.0 +2.0 1.0 1.0 +2.0 4.0 1.0 +1.0 4.0 1.0 +1.0 2.0 1.0 +0.0 2.0 1.0 +5 8 9 10 14 15 +5 10 11 12 13 14 +5 7 6 2 1 0 +5 6 5 4 3 2 +4 0 1 9 8 +4 1 2 10 9 +4 2 3 11 10 +4 3 4 12 11 +4 4 5 13 12 +4 5 6 14 13 +4 6 7 15 14 +4 7 0 8 15 \ No newline at end of file From a6ed07c55cf8c42e196dd6e6e1bf0a38f0f7b754 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Sun, 12 Apr 2015 17:54:36 +0200 Subject: [PATCH 5/7] Moved FastMathTestPerformance out of the main test tree. Is is a benchmark rather than a test. JIRA: MATH-1195 --- src/changes/changes.xml | 4 + .../userguide}/FastMathTestPerformance.java | 158 +++++++++--------- 2 files changed, 81 insertions(+), 81 deletions(-) rename src/{test/java/org/apache/commons/math4/util => userguide/java/org/apache/commons/math4/userguide}/FastMathTestPerformance.java (93%) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 0bd49c497..3dada49bc 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -54,6 +54,10 @@ If the output is not quite correct, check for invisible trailing spaces!
+ + Moved FastMathTestPerformance out of the main test tree, as is is + a benchmark rather than a test. + Added a way to build polyhedrons sets from a list of vertices and facets specified using vertices indices. diff --git a/src/test/java/org/apache/commons/math4/util/FastMathTestPerformance.java b/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java similarity index 93% rename from src/test/java/org/apache/commons/math4/util/FastMathTestPerformance.java rename to src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java index eb09f688f..8af6fcaa9 100644 --- a/src/test/java/org/apache/commons/math4/util/FastMathTestPerformance.java +++ b/src/userguide/java/org/apache/commons/math4/userguide/FastMathTestPerformance.java @@ -14,22 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.math4.util; +package org.apache.commons.math4.userguide; import org.apache.commons.math4.PerfTestUtils; import org.apache.commons.math4.util.FastMath; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.Assert; /** - * Performance tests for FastMath. - * Not enabled by default, as the class does not end in Test. + * Performance benchmark for FastMath. * - * Invoke by running
- * {@code mvn test -Dtest=FastMathTestPerformance}
- * or by running
- * {@code mvn test -Dtest=FastMathTestPerformance -DargLine="-DtestRuns=1234 -server"}
*/ public class FastMathTestPerformance { private static final int RUNS = Integer.parseInt(System.getProperty("testRuns","10000000")); @@ -40,16 +32,35 @@ public class FastMathTestPerformance { // Detail format private static final String FMT_DTL = "%-5s %6d %6.1f %6d %6.4f %6d %6.4f"; - @SuppressWarnings("boxing") - @BeforeClass - public static void header() { + public static void main(String[] args) { System.out.println(String.format(FMT_HDR, - "Name","StrictMath","FastMath","Math",RUNS, - System.getProperty("java.version"), - System.getProperty("java.runtime.version","?"), - System.getProperty("java.vm.name"), - System.getProperty("java.vm.version") - )); + "Name","StrictMath","FastMath","Math",RUNS, + System.getProperty("java.version"), + System.getProperty("java.runtime.version","?"), + System.getProperty("java.vm.name"), + System.getProperty("java.vm.version") + )); + testAbs(); + testAcos(); + testAsin(); + testAtan(); + testAtan2(); + testCbrt(); + testCos(); + testCosh(); + testExp(); + testExpm1(); + testHypot(); + testLog(); + testLog10(); + testLog1p(); + testPow(); + testSin(); + testSinh(); + testSqrt(); + testTan(); + testTanh(); + } @SuppressWarnings("boxing") @@ -63,8 +74,13 @@ public class FastMathTestPerformance { )); } - @Test - public void testLog() { + private static void assertTrue(boolean condition) { + if (!condition) { + System.err.println("assertion failed!"); + System.exit(1); + } + } + private static void testLog() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -87,11 +103,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("log",strictMath,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testLog10() { + private static void testLog10() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -114,11 +129,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("log10",strictMath,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testLog1p() { + private static void testLog1p() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -141,11 +155,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("log1p",strictMath,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testPow() { + private static void testPow() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -167,11 +180,10 @@ public class FastMathTestPerformance { } long mathTime = System.nanoTime() - time; report("pow",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testExp() { + private static void testExp() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -194,11 +206,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("exp",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testSin() { + private static void testSin() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -221,11 +232,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("sin",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testAsin() { + private static void testAsin() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -248,11 +258,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("asin",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testCos() { + private static void testCos() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -275,11 +284,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("cos",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testAcos() { + private static void testAcos() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -301,11 +309,10 @@ public class FastMathTestPerformance { } long mathTime = System.nanoTime() - time; report("acos",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testTan() { + private static void testTan() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -328,11 +335,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("tan",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testAtan() { + private static void testAtan() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -355,11 +361,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("atan",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testAtan2() { + private static void testAtan2() { double x = 0; long time = System.nanoTime(); int max = (int) FastMath.floor(FastMath.sqrt(RUNS)); @@ -389,11 +394,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("atan2",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testHypot() { + private static void testHypot() { double x = 0; long time = System.nanoTime(); int max = (int) FastMath.floor(FastMath.sqrt(RUNS)); @@ -423,11 +427,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("hypot",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testCbrt() { + private static void testCbrt() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -450,11 +453,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("cbrt",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testSqrt() { + private static void testSqrt() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -477,11 +479,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("sqrt",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testCosh() { + private static void testCosh() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -504,11 +505,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("cosh",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testSinh() { + private static void testSinh() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -531,11 +531,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("sinh",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testTanh() { + private static void testTanh() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -558,11 +557,10 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("tanh",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testExpm1() { + private static void testExpm1() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -584,11 +582,10 @@ public class FastMathTestPerformance { } long mathTime = System.nanoTime() - time; report("expm1",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } - @Test - public void testAbs() { + private static void testAbs() { double x = 0; long time = System.nanoTime(); for (int i = 0; i < RUNS; i++) { @@ -611,12 +608,11 @@ public class FastMathTestPerformance { long mathTime = System.nanoTime() - time; report("abs",strictTime,fastTime,mathTime); - Assert.assertTrue(!Double.isNaN(x)); + assertTrue(!Double.isNaN(x)); } @SuppressWarnings("boxing") - @Test - public void testSimpleBenchmark() { + private static void testSimpleBenchmark() { final String SM = "StrictMath"; final String M = "Math"; final String FM = "FastMath"; From c02d676118241dff740124c4dde7fa0ca00a6b9e Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Sun, 12 Apr 2015 19:02:10 +0200 Subject: [PATCH 6/7] Updated site menu for upcoming 3.5 release. --- src/site/site.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/site/site.xml b/src/site/site.xml index 62c1ad9c4..6f45d4713 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -27,6 +27,8 @@ + Date: Sun, 12 Apr 2015 19:02:38 +0200 Subject: [PATCH 7/7] Fixed wrong file name. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ad8578d63..4dc06225c 100644 --- a/pom.xml +++ b/pom.xml @@ -607,7 +607,7 @@ src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-hole.ply src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-out-of-plane.ply src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-too-close.ply - src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N-.ply + src/test/resources/org/apache/commons/math4/geometry/euclidean/threed/pentomino-N.ply