KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mondrian > udf > InverseNormalUdf


1 /*
2 // $Id: //open/mondrian/src/main/mondrian/udf/InverseNormalUdf.java#3 $
3 // This software is subject to the terms of the Common Public License
4 // Agreement, available at the following URL:
5 // http://www.opensource.org/licenses/cpl.html.
6 // Copyright (C) 2005-2006 Julian Hyde
7 // All Rights Reserved.
8 // You must accept the terms of that agreement to use this software.
9 */

10 package mondrian.udf;
11
12 import org.apache.commons.math.MathException;
13 import org.apache.commons.math.distribution.DistributionFactory;
14 import org.apache.commons.math.distribution.NormalDistribution;
15 import org.apache.log4j.Logger;
16
17 import mondrian.olap.Evaluator;
18 import mondrian.olap.Syntax;
19 import mondrian.olap.fun.MondrianEvaluationException;
20 import mondrian.olap.type.NumericType;
21 import mondrian.olap.type.Type;
22 import mondrian.spi.UserDefinedFunction;
23
24
25 /**
26  * A user-defined function which returns the inverse normal distribution value
27  * of its argument.
28  *
29  * <p>This particular function is useful in Six Sigma calculations, for
30  * example,
31  *
32  * <blockquote><code><pre>
33  * WITH MEMBER [Measures].[Yield]
34  * AS '([Measures].[Number of Failures] / [Measures].[Population])',
35  * FORMAT_STRING = "0.00%"
36  * MEMBER [Measures].[Sigma]
37  * AS 'IIf([Measures].[Yield] <&gt; 0,
38  * IIf([Measures].[Yield] &gt; 0.5,
39  * 0,
40  * InverseNormal(1 - ([Measures].[Yield])) + 1.5), 6)',
41  * FORMAT_STRING = "0.0000"
42  * </pre></code></blockquote>
43  */

44 public class InverseNormalUdf implements UserDefinedFunction {
45     private static final Logger LOGGER = Logger.getLogger(InverseNormalUdf.class);
46
47     private static DistributionFactory distributionFactory = DistributionFactory.newInstance();
48     private static NormalDistribution nd = distributionFactory.createNormalDistribution();
49
50     public String JavaDoc getName() {
51         return "InverseNormal";
52     }
53
54     public String JavaDoc getDescription() {
55         return "Returns inverse normal distribution of its argument";
56     }
57
58     public Syntax getSyntax() {
59         return Syntax.Function;
60     }
61
62     public Type getReturnType(Type[] types) {
63         return new NumericType();
64     }
65
66     public Type[] getParameterTypes() {
67         return new Type[] {new NumericType()};
68     }
69
70     public Object JavaDoc execute(Evaluator evaluator, Argument[] args) {
71         final Object JavaDoc argValue = args[0].evaluateScalar(evaluator);
72         LOGGER.debug("Inverse Normal argument was : " + argValue);
73         if (!(argValue instanceof Number JavaDoc)) {
74             // Argument might be a RuntimeException indicating that
75
// the cache does not yet have the required cell value. The
76
// function will be called again when the cache is loaded.
77
return null;
78         }
79
80         final Double JavaDoc d = new Double JavaDoc(((Number JavaDoc) argValue).doubleValue());
81         LOGGER.debug("Inverse Normal argument as Double was : " + d);
82
83         if (d.isNaN()) {
84             return null;
85         }
86         /*
87            If probability is nonnumeric or
88                 probability < 0 or
89                 probability > 1,
90             returns an error.
91          */

92         double dbl = d.doubleValue();
93         if (dbl < 0.0 || dbl > 1.0) {
94             LOGGER.debug("Invalid value for inverse normal distribution: " + dbl);
95             throw new MondrianEvaluationException("Invalid value for inverse normal distribution: " + dbl);
96         }
97         try {
98             Double JavaDoc result = new Double JavaDoc(nd.inverseCumulativeProbability(dbl));
99             LOGGER.debug("Inverse Normal result : " + result.doubleValue());
100             return result;
101         } catch (MathException e) {
102             LOGGER.debug("Exception calculating inverse normal distribution: " + dbl, e);
103             throw new MondrianEvaluationException("Exception calculating inverse normal distribution: " + dbl);
104         }
105     }
106
107     public String JavaDoc[] getReservedWords() {
108         return null;
109     }
110
111 }
112
113 // End InverseNormalFunDef.java
114
Popular Tags