1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.hipparchus.stat.descriptive.moment;
24
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28
29 import java.util.Arrays;
30
31 import org.hipparchus.UnitTestUtils;
32 import org.hipparchus.exception.NullArgumentException;
33 import org.hipparchus.stat.StatUtils;
34 import org.hipparchus.stat.descriptive.UnivariateStatisticAbstractTest;
35 import org.junit.Before;
36 import org.junit.Test;
37
38
39
40
41 public class SemiVarianceTest extends UnivariateStatisticAbstractTest {
42
43 private double semiVariance;
44
45 @Before
46 public void setup() {
47
48
49
50 double val =
51 Arrays.stream(testArray)
52 .filter(x -> x < this.mean)
53 .reduce(0, (x, y) -> x + (y - this.mean) * (y - this.mean));
54
55 this.semiVariance = val / (testArray.length - 1);
56 }
57
58 @Override
59 public SemiVariance getUnivariateStatistic() {
60 return new SemiVariance();
61 }
62
63 @Override
64 public double expectedValue() {
65 return semiVariance;
66 }
67
68 @Test
69 public void testInsufficientData() {
70 SemiVariance sv = getUnivariateStatistic();
71 try {
72 sv.evaluate(null);
73 fail("null is not a valid data array.");
74 } catch (NullArgumentException nae) {
75 }
76
77 try {
78 sv = sv.withVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
79 sv.evaluate(null);
80 fail("null is not a valid data array.");
81 } catch (NullArgumentException nae) {
82 }
83 assertTrue(Double.isNaN(sv.evaluate(new double[0])));
84 }
85
86 @Test
87 public void testSingleDown() {
88 SemiVariance sv = new SemiVariance();
89 double[] values = { 50.0d };
90 double singletest = sv.evaluate(values);
91 assertEquals(0.0d, singletest, 0);
92 }
93
94 @Test
95 public void testSingleUp() {
96 SemiVariance sv = new SemiVariance(SemiVariance.UPSIDE_VARIANCE);
97 double[] values = { 50.0d };
98 double singletest = sv.evaluate(values);
99 assertEquals(0.0d, singletest, 0);
100 }
101
102 @Test
103 public void testSample() {
104 final double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
105 final int length = values.length;
106 final double mean = StatUtils.mean(values);
107 SemiVariance sv = getUnivariateStatistic();
108 final double downsideSemiVariance = sv.evaluate(values);
109 assertEquals(UnitTestUtils.sumSquareDev(new double[] {-2d, 2d, 4d, -2d, 3d, 5d}, mean) / (length - 1),
110 downsideSemiVariance, 1E-14);
111
112 sv = sv.withVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
113 final double upsideSemiVariance = sv.evaluate(values);
114 assertEquals(UnitTestUtils.sumSquareDev(new double[] {22d, 11d, 14d}, mean) / (length - 1),
115 upsideSemiVariance, 1E-14);
116
117
118 assertEquals(StatUtils.variance(values), downsideSemiVariance + upsideSemiVariance, 10e-12);
119 }
120
121 @Test
122 public void testPopulation() {
123 double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
124 SemiVariance sv = new SemiVariance(false);
125
126 double singletest = sv.evaluate(values);
127 assertEquals(19.556d, singletest, 0.01d);
128
129 sv = sv.withVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
130 singletest = sv.evaluate(values);
131 assertEquals(36.222d, singletest, 0.01d);
132 }
133
134 @Test
135 public void testNonMeanCutoffs() {
136 double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
137 SemiVariance sv = new SemiVariance(false);
138
139 double singletest = sv.evaluate(values, 1.0d, SemiVariance.DOWNSIDE_VARIANCE, false, 0, values.length);
140 assertEquals(UnitTestUtils.sumSquareDev(new double[] { -2d, -2d }, 1.0d) / values.length,
141 singletest, 0.01d);
142
143 singletest = sv.evaluate(values, 3.0d, SemiVariance.UPSIDE_VARIANCE, false, 0, values.length);
144 assertEquals(UnitTestUtils.sumSquareDev(new double[] { 4d, 22d, 11d, 14d, 5d }, 3.0d) / values.length,
145 singletest,
146 0.01d);
147 }
148
149
150
151
152 @Test
153 public void testVarianceDecompMeanCutoff() {
154 double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
155 double variance = StatUtils.variance(values);
156 SemiVariance sv = new SemiVariance(true);
157 sv = sv.withVarianceDirection(SemiVariance.DOWNSIDE_VARIANCE);
158 final double lower = sv.evaluate(values);
159 sv = sv.withVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
160 final double upper = sv.evaluate(values);
161 assertEquals(variance, lower + upper, 10e-12);
162 }
163
164
165
166
167
168
169 @Test
170 public void testVarianceDecompNonMeanCutoff() {
171 double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
172 double target = 0;
173 double totalSumOfSquares = UnitTestUtils.sumSquareDev(values, target);
174 SemiVariance sv = new SemiVariance(true);
175 sv = sv.withVarianceDirection(SemiVariance.DOWNSIDE_VARIANCE);
176 double lower = sv.evaluate(values, target);
177 sv = sv.withVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
178 double upper = sv.evaluate(values, target);
179 assertEquals(totalSumOfSquares / (values.length - 1), lower + upper, 10e-12);
180 }
181
182 @Test
183 public void testNoVariance() {
184 final double[] values = {100d, 100d, 100d, 100d};
185 SemiVariance sv = getUnivariateStatistic();
186 assertEquals(0, sv.evaluate(values), 10E-12);
187 assertEquals(0, sv.evaluate(values, 100d), 10E-12);
188 assertEquals(0, sv.evaluate(values, 100d, SemiVariance.UPSIDE_VARIANCE, false, 0, values.length), 10E-12);
189 }
190
191 }