1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  package org.apache.commons.math4.legacy.stat.descriptive.moment;
19  
20  import org.apache.commons.math4.legacy.TestUtils;
21  import org.apache.commons.math4.legacy.exception.NullArgumentException;
22  import org.apache.commons.math4.legacy.stat.StatUtils;
23  import org.junit.Assert;
24  import org.junit.Test;
25  
26  
27  public class SemiVarianceTest {
28  
29      @Test
30      public void testInsufficientData() {
31          double[] nothing = null;
32          SemiVariance sv = new SemiVariance();
33          try {
34              sv.evaluate(nothing);
35              Assert.fail("null is not a valid data array.");
36          } catch (NullArgumentException nae) {
37          }
38  
39          try {
40              sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
41              sv.evaluate(nothing);
42              Assert.fail("null is not a valid data array.");
43          } catch (NullArgumentException nae) {
44          }
45          nothing = new double[] {};
46          Assert.assertTrue(Double.isNaN(sv.evaluate(nothing)));
47      }
48  
49      @Test
50      public void testSingleDown() {
51          SemiVariance sv = new SemiVariance();
52          double[] values = { 50.0d };
53          double singletest = sv.evaluate(values);
54          Assert.assertEquals(0.0d, singletest, 0);
55      }
56  
57      @Test
58      public void testSingleUp() {
59          SemiVariance sv = new SemiVariance(SemiVariance.UPSIDE_VARIANCE);
60          double[] values = { 50.0d };
61          double singletest = sv.evaluate(values);
62          Assert.assertEquals(0.0d, singletest, 0);
63      }
64  
65      @Test
66      public void testSample() {
67          final double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
68          final int length = values.length;
69          final double mean = StatUtils.mean(values); 
70          final SemiVariance sv = new SemiVariance();  
71          final double downsideSemiVariance = sv.evaluate(values); 
72          Assert.assertEquals(TestUtils.sumSquareDev(new double[] {-2d, 2d, 4d, -2d, 3d, 5d}, mean) / (length - 1),
73                  downsideSemiVariance, 1E-14);
74  
75          sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
76          final double upsideSemiVariance = sv.evaluate(values);
77          Assert.assertEquals(TestUtils.sumSquareDev(new double[] {22d, 11d, 14d}, mean) / (length - 1),
78                  upsideSemiVariance, 1E-14);
79  
80          
81          Assert.assertEquals(StatUtils.variance(values), downsideSemiVariance + upsideSemiVariance, 10e-12);
82      }
83  
84      @Test
85      public void testPopulation() {
86          double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
87          SemiVariance sv = new SemiVariance(false);
88  
89          double singletest = sv.evaluate(values);
90          Assert.assertEquals(19.556d, singletest, 0.01d);
91  
92          sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
93          singletest = sv.evaluate(values);
94          Assert.assertEquals(36.222d, singletest, 0.01d);
95      }
96  
97      @Test
98      public void testNonMeanCutoffs() {
99          double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
100         SemiVariance sv = new SemiVariance(false); 
101 
102         double singletest = sv.evaluate(values, 1.0d, SemiVariance.DOWNSIDE_VARIANCE, false, 0, values.length);
103         Assert.assertEquals(TestUtils.sumSquareDev(new double[] { -2d, -2d }, 1.0d) / values.length,
104                 singletest, 0.01d);
105 
106         singletest = sv.evaluate(values, 3.0d, SemiVariance.UPSIDE_VARIANCE, false, 0, values.length);
107         Assert.assertEquals(TestUtils.sumSquareDev(new double[] { 4d, 22d, 11d, 14d, 5d }, 3.0d) / values.length, singletest,
108                 0.01d);
109     }
110 
111     
112 
113 
114 
115     @Test
116     public void testVarianceDecompMeanCutoff() {
117         double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
118         double variance = StatUtils.variance(values);
119         SemiVariance sv = new SemiVariance(true); 
120         sv.setVarianceDirection(SemiVariance.DOWNSIDE_VARIANCE);
121         final double lower = sv.evaluate(values);
122         sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
123         final double upper = sv.evaluate(values);
124         Assert.assertEquals(variance, lower + upper, 10e-12);
125     }
126 
127     
128 
129 
130 
131 
132     @Test
133     public void testVarianceDecompNonMeanCutoff() {
134         double[] values = { -2.0d, 2.0d, 4.0d, -2.0d, 22.0d, 11.0d, 3.0d, 14.0d, 5.0d };
135         double target = 0;
136         double totalSumOfSquares = TestUtils.sumSquareDev(values, target);
137         SemiVariance sv = new SemiVariance(true); 
138         sv.setVarianceDirection(SemiVariance.DOWNSIDE_VARIANCE);
139         double lower = sv.evaluate(values, target);
140         sv.setVarianceDirection(SemiVariance.UPSIDE_VARIANCE);
141         double upper = sv.evaluate(values, target);
142         Assert.assertEquals(totalSumOfSquares / (values.length - 1), lower + upper, 10e-12);
143     }
144 
145     @Test
146     public void testNoVariance() {
147         final double[] values = {100d, 100d, 100d, 100d};
148         SemiVariance sv = new SemiVariance();
149         Assert.assertEquals(0, sv.evaluate(values), 10E-12);
150         Assert.assertEquals(0, sv.evaluate(values, 100d), 10E-12);
151         Assert.assertEquals(0, sv.evaluate(values, 100d, SemiVariance.UPSIDE_VARIANCE, false, 0, values.length), 10E-12);
152     }
153 }