Added SemiVariance. JIRA: MATH-323. Reported and patched by Larry Diamond.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@910264 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
993dcad4b1
commit
f822b3285a
3
pom.xml
3
pom.xml
|
@ -126,6 +126,9 @@
|
|||
<contributor>
|
||||
<name>Benjamin Croizet</name>
|
||||
</contributor>
|
||||
<contributor>
|
||||
<name>Larry Diamond</name>
|
||||
</contributor>
|
||||
<contributor>
|
||||
<name>Rodrigo di Lorenzo Lopes</name>
|
||||
</contributor>
|
||||
|
|
|
@ -649,6 +649,7 @@ public class MessagesResources_fr
|
|||
"valeur de quantile {0} hors bornes, doit \u00eatre dans l''intervalle ]0, 100]" },
|
||||
|
||||
// org.apache.commons.math.stat.descriptive.moment.Variance
|
||||
// org.apache.commons.math.stat.descriptive.moment.SemiVariance
|
||||
// org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic
|
||||
// org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic
|
||||
{ "input values array is null",
|
||||
|
|
|
@ -0,0 +1,377 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.stat.descriptive.moment;
|
||||
|
||||
import java.io.Serializable;
|
||||
import org.apache.commons.math.MathRuntimeException;
|
||||
import org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic;
|
||||
|
||||
/**
|
||||
* <p>Computes the semivariance of a set of values with respect to a given cutoff value.
|
||||
* We define the <i>downside semivariance</i> of a set of values <code>x</code>
|
||||
* against the <i>cutoff value</i> <code>cutoff</code> to be <br/>
|
||||
* <code>Σ (x[i] - target)<sup>2</sup> / df</code> <br/>
|
||||
* where the sum is taken over all <code>i</code> such that <code>x[i] < cutoff</code>
|
||||
* and <code>df</code> is the length of <code>x</code> (non-bias-corrected) or
|
||||
* one less than this number (bias corrected). The <i>upside semivariance</i>
|
||||
* is defined similarly, with the sum taken over values of <code>x</code> that
|
||||
* exceed the cutoff value.</p>
|
||||
*
|
||||
* <p>The cutoff value defaults to the mean, bias correction defaults to <code>true</code>
|
||||
* and the "variance direction" (upside or downside) defaults to downside. The variance direction
|
||||
* and bias correction may be set using property setters or their values can provided as
|
||||
* parameters to {@link #evaluate(double[], double, Direction, boolean, int, int)}.</p>
|
||||
*
|
||||
* <p>If the input array is null, <code>evaluate</code> methods throw
|
||||
* <code>IllegalArgumentException.</code> If the array has length 1, <code>0</code>
|
||||
* is returned, regardless of the value of the <code>cutoff.</code>
|
||||
*
|
||||
* <p><strong>Note that this class is not intended to be threadsafe.</strong> If
|
||||
* multiple threads access an instance of this class concurrently, and one or
|
||||
* more of these threads invoke property setters, external synchronization must
|
||||
* be provided to ensure correct results.</p>
|
||||
*
|
||||
* @version $Revision$ $Date$
|
||||
* @since 2.1
|
||||
*/
|
||||
|
||||
public class SemiVariance extends AbstractUnivariateStatistic implements Serializable {
|
||||
|
||||
/** Serializable version identifier */
|
||||
private static final long serialVersionUID = -2653430366886024994L;
|
||||
|
||||
/**
|
||||
* Determines whether or not bias correction is applied when computing the
|
||||
* value of the statisic. True means that bias is corrected.
|
||||
*/
|
||||
private boolean biasCorrected = true;
|
||||
|
||||
/**
|
||||
* Determines whether to calculate downside or upside SemiVariance.
|
||||
*/
|
||||
private Direction varianceDirection = Direction.DOWNSIDE;
|
||||
|
||||
/**
|
||||
* The UPSIDE Direction is used to specify that the observations above the
|
||||
* cutoff point will be used to calculate SemiVariance.
|
||||
*/
|
||||
public static final Direction UPSIDE_VARIANCE = Direction.UPSIDE;
|
||||
|
||||
/**
|
||||
* The DOWNSIDE Direction is used to specify that the observations below
|
||||
* the cutoff point will be used to calculate SemiVariance
|
||||
*/
|
||||
public static final Direction DOWNSIDE_VARIANCE = Direction.DOWNSIDE;
|
||||
|
||||
/**
|
||||
* Constructs a SemiVariance with default (true) <code>biasCorrected</code>
|
||||
* property and default (Downside) <code>varianceDirection</code> property.
|
||||
*/
|
||||
public SemiVariance() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SemiVariance with the specified <code>biasCorrected</code>
|
||||
* property and default (Downside) <code>varianceDirection</code> property.
|
||||
*
|
||||
* @param biasCorrected setting for bias correction - true means
|
||||
* bias will be corrected and is equivalent to using the argumentless
|
||||
* constructor
|
||||
*/
|
||||
public SemiVariance(final boolean biasCorrected) {
|
||||
this.biasCorrected = biasCorrected;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a SemiVariance with the specified <code>Direction</code> property
|
||||
* and default (true) <code>biasCorrected</code> property
|
||||
*
|
||||
* @param direction setting for the direction of the SemiVariance
|
||||
* to calculate
|
||||
*/
|
||||
public SemiVariance(final Direction direction) {
|
||||
this.varianceDirection = direction;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a SemiVariance with the specified <code>isBiasCorrected</code>
|
||||
* property and the specified <code>Direction</code> property.
|
||||
*
|
||||
* @param corrected setting for bias correction - true means
|
||||
* bias will be corrected and is equivalent to using the argumentless
|
||||
* constructor
|
||||
*
|
||||
* @param direction setting for the direction of the SemiVariance
|
||||
* to calculate
|
||||
*/
|
||||
public SemiVariance(final boolean corrected, final Direction direction) {
|
||||
this.biasCorrected = corrected;
|
||||
this.varianceDirection = direction;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy constructor, creates a new {@code SemiVariance} identical
|
||||
* to the {@code original}
|
||||
*
|
||||
* @param original the {@code SemiVariance} instance to copy
|
||||
*/
|
||||
public SemiVariance(final SemiVariance original) {
|
||||
copy(original, this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public SemiVariance copy() {
|
||||
SemiVariance result = new SemiVariance();
|
||||
copy(this, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies source to dest.
|
||||
* <p>Neither source nor dest can be null.</p>
|
||||
*
|
||||
* @param source SemiVariance to copy
|
||||
* @param dest SemiVariance to copy to
|
||||
* @throws NullPointerException if either source or dest is null
|
||||
*/
|
||||
public static void copy(final SemiVariance source, SemiVariance dest) {
|
||||
dest.biasCorrected = source.biasCorrected;
|
||||
dest.varianceDirection = source.varianceDirection;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method calculates {@link SemiVariance} for the entire array against the mean, using
|
||||
* instance properties varianceDirection and biasCorrection.
|
||||
*
|
||||
* @param values the input array
|
||||
* @return the SemiVariance
|
||||
* @throws IllegalArgumentException if values is null
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public double evaluate(final double[] values) {
|
||||
if (values == null) {
|
||||
throw MathRuntimeException.createIllegalArgumentException("input values array is null");
|
||||
}
|
||||
return evaluate(values, 0, values.length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Returns the {@link SemiVariance} of the designated values against the mean, using
|
||||
* instance properties varianceDirection and biasCorrection.</p>
|
||||
*
|
||||
* <p>Returns <code>NaN</code> if the array is empty and throws
|
||||
* <code>IllegalArgumentException</code> if the array is null.</p>
|
||||
*
|
||||
* @param values the input array
|
||||
* @param start index of the first array element to include
|
||||
* @param length the number of elements to include
|
||||
* @return the SemiVariance
|
||||
* @throws IllegalArgumentException if the parameters are not valid
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public double evaluate(final double[] values, final int start, final int length) {
|
||||
double m = (new Mean()).evaluate(values, start, length);
|
||||
return evaluate(values, m, varianceDirection, biasCorrected, 0, values.length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method calculates {@link SemiVariance} for the entire array against the mean, using
|
||||
* the current value of the biasCorrection instance property.
|
||||
*
|
||||
* @param values the input array
|
||||
* @param direction the {@link Direction} of the semivariance
|
||||
* @return the SemiVariance
|
||||
* @throws IllegalArgumentException if values is null
|
||||
*
|
||||
*/
|
||||
public double evaluate(final double[] values, Direction direction) {
|
||||
double m = (new Mean()).evaluate(values);
|
||||
return evaluate (values, m, direction, biasCorrected, 0, values.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the {@link SemiVariance} of the designated values against the cutoff, using
|
||||
* instance properties variancDirection and biasCorrection.</p>
|
||||
*
|
||||
* <p>Returns <code>NaN</code> if the array is empty and throws
|
||||
* <code>IllegalArgumentException</code> if the array is null.</p>
|
||||
*
|
||||
* @param values the input array
|
||||
* @param cutoff the reference point
|
||||
* @return the SemiVariance
|
||||
* @throws IllegalArgumentException if values is null
|
||||
*/
|
||||
public double evaluate(final double[] values, final double cutoff) {
|
||||
return evaluate(values, cutoff, varianceDirection, biasCorrected, 0, values.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the {@link SemiVariance} of the designated values against the cutoff in the
|
||||
* given direction, using the current value of the biasCorrection instance property.</p>
|
||||
*
|
||||
* <p>Returns <code>NaN</code> if the array is empty and throws
|
||||
* <code>IllegalArgumentException</code> if the array is null.</p>
|
||||
*
|
||||
* @param values the input array
|
||||
* @param cutoff the reference point
|
||||
* @param direction the {@link Direction} of the semivariance
|
||||
* @return the SemiVariance
|
||||
* @throws IllegalArgumentException if values is null
|
||||
*/
|
||||
public double evaluate(final double[] values, final double cutoff, final Direction direction) {
|
||||
return evaluate(values, cutoff, direction, biasCorrected, 0, values.length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <p>Returns the {@link SemiVariance} of the designated values against the cutoff
|
||||
* in the given direction with the provided bias correction.</p>
|
||||
*
|
||||
* <p>Returns <code>NaN</code> if the array is empty and throws
|
||||
* <code>IllegalArgumentException</code> if the array is null.</p>
|
||||
*
|
||||
* @param values the input array
|
||||
* @param cutoff the reference point
|
||||
* @param direction the {@link Direction} of the semivariance
|
||||
* @param corrected the BiasCorrection flag
|
||||
* @param start index of the first array element to include
|
||||
* @param length the number of elements to include
|
||||
* @return the SemiVariance
|
||||
* @throws IllegalArgumentException if the parameters are not valid
|
||||
*
|
||||
*/
|
||||
public double evaluate (final double[] values, final double cutoff, final Direction direction,
|
||||
final boolean corrected, final int start, final int length) {
|
||||
|
||||
test(values, start, length);
|
||||
if (values.length == 0) {
|
||||
return Double.NaN;
|
||||
} else {
|
||||
if (values.length == 1) {
|
||||
return 0.0;
|
||||
} else {
|
||||
final boolean booleanDirection = direction.getDirection();
|
||||
|
||||
double dev = 0.0;
|
||||
double sumsq = 0.0;
|
||||
for (int i = start; i < length; i++) {
|
||||
if ((values[i] > cutoff) == booleanDirection) {
|
||||
dev = values[i] - cutoff;
|
||||
sumsq += dev * dev;
|
||||
}
|
||||
}
|
||||
|
||||
if (corrected) {
|
||||
return sumsq / (length - 1.0);
|
||||
} else {
|
||||
return sumsq / length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true iff biasCorrected property is set to true.
|
||||
*
|
||||
* @return the value of biasCorrected.
|
||||
*/
|
||||
public boolean isBiasCorrected() {
|
||||
return biasCorrected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the biasCorrected property.
|
||||
*
|
||||
* @param biasCorrected new biasCorrected property value
|
||||
*/
|
||||
public void setBiasCorrected(boolean biasCorrected) {
|
||||
this.biasCorrected = biasCorrected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the varianceDirection property.
|
||||
*
|
||||
* @return the varianceDirection
|
||||
*/
|
||||
public Direction getVarianceDirection () {
|
||||
return varianceDirection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the variance direction
|
||||
*
|
||||
* @param varianceDirection the direction of the semivariance
|
||||
*/
|
||||
public void setVarianceDirection(Direction varianceDirection) {
|
||||
this.varianceDirection = varianceDirection;
|
||||
}
|
||||
|
||||
/**
|
||||
* The direction of the semivariance - either upside or downside. The direction
|
||||
* is represented by boolean, with true corresponding to UPSIDE semivariance.
|
||||
*/
|
||||
public enum Direction {
|
||||
/**
|
||||
* The UPSIDE Direction is used to specify that the observations above the
|
||||
* cutoff point will be used to calculate SemiVariance
|
||||
*/
|
||||
UPSIDE (true),
|
||||
|
||||
/**
|
||||
* The DOWNSIDE Direction is used to specify that the observations below
|
||||
* the cutoff point will be used to calculate SemiVariance
|
||||
*/
|
||||
DOWNSIDE (false);
|
||||
|
||||
/**
|
||||
* boolean value UPSIDE <-> true
|
||||
*/
|
||||
private boolean direction;
|
||||
|
||||
/**
|
||||
* Create a Direction with the given value.
|
||||
*
|
||||
* @param b boolean value representing the Direction. True corresponds to UPSIDE.
|
||||
*/
|
||||
Direction (boolean b) {
|
||||
direction = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this Direction. True corresponds to UPSIDE.
|
||||
*
|
||||
* @return true if direction is UPSIDE; false otherwise
|
||||
*/
|
||||
boolean getDirection () {
|
||||
return direction;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,6 +39,9 @@ The <action> type attribute can be add,update,fix,remove.
|
|||
</properties>
|
||||
<body>
|
||||
<release version="2.1" date="TBD" description="TBD">
|
||||
<action dev="psteitz" type="add" issue="MATH-323" due-to="Larry Diamond">
|
||||
Added SemiVariance statistic.
|
||||
</action>
|
||||
<action dev="luc" type="add" issue="MATH-341" >
|
||||
Added a warning in the getCoefficients method documentation for
|
||||
PolynomialFunctionLagrangeForm. Computation may be ill-conditioned
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.stat.descriptive.moment;
|
||||
|
||||
import org.apache.commons.math.TestUtils;
|
||||
import org.apache.commons.math.stat.StatUtils;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SemiVarianceTest extends TestCase {
|
||||
|
||||
public void testInsufficientData() {
|
||||
double[] nothing = null;
|
||||
SemiVariance sv = new SemiVariance();
|
||||
try {
|
||||
sv.evaluate(nothing);
|
||||
fail("null is not a valid data array.");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
}
|
||||
|
||||
try {
|
||||
sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
|
||||
sv.evaluate(nothing);
|
||||
fail("null is not a valid data array.");
|
||||
} catch (IllegalArgumentException iae) {
|
||||
}
|
||||
nothing = new double[] {};
|
||||
assertTrue(Double.isNaN(sv.evaluate(nothing)));
|
||||
}
|
||||
|
||||
public void testSingleDown() {
|
||||
SemiVariance sv = new SemiVariance();
|
||||
double[] values = { 50.0d };
|
||||
double singletest = sv.evaluate(values);
|
||||
assertEquals(0.0d, singletest, 0);
|
||||
}
|
||||
|
||||
public void testSingleUp() {
|
||||
SemiVariance sv = new SemiVariance(SemiVariance.UPSIDE_VARIANCE);
|
||||
double[] values = { 50.0d };
|
||||
double singletest = sv.evaluate(values);
|
||||
assertEquals(0.0d, singletest, 0);
|
||||
}
|
||||
|
||||
public void testSample() {
|
||||
final double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
|
||||
final int length = values.length;
|
||||
final double mean = StatUtils.mean(values); // 6.333...
|
||||
final SemiVariance sv = new SemiVariance(); // Default bias correction is true
|
||||
final double downsideSemiVariance = sv.evaluate(values); // Downside is the default
|
||||
assertEquals(TestUtils.sumSquareDev(new double[] {-2d, 2d, 4d, -2d, 3d, 5d}, mean) / (length - 1),
|
||||
downsideSemiVariance, 1E-14);
|
||||
|
||||
sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
|
||||
final double upsideSemiVariance = sv.evaluate(values);
|
||||
assertEquals(TestUtils.sumSquareDev(new double[] {22d, 11d, 14d}, mean) / (length - 1),
|
||||
upsideSemiVariance, 1E-14);
|
||||
|
||||
// Verify that upper + lower semivariance against the mean sum to variance
|
||||
assertEquals(StatUtils.variance(values), downsideSemiVariance + upsideSemiVariance, 10e-12);
|
||||
}
|
||||
|
||||
public void testPopulation() {
|
||||
double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
|
||||
SemiVariance sv = new SemiVariance(false);
|
||||
|
||||
double singletest = sv.evaluate(values);
|
||||
assertEquals(19.556d, singletest, 0.01d);
|
||||
|
||||
sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
|
||||
singletest = sv.evaluate(values);
|
||||
assertEquals(36.222d, singletest, 0.01d);
|
||||
}
|
||||
|
||||
public void testNonMeanCutoffs() {
|
||||
double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
|
||||
SemiVariance sv = new SemiVariance(false); // Turn off bias correction - use df = length
|
||||
|
||||
double singletest = sv.evaluate(values, 1.0d, SemiVariance.DOWNSIDE_VARIANCE, false, 0, values.length);
|
||||
assertEquals(TestUtils.sumSquareDev(new double[] { -2d, -2d }, 1.0d) / values.length,
|
||||
singletest, 0.01d);
|
||||
|
||||
singletest = sv.evaluate(values, 3.0d, SemiVariance.UPSIDE_VARIANCE, false, 0, values.length);
|
||||
assertEquals(TestUtils.sumSquareDev(new double[] { 4d, 22d, 11d, 14d, 5d }, 3.0d) / values.length, singletest,
|
||||
0.01d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the lower + upper semivariance against the mean sum to the
|
||||
* variance.
|
||||
*/
|
||||
public void testVarianceDecompMeanCutoff() {
|
||||
double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
|
||||
double variance = StatUtils.variance(values);
|
||||
SemiVariance sv = new SemiVariance(true); // Bias corrected
|
||||
sv.setVarianceDirection(SemiVariance.DOWNSIDE_VARIANCE);
|
||||
final double lower = sv.evaluate(values);
|
||||
sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
|
||||
final double upper = sv.evaluate(values);
|
||||
assertEquals(variance, lower + upper, 10e-12);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that upper and lower semivariances against a cutoff sum to the sum
|
||||
* of squared deviations of the full set of values against the cutoff
|
||||
* divided by df = length - 1 (assuming bias-corrected).
|
||||
*/
|
||||
public void testVarianceDecompNonMeanCutoff() {
|
||||
double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
|
||||
double target = 0;
|
||||
double totalSumOfSquares = TestUtils.sumSquareDev(values, target);
|
||||
SemiVariance sv = new SemiVariance(true); // Bias corrected
|
||||
sv.setVarianceDirection(SemiVariance.DOWNSIDE_VARIANCE);
|
||||
double lower = sv.evaluate(values, target);
|
||||
sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
|
||||
double upper = sv.evaluate(values, target);
|
||||
assertEquals(totalSumOfSquares / (values.length - 1), lower + upper, 10e-12);
|
||||
}
|
||||
|
||||
public void testNoVariance() {
|
||||
final double[] values = {100d, 100d, 100d, 100d};
|
||||
SemiVariance sv = new SemiVariance();
|
||||
assertEquals(0, sv.evaluate(values), 10E-12);
|
||||
assertEquals(0, sv.evaluate(values, 100d), 10E-12);
|
||||
assertEquals(0, sv.evaluate(values, 100d, SemiVariance.UPSIDE_VARIANCE, false, 0, values.length), 10E-12);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue