001    /*
002    // $Id: //open/mondrian/src/main/mondrian/olap/fun/CovarianceFunDef.java#3 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 2006-2007 Julian Hyde
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    */
010    package mondrian.olap.fun;
011    
012    import mondrian.olap.FunDef;
013    import mondrian.olap.Evaluator;
014    import mondrian.olap.Dimension;
015    import mondrian.calc.Calc;
016    import mondrian.calc.ExpCompiler;
017    import mondrian.calc.ListCalc;
018    import mondrian.calc.impl.ValueCalc;
019    import mondrian.calc.impl.AbstractCalc;
020    import mondrian.calc.impl.AbstractDoubleCalc;
021    import mondrian.mdx.ResolvedFunCall;
022    
023    import java.util.List;
024    
025    /**
026     * Definition of the <code>Covariance</code> and <code>CovarianceN</code> MDX functions.
027     *
028     * @author jhyde
029     * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/CovarianceFunDef.java#3 $
030     * @since Mar 23, 2006
031     */
032    class CovarianceFunDef extends FunDefBase {
033        static final ReflectiveMultiResolver CovarianceResolver = new ReflectiveMultiResolver(
034                "Covariance",
035                "Covariance(<Set>, <Numeric Expression>[, <Numeric Expression>])",
036                "Returns the covariance of two series evaluated over a set (biased).",
037                new String[]{"fnxn","fnxnn"},
038                CovarianceFunDef.class);
039    
040        static final MultiResolver CovarianceNResolver = new ReflectiveMultiResolver(
041                "CovarianceN",
042                "CovarianceN(<Set>, <Numeric Expression>[, <Numeric Expression>])",
043                "Returns the covariance of two series evaluated over a set (unbiased).",
044                new String[]{"fnxn","fnxnn"},
045                CovarianceFunDef.class);
046    
047        private final boolean biased;
048    
049        public CovarianceFunDef(FunDef dummyFunDef) {
050            super(dummyFunDef);
051            this.biased = dummyFunDef.getName().equals("Covariance");
052        }
053    
054        public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
055            final ListCalc listCalc =
056                    compiler.compileList(call.getArg(0));
057            final Calc calc1 =
058                    compiler.compileScalar(call.getArg(1), true);
059            final Calc calc2 = call.getArgCount() > 2 ?
060                    compiler.compileScalar(call.getArg(2), true) :
061                    new ValueCalc(call);
062            return new AbstractDoubleCalc(call, new Calc[] {listCalc, calc1, calc2}) {
063                public double evaluateDouble(Evaluator evaluator) {
064                    List memberList = listCalc.evaluateList(evaluator);
065                    return (Double)covariance(
066                            evaluator.push(), memberList,
067                            calc1, calc2, biased);
068                }
069    
070                public boolean dependsOn(Dimension dimension) {
071                    return anyDependsButFirst(getCalcs(), dimension);
072                }
073            };
074        }
075    }
076    
077    // End CovarianceFunDef.java