Example #1
0
        /**
         * returns the OperationEval concrete impl instance corresponding
         * to the supplied operationPtg
         */
        public static ValueEval Evaluate(OperationPtg ptg, ValueEval[] args,
                                         OperationEvaluationContext ec)
        {
            if (ptg == null)
            {
                throw new ArgumentException("ptg must not be null");
            }
            Frame.Utils.NPOI.SS.Formula.Functions.Function result = _instancesByPtgClass[ptg] as Frame.Utils.NPOI.SS.Formula.Functions.Function;

            if (result != null)
            {
                return(result.Evaluate(args, ec.RowIndex, (short)ec.ColumnIndex));
            }

            if (ptg is AbstractFunctionPtg)
            {
                AbstractFunctionPtg fptg = (AbstractFunctionPtg)ptg;
                int functionIndex        = fptg.GetFunctionIndex();
                switch (functionIndex)
                {
                case Frame.Utils.NPOI.SS.Formula.Function.FunctionMetadataRegistry.FUNCTION_INDEX_INDIRECT:
                    return(Indirect.instance.Evaluate(args, ec));

                case Frame.Utils.NPOI.SS.Formula.Function.FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL:
                    return(UserDefinedFunction.instance.Evaluate(args, ec));
                }

                return(FunctionEval.GetBasicFunction(functionIndex).Evaluate(args, ec.RowIndex, ec.ColumnIndex));
            }
            throw new Exception("Unexpected operation ptg class (" + ptg.GetType().Name + ")");
        }
Example #2
0
// Change values in some range
    public void modify(SpreadSheetRange <AI1, AI2> range, FunctionEval <V> function)
    { // Using a delegate to change the values in a range!
        // Objective is to iterate in a range and apply a function to each
        // element in that range

        AI1 rmin = range.upperLeft.first;
        AI2 cmin = range.upperLeft.second;

        AI1 rmax = range.lowerRight.first;
        AI2 cmax = range.lowerRight.second;

        int Rmin = r[rmin]; int Rmax = r[rmax];
        int Cmin = c[cmin]; int Cmax = c[cmax];


        // Now must find the integer indices corresponding to these
        V d;

        for (int ri = Rmin; ri <= Rmax; ri++)
        {
            for (int ci = Cmin; ci <= Cmax; ci++)
            {
                d = mat[ri, ci];
                function(ref d);
                mat[ri, ci] = d;
            }
        }
    }
Example #3
0
        /**
         * Return a collection of functions that POI can evaluate
         *
         * @return names of functions supported by POI
         */
        public static IList <String> GetSupportedFunctionNames()
        {
            List <String> lst = new List <String>();

            lst.AddRange(FunctionEval.GetSupportedFunctionNames());
            lst.AddRange(AnalysisToolPak.GetSupportedFunctionNames());
            return(lst.AsReadOnly());
        }
Example #4
0
        /**
         * Return a collection of functions that POI does not support
         *
         * @return names of functions NOT supported by POI
         */

        public static List <string> GetNotSupportedFunctionNames()
        {
            List <string> lst = new List <string>();

            lst.AddRange(FunctionEval.GetNotSupportedFunctionNames());
            lst.AddRange(AnalysisToolPak.GetNotSupportedFunctionNames());
            return(lst);
        }
Example #5
0
        public void EvaluateTest2()
        {
            FunctionEval fe = new FunctionEval();

            String s1     = "5*x^0";
            double result = fe.Evaluate(s1, 5);

            Assert.AreEqual(5, result);
        }
Example #6
0
        public void EvaluateTest4()
        {
            FunctionEval fe = new FunctionEval();

            String s1     = "2*3+7-1*1";
            double result = fe.Evaluate(s1);

            Assert.AreEqual(2 * 3 + 7 - 1 * 1, result);
        }
Example #7
0
        public void EvaluateTest1()
        {
            FunctionEval fe = new FunctionEval();

            String s1     = "2*3*x^0";
            double result = fe.Evaluate(s1, 3);

            Assert.AreEqual(6, result);
        }
Example #8
0
        public void TestRegisterInRuntime()
        {
            HSSFWorkbook         wb    = new HSSFWorkbook();
            HSSFSheet            sheet = (HSSFSheet)wb.CreateSheet("Sheet1");
            HSSFRow              row   = (HSSFRow)sheet.CreateRow(0);
            HSSFFormulaEvaluator fe    = new HSSFFormulaEvaluator(wb);

            HSSFCell cellA = (HSSFCell)row.CreateCell(0);

            cellA.CellFormula = ("FISHER(A5)");
            CellValue cv;

            try
            {
                //NPOI
                //Run it twice in NUnit Gui Window, the first passed but the second failed.
                //Maybe the function was cached. Ignore it.
                cv = fe.Evaluate(cellA);
                Assert.Fail("expectecd exception");
            }
            catch (NotImplementedException)
            {
                ;
            }

            FunctionEval.RegisterFunction("FISHER", new Function1());/*Function() {
                                                                      * public ValueEval Evaluate(ValueEval[] args, int srcRowIndex, int srcColumnIndex) {
                                                                      * return ErrorEval.NA;
                                                                      * }
                                                                      * });*/

            cv = fe.Evaluate(cellA);
            Assert.AreEqual(ErrorEval.NA.ErrorCode, cv.ErrorValue);

            HSSFCell cellB = (HSSFCell)row.CreateCell(1);

            cellB.CellFormula = ("CUBEMEMBERPROPERTY(A5)");
            try
            {
                cv = fe.Evaluate(cellB);
                Assert.Fail("expectecd exception");
            }
            catch (NotImplementedException)
            {
                ;
            }

            AnalysisToolPak.RegisterFunction("CUBEMEMBERPROPERTY", new FreeRefFunction1());/*FreeRefFunction() {
                                                                                            * public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec) {
                                                                                            * return ErrorEval.NUM_ERROR;
                                                                                            * }
                                                                                            * });*/

            cv = fe.Evaluate(cellB);
            Assert.AreEqual(ErrorEval.NUM_ERROR.ErrorCode, cv.ErrorValue);
        }
Example #9
0
        public void HeunTest()
        {
            double       epsilon  = .001;
            double       expected = 4.0;
            FunctionEval fe       = new FunctionEval();

            double  result   = fe.Euler("2*x", 0, 0, 2);
            Boolean accurate = Math.Abs(result - expected) < epsilon;

            Assert.IsTrue(accurate);
        }
Example #10
0
        /**
         * returns the OperationEval concrete impl instance corresponding
         * to the supplied operationPtg
         */
        public static ValueEval Evaluate(OperationPtg ptg, ValueEval[] args,
                                         OperationEvaluationContext ec)
        {
            if (ptg == null)
            {
                throw new ArgumentException("ptg must not be null");
            }
            NPOI.SS.Formula.Functions.Function result = _instancesByPtgClass[ptg] as NPOI.SS.Formula.Functions.Function;

            FreeRefFunction udfFunc = null;

            if (result == null)
            {
                if (ptg is AbstractFunctionPtg)
                {
                    AbstractFunctionPtg fptg = (AbstractFunctionPtg)ptg;
                    int functionIndex        = fptg.FunctionIndex;
                    switch (functionIndex)
                    {
                    case NPOI.SS.Formula.Function.FunctionMetadataRegistry.FUNCTION_INDEX_INDIRECT:
                        udfFunc = Indirect.instance;
                        break;

                    case NPOI.SS.Formula.Function.FunctionMetadataRegistry.FUNCTION_INDEX_EXTERNAL:
                        udfFunc = UserDefinedFunction.instance;
                        break;

                    default:
                        result = FunctionEval.GetBasicFunction(functionIndex);
                        break;
                    }
                }
            }

            if (result != null)
            {
                if (result is ArrayFunction)
                {
                    ArrayFunction func = (ArrayFunction)result;
                    ValueEval     eval = EvaluateArrayFunction(func, args, ec);
                    if (eval != null)
                    {
                        return(eval);
                    }
                }
                return(result.Evaluate(args, ec.RowIndex, (short)ec.ColumnIndex));
            }
            else if (udfFunc != null)
            {
                return(udfFunc.Evaluate(args, ec));
            }
            throw new Exception("Unexpected operation ptg class (" + ptg.GetType().Name + ")");
        }
Example #11
0
        /**
         * @param startRowIndex row index in the spreadsheet where the first function/operator is found
         * @param TestFocusFunctionName name of a single function/operator to Test alone.
         * Typically pass <code>null</code> to Test all functions
         */
        private void ProcessFunctionGroup(int startRowIndex, String testFocusFunctionName)
        {
            HSSFFormulaEvaluator        evaluator = new HSSFFormulaEvaluator(workbook);
            ReadOnlyCollection <String> funcs     = FunctionEval.GetSupportedFunctionNames();
            int rowIndex = startRowIndex;

            while (true)
            {
                IRow   r = sheet.GetRow(rowIndex);
                String targetFunctionName = GetTargetFunctionName(r);
                if (targetFunctionName == null)
                {
                    throw new AssertionException("Test spreadsheet cell empty on row ("
                                                 + (rowIndex + 1) + "). Expected function name or '"
                                                 + SS.FUNCTION_NAMES_END_SENTINEL + "'");
                }
                if (targetFunctionName.Equals(SS.FUNCTION_NAMES_END_SENTINEL))
                {
                    // found end of functions list
                    break;
                }
                if (testFocusFunctionName == null || targetFunctionName.Equals(testFocusFunctionName, StringComparison.CurrentCultureIgnoreCase))
                {
                    // expected results are on the row below
                    IRow expectedValuesRow = sheet.GetRow(rowIndex + 1);
                    if (expectedValuesRow == null)
                    {
                        int missingRowNum = rowIndex + 2; //+1 for 1-based, +1 for next row
                        throw new AssertionException("Missing expected values row for function '"
                                                     + targetFunctionName + " (row " + missingRowNum + ")");
                    }
                    switch (ProcessFunctionRow(evaluator, targetFunctionName, r, expectedValuesRow))
                    {
                    case Result.ALL_EVALUATIONS_SUCCEEDED: _functionSuccessCount++; break;

                    case Result.SOME_EVALUATIONS_FAILED: _functionFailureCount++; break;

                    default:
                        throw new SystemException("unexpected result");

                    case Result.NO_EVALUATIONS_FOUND:     // do nothing
                        String uname = targetFunctionName.ToUpper();
                        if (startRowIndex >= SS.START_FUNCTIONS_ROW_INDEX &&
                            funcs.Contains(uname))
                        {
                            Debug.WriteLine(uname + ": function is supported but missing test data", "");
                        }
                        break;
                    }
                }
                rowIndex += SS.NUMBER_OF_ROWS_PER_FUNCTION;
            }
        }
Example #12
0
        public static bool CheckDerivatives(FunctionEval func, double[] x0)
        {
            double eps     = 1e-4;
            int    K       = x0.Length;
            var    grad    = Vector.Zero(K);
            var    dummy   = Vector.Zero(K);
            double f0      = func(Vector.FromArray(x0), ref grad);
            bool   allGood = true;

            for (int i = 0; i < K; i++)
            {
                var    x    = x0.Select(j => j).ToArray();
                double eps2 = eps * Math.Max(Math.Abs(x[i]), 0.1);
                x[i] += eps2;
                double f  = func(Vector.FromArray(x), ref dummy);
                double fd = (f - f0) / eps2;
                Console.WriteLine("{2} Analytic gradient: {0} finite difference: {1}", grad[i], fd, i);
            }
            return(allGood);
        }
Example #13
0
        /// <summary>
        /// Check whether "func" correctly calculates derivatives
        /// </summary>
        /// <param name="func">Return the objective and calculates gradients</param>
        /// <param name="x0">The point to perform the check around</param>
        /// <returns>Whether the derivatives are correctly calculated. </returns>
        public static bool CheckDerivatives(FunctionEval func, Vector x0)
        {
            double eps     = 1e-4;
            int    K       = x0.Count;
            var    grad    = Vector.Zero(K);
            Vector dummy   = Vector.Zero(K);
            double f0      = func(x0, ref grad);
            bool   allGood = true;

            for (int i = 0; i < K; i++)
            {
                var    x    = x0.Clone();
                double eps2 = eps * System.Math.Max(System.Math.Abs(x[i]), 1e-8);
                x[i] += eps2;
                double f  = func(x, ref dummy);
                double fd = (f - f0) / eps2;
                Console.WriteLine("{2} Analytic gradient: {0} finite difference: {1}", grad[i], fd, i);
            }
            return(allGood);
        }
Example #14
0
        /// <summary>
        /// Run an unconstrained minimization using BFGS
        /// </summary>
        /// <param name="x0">Starting step</param>
        /// <param name="normOfFirstStep">Norm of first step</param>
        /// <param name="func">Multivariate function and derivative evaluator</param>
        /// <returns>The local minimum point</returns>
        public virtual Vector Run(Vector x0, double normOfFirstStep, FunctionEval func)
        {
            dimension = x0.Count;
            currentX  = Vector.Copy(x0);

            if (func == null)
            {
                throw new ArgumentException("Null function");
            }

            cancel = false;

            // Initialize all the fields needed for optimisation
            feval        = new FunctionEval(func);
            searchDir    = Vector.Zero(dimension);
            currentDeriv = Vector.Zero(dimension);

            // Following vectors are the components of the
            // inverse Hessian update
            Vector S                 = Vector.Zero(dimension);
            Vector Y                 = Vector.Zero(dimension);
            Vector minusRhoS         = Vector.Zero(dimension);
            Matrix EyeMinusSYt       = new Matrix(dimension, dimension);
            Vector prevDeriv         = Vector.Zero(dimension);
            PositiveDefiniteMatrix H = new PositiveDefiniteMatrix(dimension, dimension);

            H.SetToIdentity();
            Matrix HWork = new Matrix(dimension, dimension);

            // Get the derivatives
            currentObj = feval(currentX, ref currentDeriv);
            double prevObj = currentObj;
            double rho;
            double step             = 0.0;
            double step0            = initialStep;
            double convergenceCheck = double.MaxValue;
            double invDim           = 1.0 / dimension;

            iter = 0;
            while (convergenceCheck > this.epsilon && !cancel)
            {
                prevDeriv.SetTo(currentDeriv);

                // Compute search direction
                searchDir.SetToProduct(H, currentDeriv);

                // Negate
                for (int i = 0; i < dimension; i++)
                {
                    searchDir[i] = -searchDir[i];
                }

                if (iter == 0)
                {
                    double sdNorm = System.Math.Sqrt(searchDir.Inner(searchDir));
                    double sdMult = normOfFirstStep / sdNorm;
                    searchDir.SetToProduct(searchDir, sdMult);
                    for (int i = 0; i < dimension; i++)
                    {
                        H[i, i] = sdMult;
                    }
                }

                //------------------------------------------------------
                // Line search enforces strong Wolfe conditions
                // so curvature condition is guaranteed
                //------------------------------------------------------
                step = TryLineSearch(step0, stepMax, currentDeriv.Inner(searchDir));

                // Get the delta between the old and new point
                S.SetToProduct(searchDir, step);

                // Update the current point
                currentX.SetToSum(currentX, S);

                // Calculate the objective and the derivative at the new point
                //double objVal = feval(currentX, ref currentDeriv);

                // If the step is 0, break now, once we have re-evaluated the function and derivs.
                if (step == 0.0)
                {
                    break;
                }

                // Difference of derivs
                Y.SetToDifference(currentDeriv, prevDeriv);

                // BFGS update
                rho = 1.0 / (S.Inner(Y));
                if (iter == 0)
                {
                    // Modify the Hessian to yTs/yTy times Identity
                    double beta = S.Inner(S) * rho;
                    for (int i = 0; i < dimension; i++)
                    {
                        H[i, i] = beta;
                    }
                }


                EyeMinusSYt.SetToIdentity();
                EyeMinusSYt.SetToSumWithOuter(EyeMinusSYt, -rho, S, Y);
                HWork.SetToProduct(EyeMinusSYt, H);
                H.SetToProduct(HWork, EyeMinusSYt.Transpose());
                H.SetToSumWithOuter(H, rho, S, S);

                switch (convergenceCriteria)
                {
                case ConvergenceCriteria.Gradient:
                    convergenceCheck = System.Math.Sqrt(invDim * currentDeriv.Inner(currentDeriv));
                    break;

                case ConvergenceCriteria.Objective:
                    convergenceCheck = System.Math.Abs(prevObj - currentObj) / System.Math.Max(1, System.Math.Max(prevObj, currentObj));
                    break;
                }
                prevObj = currentObj;
                // Let anyone who's interested know that we have completed an iteration
                RaiseIterationEvent(iter, currentObj, convergenceCheck);

                if (++iter > maxIterations)
                {
                    break;
                }
            }
            return(currentX);
        }
Example #15
0
        /// <summary>
        /// Run an unconstrained minimization using BFGS
        /// </summary>
        /// <param name="x0">Starting step</param>
        /// <param name="normOfFirstStep">Norm of first step</param>
        /// <param name="func">Multivariate function and derivative evaluator</param>
        /// <returns>The local minimum point</returns>
        public override Vector Run(Vector x0, double normOfFirstStep, FunctionEval func)
        {
            Init();
            dimension = x0.Count;
            if (approxDim >= dimension)
            {
                return(base.Run(x0, normOfFirstStep, func));
            }

            if (func == null)
            {
                throw new ArgumentException("Null function");
            }

            cancel = false;

            // Initialize all the fields needed for optimisation
            feval        = new FunctionEval(func);
            searchDir    = Vector.Zero(dimension, sparsity: x0.Sparsity);
            currentX     = Vector.Copy(x0);
            currentDeriv = Vector.Zero(dimension, sparsity: x0.Sparsity);

            // Following vectors are the components of the
            // inverse Hessian update
            Vector S         = Vector.Zero(dimension, sparsity: x0.Sparsity);
            Vector Y         = Vector.Zero(dimension, sparsity: x0.Sparsity);
            Vector q         = Vector.Zero(dimension, sparsity: x0.Sparsity);
            Vector alpha     = Vector.Zero(approxDim);
            Vector work      = Vector.Zero(dimension, sparsity: x0.Sparsity);
            Vector prevDeriv = Vector.Zero(dimension, sparsity: x0.Sparsity);
            Vector H0        = Vector.Zero(dimension, sparsity: x0.Sparsity);

            // Get the derivatives
            currentObj = feval(currentX, ref currentDeriv);

            double beta;
            double prevObj          = currentObj;
            double step             = 0.0;
            double step0            = initialStep;
            double convergenceCheck = double.MaxValue;
            double invDim           = 1.0 / dimension;

            iter = 0;
            while (convergenceCheck > this.epsilon && !cancel)
            {
                prevDeriv.SetTo(currentDeriv);

                // H0 = gamma x Identity
                if (iter == 0)
                {
                    double sdNorm = System.Math.Sqrt(currentDeriv.Inner(currentDeriv));
                    H0.SetAllElementsTo(normOfFirstStep / sdNorm);
                }
                else
                {
                    H0.SetAllElementsTo(ess[0].Inner(wye[0]) / wye[0].Inner(wye[0]));
                }

                //---------------------------------------------
                // L-BFGS two loop recursion. Algorithm 7.4 in
                // Nocedal and Wright 2006
                //---------------------------------------------
                q.SetTo(currentDeriv);
                int cnt = ess.Count;
                for (int i = 0; i < cnt; i++)
                {
                    alpha[i] = rho[i] * ess[i].Inner(q);
                    work.SetToProduct(wye[i], alpha[i]);
                    q.SetToDifference(q, work);
                }

                searchDir.SetToProduct(q, H0);

                for (int i = cnt - 1; i >= 0; i--)
                {
                    beta = rho[i] * wye[i].Inner(searchDir);
                    work.SetToProduct(ess[i], alpha[i] - beta);
                    searchDir.SetToSum(searchDir, work);
                }

                // Negate
                searchDir.Scale(-1.0);

                //------------------------------------------------------
                // Line search enforces strong Wolfe conditions
                // so curvature condition is guaranteed
                //------------------------------------------------------
                step = TryLineSearch(step0, stepMax, currentDeriv.Inner(searchDir));

                // Discard items falling off the bottom of the list
                if (cnt >= approxDim)
                {
                    ess.RemoveAt(cnt - 1);
                    wye.RemoveAt(cnt - 1);
                    rho.RemoveAt(cnt - 1);
                }

                // we have done this calculation already...
                // Get the delta between the old and new point
                S.SetToProduct(searchDir, step);
                ess.Insert(0, Vector.Copy(S));

                // Update the current point
                currentX.SetToSum(currentX, S);

                // Find the derivative at the new point
                // we should already have this
                //if (objVal != currentObj)
                //    throw new InferRuntimeException("error");

                // If the step is 0, break now, once we have re-evaluated the function and derivs.
                if (step == 0.0)
                {
                    if (debug)
                    {
                        Console.WriteLine("Step size is 0.0, stopping LBFGS.");
                    }
                    break;
                }

                // Difference of derivs
                Y.SetToDifference(currentDeriv, prevDeriv);
                wye.Insert(0, Vector.Copy(Y));

                // Rho
                rho.Insert(0, 1.0 / (S.Inner(Y)));

                // Value used for convergence
                switch (convergenceCriteria)
                {
                case ConvergenceCriteria.Gradient:
                    convergenceCheck = System.Math.Sqrt(invDim * currentDeriv.Inner(currentDeriv));
                    break;

                case ConvergenceCriteria.Objective:
                    convergenceCheck = System.Math.Abs(prevObj - currentObj) / System.Math.Max(1, System.Math.Max(prevObj, currentObj));
                    break;
                }
                prevObj = currentObj;
                // Let anyone who's interested know that we have completed an iteration
                RaiseIterationEvent(iter, currentObj, convergenceCheck);

                if (++iter > maxIterations)
                {
                    if (debug)
                    {
                        Console.WriteLine("Max iterations reached, stopping LBFGS.");
                    }
                    break;
                }
            }
            return(currentX);
        }
Example #16
0
        /**
         * Register a function in runtime.
         *
         * @param name  the function name
         * @param func  the functoin to register
         * @throws IllegalArgumentException if the function is unknown or already  registered.
         * @since 3.8 beta6
         */

        public static void RegisterFunction(string name, Functions.Function func)
        {
            FunctionEval.RegisterFunction(name, func);
        }
        /**
         * @param startRowIndex row index in the spreadsheet where the first function/operator is found
         * @param testFocusFunctionName name of a single function/operator to test alone.
         * Typically pass <code>null</code> to test all functions
         */
        private void ProcessFunctionGroup(int startRowIndex, string testFocusFunctionName)
        {
            HSSFFormulaEvaluator        evaluator = new HSSFFormulaEvaluator(workbook);
            ReadOnlyCollection <string> funcs     = FunctionEval.GetSupportedFunctionNames();

            int rowIndex = startRowIndex;

            while (true)
            {
                IRow r = sheet.GetRow(rowIndex);

                // only Evaluate non empty row
                if (r != null)
                {
                    string targetFunctionName = GetTargetFunctionName(r);
                    string targetTestName     = GetTargetTestName(r);
                    if (targetFunctionName == null)
                    {
                        throw new AssertFailedException("Test spreadsheet cell empty on row ("
                                                        + (rowIndex + 1) + "). Expected function name or '"
                                                        + SS.FUNCTION_NAMES_END_SENTINEL + "'");
                    }
                    if (targetFunctionName.Equals(SS.FUNCTION_NAMES_END_SENTINEL))
                    {
                        // found end of functions list
                        break;
                    }
                    if (testFocusFunctionName == null || targetFunctionName.Equals(testFocusFunctionName, StringComparison.CurrentCultureIgnoreCase))
                    {
                        // expected results are on the row below
                        ICell expectedValueCell = r.GetCell(SS.COLUMN_INDEX_EXPECTED_VALUE);
                        if (expectedValueCell == null)
                        {
                            int missingRowNum = rowIndex + 1;
                            throw new AssertFailedException("Missing expected values cell for function '"
                                                            + targetFunctionName + ", test" + targetTestName + " (row " +
                                                            missingRowNum + ")");
                        }

                        switch (ProcessFunctionRow(evaluator, targetFunctionName, targetTestName, r, expectedValueCell))
                        {
                        case Result.ALL_EVALUATIONS_SUCCEEDED: _functionSuccessCount++; break;

                        case Result.SOME_EVALUATIONS_FAILED: _functionFailureCount++; break;

                        default:
                            throw new Exception("unexpected result");

                        case Result.NO_EVALUATIONS_FOUND:     // do nothing
                            string uname = targetFunctionName.ToUpper();
                            if (startRowIndex >= SS.START_FUNCTIONS_ROW_INDEX &&
                                funcs.Contains(uname))
                            {
                                logger.Log(POILogger.WARN, uname + ": function is supported but missing test data");
                            }
                            break;
                        }
                    }
                }
                rowIndex++;
            }
        }
Example #18
0
        public void TestExceptions()
        {
            NPOI.SS.Formula.Functions.Function func = new Function2();
            try
            {
                FunctionEval.RegisterFunction("SUM", func);
                Assert.Fail("expectecd exception");
            }
            catch (ArgumentException e)
            {
                Assert.AreEqual("POI already implememts SUM" +
                                ". You cannot override POI's implementations of Excel functions", e.Message);
            }
            try
            {
                FunctionEval.RegisterFunction("SUMXXX", func);
                Assert.Fail("expectecd exception");
            }
            catch (ArgumentException e)
            {
                Assert.AreEqual("Unknown function: SUMXXX", e.Message);
            }
            try
            {
                FunctionEval.RegisterFunction("ISODD", func);
                Assert.Fail("expectecd exception");
            }
            catch (ArgumentException e)
            {
                Assert.AreEqual("ISODD is a function from the Excel Analysis Toolpack. " +
                                "Use AnalysisToolpack.RegisterFunction(String name, FreeRefFunction func) instead.", e.Message);
            }

            FreeRefFunction atpFunc = new FreeRefFunction2();/*FreeRefFunction() {
                                                              * public ValueEval Evaluate(ValueEval[] args, OperationEvaluationContext ec) {
                                                              * return ErrorEval.NUM_ERROR;
                                                              * }
                                                              * };*/

            try
            {
                AnalysisToolPak.RegisterFunction("ISODD", atpFunc);
                Assert.Fail("expectecd exception");
            }
            catch (ArgumentException e)
            {
                Assert.AreEqual("POI already implememts ISODD" +
                                ". You cannot override POI's implementations of Excel functions", e.Message);
            }
            try
            {
                AnalysisToolPak.RegisterFunction("ISODDXXX", atpFunc);
                Assert.Fail("expectecd exception");
            }
            catch (ArgumentException e)
            {
                Assert.AreEqual("ISODDXXX is not a function from the Excel Analysis Toolpack.", e.Message);
            }
            try
            {
                AnalysisToolPak.RegisterFunction("SUM", atpFunc);
                Assert.Fail("expectecd exception");
            }
            catch (ArgumentException e)
            {
                Assert.AreEqual("SUM is a built-in Excel function. " +
                                "Use FunctoinEval.RegisterFunction(String name, Function func) instead.", e.Message);
            }
        }
Example #19
0
        /// <summary>
        /// Try to optimise the kernel parameters under the specified marginal likelihood function. Note that only
        /// one step is taken since this will be called within a VB algorithm so it is inefficient to run to
        /// convergence
        /// </summary>
        /// <param name="marginalLikelihoodFunction"></param>
        /// <param name="result">The resulting precision matrix (to be cached for efficiency)</param>
        public void Optimise(MarginalLikelihoodFunction marginalLikelihoodFunction,
                             ref PositiveDefiniteMatrix result)
        {
            callsCounter++;
            if (callsCounter <= settings.iterationsBeforeOptimiseHypers || hypersToOptimise.Length == 0)
            {
                return;
            }
            var startingPoint = hypersToOptimise.Select(i => kernel[i]).ToArray();

            switch (settings.solverMethod)
            {
            case Settings.SolverMethod.MySolver:
                if (hypersToOptimise.Length > 1)
                {
                    throw new ApplicationException("MySolver cannot currently optimise in more than 1D, please use LBFGS or GradientDescent");
                }
                Converter <double, double> f3 = ll =>
                {
                    kernel[hypersToOptimise[0]] = ll;
                    var prec = Utils.GramMatrix(kernel, xData).Inverse();
                    return(marginalLikelihoodFunction(prec, null, null));
                };
                double maxLoc = My1DOptimiser(f3, kernel[hypersToOptimise[0]]);
                kernel[hypersToOptimise[0]] = maxLoc;
                //Console.WriteLine("ll {0}, likelihood went from {1} to {2}", kernel[0], f3(startingPoint[0]), f3(kernel[0]));
                result = Utils.GramMatrix(kernel, xData).Inverse();
                return;

            case Settings.SolverMethod.GradientDescent:
                FunctionEval fgd = delegate(Vector hypers, ref Vector gradientVector)
                {
                    PositiveDefiniteMatrix[] gradK = (gradientVector == null) ?
                                                     null :
                                                     System.Linq.Enumerable.Range(0, hypers.Count).Select(_ => new PositiveDefiniteMatrix(xData.Length, xData.Length)).ToArray();
                    var prec = GramPrecision(hypers.ToArray(), ref gradK);
                    return(marginalLikelihoodFunction(prec, gradK, gradientVector));
                };
                Vector gradientVect = Vector.Zero(hypersToOptimise.Length), dummy = null;
                var    startPointerVector = Vector.FromArray(startingPoint);
                // take a small step in the steepest ascent direction
                double f0   = fgd(startPointerVector, ref gradientVect);
                double eps  = .1;
                var    absg = Math.Sqrt(gradientVect.Sum(o => o * o));
                var    xnew = Vector.FromArray(startingPoint) + gradientVect * (eps / absg);
                // find the function value here
                double fnew = fgd(xnew, ref dummy);
                // use this to approximate the curvature under a quadratic assumption
                double m = (fnew - f0) / (eps * eps) - absg / eps;
                double fopt;
                if (m < -1e-2)     // good, m negative implies we have a convex function!
                {
                    // go to the minimum of our quadratic approximation
                    double step = 1.0;
                    var    xopt = Vector.FromArray(startingPoint) - gradientVect * (step / (2.0 * m));
                    fopt = fgd(xopt, ref dummy);
                    // keep back tracking until the function improves
                    while (fopt < f0)
                    {
                        step *= .5;
                        xopt  = Vector.FromArray(startingPoint) - gradientVect * (step / (2.0 * m));
                        fopt  = fgd(xopt, ref dummy);
                        if (step < 1.0e-10)
                        {
                            throw new ApplicationException("step size was tiny");
                        }
                    }
                }
                else
                {
                    if (fnew <= f0)
                    {
                        Console.WriteLine("Seem to be at the minimum! Gradient=" + absg);
                        return;
                    }
                    double step    = 1.0;
                    double stepVal = fnew;
                    step *= 2.0;
                    double nextStepVal = fgd(startPointerVector + gradientVect * (step * eps / absg), ref dummy);
                    // keep going until marginal likelihood decreases
                    while (nextStepVal > stepVal)
                    {
                        step       *= 2.0;
                        stepVal     = nextStepVal;
                        nextStepVal = fgd(startPointerVector + gradientVect * (step * eps / absg), ref dummy);
                        if (step > 1e6)
                        {
                            throw new ApplicationException("Kernel hyperparameter optimisation diverged");
                        }
                    }
                    step /= 2.0;
                    fopt  = fgd(startPointerVector + gradientVect * (step * eps / absg), ref dummy);
                    if (fopt < f0)
                    {
                        throw new ApplicationException("Kernel hyperparameter optimisation diverged");
                    }
                }

                result = Utils.GramMatrix(kernel, xData).Inverse();
                Console.WriteLine("ll {0}, likelihood went from {1} to {2}", kernel[0], f0, fopt);
                if (double.IsNaN(fopt) || fopt < f0)
                {
                    throw new ApplicationException();
                }
                return;
            }
            throw new ApplicationException();
        }