fixed javadoc, checkstyle and findbugs warnings

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1131153 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2011-06-03 19:23:56 +00:00
parent 356a99a7bb
commit 8a5f904b36
24 changed files with 119 additions and 147 deletions

View File

@ -65,7 +65,11 @@
<!-- The following equality test is intentional and needed for semantic purposes -->
<Match>
<Class name="org.apache.commons.math.geometry.euclidean.threed.Vector3D" />
<Or>
<Class name="org.apache.commons.math.geometry.euclidean.oned.Vector1D" />
<Class name="org.apache.commons.math.geometry.euclidean.twod.Vector2D" />
<Class name="org.apache.commons.math.geometry.euclidean.threed.Vector3D" />
</Or>
<Method name="equals" params="java.lang.Object" returns="boolean" />
<Bug pattern="FE_FLOATING_POINT_EQUALITY" />
</Match>
@ -192,7 +196,7 @@
</Match>
<Match>
<Class name="org.apache.commons.math.linear.Array2DRowFieldMatrix"/>
<Method name="&lt;init>" params="org.apache.commons.math.FieldElement[][],boolean" returns="void" />
<Method name="&lt;init>" params="org.apache.commons.math.Field,org.apache.commons.math.FieldElement[][],boolean" returns="void" />
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>

View File

@ -16,9 +16,8 @@
*/
package org.apache.commons.math.exception;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.exception.util.ExceptionContext;
import org.apache.commons.math.exception.util.ExceptionContextProvider;
import org.apache.commons.math.exception.util.LocalizedFormats;
/**
* Class to signal parse failures.

View File

@ -1056,12 +1056,12 @@ public class BigFraction
/**
* <p>
* Subtracts the value of a {@code long} from the value of this
* Subtracts the value of a {@code long} from the value of this
* {@code BigFraction}, returning the result in reduced form.
* </p>
*
* @param l the {@code long} to subtract.
* @return a {@ code BigFraction} instance with the resulting values.
* @return a {@code BigFraction} instance with the resulting values.
*/
public BigFraction subtract(final long l) {
return subtract(BigInteger.valueOf(l));

View File

@ -36,7 +36,8 @@ import org.apache.commons.math.exception.MathParseException;
* returned. In the second case, however, the parse position after parsing will be
* just after the closing curly brace, i.e. just before the trailing space.</p>
*
* @version $Id:$
* @param <S> Type of the space.
* @version $Id$
* @since 3.0
*/
public abstract class VectorFormat<S extends Space> {
@ -219,7 +220,7 @@ public abstract class VectorFormat<S extends Space> {
* @throws MathParseException if the beginning of the specified string
* cannot be parsed.
*/
public abstract Vector<S> parse(String source);
public abstract Vector<S> parse(String source) throws MathParseException;
/**
* Parses a string to produce a {@link Vector} object.

View File

@ -22,11 +22,10 @@ import java.util.List;
import org.apache.commons.math.geometry.partitioning.AbstractRegion;
import org.apache.commons.math.geometry.partitioning.BSPTree;
import org.apache.commons.math.geometry.partitioning.Region;
import org.apache.commons.math.geometry.partitioning.SubHyperplane;
/** This class represents a 1D region: a set of intervals.
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public class IntervalsSet extends AbstractRegion<Euclidean1D, Euclidean1D> {
@ -73,7 +72,7 @@ public class IntervalsSet extends AbstractRegion<Euclidean1D, Euclidean1D> {
* boundary does not really separate an inside open from an outside
* open (open having here its topological meaning), then subsequent
* calls to the {@link
* Region#checkPoint(org.apache.commons.math.geometry.partitioning.Point)
* org.apache.commons.math.geometry.partitioning.Region#checkPoint(org.apache.commons.math.geometry.Vector)
* checkPoint} method will not be meaningful anymore.</p>
* <p>If the boundary is empty, the region will represent the whole
* space.</p>

View File

@ -18,14 +18,12 @@ package org.apache.commons.math.geometry.euclidean.oned;
import org.apache.commons.math.geometry.Vector;
import org.apache.commons.math.geometry.partitioning.Hyperplane;
import org.apache.commons.math.geometry.partitioning.Region;
import org.apache.commons.math.geometry.partitioning.SubHyperplane;
/** This class represents a 1D oriented hyperplane.
* <p>An hyperplane in 1D is a simple point, its orientation being a
* boolean.</p>
* <p>Instances of this class are guaranteed to be immutable.</p>
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public class OrientedPoint implements Hyperplane<Euclidean1D> {
@ -64,10 +62,13 @@ public class OrientedPoint implements Hyperplane<Euclidean1D> {
/** Build a region covering the whole hyperplane.
* <p>Since this class represent zero dimension spaces which does
* not have lower dimension sub-spaces, this method returns a dummy
* implementation of a {@link Region Region} (always the same
* instance). This implementation is only used to allow the {@link
* SubHyperplane SubHyperplane} class implementation to work
* properly, it should <em>not</em> be used otherwise.</p>
* implementation of a {@link
* org.apache.commons.math.geometry.partitioning.Region Region}
* (always the same instance). This implementation is only used to
* allow the {@link
* org.apache.commons.math.geometry.partitioning.SubHyperplane
* SubHyperplane} class implementation to work properly, it should
* <em>not</em> be used otherwise.</p>
* @return a dummy region
*/
public SubOrientedPoint wholeHyperplane() {
@ -82,19 +83,7 @@ public class OrientedPoint implements Hyperplane<Euclidean1D> {
return new IntervalsSet();
}
/** Check if the instance has the same orientation as another hyperplane.
* <p>This method is expected to be called on parallel hyperplanes
* (i.e. when the {@link #side side} method would return {@link
* org.apache.commons.math.geometry.partitioning.Hyperplane.Side#HYPER}
* for some sub-hyperplane having the specified hyperplane
* as its underlying hyperplane). The method should <em>not</em>
* re-check for parallelism, only for orientation, typically by
* testing something like the sign of the dot-products of
* normals.</p>
* @param other other hyperplane to check against the instance
* @return true if the instance and the other hyperplane have
* the same orientation
*/
/** {@inheritDoc} */
public boolean sameOrientationAs(final Hyperplane<Euclidean1D> other) {
return !(direct ^ ((OrientedPoint) other).direct);
}

View File

@ -21,11 +21,11 @@ import org.apache.commons.math.geometry.partitioning.Hyperplane;
import org.apache.commons.math.geometry.partitioning.Region;
import org.apache.commons.math.geometry.partitioning.Side;
/** This class represents sub-hyperplane for {@link OrOrientedPoint}.
/** This class represents sub-hyperplane for {@link OrientedPoint}.
* <p>An hyperplane in 1D is a simple point, its orientation being a
* boolean.</p>
* <p>Instances of this class are guaranteed to be immutable.</p>
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public class SubOrientedPoint extends AbstractSubHyperplane<Euclidean1D, Euclidean1D> {

View File

@ -56,7 +56,7 @@ import org.apache.commons.math.util.MathUtils;
* left half plane is the set of points with negative offsets and the
* right half plane is the set of points with positive offsets.</p>
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public class Line implements Hyperplane<Euclidean2D>, Embedding<Euclidean2D, Euclidean1D> {
@ -227,38 +227,18 @@ public class Line implements Hyperplane<Euclidean2D>, Embedding<Euclidean2D, Euc
* @param line line to check
* @return offset of the line
*/
public double getOffset(final Hyperplane<Euclidean2D> hyperplane) {
Line line = (Line) hyperplane;
public double getOffset(final Line line) {
return originOffset +
((cos * line.cos + sin * line.sin > 0) ? -line.originOffset : line.originOffset);
}
/** Get the offset (oriented distance) of a point to the line.
* <p>The offset is 0 if the point belongs to the line, it is
* positive if the point is on the right side of the line and
* negative if it is on the left side, according to its natural
* orientation.</p>
* @param point point to check (must be a {@link Vector2D Vector2D} instance)
* @return offset of the point
*/
/** {@inheritDoc} */
public double getOffset(final Vector<Euclidean2D> point) {
Vector2D p2 = (Vector2D) point;
return sin * p2.getX() - cos * p2.getY() + originOffset;
}
/** Check if the instance has the same orientation as another hyperplane.
* <p>This method is expected to be called on parallel hyperplanes
* (i.e. when the {@link #side side} method would return {@link
* org.apache.commons.math.geometry.partitioning.Hyperplane.Side#HYPER HYPER}
* for some sub-hyperplane having the specified hyperplane
* as its underlying hyperplane). The method should <em>not</em>
* re-check for parallelism, only for orientation, typically by
* testing something like the sign of the dot-products of
* normals.</p>
* @param other other hyperplane to check against the instance
* @return true if the instance and the other hyperplane have
* the same orientation
*/
/** {@inheritDoc} */
public boolean sameOrientationAs(final Hyperplane<Euclidean2D> other) {
final Line otherL = (Line) other;
return (sin * otherL.sin + cos * otherL.cos) >= 0.0;

View File

@ -41,7 +41,7 @@ import org.apache.commons.math.geometry.partitioning.SubHyperplane;
* internal loops is computed as the reverse of the orientation of
* their immediate surrounding loop.</p>
* @version $Id:$
* @version $Id$
* @since 3.0
*/
class NestedLoops {
@ -89,7 +89,7 @@ class NestedLoops {
final Vector2D previous = current;
current = loop[i];
final Line line = new Line(previous, current);
final IntervalsSet region =
final IntervalsSet region =
new IntervalsSet(line.toSubSpace(previous).getX(), line.toSubSpace(current).getX());
edges.add(new SubLine(line, region));
}

View File

@ -24,14 +24,13 @@ import org.apache.commons.math.exception.MathInternalError;
import org.apache.commons.math.geometry.euclidean.oned.Euclidean1D;
import org.apache.commons.math.geometry.euclidean.oned.Vector1D;
import org.apache.commons.math.geometry.partitioning.BSPTree;
import org.apache.commons.math.geometry.partitioning.Region;
import org.apache.commons.math.geometry.partitioning.SubHyperplane;
import org.apache.commons.math.geometry.partitioning.AbstractRegion;
import org.apache.commons.math.geometry.partitioning.utilities.AVLTree;
import org.apache.commons.math.util.FastMath;
/** This class represents a 2D region: a set of polygons.
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public class PolygonsSet extends AbstractRegion<Euclidean2D, Euclidean1D> {
@ -71,7 +70,7 @@ public class PolygonsSet extends AbstractRegion<Euclidean2D, Euclidean1D> {
* boundary does not really separate an inside open from an outside
* open (open having here its topological meaning), then subsequent
* calls to the {@link
* Region#checkPoint(org.apache.commons.math.geometry.partitioning.Point)
* org.apache.commons.math.geometry.partitioning.Region#checkPoint(org.apache.commons.math.geometry.Vector)
* checkPoint} method will not be meaningful anymore.</p>
* <p>If the boundary is empty, the region will represent the whole
* space.</p>

View File

@ -30,7 +30,7 @@ import org.apache.commons.math.geometry.Vector;
* @param <S> Type of the space.
* @param <T> Type of the sub-space.
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public abstract class AbstractRegion<S extends Space, T extends Space> implements Region<S> {
@ -136,6 +136,34 @@ public abstract class AbstractRegion<S extends Space, T extends Space> implement
/** {@inheritDoc} */
public abstract AbstractRegion<S, T> buildNew(BSPTree<S> newTree);
/** Build a convex region from an array of bounding hyperplanes.
* @param hyperplanes array of bounding hyperplanes (if null, an
* empty region will be built)
*/
public AbstractRegion(final Hyperplane<S>[] hyperplanes) {
if ((hyperplanes == null) || (hyperplanes.length == 0)) {
tree = new BSPTree<S>(Boolean.FALSE);
} else {
// use the first hyperplane to build the right class
tree = hyperplanes[0].wholeSpace().getTree(false);
// chop off parts of the space
BSPTree<S> node = tree;
node.setAttribute(Boolean.TRUE);
for (final Hyperplane<S> hyperplane : hyperplanes) {
if (node.insertCut(hyperplane)) {
node.setAttribute(null);
node.getPlus().setAttribute(Boolean.FALSE);
node = node.getMinus();
node.setAttribute(Boolean.TRUE);
}
}
}
}
/** Recursively build a tree by inserting cut sub-hyperplanes.
* @param node current tree node (it is a leaf node at the beginning
* of the call)
@ -187,35 +215,6 @@ public abstract class AbstractRegion<S extends Space, T extends Space> implement
}
/** Build a convex region from an array of bounding hyperplanes.
* @param hyperplanes array of bounding hyperplanes (if null, an
* empty region will be built)
* @return a new convex region, or null if the collection is empty
*/
public AbstractRegion(final Hyperplane<S>[] hyperplanes) {
if ((hyperplanes == null) || (hyperplanes.length == 0)) {
tree = new BSPTree<S>(Boolean.FALSE);
} else {
// use the first hyperplane to build the right class
tree = hyperplanes[0].wholeSpace().getTree(false);
// chop off parts of the space
BSPTree<S> node = tree;
node.setAttribute(Boolean.TRUE);
for (final Hyperplane<S> hyperplane : hyperplanes) {
if (node.insertCut(hyperplane)) {
node.setAttribute(null);
node.getPlus().setAttribute(Boolean.FALSE);
node = node.getMinus();
node.setAttribute(Boolean.TRUE);
}
}
}
}
/** {@inheritDoc} */
public AbstractRegion<S, T> copySelf() {
return buildNew(tree.copySelf());
@ -257,7 +256,8 @@ public abstract class AbstractRegion<S extends Space, T extends Space> implement
* @param node root node of the region
* @param point point to check
* @return a code representing the point status: either {@link
* Location#INSIDE}, {@link Location#OUTSIDE} or {@link Location#BOUNDARY}
* Region.Location#INSIDE INSIDE}, {@link Region.Location#OUTSIDE
* OUTSIDE} or {@link Region.Location#BOUNDARY BOUNDARY}
*/
protected Location checkPoint(final BSPTree<S> node, final Vector<S> point) {
final BSPTree<S> cell = node.getCell(point);

View File

@ -29,6 +29,7 @@ import org.apache.commons.math.geometry.partitioning.SubHyperplane;
* hyperplanes are the cut hyperplanes closer to the tree root.</p>
* @param <S> Type of the embedding space.
* @param <T> Type of the embedded sub-space.
* @version $Revision$
* @since 3.0
@ -53,11 +54,12 @@ public abstract class AbstractSubHyperplane<S extends Space, T extends Space>
}
/** Build a sub-hyperplane from an hyperplane and a region.
* @param hyperplane underlying hyperplane
* @param remainingRegion remaining region of the hyperplane
* @param hyper underlying hyperplane
* @param remaining remaining region of the hyperplane
* @return a new sub-hyperplane
*/
protected abstract AbstractSubHyperplane<S, T> buildNew(final Hyperplane<S> hyperplane,
final Region<T> remainingRegion);
protected abstract AbstractSubHyperplane<S, T> buildNew(final Hyperplane<S> hyper,
final Region<T> remaining);
/** {@inheritDoc} */
public AbstractSubHyperplane<S, T> copySelf() {
@ -144,10 +146,10 @@ public abstract class AbstractSubHyperplane<S extends Space, T extends Space>
}
/** {@inheritDoc} */
public abstract Side side(Hyperplane<S> hyperplane);
public abstract Side side(Hyperplane<S> hyper);
/** {@inheritDoc} */
public abstract SplitSubHyperplane<S> split(Hyperplane<S> hyperplane);
public abstract SplitSubHyperplane<S> split(Hyperplane<S> hyper);
/** {@inheritDoc} */
public boolean isEmpty() {

View File

@ -56,7 +56,7 @@ import org.apache.commons.math.util.FastMath;
* @param <S> Type of the space.
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public class BSPTree<S extends Space> {
@ -427,9 +427,7 @@ public class BSPTree<S extends Space> {
* cells would use four different objects to implement the final
* merging phase of the four set operations union, intersection,
* difference and symmetric difference (exclusive or).</p>
* @param <SpacePoint> Type of the space points.
* @param <SubSpacePoint> Type of the sub-space points.
* @version $Revision$ $Date$
* @param <S> Type of the space.
*/
public static interface LeafMerger<S extends Space> {

View File

@ -40,13 +40,12 @@ import org.apache.commons.math.geometry.Space;
* </li>
* </ul>
* @param <SpacePoint> Type of the space points.
* @param <SubSpacePoint> Type of the sub-space points.
* @param <S> Type of the space.
* @see BSPTree
* @see SubHyperplane
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public interface BSPTreeVisitor<S extends Space> {

View File

@ -28,7 +28,7 @@ import org.apache.commons.math.geometry.Space;
* processing methods.</p>
* @param <S> Type of the space.
* @see Region#getTree
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public class BoundaryAttribute<S extends Space> {
@ -37,13 +37,13 @@ public class BoundaryAttribute<S extends Space> {
* boundary and has the outside of the region on the plus side of
* its underlying hyperplane (may be null).
*/
final SubHyperplane<S> plusOutside;
private final SubHyperplane<S> plusOutside;
/** Part of the node cut sub-hyperplane that belongs to the
* boundary and has the inside of the region on the plus side of
* its underlying hyperplane (may be null).
*/
final SubHyperplane<S> plusInside;
private final SubHyperplane<S> plusInside;
/** Simple constructor.
* @param plusOutside part of the node cut sub-hyperplane that
@ -81,4 +81,4 @@ public class BoundaryAttribute<S extends Space> {
return plusInside;
}
}
}

View File

@ -20,7 +20,7 @@ import org.apache.commons.math.geometry.Space;
/** Visitor computing the boundary size.
* @param <S> Type of the space.
* @version $Id:$
* @version $Id$
* @since 3.0
*/
class BoundarySizeVisitor<S extends Space> implements BSPTreeVisitor<S> {
@ -44,11 +44,11 @@ class BoundarySizeVisitor<S extends Space> implements BSPTreeVisitor<S> {
@SuppressWarnings("unchecked")
final BoundaryAttribute<S> attribute =
(BoundaryAttribute<S>) node.getAttribute();
if (attribute.plusOutside != null) {
boundarySize += attribute.plusOutside.getSize();
if (attribute.getPlusOutside() != null) {
boundarySize += attribute.getPlusOutside().getSize();
}
if (attribute.plusInside != null) {
boundarySize += attribute.plusInside.getSize();
if (attribute.getPlusInside() != null) {
boundarySize += attribute.getPlusInside().getSize();
}
}
@ -63,4 +63,4 @@ class BoundarySizeVisitor<S extends Space> implements BSPTreeVisitor<S> {
return boundarySize;
}
}
}

View File

@ -30,9 +30,9 @@ import org.apache.commons.math.geometry.Space;
* space). They can be more exotic objects in specific fields, for
* example a circle on the surface of the unit sphere.</p>
* @param <SpacePoint> Type of the space points.
* @param <S> Type of the space.
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public interface Hyperplane<S extends Space> {
@ -56,13 +56,10 @@ public interface Hyperplane<S extends Space> {
double getOffset(Vector<S> point);
/** Check if the instance has the same orientation as another hyperplane.
* <p>This method is expected to be called on parallel hyperplanes
* (i.e. when the {@link #side side} method would return {@link
* Side#HYPER} for some sub-hyperplane having the specified hyperplane
* as its underlying hyperplane). The method should <em>not</em>
* re-check for parallelism, only for orientation, typically by
* testing something like the sign of the dot-products of
* normals.</p>
* <p>This method is expected to be called on parallel hyperplanes. The
* method should <em>not</em> re-check for parallelism, only for
* orientation, typically by testing something like the sign of the
* dot-products of normals.</p>
* @param other other hyperplane to check against the instance
* @return true if the instance and the other hyperplane have
* the same orientation

View File

@ -41,7 +41,7 @@ import org.apache.commons.math.geometry.Vector;
* @param <S> Type of the space.
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public interface Region<S extends Space> {
@ -173,11 +173,10 @@ public interface Region<S extends Space> {
/** Compute the relative position of the instance with respect to an
* hyperplane.
* @param hyperplane reference hyperplane
* @return one of {@link Hyperplane.Side#PLUS Hyperplane.Side.PLUS}, {@link
* Hyperplane.Side#MINUS Hyperplane.Side.MINUS}, {@link Hyperplane.Side#BOTH
* Hyperplane.Side.BOTH} or {@link Hyperplane.Side#HYPER Hyperplane.Side.HYPER}
* (the latter result can occur only if the tree contains only one
* cut hyperplane)
* @return one of {@link Side#PLUS Side.PLUS}, {@link Side#MINUS
* Side.MINUS}, {@link Side#BOTH Side.BOTH} or {@link Side#HYPER
* Side.HYPER} (the latter result can occur only if the tree
* contains only one cut hyperplane)
*/
Side side(final Hyperplane<S> hyperplane);

View File

@ -30,7 +30,7 @@ import org.apache.commons.math.geometry.Space;
* @param <S> Type of the embedding space.
* @version $Id:$
* @version $Id$
* @since 3.0
*/
public interface SubHyperplane<S extends Space> {
@ -83,10 +83,8 @@ public interface SubHyperplane<S extends Space> {
*/
SubHyperplane<S> reunite(SubHyperplane<S> other);
/** Class holding the results of the {@link Hyperplane#split Hyperplane.split}
* method.
* @param <S> Type of the embedding space.
* @param <T> Type of the embedded sub-space.
/** Class holding the results of the {@link #split split} method.
* @param <U> Type of the embedding space.
*/
public static class SplitSubHyperplane<U extends Space> {

View File

@ -314,16 +314,16 @@ public abstract class MultistepIntegrator extends AdaptiveStepsizeIntegrator {
private class NordsieckInitializer implements StepHandler {
/** Steps counter. */
int count;
private int count;
/** First steps times. */
final double[] t;
private final double[] t;
/** First steps states. */
final double[][] y;
private final double[][] y;
/** First steps derivatives. */
final double[][] yDot;
private final double[][] yDot;
/** Simple constructor.
* @param nSteps number of steps of the multistep method (excluding the one being computed)

View File

@ -237,7 +237,14 @@ public class AdamsNordsieckTransformer {
}
/** {@inheritDoc} */
/** Initialize the high order scaled derivatives at step start.
* @param h step size to use for scaling
* @param t first steps times
* @param y first steps states
* @param yDot first steps derivatives
* @return Nordieck vector at first step (h<sup>2</sup>/2 y''<sub>n</sub>,
* h<sup>3</sup>/6 y'''<sub>n</sub> ... h<sup>k</sup>/k! y<sup>(k)</sup><sub>n</sub>)
*/
public Array2DRowRealMatrix initializeHighOrderDerivatives(final double h, final double[] t,
final double[][] y,
final double[][] yDot) {

View File

@ -35,12 +35,12 @@ public class SimplexSolver extends AbstractLinearOptimizer {
/** Default amount of error to accept for algorithm convergence. */
private static final double DEFAULT_EPSILON = 1.0e-6;
/** Amount of error to accept for algorithm convergence. */
protected final double epsilon;
/** Default amount of error to accept in floating point comparisons (as ulps). */
private static final int DEFAULT_ULPS = 10;
/** Amount of error to accept for algorithm convergence. */
protected final double epsilon;
/** Amount of error to accept in floating point comparisons (as ulps). */
protected final int maxUlps;

View File

@ -159,6 +159,7 @@ public class KMeansPlusPlusClusterer<T extends Clusterable<T>> {
* @param <T> type of the points to cluster
* @param clusters the {@link Cluster}s to add the points to
* @param points the points to add to the given {@link Cluster}s
* @param assignments points assignments to clusters
* @return the number of points assigned to different clusters as the iteration before
*/
private static <T extends Clusterable<T>> int

View File

@ -1282,12 +1282,12 @@ public final class MathUtils {
}
/**
* <p>Reduce {@code |a - offset|} to the primary interval
* <p>Reduce {@code |a - offset|} to the primary interval
* {@code [0, |period|)}.</p>
*
*
* <p>Specifically, the value returned is <br/>
* {@code a - |period| * floor((a - offset) / |period|) - offset}.</p>
*
*
* <p>If any of the parameters are {@code NaN} or infinite, the result is
* {@code NaN}.</p>
*