[Libreoffice-commits] core.git: 35 commits - sc/qa sc/source

I-Jui Sung (Ray) ray at multicorewareinc.com
Wed Nov 13 15:46:51 PST 2013


 sc/qa/unit/data/ods/opencl/math/ArcCot.ods             |binary
 sc/qa/unit/data/ods/opencl/math/ArcCotHyp.ods          |binary
 sc/qa/unit/data/ods/opencl/math/ArcSin.ods             |binary
 sc/qa/unit/data/ods/opencl/math/ArcSinHyp.ods          |binary
 sc/qa/unit/data/ods/opencl/math/ArcTan.ods             |binary
 sc/qa/unit/data/ods/opencl/math/ArcTanHyp.ods          |binary
 sc/qa/unit/data/ods/opencl/math/BitAnd.ods             |binary
 sc/qa/unit/data/ods/opencl/statistical/LogNormDist.ods |binary
 sc/qa/unit/data/xls/opencl/financial/Accrint.xls       |binary
 sc/qa/unit/data/xls/opencl/financial/Coupncd.xls       |binary
 sc/qa/unit/data/xls/opencl/math/LN.xls                 |binary
 sc/qa/unit/data/xls/opencl/math/ROUND.xls              |binary
 sc/qa/unit/data/xls/opencl/math/cosh.xls               |binary
 sc/qa/unit/data/xls/opencl/statistical/CritBinom.xls   |binary
 sc/qa/unit/data/xls/opencl/statistical/Forecast.xls    |binary
 sc/qa/unit/data/xls/opencl/statistical/GammaDist.xls   |binary
 sc/qa/unit/data/xls/opencl/statistical/LogInv.xls      |binary
 sc/qa/unit/opencl-test.cxx                             |  450 +++++++
 sc/source/core/opencl/formulagroupcl.cxx               |   72 +
 sc/source/core/opencl/op_financial.cxx                 |  228 +++
 sc/source/core/opencl/op_financial.hxx                 |   18 
 sc/source/core/opencl/op_math.cxx                      |  277 ++++
 sc/source/core/opencl/op_math.hxx                      |   71 +
 sc/source/core/opencl/op_statistical.cxx               |  597 +++++++++
 sc/source/core/opencl/op_statistical.hxx               |   41 
 sc/source/core/opencl/opinlinefun_finacial.cxx         |   46 
 sc/source/core/opencl/opinlinefun_statistical.cxx      | 1089 +++++++++++++++++
 sc/source/core/tool/token.cxx                          |   15 
 28 files changed, 2903 insertions(+), 1 deletion(-)

New commits:
commit f50699c816de8e4be3433c6387e37d92aedd41a0
Author: I-Jui (Ray) Sung <ray at multicorewareinc.com>
Date:   Wed Nov 13 17:41:50 2013 -0600

    GPU Calc: Eliminated compiler warnings
    
    Change-Id: If7ccf5193689ac770be317ac2f786096f5160797

diff --git a/sc/source/core/opencl/op_financial.cxx b/sc/source/core/opencl/op_financial.cxx
index 3e5db57..3b226c5 100644
--- a/sc/source/core/opencl/op_financial.cxx
+++ b/sc/source/core/opencl/op_financial.cxx
@@ -1784,25 +1784,22 @@ void OpAccrint::GenSlidingWindowFunction(
 #ifdef ISNAN
     FormulaToken* tmpCur0 = vSubArguments[0]->GetFormulaToken();
     const formula::SingleVectorRefToken*tmpCurDVR0= dynamic_cast<const
-    formula::SingleVectorRefToken *>(tmpCur0);
-    FormulaToken* tmpCur1 = vSubArguments[1]->GetFormulaToken();
-    const formula::SingleVectorRefToken*tmpCurDVR1= dynamic_cast<const
-    formula::SingleVectorRefToken *>(tmpCur1);
+        formula::SingleVectorRefToken *>(tmpCur0);
     FormulaToken* tmpCur2 = vSubArguments[2]->GetFormulaToken();
     const formula::SingleVectorRefToken*tmpCurDVR2= dynamic_cast<const
-    formula::SingleVectorRefToken *>(tmpCur2);
+        formula::SingleVectorRefToken *>(tmpCur2);
     FormulaToken* tmpCur3 = vSubArguments[3]->GetFormulaToken();
     const formula::SingleVectorRefToken*tmpCurDVR3= dynamic_cast<const
-    formula::SingleVectorRefToken *>(tmpCur3);
+        formula::SingleVectorRefToken *>(tmpCur3);
     FormulaToken* tmpCur4 = vSubArguments[4]->GetFormulaToken();
     const formula::SingleVectorRefToken*tmpCurDVR4= dynamic_cast<const
-    formula::SingleVectorRefToken *>(tmpCur4);
+        formula::SingleVectorRefToken *>(tmpCur4);
     FormulaToken* tmpCur5 = vSubArguments[5]->GetFormulaToken();
     const formula::SingleVectorRefToken*tmpCurDVR5= dynamic_cast<const
-    formula::SingleVectorRefToken *>(tmpCur5);
+        formula::SingleVectorRefToken *>(tmpCur5);
     FormulaToken* tmpCur6 = vSubArguments[6]->GetFormulaToken();
     const formula::SingleVectorRefToken*tmpCurDVR6= dynamic_cast<const
-    formula::SingleVectorRefToken *>(tmpCur6);
+        formula::SingleVectorRefToken *>(tmpCur6);
     ss<< "    int buffer_nIssue_len = ";
     ss<< tmpCurDVR0->GetArrayLength();
     ss<< ";\n";
commit 78feb4327ec0edd7d5f1d38fde34658e4e6d6dee
Author: yiming ju <yiming at multicorewareinc.com>
Date:   Thu Nov 7 15:03:42 2013 +0800

    GPU Calc: unit test cases for ROUND
    
    Need open macro NO_FALLBACK_TO_SWINTERP in formulagroupcl.cxx for test
    
    AMLOEXT-156 BUG
    
    Change-Id: Ieb606f55ab21f288215de29f5fd6c1e46e1b39ed
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/qa/unit/data/xls/opencl/math/ROUND.xls b/sc/qa/unit/data/xls/opencl/math/ROUND.xls
new file mode 100644
index 0000000..0076e36
Binary files /dev/null and b/sc/qa/unit/data/xls/opencl/math/ROUND.xls differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index ffd7e8c..894933f 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -177,6 +177,7 @@ public:
     void testStatisticalFormulaLogNormDist();
     void testStatisticalFormulaGammaDist();
     void testMathFormulaLN();
+    void testMathFormulaRound();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -285,6 +286,7 @@ public:
     CPPUNIT_TEST(testStatisticalFormulaLogNormDist);
     CPPUNIT_TEST(testStatisticalFormulaGammaDist);
     CPPUNIT_TEST(testMathFormulaLN);
+    CPPUNIT_TEST(testMathFormulaRound);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -3071,6 +3073,35 @@ void ScOpenclTest::testMathFormulaLN()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[ AMLOEXT-156]
+void ScOpenclTest::testMathFormulaRound()
+{
+    if (!detectOpenCLDevice())
+        return;
+    ScDocShellRef xDocSh = loadDoc("opencl/math/ROUND.", XLS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+    ScDocShellRef xDocShRes = loadDoc("opencl/math/ROUND.", XLS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Check the results of formula cells in the shared formula range.
+    for (SCROW i = 1; i <= 9; ++i)
+    {
+        double fLibre = pDoc->GetValue(ScAddress(1,i,0));
+        double fExcel = pDocRes->GetValue(ScAddress(1,i,0));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
+    }
+    for (SCROW i = 15; i <= 25; ++i)
+    {
+        double fLibre = pDoc->GetValue(ScAddress(1,i,0));
+        double fExcel = pDocRes->GetValue(ScAddress(1,i,0));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
+    }
+    xDocSh->DoClose();
+    xDocShRes->DoClose();
+}
 //[AMLOEXT-157]
 void ScOpenclTest::testStatisticalFormulaGammaDist()
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 2e4aa24..b302757 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1411,6 +1411,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocLogNormDist:
             case ocGammaDist:
             case ocLn:
+            case ocRound:
             // Don't change the state.
             break;
             default:
commit 2d30a56f77dc7e50fd6050f223b52c2a0c0ab311
Author: yiming ju <yiming at multicorewareinc.com>
Date:   Thu Nov 7 15:08:02 2013 +0800

    GPU Calc: implemented ROUND
    
    AMLOEXT-156 FIX
    
    Change-Id: I149b663736b1d126414ce034262e83fd05a558fb
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index 0fccd9d..96ba732 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1196,6 +1196,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                          ft->Children[i],new OpLn));
                 break;
+            case ocRound:
+                mvSubArguments.push_back(SoPHelper(ts,
+                         ft->Children[i],new OpRound));
+                break;
             case ocExternal:
                 if ( !(pChild->GetExternal().compareTo(OUString(
                     "com.sun.star.sheet.addin.Analysis.getEffect"))))
diff --git a/sc/source/core/opencl/op_math.cxx b/sc/source/core/opencl/op_math.cxx
index 569a717..7e76952 100644
--- a/sc/source/core/opencl/op_math.cxx
+++ b/sc/source/core/opencl/op_math.cxx
@@ -629,6 +629,33 @@ void OpLn::GenSlidingWindowFunction(
     ss << "    return tmp;\n";
     ss << "}";
 }
+
+void OpRound::GenSlidingWindowFunction(std::stringstream &ss,
+             const std::string sSymName, SubArguments &vSubArguments)
+{
+    ss << "\ndouble " << sSymName;
+    ss << "_"<< BinFuncName() <<"(";
+    for (unsigned i = 0; i < vSubArguments.size(); i++)
+    {
+        if (i)
+            ss << ",";
+        vSubArguments[i]->GenSlidingWindowDecl(ss);
+    }
+    ss << ")\n{\n";
+    ss << "    int gid0=get_global_id(0);\n";
+    ss << "    int singleIndex =  gid0;\n";
+    GenTmpVariables(ss,vSubArguments);
+    CheckAllSubArgumentIsNan(ss,vSubArguments);
+    ss << "    for(int i=0;i<tmp1;i++)\n";
+    ss << "        tmp0 = tmp0 * 10;\n";
+    ss << "    double tmp=round(tmp0);\n";
+    ss << "    for(int i=0;i<tmp1;i++)\n";
+    ss << "        tmp = tmp / 10;\n";
+    ss << "    return tmp;\n";
+    ss << "}";
+}
+
+
 }}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_math.hxx b/sc/source/core/opencl/op_math.hxx
index 2167ce5..8a151a8 100644
--- a/sc/source/core/opencl/op_math.hxx
+++ b/sc/source/core/opencl/op_math.hxx
@@ -160,6 +160,13 @@ public:
             const std::string sSymName, SubArguments &vSubArguments);
     virtual std::string BinFuncName(void) const { return "Ln"; }
 };
+class OpRound: public CheckVariables
+{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments);
+    virtual std::string BinFuncName(void) const { return "Round"; }
+};
 }}
 
 #endif
commit b07bfeea13e32a6fbf70d5932901a95c02ebf878
Author: yiming ju <yiming at multicorewareinc.com>
Date:   Thu Nov 7 14:54:11 2013 +0800

    GPU Calc: unit test cases for LN
    
    Need open macro NO_FALLBACK_TO_SWINTERP in formulagroupcl.cxx for test
    
    AMLOEXT-154 BUG
    
    Change-Id: Icf35e717a740515e86195699b776d0910c71b1f0
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/qa/unit/data/xls/opencl/math/LN.xls b/sc/qa/unit/data/xls/opencl/math/LN.xls
new file mode 100644
index 0000000..e57d809
Binary files /dev/null and b/sc/qa/unit/data/xls/opencl/math/LN.xls differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index 4c27c58..ffd7e8c 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -176,6 +176,7 @@ public:
     void testStatisticalFormulaForecast();
     void testStatisticalFormulaLogNormDist();
     void testStatisticalFormulaGammaDist();
+    void testMathFormulaLN();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -283,6 +284,7 @@ public:
     CPPUNIT_TEST(testStatisticalFormulaForecast);
     CPPUNIT_TEST(testStatisticalFormulaLogNormDist);
     CPPUNIT_TEST(testStatisticalFormulaGammaDist);
+    CPPUNIT_TEST(testMathFormulaLN);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -3046,6 +3048,29 @@ void ScOpenclTest::testMathFormulaBitAnd()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-154]
+void ScOpenclTest::testMathFormulaLN()
+{
+    if (!detectOpenCLDevice())
+        return;
+    ScDocShellRef xDocSh = loadDoc("opencl/math/LN.", XLS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+    ScDocShellRef xDocShRes = loadDoc("opencl/math/LN.", XLS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Check the results of formula cells in the shared formula range.
+    for (SCROW i = 1; i <= 9; ++i)
+    {
+        double fLibre = pDoc->GetValue(ScAddress(1,i,0));
+        double fExcel = pDocRes->GetValue(ScAddress(1,i,0));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
+    }
+    xDocSh->DoClose();
+    xDocShRes->DoClose();
+}
 //[AMLOEXT-157]
 void ScOpenclTest::testStatisticalFormulaGammaDist()
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 1fb60b2..2e4aa24 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1410,6 +1410,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocForecast:
             case ocLogNormDist:
             case ocGammaDist:
+            case ocLn:
             // Don't change the state.
             break;
             default:
commit 6cd4e84d34a2644201bf6dbb7719a8d054b73ad0
Author: yiming ju <yiming at multicorewareinc.com>
Date:   Thu Nov 7 14:58:22 2013 +0800

    GPU Calc: implemented LN
    
    AMLOEXT-154 FIX
    
    Change-Id: I5c00fed99996bc87c8ad0026ffbe4c1822e108d6
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index f191af0..0fccd9d 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1192,6 +1192,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                          ft->Children[i], new OpGammaDist));
                 break;
+            case ocLn:
+                mvSubArguments.push_back(SoPHelper(ts,
+                         ft->Children[i],new OpLn));
+                break;
             case ocExternal:
                 if ( !(pChild->GetExternal().compareTo(OUString(
                     "com.sun.star.sheet.addin.Analysis.getEffect"))))
diff --git a/sc/source/core/opencl/op_math.cxx b/sc/source/core/opencl/op_math.cxx
index 9b8b179..569a717 100644
--- a/sc/source/core/opencl/op_math.cxx
+++ b/sc/source/core/opencl/op_math.cxx
@@ -607,6 +607,28 @@ void OpBitAnd::GenSlidingWindowFunction(std::stringstream &ss,
     ss << "    return (int)num1 & (int)num2;\n";
     ss << "}";
 }
+void OpLn::GenSlidingWindowFunction(
+    std::stringstream &ss, const std::string sSymName, SubArguments &vSubArguments)
+{
+    ss << "\ndouble " << sSymName;
+    ss << "_"<< BinFuncName() <<"(";
+    for (unsigned i = 0; i < vSubArguments.size(); i++)
+    {
+        if (i)
+            ss << ",";
+        vSubArguments[i]->GenSlidingWindowDecl(ss);
+    }
+    ss << ")\n{\n";
+    ss << "    int gid0=get_global_id(0);\n";
+    ss << "    int singleIndex =  gid0;\n";
+
+    GenTmpVariables(ss,vSubArguments);
+    CheckAllSubArgumentIsNan(ss,vSubArguments);
+
+    ss << "    double tmp=log1p(tmp0-1);\n";
+    ss << "    return tmp;\n";
+    ss << "}";
+}
 }}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_math.hxx b/sc/source/core/opencl/op_math.hxx
index 008d7fa..2167ce5 100644
--- a/sc/source/core/opencl/op_math.hxx
+++ b/sc/source/core/opencl/op_math.hxx
@@ -153,6 +153,13 @@ public:
         virtual std::string GetBottom(void) { return "0.0"; }
     virtual std::string BinFuncName(void) const { return "ScBitAnd"; }
 };
+class OpLn: public CheckVariables
+{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments);
+    virtual std::string BinFuncName(void) const { return "Ln"; }
+};
 }}
 
 #endif
commit e2736b7c556245c8ab72540a1de7dcbe94d83e32
Author: mingli <mingli at multicorewareinc.com>
Date:   Thu Nov 7 14:24:59 2013 +0800

    GPU Calc: unit test cases for GAMMADIST
    
    Need open macro NO_FALLBACK_TO_SWINTERP in formulagroupcl.cxx for test
    
    AMLOEXT-157 BUG
    
    Change-Id: I7f97ee47050378fa411b5e635141847929c55b46
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/qa/unit/data/xls/opencl/statistical/GammaDist.xls b/sc/qa/unit/data/xls/opencl/statistical/GammaDist.xls
new file mode 100644
index 0000000..d10bbe2
Binary files /dev/null and b/sc/qa/unit/data/xls/opencl/statistical/GammaDist.xls differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index 3283c27..4c27c58 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -175,6 +175,7 @@ public:
     void testMathFormulaBitAnd();
     void testStatisticalFormulaForecast();
     void testStatisticalFormulaLogNormDist();
+    void testStatisticalFormulaGammaDist();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -281,6 +282,7 @@ public:
     CPPUNIT_TEST(testMathFormulaBitAnd);
     CPPUNIT_TEST(testStatisticalFormulaForecast);
     CPPUNIT_TEST(testStatisticalFormulaLogNormDist);
+    CPPUNIT_TEST(testStatisticalFormulaGammaDist);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -3044,6 +3046,30 @@ void ScOpenclTest::testMathFormulaBitAnd()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-157]
+void ScOpenclTest::testStatisticalFormulaGammaDist()
+{
+    if (!detectOpenCLDevice())
+        return;
+
+    ScDocShellRef xDocSh = loadDoc("opencl/statistical/GammaDist.", XLS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+    ScDocShellRef xDocShRes = loadDoc("opencl/statistical/GammaDist.", XLS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Check the results of formula cells in the shared formula range.
+    for (SCROW i = 1; i <= 19; ++i)
+    {
+        double fLibre = pDoc->GetValue(ScAddress(4,i,0));
+        double fExcel = pDocRes->GetValue(ScAddress(4,i,0));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
+    }
+    xDocSh->DoClose();
+    xDocShRes->DoClose();
+}
 ScOpenclTest::ScOpenclTest()
       : ScBootstrapFixture( "/sc/qa/unit/data" )
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 7f794e5..1fb60b2 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1409,6 +1409,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocBitAnd:
             case ocForecast:
             case ocLogNormDist:
+            case ocGammaDist:
             // Don't change the state.
             break;
             default:
commit a14622c88eda570e029eeb81baadda37d4417196
Author: mingli <mingli at multicorewareinc.com>
Date:   Thu Nov 7 14:34:23 2013 +0800

    GPU Calc: implemented GAMMADIST
    
    AMLOEXT-157 FIX
    
    Change-Id: I806b6522e7481af87c03fbd1b1d500eb5cd1b9bf
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index 68f90ee..f191af0 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1188,6 +1188,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                          ft->Children[i], new OpLogNormDist));
                 break;
+            case ocGammaDist:
+                mvSubArguments.push_back(SoPHelper(ts,
+                         ft->Children[i], new OpGammaDist));
+                break;
             case ocExternal:
                 if ( !(pChild->GetExternal().compareTo(OUString(
                     "com.sun.star.sheet.addin.Analysis.getEffect"))))
diff --git a/sc/source/core/opencl/op_statistical.cxx b/sc/source/core/opencl/op_statistical.cxx
index a58eee8..8e39c36 100644
--- a/sc/source/core/opencl/op_statistical.cxx
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -2471,7 +2471,88 @@ void OpLogNormDist::GenSlidingWindowFunction(std::stringstream &ss,
     ss << "    return tmp;\n";
     ss << "}\n";
 }
+void OpGammaDist::BinInlineFun(std::set<std::string>& decls,
+    std::set<std::string>& funs)
+{
+    decls.insert(fBigInvDecl);decls.insert(fLogDblMaxDecl);
+    decls.insert(fHalfMachEpsDecl);decls.insert(fMaxGammaArgumentDecl);
+    decls.insert(GetGammaSeriesDecl);decls.insert(GetGammaContFractionDecl);
+    decls.insert(GetLowRegIGammaDecl);decls.insert(GetGammaDistDecl);
+    decls.insert(GetGammaDistPDFDecl);
+    funs.insert(GetGammaSeries);funs.insert(GetGammaContFraction);
+    funs.insert(GetLowRegIGamma);funs.insert(GetGammaDist);
+    funs.insert(GetGammaDistPDF);
+}
 
+void OpGammaDist::GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments)
+{
+        FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+        const formula::SingleVectorRefToken*tmpCurDVR0= dynamic_cast<const
+formula::SingleVectorRefToken *>(tmpCur0);
+        FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+        const formula::SingleVectorRefToken*tmpCurDVR1= dynamic_cast<const
+formula::SingleVectorRefToken *>(tmpCur1);
+        FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+        const formula::SingleVectorRefToken*tmpCurDVR2= dynamic_cast<const
+formula::SingleVectorRefToken *>(tmpCur2);
+        FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+        const formula::SingleVectorRefToken*tmpCurDVR3= dynamic_cast<const
+formula::SingleVectorRefToken *>(tmpCur3);
+        ss << "\ndouble " << sSymName;
+        ss << "_"<< BinFuncName() <<"(";
+        for (unsigned i = 0; i < vSubArguments.size(); i++)
+        {
+            if (i)
+                ss << ",";
+            vSubArguments[i]->GenSlidingWindowDecl(ss);
+        }
+        ss << ") {\n";
+        ss << "    int gid0=get_global_id(0);\n";
+        ss << "    double arg0 = ";
+        ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+        ss << ";\n";
+        ss << "    double arg1 = ";
+        ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+        ss << ";\n";
+        ss << "    double arg2 = ";
+        ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+        ss << ";\n";
+        ss << "    double arg3 = ";
+        ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+        ss << ";\n";
+        ss << "    double tmp;\n";
+#ifdef ISNAN
+        ss << "    if(isNan(arg0)||(gid0>=";
+        ss << tmpCurDVR0->GetArrayLength();
+        ss << "))\n";
+        ss << "        arg0 = 0;\n";
+#endif
+#ifdef ISNAN
+        ss << "    if(isNan(arg1)||(gid0>=";
+        ss << tmpCurDVR1->GetArrayLength();
+        ss << "))\n";
+        ss << "        arg1 = 0;\n";
+#endif
+#ifdef ISNAN
+        ss << "    if(isNan(arg2)||(gid0>=";
+        ss << tmpCurDVR2->GetArrayLength();
+        ss << "))\n";
+        ss << "        arg2 = 0;\n";
+#endif
+#ifdef ISNAN
+        ss << "    if(isNan(arg3)||(gid0>=";
+        ss << tmpCurDVR3->GetArrayLength();
+        ss << "))\n";
+        ss << "        arg3 = 0;\n";
+#endif
+        ss << "    if (arg3)\n";
+        ss << "        tmp=GetGammaDist( arg0, arg1, arg2);\n";
+        ss << "    else\n";
+        ss << "        tmp=GetGammaDistPDF( arg0, arg1, arg2);\n";
+        ss << "    return tmp;\n";
+        ss << "}\n";
+}
 }}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_statistical.hxx b/sc/source/core/opencl/op_statistical.hxx
index 92b67dc..7d8fa5e 100644
--- a/sc/source/core/opencl/op_statistical.hxx
+++ b/sc/source/core/opencl/op_statistical.hxx
@@ -225,6 +225,14 @@ public:
             const std::string sSymName, SubArguments &vSubArguments);
     virtual std::string BinFuncName(void) const { return "LogNormdist"; }
 };
+class OpGammaDist: public Normal
+{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments);
+    void BinInlineFun(std::set<std::string>& decls,std::set<std::string>& funs);
+    virtual std::string BinFuncName(void) const { return "GammaDist"; }
+};
 }}
 
 #endif
diff --git a/sc/source/core/opencl/opinlinefun_statistical.cxx b/sc/source/core/opencl/opinlinefun_statistical.cxx
index 31e9dc2..f9d3579 100644
--- a/sc/source/core/opencl/opinlinefun_statistical.cxx
+++ b/sc/source/core/opencl/opinlinefun_statistical.cxx
@@ -9,13 +9,711 @@
 
 #ifndef SC_OPENCL_OPINLINFUN_statistical
 #define SC_OPENCL_OPINLINFUN_statistical
+std::string MinDecl = "#define Min 2.22507e-308\n";
+std::string F_PIDecl="#define F_PI 3.1415926\n";
 std::string fBigInvDecl ="#define fBigInv  2.22045e-016\n";
+std::string fMachEpsDecl ="#define fMachEps  2.22045e-016\n";
 std::string fLogDblMaxDecl ="#define fLogDblMax  log(1.79769e+308)\n";
 std::string fHalfMachEpsDecl ="#define fHalfMachEps  0.5*2.22045e-016\n";
-std::string MinDecl = "#define Min 2.22507e-308\n";
 
 std::string fMaxGammaArgumentDecl =
 "#define fMaxGammaArgument  171.624376956302\n";
+std::string GetGammaSeriesDecl=
+"double GetGammaSeries( double fA, double fX );\n";
+std::string GetGammaSeries =
+"double GetGammaSeries( double fA, double fX )\n"
+"{\n"
+"    double fDenomfactor = fA;\n"
+"     double fSummand = 1.0/fA;\n"
+"    double fSum = fSummand;\n"
+"    int nCount=1;\n"
+"    do\n"
+"    {\n"
+"        fDenomfactor = fDenomfactor + 1.0;\n"
+"        fSummand = fSummand * fX/fDenomfactor;\n"
+"        fSum = fSum + fSummand;\n"
+"        nCount = nCount+1;\n"
+"    } while ( fSummand/fSum > fHalfMachEps && nCount<=10000);\n"
+"    if (nCount>10000)\n"
+"    {\n"
+"    }\n"
+"    return fSum;\n"
+"}\n";
+std::string GetGammaContFractionDecl =  "double GetGammaContFraction( double "
+"fA, double fX );\n";
+std::string GetGammaContFraction =
+"double GetGammaContFraction( double fA, double fX )\n"
+"{\n"
+"    double fBig = 1.0/fBigInv;\n"
+"    double fCount = 0.0;\n"
+"    double fNum = 0.0;\n"
+"    double fY = 1.0 - fA;\n"
+"    double fDenom = fX + 2.0-fA;\n"
+"    double fPk = 0.0;\n"
+"    double fPkm1 = fX + 1.0;\n"
+"    double fPkm2 = 1.0;\n"
+"    double fQk = 1.0;\n"
+"    double fQkm1 = fDenom * fX;\n"
+"    double fQkm2 = fX;\n"
+"    double fApprox = fPkm1/fQkm1;\n"
+"    bool bFinished = false;\n"
+"    double fR = 0.0;\n"
+"    do\n"
+"    {\n"
+"        fCount = fCount +1.0;\n"
+"        fY = fY+ 1.0;\n"
+"        fNum = fY * fCount;\n"
+"        fDenom = fDenom +2.0;\n"
+"        fPk = fPkm1 * fDenom  -  fPkm2 * fNum;\n"
+"        fQk = fQkm1 * fDenom  -  fQkm2 * fNum;\n"
+"        if (fQk != 0.0)\n"
+"        {\n"
+"            fR = fPk/fQk;\n"
+"            bFinished = (fabs( (fApprox - fR)/fR ) <= fHalfMachEps);\n"
+"            fApprox = fR;\n"
+"        }\n"
+"        fPkm2 = fPkm1;\n"
+"        fPkm1 = fPk;\n"
+"        fQkm2 = fQkm1;\n"
+"        fQkm1 = fQk;\n"
+"        if (fabs(fPk) > fBig)\n"
+"        {\n"
+"            fPkm2 = fPkm2 * fBigInv;\n"
+"            fPkm1 = fPkm1 * fBigInv;\n"
+"            fQkm2 = fQkm2 * fBigInv;\n"
+"            fQkm1 = fQkm1 * fBigInv;\n"
+"        }\n"
+"    } while (!bFinished && fCount<10000);\n"
+"    if (!bFinished)\n"
+"    {\n"
+"    }\n"
+"    return fApprox;\n"
+"}\n";
+std::string GetLowRegIGammaDecl = "double GetLowRegIGamma( double "
+"fA, double fX );\n";
+std::string GetLowRegIGamma =
+"double GetLowRegIGamma( double fA, double fX )\n"
+"{\n"
+"    double fLnFactor = fA * log(fX) - fX - lgamma(fA);\n"
+"    double fFactor = exp(fLnFactor);\n"
+"    if (fX>fA+1.0) \n"
+"        return 1.0 - fFactor * GetGammaContFraction(fA,fX);\n"
+"    else\n"
+"        return fFactor * GetGammaSeries(fA,fX);\n"
+"}\n";
+std::string GetGammaDistDecl = "double GetGammaDist( double fX, double "
+"fAlpha, double fLambda );\n";
+std::string GetGammaDist =
+"double GetGammaDist( double fX, double fAlpha, double fLambda )\n"
+"{\n"
+"    if (fX <= 0.0)\n"
+"        return 0.0;\n"
+"    else\n"
+"        return GetLowRegIGamma( fAlpha, fX / fLambda);\n"
+"}\n";
+std::string GetGammaDistPDFDecl =  "double GetGammaDistPDF( double fX"
+", double fAlpha, double fLambda );\n";
+std::string GetGammaDistPDF =
+"double GetGammaDistPDF( double fX, double fAlpha, double fLambda )\n"
+"{\n"
+"    if (fX < 0.0)\n"
+"        return 0.0;\n"
+"    else if (fX == 0)\n"
+"    {\n"
+"        if (fAlpha < 1.0)\n"
+"        {\n"
+"            return HUGE_VAL;\n"
+"        }\n"
+"        else if (fAlpha == 1)\n"
+"        {\n"
+"            return (1.0 / fLambda);\n"
+"        }\n"
+"        else\n"
+"        {\n"
+"            return 0.0;\n"
+"        }\n"
+"    }\n"
+"    else\n"
+"    {\n"
+"        double fXr = fX / fLambda;\n"
+"        if (fXr > 1.0)\n"
+"        {\n"
+"            if (log(fXr) * (fAlpha-1.0) < fLogDblMax &&"
+"fAlpha < fMaxGammaArgument)\n"
+"            {\n"
+"                return pow( fXr, fAlpha-1.0) * exp(-fXr) / "
+"fLambda / tgamma(fAlpha);\n"
+"            }\n"
+"            else\n"
+"            {\n"
+"                return exp( (fAlpha-1.0) * log(fXr) - fXr - "
+"log(fLambda) - lgamma(fAlpha));\n"
+"            }\n"
+"        }\n"
+"        else\n"
+"        {\n"
+"            if (fAlpha<fMaxGammaArgument)\n"
+"            {\n"
+"                return pow( fXr, fAlpha-1.0) * exp(-fXr) / "
+"fLambda / tgamma(fAlpha);\n"
+"            }\n"
+"            else\n"
+"            {\n"
+"                return pow( fXr, fAlpha-1.0) * exp(-fXr) / "
+"fLambda / exp( lgamma(fAlpha));\n"
+"            }\n"
+"        }\n"
+"    }\n"
+"}\n";
+std::string GetBetaDistDecl =
+"double GetBetaDist(double fXin, double fAlpha, double fBeta);\n";
+std::string GetBetaDist =
+"double GetBetaDist(double fXin, double fAlpha, double fBeta)\n"
+"{\n"
+"    if (fXin <= 0.0)\n"
+"        return 0.0;\n"
+"    if (fXin >= 1.0)\n"
+"        return 1.0;\n"
+"    if (fBeta == 1.0)\n"
+"        return pow(fXin, fAlpha);\n"
+"    if (fAlpha == 1.0)\n"
+"        return -expm1(fBeta * log1p(-fXin));\n"
+"    double fResult;\n"
+"    double fY = (0.5-fXin)+0.5;\n"
+"    double flnY = log1p(-fXin);\n"
+"    double fX = fXin;\n"
+"    double flnX = log(fXin);\n"
+"    double fA = fAlpha;\n"
+"    double fB = fBeta;\n"
+"    bool bReflect = fXin > fAlpha/(fAlpha+fBeta);\n"
+"    if (bReflect)\n"
+"    {\n"
+"        fA = fBeta;\n"
+"        fB = fAlpha;\n"
+"        fX = fY;\n"
+"        fY = fXin;\n"
+"        flnX = flnY;\n"
+"        flnY = log(fXin);\n"
+"    }\n"
+"    fResult = lcl_GetBetaHelperContFrac(fX,fA,fB);\n"
+"    fResult = fResult/fA;\n"
+"    double fP = fA/(fA+fB);\n"
+"    double fQ = fB/(fA+fB);\n"
+"    double fTemp;\n"
+"    if (fA > 1.0 && fB > 1.0 && fP < 0.97 && fQ < 0.97)\n"
+"        fTemp = GetBetaDistPDF(fX,fA,fB)*fX*fY;\n"
+"    else\n"
+"        fTemp = exp(fA*flnX + fB*flnY - GetLogBeta(fA,fB));\n"
+"    fResult *= fTemp;\n"
+"    if (bReflect)\n"
+"        fResult = 0.5 - fResult + 0.5;\n"
+"    if (fResult > 1.0)\n"
+"        fResult = 1.0;\n"
+"    if (fResult < 0.0)\n"
+"        fResult = 0.0;\n"
+"    return fResult;\n"
+"}\n";
+std::string GetFDistDecl =
+    "double GetFDist(double x, double fF1, double fF2);\n";
+std::string GetFDist =
+"double GetFDist(double x, double fF1, double fF2)\n"
+"{\n"
+"    double arg = fF2/(fF2+fF1*x);\n"
+"    double alpha = fF2/2.0;\n"
+"    double beta = fF1/2.0;\n"
+"    return (GetBetaDist(arg, alpha, beta));\n"
+"}\n";
+std::string GetGammaInvValueDecl = "double"
+" GetGammaInvValue(double fAlpha,double fBeta,double fX1 );\n";
+std::string GetGammaInvValue =
+"double GetGammaInvValue(double fAlpha,double fBeta,double fX1 )\n"
+"{\n"
+"    if (fX1 <= 0.0)\n"
+"        return 0.0;\n"
+"    else\n"
+"    {\n"
+"        double fX=fX1/fBeta;\n"
+"        double fLnFactor = fAlpha * log(fX) - fX - lgamma(fAlpha);\n"
+"        double fFactor = exp(fLnFactor);\n"
+"        if (fX>fAlpha+1.0)\n"
+"            return 1.0 - fFactor * GetGammaContFraction(fAlpha,fX);\n"
+"        else\n"
+"            return fFactor * GetGammaSeries(fAlpha,fX);\n"
+"    }\n"
+"}\n";
+std::string GetFInvValueDecl = "double GetFInvValue(double fF1,double fF2"
+",double fX1 );";
+std::string GetFInvValue =
+"double GetFInvValue(double fF1,double fF2,double fX1 )\n"
+"{\n"
+"    double arg = fF2/(fF2+fF1*fX1);\n"
+"    double alpha = fF2/2.0;\n"
+"    double beta = fF1/2.0;\n"
+"    double fXin,fAlpha,fBeta;\n"
+"        fXin=arg;fAlpha=alpha;fBeta=beta;\n"
+"    if (fXin <= 0.0)\n"
+"        return 0.0;\n"
+"    if (fXin >= 1.0)\n"
+"        return 1.0;\n"
+"    if (fBeta == 1.0)\n"
+"        return pow(fXin, fAlpha);\n"
+"    if (fAlpha == 1.0)\n"
+"        return -expm1(fBeta * log1p(-fXin));\n"
+"    double fResult;\n"
+"    double fY = (0.5-fXin)+0.5;\n"
+"    double flnY = log1p(-fXin);\n"
+"    double fX = fXin;\n"
+"    double flnX = log(fXin);\n"
+"    double fA = fAlpha;\n"
+"    double fB = fBeta;\n"
+"    bool bReflect = fXin > fAlpha/(fAlpha+fBeta);\n"
+"    if (bReflect)\n"
+"    {\n"
+"        fA = fBeta;\n"
+"        fB = fAlpha;\n"
+"        fX = fY;\n"
+"        fY = fXin;\n"
+"        flnX = flnY;\n"
+"        flnY = log(fXin);\n"
+"    }\n"
+"    fResult = lcl_GetBetaHelperContFrac(fX,fA,fB);\n"
+"    fResult = fResult/fA;\n"
+"    double fP = fA/(fA+fB);\n"
+"    double fQ = fB/(fA+fB);\n"
+"    double fTemp;\n"
+"    if (fA > 1.0 && fB > 1.0 && fP < 0.97 && fQ < 0.97)\n"
+"        fTemp = GetBetaDistPDF(fX,fA,fB)*fX*fY;\n"
+"    else\n"
+"        fTemp = exp(fA*flnX + fB*flnY - GetLogBeta(fA,fB));\n"
+"    fResult *= fTemp;\n"
+"    if (bReflect)\n"
+"        fResult = 0.5 - fResult + 0.5;\n"
+"    if (fResult > 1.0)\n"
+"        fResult = 1.0;\n"
+"    if (fResult < 0.0)\n"
+"        fResult = 0.0;\n"
+"    return fResult;\n"
+"}\n";
+std::string GetBinomDistPMFDecl =
+    "double GetBinomDistPMF(double x, double n, double p);";
+std::string GetBinomDistPMF =
+"double GetBinomDistPMF(double x, double n, double p)\n"
+"{\n"
+"   double q = (0.5 - p) + 0.5;\n"
+"   double fFactor = pow(q, n);\n"
+"   if (fFactor <= Min)\n"
+"   {\n"
+"       fFactor = pow(p, n);\n"
+"       if (fFactor <= Min)\n"
+"           return GetBetaDistPDF(p, x + 1.0, n - x + 1.0)/(n + 1.0);\n"
+"       else\n"
+"       {\n"
+"           uint max = (uint)(n - x);\n"
+"           for (uint i = 0; i < max && fFactor > 0.0; ++i)\n"
+"               fFactor *= (n - i)/(i + 1)*q/p;\n"
+"           return fFactor;\n"
+"       }\n"
+"   }\n"
+"   else\n"
+"   {\n"
+"       uint max = (uint)x;\n"
+"       for (uint i = 0; i < max && fFactor > 0.0; ++i)\n"
+"           fFactor *= (n - i)/(i + 1)*p/q;\n"
+"       return fFactor;\n"
+"   }\n"
+"}\n";
+
+
+std::string lcl_GetBinomDistRangeDecl =
+    "double lcl_GetBinomDistRange(double n, \n"
+"double xs, double xe, double fFactor, double p, double q);";
+std::string lcl_GetBinomDistRange=
+"double lcl_GetBinomDistRange(double n, double xs, double xe,\n"
+"   double fFactor, double p, double q)\n"
+"{\n"
+"   uint i;\n"
+"   double fSum;\n"
+"   uint nXs = (uint)xs;\n"
+"   for (i = 1; i <= nXs && fFactor > 0.0; ++i)\n"
+"       fFactor *= (n - i + 1)/i*p/q;\n"
+"   fSum = fFactor;\n"
+"   uint nXe =(uint)xe;\n"
+"   for (i = nXs + 1; i <= nXe && fFactor > 0.0; ++i)\n"
+"   {\n"
+"       fFactor *= (n - i + 1)/i*p/q;\n"
+"       fSum += fFactor;\n"
+"   }\n"
+"   return (fSum > 1.0) ? 1.0 : fSum;\n"
+"}\n";
+
+std::string GetLogGammaDecl = "double GetLogGamma(double fZ);\n";
+std::string GetLogGamma =
+"double GetLogGamma(double fZ)\n"
+"{\n"
+"   if (fZ >= fMaxGammaArgument)\n"
+"       return lcl_GetLogGammaHelper(fZ);\n"
+"   if (fZ >= 1.0)\n"
+"       return log(lcl_GetGammaHelper(fZ));\n"
+"   if (fZ >= 0.5)\n"
+"       return log( lcl_GetGammaHelper(fZ+1) / fZ);\n"
+"   return lcl_GetLogGammaHelper(fZ+2) - log(fZ+1) - log(fZ);\n"
+"}\n";
+
+
+std::string GetChiDistDecl = "double GetChiDist(double fX, double fDF);\n";
+std::string GetChiDist =
+"double GetChiDist(double fX, double fDF)\n"
+"{\n"
+"   if (fX <= 0.0)\n"
+"       return  1.0;\n"
+"   else\n"
+"       return GetUpRegIGamma( fDF /2.0, fX/2.0);\n"
+"}\n";
+
+
+std::string GetChiSqDistCDFDecl =
+"double GetChiSqDistCDF(double fX, double fDF);\n";
+std::string GetChiSqDistCDF =
+"double GetChiSqDistCDF(double fX, double fDF)\n"
+"{\n"
+"   if (fX <= 0.0)\n"
+"       return 0.0;"
+"   else\n"
+"       return GetLowRegIGamma( fDF/2.0, fX/2.0);\n"
+"}\n";
+
+
+std::string GetChiSqDistPDFDecl=
+"double GetChiSqDistPDF(double fX, double fDF);\n";
+std::string GetChiSqDistPDF =
+"double GetChiSqDistPDF(double fX, double fDF)\n"
+"{\n"
+"   double fValue;\n"
+"   if (fX <= 0.0)\n"
+"       return 0.0;\n"
+"   if (fDF*fX > 1391000.0)\n"
+"   {\n"
+"       fValue = exp((0.5*fDF - 1) * log(fX*0.5) - 0.5 * fX - log(2.0)"
+" - lgamma(0.5*fDF));\n"
+"   }\n"
+"   else\n"
+"   {\n"
+"       double fCount;\n"
+"       if (fmod(fDF,2.0)<0.5)\n"
+"       {\n"
+"           fValue = 0.5;\n"
+"           fCount = 2.0;\n"
+"       }\n"
+"       else\n"
+"       {\n"
+"           fValue = 1/sqrt(fX*2*F_PI);\n"
+"           fCount = 1.0;\n"
+"       }\n"
+"       while ( fCount < fDF)\n"
+"       {\n"
+"           fValue *= (fX / fCount);\n"
+"           fCount += 2.0;\n"
+"       }\n"
+"       if (fX>=1425.0)\n"
+"           fValue = exp(log(fValue)-fX/2);\n"
+"       else\n"
+"           fValue *= exp(-fX/2);\n"
+"   }\n"
+"    return fValue;\n"
+"}\n";
+
+
+std::string lcl_IterateInverseBetaInvDecl =
+"static double lcl_IterateInverseBetaInv(double fp, double fAlpha, \n"
+"   double fBeta, double fAx, double fBx, bool *rConvError );\n";
+std::string lcl_IterateInverseBetaInv =
+"static double lcl_IterateInverseBetaInv(double fp, double fAlpha, \n"
+"   double fBeta, double fAx, double fBx, bool *rConvError )\n"
+"{\n"
+"   *rConvError = false;\n"
+"    double fYEps = 1.0E-307;\n"
+"   if(!(fAx < fBx))\n"
+"   {\n"
+"       //print error\n"
+"   }\n"
+"   double fAy = fp - GetBetaDist(fAx, fAlpha, fBeta);\n"
+"   double fBy = fp - GetBetaDist(fBx, fAlpha, fBeta);\n"
+"   double fTemp;\n"
+"   unsigned short nCount;\n"
+"   for (nCount = 0; nCount < 1000 && !lcl_HasChangeOfSign(fAy,fBy);"
+" nCount++)\n"
+"   {\n"
+"       if (fabs(fAy) <= fabs(fBy))\n"
+"       {\n"
+"           fTemp = fAx;\n"
+"           fAx += 2.0 * (fAx - fBx);\n"
+"           if (fAx < 0.0)\n"
+"               fAx = 0.0;\n"
+"           fBx = fTemp;\n"
+"           fBy = fAy;\n"
+"           fAy = fp - GetBetaDist(fAx, fAlpha, fBeta);\n"
+"       }\n"
+"       else\n"
+"       {\n"
+"           fTemp = fBx;\n"
+"           fBx += 2.0 * (fBx - fAx);\n"
+"           fAx = fTemp;\n"
+"           fAy = fBy;\n"
+"           fBy = fp - GetBetaDist(fBx, fAlpha, fBeta);\n"
+"       }\n"
+"   }\n"
+"   if (fAy == 0.0)\n"
+"       return fAx;\n"
+"   if (fBy == 0.0)\n"
+"       return fBx;\n"
+"   if (!lcl_HasChangeOfSign( fAy, fBy))\n"
+"   {\n"
+"       *rConvError = true;\n"
+"       return 0.0;\n"
+"   }\n"
+"   double fPx = fAx;\n"
+"   double fPy = fAy;\n"
+"   double fQx = fBx;\n"
+"   double fQy = fBy;\n"
+"   double fRx = fAx;\n"
+"   double fRy = fAy;\n"
+"   double fSx = 0.5 * (fAx + fBx);\n"
+"   bool bHasToInterpolate = true;\n"
+"   nCount = 0;\n"
+"   while ( nCount < 500 && fabs(fRy) > fYEps &&\n"
+"               (fBx-fAx) > fmax( fabs(fAx), fabs(fBx)) * fXEps )\n"
+"   {\n"
+"       if (bHasToInterpolate)\n"
+"       {\n"
+"           if (fPy!=fQy && fQy!=fRy && fRy!=fPy)\n"
+"           {\n"
+"               fSx = fPx * fRy * fQy / (fRy-fPy) / (fQy-fPy)\n"
+"                   + fRx * fQy * fPy / (fQy-fRy) / (fPy-fRy)\n"
+"                   + fQx * fPy * fRy / (fPy-fQy) / (fRy-fQy);\n"
+"               bHasToInterpolate = (fAx < fSx) && (fSx < fBx);\n"
+"           }\n"
+"           else\n"
+"               bHasToInterpolate = false;\n"
+"       }\n"
+"       if(!bHasToInterpolate)\n"
+"       {\n"
+"           fSx = 0.5 * (fAx + fBx);\n"
+"           fPx = fAx; fPy = fAy;\n"
+"           fQx = fBx; fQy = fBy;\n"
+"           bHasToInterpolate = true;\n"
+"       }\n"
+"       fPx = fQx; fQx = fRx; fRx = fSx;\n"
+"       fPy = fQy; fQy = fRy; fRy = fp - GetBetaDist(fSx, fAlpha, fBeta);\n"
+"       if (lcl_HasChangeOfSign( fAy, fRy))\n"
+"       {\n"
+"           fBx = fRx; fBy = fRy;\n"
+"       }\n"
+"       else\n"
+"       {\n"
+"           fAx = fRx; fAy = fRy;\n"
+"       }\n"
+"       bHasToInterpolate = bHasToInterpolate && (fabs(fRy) *"
+" 2.0 <= fabs(fQy));\n"
+"       ++nCount;\n"
+"   }\n"
+"   return fRx;\n"
+"}\n";
+
+
+std::string lcl_IterateInverseChiInvDecl =
+"static double lcl_IterateInverseChiInv"
+"(double fp, double fdf, double fAx, double fBx, bool *rConvError);\n";
+std::string lcl_IterateInverseChiInv =
+"static double lcl_IterateInverseChiInv"
+"(double fp, double fdf, double fAx, double fBx, bool *rConvError)\n"
+"{\n"
+"   *rConvError = false;\n"
+"    double fYEps = 1.0E-307;\n"
+"    double fXEps = fMachEps;\n"
+"   if(!(fAx < fBx))\n"
+"   {\n"
+"       //print error\n"
+"   }"
+"   double fAy = fp - GetChiDist(fAx, fdf);\n"
+"   double fBy = fp - GetChiDist(fBx, fdf);\n"
+"   double fTemp;\n"
+"   unsigned short nCount;\n"
+"   for (nCount = 0; nCount < 1000 && "
+"!lcl_HasChangeOfSign(fAy,fBy); nCount++)\n"
+"   {\n"
+"       if (fabs(fAy) <= fabs(fBy))\n"
+"       {\n"
+"           fTemp = fAx;\n"
+"           fAx += 2.0 * (fAx - fBx);\n"
+"           if (fAx < 0.0)\n"
+"               fAx = 0.0;\n"
+"           fBx = fTemp;\n"
+"           fBy = fAy;\n"
+"           fAy = fp - GetChiDist(fAx, fdf);\n"
+"       }\n"
+"       else\n"
+"       {\n"
+"           fTemp = fBx;\n"
+"           fBx += 2.0 * (fBx - fAx);\n"
+"           fAx = fTemp;\n"
+"           fAy = fBy;\n"
+"           fBy = fp - GetChiDist(fBx, fdf);\n"
+"       }\n"
+"   }\n"
+"   if (fAy == 0.0)\n"
+"       return fAx;\n"
+"   if (fBy == 0.0)\n"
+"       return fBx;\n"
+"   if (!lcl_HasChangeOfSign( fAy, fBy))\n"
+"   {\n"
+"       *rConvError = true;\n"
+"       return 0.0;\n"
+"   }\n"
+"   double fPx = fAx;\n"
+"   double fPy = fAy;\n"
+"   double fQx = fBx;\n"
+"   double fQy = fBy;\n"
+"   double fRx = fAx;\n"
+"   double fRy = fAy;\n"
+"   double fSx = 0.5 * (fAx + fBx);\n"
+"   bool bHasToInterpolate = true;\n"
+"   nCount = 0;\n"
+"   while ( nCount < 500 && fabs(fRy) > fYEps &&\n"
+"       (fBx-fAx) > fmax( fabs(fAx), fabs(fBx)) * fXEps )\n"
+"   {\n"
+"       if (bHasToInterpolate)\n"
+"       {\n"
+"           if (fPy!=fQy && fQy!=fRy && fRy!=fPy)\n"
+"           {\n"
+"               fSx = fPx * fRy * fQy / (fRy-fPy) / (fQy-fPy)\n"
+"                   + fRx * fQy * fPy / (fQy-fRy) / (fPy-fRy)\n"
+"                   + fQx * fPy * fRy / (fPy-fQy) / (fRy-fQy);\n"
+"               bHasToInterpolate = (fAx < fSx) && (fSx < fBx);\n"
+"           }\n"
+"           else\n"
+"               bHasToInterpolate = false;\n"
+"       }\n"
+"       if(!bHasToInterpolate)\n"
+"       {\n"
+"           fSx = 0.5 * (fAx + fBx);\n"
+"           fPx = fAx; fPy = fAy;\n"
+"           fQx = fBx; fQy = fBy;\n"
+"           bHasToInterpolate = true;\n"
+"       }\n"
+"       fPx = fQx; fQx = fRx; fRx = fSx;\n"
+"       fPy = fQy; fQy = fRy; fRy = fp - GetChiDist(fSx, fdf);\n"
+"       if (lcl_HasChangeOfSign( fAy, fRy))\n"
+"       {\n"
+"           fBx = fRx; fBy = fRy;\n"
+"       }\n"
+"       else\n"
+"       {\n"
+"           fAx = fRx; fAy = fRy;\n"
+"       }\n"
+"       bHasToInterpolate = bHasToInterpolate && (fabs(fRy)"
+" * 2.0 <= fabs(fQy));\n"
+"       ++nCount;\n"
+"   }\n"
+"   return fRx;\n"
+"}\n";
+
+std::string lcl_IterateInverseChiSQInvDecl =
+"static double lcl_IterateInverseChiSQInv( double fp, double fdf, \n"
+"   double fAx, double fBx, bool *rConvError );\n";
+std::string lcl_IterateInverseChiSQInv =
+"static double lcl_IterateInverseChiSQInv( double fp, double fdf, \n"
+"   double fAx, double fBx, bool *rConvError )\n"
+"{\n"
+"   *rConvError = false;\n"
+"    double fYEps = 1.0E-307;\n"
+"    double fXEps = fMachEps;\n"
+
+"   if(!(fAx < fBx))\n"
+"   {\n"
+"       //print error\n"
+"   }\n"
+"   double fAy = fp - GetChiSqDistCDF(fAx, fdf);\n"
+"   double fBy = fp - GetChiSqDistCDF(fBx, fdf);\n"
+"   double fTemp;\n"
+"   unsigned short nCount;\n"
+"   for (nCount = 0; nCount < 1000 && !lcl_HasChangeOfSign(fAy,fBy);"
+" nCount++)\n"
+"   {\n"
+"       if (fabs(fAy) <= fabs(fBy))\n"
+"       {\n"
+"           fTemp = fAx;\n"
+"           fAx += 2.0 * (fAx - fBx);\n"
+"           if (fAx < 0.0)\n"
+"               fAx = 0.0;\n"
+"           fBx = fTemp;\n"
+"           fBy = fAy;\n"
+"           fAy = fp - GetChiSqDistCDF(fAx, fdf);\n"
+"       }\n"
+"       else\n"
+"       {\n"
+"           fTemp = fBx;\n"
+"           fBx += 2.0 * (fBx - fAx);\n"
+"           fAx = fTemp;\n"
+"           fAy = fBy;\n"
+"           fBy = fp - GetChiSqDistCDF(fBx, fdf);\n"
+"       }\n"
+"   }\n"
+"   if (fAy == 0.0)\n"
+"       return fAx;\n"
+"   if (fBy == 0.0)\n"
+"       return fBx;\n"
+"   if (!lcl_HasChangeOfSign( fAy, fBy))\n"
+"   {\n"
+"       *rConvError = true;\n"
+"       return 0.0;\n"
+"   }\n"
+"   double fPx = fAx;\n"
+"   double fPy = fAy;\n"
+"   double fQx = fBx;\n"
+"   double fQy = fBy;\n"
+"   double fRx = fAx;\n"
+"   double fRy = fAy;\n"
+"   double fSx = 0.5 * (fAx + fBx);\n"
+"   bool bHasToInterpolate = true;\n"
+"   nCount = 0;\n"
+"   while ( nCount < 500 && fabs(fRy) > fYEps &&\n"
+"       (fBx-fAx) > fmax( fabs(fAx), fabs(fBx)) * fXEps )\n"
+"   {\n"
+"       if (bHasToInterpolate)\n"
+"       {\n"
+"           if (fPy!=fQy && fQy!=fRy && fRy!=fPy)\n"
+"           {\n"
+"               fSx = fPx * fRy * fQy / (fRy-fPy) / (fQy-fPy)\n"
+"                   + fRx * fQy * fPy / (fQy-fRy) / (fPy-fRy)\n"
+"                   + fQx * fPy * fRy / (fPy-fQy) / (fRy-fQy);\n"
+"               bHasToInterpolate = (fAx < fSx) && (fSx < fBx);\n"
+"           }\n"
+"           else\n"
+"               bHasToInterpolate = false;\n"
+"       }\n"
+"       if(!bHasToInterpolate)\n"
+"       {\n"
+"           fSx = 0.5 * (fAx + fBx);\n"
+"           fPx = fAx; fPy = fAy;\n"
+"           fQx = fBx; fQy = fBy;\n"
+"           bHasToInterpolate = true;\n"
+"       }\n"
+"       fPx = fQx; fQx = fRx; fRx = fSx;\n"
+"       fPy = fQy; fQy = fRy; fRy = fp - GetChiSqDistCDF(fSx, fdf);\n"
+"       if (lcl_HasChangeOfSign( fAy, fRy))\n"
+"       {\n"
+"           fBx = fRx; fBy = fRy;\n"
+"       }\n"
+"       else\n"
+"       {\n"
+"           fAx = fRx; fAy = fRy;\n"
+"       }\n"
+"       bHasToInterpolate = bHasToInterpolate && (fabs(fRy) * 2.0"
+" <= fabs(fQy));\n"
+"       ++nCount;\n"
+"   }\n"
+"   return fRx;\n"
+"}\n";
 
 std::string gaussinvDecl = "double gaussinv(double x);\n";
 std::string gaussinv =
@@ -178,6 +876,395 @@ std::string gaussinv =
 "    return z;\n"
 "}\n";
 
+std::string lcl_GetLogGammaHelperDecl=
+"static double lcl_GetLogGammaHelper(double fZ);\n";
+std::string lcl_GetLogGammaHelper =
+"static double lcl_GetLogGammaHelper(double fZ)\n"
+"{\n"
+"    double fg = 6.024680040776729583740234375;\n"
+"   double fZgHelp = fZ + fg - 0.5;\n"
+"   return log( lcl_getLanczosSum(fZ)) + (fZ-0.5) * log(fZgHelp) - fZgHelp;\n"
+"}\n";
+std::string lcl_GetGammaHelperDecl=
+"static double lcl_GetGammaHelper(double fZ);\n";
+std::string lcl_GetGammaHelper =
+"static double lcl_GetGammaHelper(double fZ)\n"
+"{\n"
+"   double fGamma = lcl_getLanczosSum(fZ);\n"
+"   double fg = 6.024680040776729583740234375;\n"
+"   double fZgHelp = fZ + fg - 0.5;\n"
+"   double fHalfpower = pow( fZgHelp, fZ / 2 - 0.25);\n"
+"   fGamma *= fHalfpower;\n"
+"   fGamma /= exp(fZgHelp);\n"
+"   fGamma *= fHalfpower;\n"
+"   fGamma = 120.4;\n"
+"   if (fZ <= 20.0 && fZ == (int)fZ)\n"
+"   {\n"
+"     fGamma = (int)(fGamma+0.5);\n"
+"   }\n"
+"   return fGamma;\n"
+"}\n";
+std::string lcl_getLanczosSumDecl=
+"static double lcl_getLanczosSum(double fZ);\n";
+std::string lcl_getLanczosSum =
+"static double lcl_getLanczosSum(double fZ)          \n"
+"{                                                   \n"
+"    double fNum[13] ={                        \n"
+"        23531376880.41075968857200767445163675473,  \n"
+"        42919803642.64909876895789904700198885093,  \n"
+"        35711959237.35566804944018545154716670596,  \n"
+"        17921034426.03720969991975575445893111267,  \n"
+"        6039542586.35202800506429164430729792107,   \n"
+"        1439720407.311721673663223072794912393972,  \n"
+"        248874557.8620541565114603864132294232163,  \n"
+"        31426415.58540019438061423162831820536287,  \n"
+"        2876370.628935372441225409051620849613599,  \n"
+"        186056.2653952234950402949897160456992822,  \n"
+"        8071.672002365816210638002902272250613822,  \n"
+"        210.8242777515793458725097339207133627117,  \n"
+"        2.506628274631000270164908177133837338626   \n"
+"        };                                          \n"
+"    double fDenom[13] = {                     \n"
+"        0,\n"
+"        39916800,\n"
+"        120543840,\n"
+"        150917976,\n"
+"        105258076,\n"
+"        45995730,\n"
+"        13339535,\n"
+"        2637558,\n"
+"        357423,\n"
+"        32670,\n"
+"        1925,\n"
+"        66,\n"
+"        1\n"
+"        };\n"
+"    double fSumNum;\n"
+"    double fSumDenom;\n"
+"    int nI;\n"
+"    if (fZ<=1.0)\n"
+"    {\n"
+"      fSumNum = fNum[12];\n"
+"      fSumDenom = fDenom[12];\n"
+"      for (nI = 11; nI >= 0; --nI)\n"
+"        {\n"
+"          fSumNum *= fZ;\n"
+"          fSumNum += fNum[nI];\n"
+"          fSumDenom *= fZ;\n"
+"          fSumDenom += fDenom[nI];\n"
+"        }\n"
+"    }\n"
+"    else\n"
+"    {\n"
+"      double fZInv = 1/fZ;\n"
+"      fSumNum = fNum[0];\n"
+"      fSumDenom = fDenom[0];\n"
+"      for (nI = 1; nI <=12; ++nI)\n"
+"      {\n"
+"          fSumNum *= fZInv;\n"
+"          fSumNum += fNum[nI];\n"
+"          fSumDenom *= fZInv;\n"
+"          fSumDenom += fDenom[nI];\n"
+"      }\n"
+"     }\n"
+"     return fSumNum/fSumDenom;\n"
+"}\n";
+
+std::string GetUpRegIGammaDecl=
+" double GetUpRegIGamma( double fA, double fX ) ;\n";
+std::string GetUpRegIGamma =
+"double GetUpRegIGamma( double fA, double fX )\n"
+"{\n"
+"    double fLnFactor= fA*log(fX)-fX-lgamma(fA);\n"
+"    double fFactor = exp(fLnFactor); \n"
+"    if (fX>fA+1.0) \n"
+"            return fFactor * GetGammaContFraction(fA,fX);\n"
+"    else \n"
+"            return 1.0 -fFactor * GetGammaSeries(fA,fX);\n"
+"}\n";
+
+std::string lcl_HasChangeOfSignDecl=
+"static inline bool lcl_HasChangeOfSign( double u, double w );\n";
+std::string lcl_HasChangeOfSign =
+"static inline bool lcl_HasChangeOfSign( double u, double w )\n"
+"{\n"
+"    return (u < 0.0 && w > 0.0) || (u > 0.0 && w < 0.0);\n"
+"}\n";
+
+std::string GetTDistDecl=" double GetTDist(double T, double fDF);\n";
+std::string GetTDist =
+"double GetTDist(double T, double fDF)\n"
+"{\n"
+"    return 0.5 * GetBetaDist(fDF/(fDF+T*T), fDF/2.0, 0.5);\n"
+"}\n";
+
+std::string GetBetaDecl=" double GetBeta(double fAlpha, double fBeta);\n";
+std::string GetBeta =
+"double GetBeta(double fAlpha, double fBeta)\n"
+"{\n"
+"    double fA;\n"
+"    double fB;\n"
+"    if (fAlpha > fBeta)\n"
+"    {\n"
+"        fA = fAlpha; fB = fBeta;\n"
+"    }\n"
+"    else\n"
+"    {\n"
+"        fA = fBeta; fB = fAlpha;\n"
+"    }\n"
+"    if (fA+fB < fMaxGammaArgument)\n"
+"        return tgamma(fA)/tgamma(fA + fB)*tgamma(fB);\n"
+"    double fg = 6.024680040776729583740234375;\n"
+"    double fgm = fg - 0.5;\n"
+"    double fLanczos = lcl_getLanczosSum(fA);\n"
+"    fLanczos /= lcl_getLanczosSum(fA + fB);\n"
+"    fLanczos *= lcl_getLanczosSum(fB);\n"
+"    double fABgm = fA + fB + fgm;\n"
+"    fLanczos *= sqrt((fABgm/(fA + fgm))/(fB + fgm));\n"
+"    double fTempA = fB/(fA + fgm);\n"
+"    double fTempB = fA/(fB + fgm);\n"
+"    double fResult = exp(-fA*log1p(fTempA) - fB*log1p(fTempB) - fgm);\n"
+"    fResult *= fLanczos;\n"
+"    return fResult;\n"
+"}\n";
+
+std::string GetLogBetaDecl=
+" double GetLogBeta(double fAlpha, double fBeta);\n";
+std::string GetLogBeta =
+"double GetLogBeta(double fAlpha, double fBeta)\n"
+"{\n"
+"    double fA;\n"
+"    double fB;\n"
+"    if (fAlpha > fBeta)\n"
+"    {\n"
+"        fA = fAlpha; fB = fBeta;\n"
+"    }\n"
+"    else\n"
+"    {\n"
+"        fA = fBeta; fB = fAlpha;\n"
+"    }\n"
+"    double fg = 6.024680040776729583740234375;\n"
+"    double fgm = fg - 0.5;\n"
+"    double fLanczos = lcl_getLanczosSum(fA);\n"
+"    fLanczos /= lcl_getLanczosSum(fA + fB);\n"
+"    fLanczos *= lcl_getLanczosSum(fB);\n"
+"    double fLogLanczos = log(fLanczos);\n"
+"    double fABgm = fA + fB + fgm;\n"
+"    fLogLanczos += 0.5*(log(fABgm) - log(fA + fgm) - log(fB + fgm));\n"
+"    double fTempA = fB/(fA + fgm);\n"
+"    double fTempB = fA/(fB + fgm);\n"
+"    double fResult = -fA * log1p(fTempA)\n"
+"        -fB * log1p(fTempB)-fgm;\n"
+"    fResult += fLogLanczos;\n"
+"    return fResult;\n"
+"}\n";
+
+std::string GetBetaDistPDFDecl=
+"double GetBetaDistPDF(double fX, double fA, double fB);\n";
+std::string GetBetaDistPDF =
+"double GetBetaDistPDF(double fX, double fA, double fB)\n"
+"{\n"
+"    if (fA == 1.0) \n"
+"    {\n"
+"        if (fB == 1.0)\n"
+"            return 1.0;\n"
+"        if (fB == 2.0)\n"
+"            return -2.0*fX + 2.0;\n"
+"        if (fX == 1.0 && fB < 1.0)\n"
+"        {\n"
+"            return HUGE_VAL;\n"
+"        }\n"
+"        if (fX <= 0.01)\n"
+"            return fB + fB * expm1((fB-1.0) * log1p(-fX));\n"
+"        else \n"
+"            return fB * pow(0.5-fX+0.5,fB-1.0);\n"
+"    }\n"
+"    if (fB == 1.0) \n"
+"    {\n"
+"    if (fA == 2.0)\n"
+"        return fA * fX;\n"
+"        if (fX == 0.0 && fA < 1.0)\n"
+"        {\n"
+"            return HUGE_VAL;\n"
+"        }\n"
+"        return fA * pow(fX,fA-1);\n"
+"    }\n"
+"    if (fX <= 0.0)\n"
+"    {\n"
+"        if (fA < 1.0 && fX == 0.0)\n"
+"        {\n"
+"            return HUGE_VAL;\n"
+"        }\n"
+"        else\n"
+"            return 0.0;\n"
+"    }\n"
+"    if (fX >= 1.0)\n"
+"    {\n"
+"        if (fB < 1.0 && fX == 1.0)\n"
+"        {\n"
+"            return HUGE_VAL;\n"
+"        }\n"
+"        else \n"
+"        return 0.0;\n"
+"    }\n"
+"    double fLogDblMax = log( 1.79769e+308 );\n"
+"    double fLogDblMin = log( 2.22507e-308 );\n"
+"    double fLogY = (fX < 0.1) ? log1p(-fX) : log(0.5-fX+0.5);\n"
+"    double fLogX = log(fX);\n"
+"    double fAm1LogX = (fA-1.0) * fLogX;\n"
+"    double fBm1LogY = (fB-1.0) * fLogY;\n"
+"    double fLogBeta = GetLogBeta(fA,fB);\n"
+"    if (   fAm1LogX < fLogDblMax  && fAm1LogX > fLogDblMin\n"
+"        && fBm1LogY < fLogDblMax  && fBm1LogY > fLogDblMin\n"
+"        && fLogBeta < fLogDblMax  && fLogBeta > fLogDblMin\n"
+"        && fAm1LogX + fBm1LogY < fLogDblMax && fAm1LogX + fBm1LogY > \n"
+"           fLogDblMin)\n"
+"        return pow(fX,fA-1.0) * pow(0.5-fX+0.5,fB-1.0) / GetBeta(fA,fB);\n"
+"    else \n"
+"         return exp( fAm1LogX + fBm1LogY - fLogBeta);\n"
+"}\n";
+
+std::string lcl_GetBetaHelperContFracDecl=
+"double lcl_GetBetaHelperContFrac(double fX, double fA, double fB);\n";
+std::string lcl_GetBetaHelperContFrac =
+"double lcl_GetBetaHelperContFrac(double fX, double fA, double fB)\n"
+"{   \n"
+
+"    double a1, b1, a2, b2, fnorm, apl2m, d2m, d2m1, cfnew, cf;\n"
+"    a1 = 1.0; b1 = 1.0;\n"
+"    b2 = 1.0 - (fA+fB)/(fA+1.0)*fX;\n"
+"    if (b2 == 0.0)\n"
+"    {\n"
+"      a2 = 0.0;\n"
+"      fnorm = 1.0;\n"
+"      cf = 1.0;\n"
+"    }\n"
+"    else\n"
+"    {\n"
+"      a2 = 1.0;\n"
+"      fnorm = 1.0/b2;\n"
+"      cf = a2*fnorm;\n"
+"    }\n"
+"    cfnew = 1.0;\n"
+"    double rm = 1.0;\n"
+"    double fMaxIter = 50000.0;\n"
+"    bool bfinished = false;\n"
+"    do\n"
+"    {\n"
+"      apl2m = fA + 2.0*rm;\n"
+"      d2m = rm*(fB-rm)*fX/((apl2m-1.0)*apl2m);\n"
+"      d2m1 = -(fA+rm)*(fA+fB+rm)*fX/(apl2m*(apl2m+1.0));\n"
+"      a1 = (a2+d2m*a1)*fnorm;\n"
+"      b1 = (b2+d2m*b1)*fnorm;\n"
+"      a2 = a1 + d2m1*a2*fnorm;\n"
+"      b2 = b1 + d2m1*b2*fnorm;\n"
+"      if (b2 != 0.0) \n"
+"      {\n"
+"        fnorm = 1.0/b2;\n"
+"        cfnew = a2*fnorm;\n"
+"        bfinished = (fabs(cf-cfnew) < fabs(cf)*fMachEps);\n"
+"      }\n"
+"      cf = cfnew;\n"
+"      rm += 1.0;\n"
+"     }\n"
+"    while (rm < fMaxIter && !bfinished);\n"
+"    return cf;\n"
+"}\n";
+
+std::string lcl_IterateInverseDecl=
+"double lcl_IterateInverse("
+"double fAx, double fBx, bool* rConvError,double fp,double fDF );\n";
+std::string lcl_IterateInverse =
+"double lcl_IterateInverse( "
+"double fAx, double fBx, bool* rConvError,double fp,double fDF )\n"
+"{\n"
+"    *rConvError = false;\n"
+"    double fYEps = 1.0E-307;\n"
+"    double fXEps =DBL_EPSILON;\n"
+"    if(fAx>fBx)\n"
+"      return 0.0;//means wrong condition.\n"
+"    double fAy = GetValue(fAx,fp,fDF);\n"
+"    double fBy = GetValue(fBx,fp,fDF);\n"
+"    double fTemp;\n"
+"    unsigned short nCount;\n"
+"    for (nCount =0;nCount<1000&&!lcl_HasChangeOfSign(fAy,fBy);nCount++)\n"
+"    {\n"
+"        if (fabs(fAy) <= fabs(fBy)) \n"
+"        {\n"
+"            fTemp = fAx;\n"
+"            fAx += 2.0 * (fAx - fBx);\n"
+"            if (fAx < 0.0)\n"
+"                fAx = 0.0;\n"
+"            fBx = fTemp;\n"
+"            fBy = fAy;\n"
+"            fAy = GetValue(fAx,fp,fDF);\n"
+"        }\n"
+"        else\n"
+"        {\n"
+"            fTemp = fBx;\n"
+"            fBx += 2.0 * (fBx - fAx);\n"
+"            fAx = fTemp;\n"
+"            fAy = fBy;\n"
+"            fBy = GetValue(fBx,fp,fDF);  \n"
+"        }\n"
+"    }\n"
+"    if (fAy == 0.0)\n"
+"        return fAx;\n"
+"    if (fBy == 0.0)\n"
+"        return fBx;\n"
+"    if (!lcl_HasChangeOfSign( fAy, fBy))\n"
+"    {\n"
+"        *rConvError = true;\n"
+"        return 0.0;\n"
+"    }\n"
+"    double fPx = fAx;\n"
+"    double fPy = fAy;\n"
+"    double fQx = fBx;\n"
+"    double fQy = fBy;\n"
+"    double fRx = fAx;\n"
+"    double fRy = fAy;\n"
+"    double fSx = 0.5 * (fAx + fBx); \n"
+"    bool bHasToInterpolate = true;\n"
+"    nCount = 0;\n"
+"    while ( nCount < 500 && fabs(fRy) > fYEps &&\n"
+"            (fBx-fAx) > max( fabs(fAx), fabs(fBx)) * fXEps )\n"
+"    {\n"
+"        if (bHasToInterpolate)\n"
+"        {\n"
+"            if (fPy!=fQy && fQy!=fRy && fRy!=fPy)\n"
+"            {\n"
+"                fSx = fPx * fRy * fQy / (fRy-fPy) / (fQy-fPy)\n"
+"                    + fRx * fQy * fPy / (fQy-fRy) / (fPy-fRy)\n"
+"                    + fQx * fPy * fRy / (fPy-fQy) / (fRy-fQy);\n"
+"                bHasToInterpolate = (fAx < fSx) && (fSx < fBx);\n"
+"            }\n"
+"            else\n"
+"                bHasToInterpolate = false;\n"
+"        }\n"
+"        if(!bHasToInterpolate)\n"
+"        {\n"
+"            fSx = 0.5 * (fAx + fBx);\n"
+"            \n"
+"            fPx = fAx; fPy = fAy;\n"
+"            fQx = fBx; fQy = fBy;\n"
+"            bHasToInterpolate = true;\n"
+"        }\n"
+"        fPx = fQx; fQx = fRx; fRx = fSx;\n"
+"        fPy = fQy; fQy = fRy; fRy = GetValue(fSx,fp,fDF);\n"
+"        if (lcl_HasChangeOfSign( fAy, fRy))\n"
+"        {\n"
+"            fBx = fRx; fBy = fRy;\n"
+"        }\n"
+"        else\n"
+"        {\n"
+"            fAx = fRx; fAy = fRy;\n"
+"        }\n"
+"        bHasToInterpolate ="
+"            bHasToInterpolate && (fabs(fRy) * 2.0 <= fabs(fQy));\n"
+"        ++nCount;\n"
+"    }\n"
+"    return fRx;\n"
+"}\n";
 
 #endif
 
commit 848b91fbdf668d0de0511992d8ca22911d63c0b6
Author: mingli <mingli at multicorewareinc.com>
Date:   Thu Nov 7 14:14:51 2013 +0800

    GPU Calc: unit test cases for LOGNORMDIST
    
    Need open macro NO_FALLBACK_TO_SWINTERP in formulagroupcl.cxx for test
    
    AMLOEXT-112 BUG
    
    Change-Id: I4ab444e974499138afe330c9ccb9da640f8d3724
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/qa/unit/data/ods/opencl/statistical/LogNormDist.ods b/sc/qa/unit/data/ods/opencl/statistical/LogNormDist.ods
new file mode 100644
index 0000000..be191d4
Binary files /dev/null and b/sc/qa/unit/data/ods/opencl/statistical/LogNormDist.ods differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index ef51e07..3283c27 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -174,6 +174,7 @@ public:
     void testMathFormulaArcTanHyp();
     void testMathFormulaBitAnd();
     void testStatisticalFormulaForecast();
+    void testStatisticalFormulaLogNormDist();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -279,6 +280,7 @@ public:
     CPPUNIT_TEST(testMathFormulaArcTanHyp);
     CPPUNIT_TEST(testMathFormulaBitAnd);
     CPPUNIT_TEST(testStatisticalFormulaForecast);
+    CPPUNIT_TEST(testStatisticalFormulaLogNormDist);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2374,6 +2376,31 @@ void ScOpenclTest:: testFinancialDurationFormula()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-112]
+void ScOpenclTest::testStatisticalFormulaLogNormDist()
+{
+    if (!detectOpenCLDevice())
+        return;
+
+    ScDocShellRef xDocSh = loadDoc("opencl/statistical/LogNormDist.", ODS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+
+    ScDocShellRef xDocShRes = loadDoc("opencl/statistical/LogNormDist.", ODS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Check the results of formula cells in the shared formula range.
+    for (SCROW i = 1; i <= 19; ++i)
+    {
+        double fLibre = pDoc->GetValue(ScAddress(4,i,0));
+        double fExcel = pDocRes->GetValue(ScAddress(4,i,0));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
+    }
+    xDocSh->DoClose();
+    xDocShRes->DoClose();
+}
 //[AMLOEXT-113]
 void ScOpenclTest::testMathFormulaArcCos()
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index b9e9e9b..7f794e5 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1408,6 +1408,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocArcTanHyp:
             case ocBitAnd:
             case ocForecast:
+            case ocLogNormDist:
             // Don't change the state.
             break;
             default:
commit 522393aea30a8e33b6a65e45370ce9b0aad890b8
Author: mingli <mingli at multicorewareinc.com>
Date:   Thu Nov 7 14:18:10 2013 +0800

    GPU Calc: implemented LOGNORMDIST
    
    AMLOEXT-112 FIX
    
    Change-Id: Ifdf8388ab5375d6463b8648b890787a3c3db0325
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index 5f5a3bb..68f90ee 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1184,6 +1184,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                          ft->Children[i], new OpForecast));
                 break;
+            case ocLogNormDist:
+                mvSubArguments.push_back(SoPHelper(ts,
+                         ft->Children[i], new OpLogNormDist));
+                break;
             case ocExternal:
                 if ( !(pChild->GetExternal().compareTo(OUString(
                     "com.sun.star.sheet.addin.Analysis.getEffect"))))
diff --git a/sc/source/core/opencl/op_statistical.cxx b/sc/source/core/opencl/op_statistical.cxx
index 134a729..a58eee8 100644
--- a/sc/source/core/opencl/op_statistical.cxx
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -2395,6 +2395,82 @@ void OpForecast::GenSlidingWindowFunction(std::stringstream &ss,
     ss <<"    return tmp;\n";
     ss << "}";
 }
+void OpLogNormDist::GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments)
+{
+    FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+    const formula::SingleVectorRefToken*tmpCurDVR0= dynamic_cast<const
+        formula::SingleVectorRefToken *>(tmpCur0);
+    FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+    const formula::SingleVectorRefToken*tmpCurDVR1= dynamic_cast<const
+        formula::SingleVectorRefToken *>(tmpCur1);
+    FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+    const formula::SingleVectorRefToken*tmpCurDVR2= dynamic_cast<const
+        formula::SingleVectorRefToken *>(tmpCur2);
+    FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+    const formula::SingleVectorRefToken*tmpCurDVR3= dynamic_cast<const
+        formula::SingleVectorRefToken *>(tmpCur3);
+    ss << "\ndouble " << sSymName;
+    ss << "_"<< BinFuncName() <<"(";
+    for (unsigned i = 0; i < vSubArguments.size(); i++)
+    {
+        if (i)
+            ss << ",";
+        vSubArguments[i]->GenSlidingWindowDecl(ss);
+    }
+    ss << ") {\n";
+    ss << "    int gid0=get_global_id(0);\n";
+    ss << "    double arg0 = ";
+    ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+    ss << ";\n";
+    ss << "    double arg1 = ";
+    ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+    ss << ";\n";
+    ss << "    double arg2 = ";
+    ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+    ss << ";\n";
+    ss << "    double arg3 = ";
+    ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+    ss << ";\n";
+    ss << "    double tmp;\n";
+#ifdef ISNAN
+    ss << "    if(isNan(arg0)||(gid0>=";
+    ss << tmpCurDVR0->GetArrayLength();
+    ss << "))\n";
+    ss << "        arg0 = 0;\n";
+#endif
+#ifdef ISNAN
+    ss << "    if(isNan(arg1)||(gid0>=";
+    ss << tmpCurDVR1->GetArrayLength();
+    ss << "))\n";
+    ss << "        arg1 = 0;\n";
+#endif
+#ifdef ISNAN
+    ss << "    if(isNan(arg2)||(gid0>=";
+    ss << tmpCurDVR2->GetArrayLength();
+    ss << "))\n";
+    ss << "        arg2 = 0;\n";
+#endif
+#ifdef ISNAN
+    ss << "    if(isNan(arg3)||(gid0>=";
+    ss << tmpCurDVR3->GetArrayLength();
+    ss << "))\n";
+    ss << "        arg3 = 0;\n";
+#endif
+    ss << "    double temp = (log(arg0)-arg1)/arg2;\n";
+    ss << "    if(arg3)\n";
+    ss << "    {\n";
+    ss << "        if(arg0<=0)\n";
+    ss << "            tmp = 0.0;\n";
+    ss << "        else\n";
+    ss << "            tmp = 0.5 * erfc(-temp * 0.7071067811865475);\n";
+    ss << "    }\n";
+    ss << "    else\n";
+    ss << "        tmp = (0.39894228040143268 * exp(-(temp * temp)";
+    ss << " / 2.0))/arg2/arg0;\n";
+    ss << "    return tmp;\n";
+    ss << "}\n";
+}
 
 }}
 
diff --git a/sc/source/core/opencl/op_statistical.hxx b/sc/source/core/opencl/op_statistical.hxx
index 73f7ece..92b67dc 100644
--- a/sc/source/core/opencl/op_statistical.hxx
+++ b/sc/source/core/opencl/op_statistical.hxx
@@ -218,6 +218,13 @@ public:
             const std::string sSymName, SubArguments &vSubArguments);
     virtual std::string BinFuncName(void) const { return "Forecast"; }
 };
+class OpLogNormDist: public Normal
+{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments);
+    virtual std::string BinFuncName(void) const { return "LogNormdist"; }
+};
 }}
 
 #endif
commit 84a8d2dde9b624f6c2ee6ba52dea3612ba6a4a25
Author: mingli <mingli at multicorewareinc.com>
Date:   Thu Nov 7 14:03:03 2013 +0800

    GPU Calc: unit test cases for FORECAST
    
    Need open macro NO_FALLBACK_TO_SWINTERP in formulagroupcl.cxx for test
    
    AMLOEXT-109 BUG
    
    Change-Id: I71c31ec1ce58ed55cf47b573459c2af9402ae8ab
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/qa/unit/data/xls/opencl/statistical/Forecast.xls b/sc/qa/unit/data/xls/opencl/statistical/Forecast.xls
new file mode 100644
index 0000000..aee8c9f
Binary files /dev/null and b/sc/qa/unit/data/xls/opencl/statistical/Forecast.xls differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index 4755b9b..ef51e07 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -173,6 +173,7 @@ public:
     void testMathFormulaArcTan();
     void testMathFormulaArcTanHyp();
     void testMathFormulaBitAnd();
+    void testStatisticalFormulaForecast();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -277,6 +278,7 @@ public:
     CPPUNIT_TEST(testMathFormulaArcTan);
     CPPUNIT_TEST(testMathFormulaArcTanHyp);
     CPPUNIT_TEST(testMathFormulaBitAnd);
+    CPPUNIT_TEST(testStatisticalFormulaForecast);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -1981,6 +1983,30 @@ void ScOpenclTest::testFinacialNPERFormula()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-109]
+void ScOpenclTest::testStatisticalFormulaForecast()
+{
+    if (!detectOpenCLDevice())
+        return;
+
+    ScDocShellRef xDocSh = loadDoc("opencl/statistical/Forecast.", XLS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+    ScDocShellRef xDocShRes = loadDoc("opencl/statistical/Forecast.", XLS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Check the results of formula cells in the shared formula range.
+    for (SCROW i = 1; i <= 19; ++i)
+    {
+        double fLibre = pDoc->GetValue(ScAddress(3,i,0));
+        double fExcel = pDocRes->GetValue(ScAddress(3,i,0));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
+    }
+    xDocSh->DoClose();
+    xDocShRes->DoClose();
+}
 //[AMLOEXT-110]
 void ScOpenclTest::testFinancialAmorlincFormula()
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index f9c5806..b9e9e9b 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1407,6 +1407,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocArcTan:
             case ocArcTanHyp:
             case ocBitAnd:
+            case ocForecast:
             // Don't change the state.
             break;
             default:
commit 38303bba7af44cbc876eee0ed38c713b60d29966
Author: mingli <mingli at multicorewareinc.com>
Date:   Thu Nov 7 14:09:16 2013 +0800

    GPU Calc: implemented FORECAST
    
    AMLOEXT-109 FIX
    
    Change-Id: I3be61f73e7a2d48b4977bb80ecd8df8e86f49929
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index ddaa107..5f5a3bb 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1180,6 +1180,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                     ft->Children[i], new OpBitAnd));
                 break;
+            case ocForecast:
+                mvSubArguments.push_back(SoPHelper(ts,
+                         ft->Children[i], new OpForecast));
+                break;
             case ocExternal:
                 if ( !(pChild->GetExternal().compareTo(OUString(
                     "com.sun.star.sheet.addin.Analysis.getEffect"))))
diff --git a/sc/source/core/opencl/op_statistical.cxx b/sc/source/core/opencl/op_statistical.cxx
index 5cf6854..134a729 100644
--- a/sc/source/core/opencl/op_statistical.cxx
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -2285,6 +2285,116 @@ void OpLogInv:: GenSlidingWindowFunction(std::stringstream &ss,
     ss << "    return tmp;\n";
     ss << "}\n";
 }
+void OpForecast::GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments)
+{
+    FormulaToken *pCur0 = vSubArguments[0]->GetFormulaToken();
+    assert(pCur0);
+    const formula::SingleVectorRefToken*pCurDVR0= dynamic_cast<const
+          formula::SingleVectorRefToken *>(pCur0);
+    FormulaToken *pCur1 = vSubArguments[1]->GetFormulaToken();
+    assert(pCur1);
+    const formula::DoubleVectorRefToken* pCurDVR1 =
+        dynamic_cast<const formula::DoubleVectorRefToken *>(pCur1);
+    size_t nCurWindowSize = pCurDVR1->GetRefRowSize();
+    FormulaToken *pCur2 = vSubArguments[2]->GetFormulaToken();
+    assert(pCur2);
+    const formula::DoubleVectorRefToken* pCurDVR2 =
+        dynamic_cast<const formula::DoubleVectorRefToken *>(pCur2);
+    size_t nCurWindowSize1 = pCurDVR2->GetRefRowSize();
+    ss << "\ndouble " << sSymName;
+    ss << "_"<< BinFuncName() <<"( ";
+    for (unsigned i = 0; i < vSubArguments.size(); i++)
+    {
+        if (i)
+            ss << ",";
+        vSubArguments[i]->GenSlidingWindowDecl(ss);
+    }
+    ss << ") {\n";
+    ss << "    int gid0 = get_global_id(0);\n";
+    ss << "    double fSumX = 0.0;\n";
+    ss << "    double fSumY = 0.0;\n";
+    ss << "    double fSumDeltaXDeltaY = 0.0;\n";
+    ss << "    double fSumSqrDeltaX = 0.0;\n";
+    ss << "    double arg0 = ";
+    ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+    ss << ";\n";
+#ifdef ISNAN
+    ss<< "    if(isNan(arg0)||(gid0>=";
+    ss<<pCurDVR0->GetArrayLength();
+    ss<<"))\n";
+    ss<<"        arg0 = 0;\n";
+#endif
+    ss << "    int length="<<nCurWindowSize;
+    ss << ";\n";
+    ss << "    int length1= "<<nCurWindowSize1;
+    ss << ";\n";
+    ss << "    if(length!=length1)\n";
+    ss << "        return 0;\n";
+    ss << "    double tmp = 0;\n";
+    ss << "    for (int i = 0; i <" << nCurWindowSize << "; i++)\n";
+    ss << "    {\n";
+    ss << "        double arg1 = ";
+    ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+    ss << ";\n";
+    ss << "        double arg2 = ";
+    ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+    ss << ";\n";
+#ifdef ISNAN
+    ss << "        if(isNan(arg1)||((gid0+i)>=";
+    ss << pCurDVR1->GetArrayLength();
+    ss << "))\n";
+    ss << "        {\n";
+    ss << "            length--;\n";
+    ss << "            continue;\n";
+    ss << "        }\n";
+#endif
+#ifdef ISNAN
+    ss << "        if(isNan(arg2)||((gid0+i)>=";
+    ss << pCurDVR2->GetArrayLength();
+    ss << "))\n";
+    ss << "        {\n";
+    ss << "            length--;\n";
+    ss << "            continue;\n";
+    ss << "        }\n";
+#endif
+    ss << "        fSumY+=arg1;\n";
+    ss << "        fSumX+=arg2;\n";
+    ss << "    }\n";
+    ss << "    double fMeanX = fSumX / length;\n";
+    ss << "    double fMeanY = fSumY / length;\n";
+    ss << "    for (int i = 0; i <" << nCurWindowSize << "; i++)\n";
+    ss << "    {\n";
+    ss << "        double arg1 = ";
+    ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+    ss << ";\n";
+    ss << "        double arg2 = ";
+    ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+    ss << ";\n";
+#ifdef ISNAN
+    ss << "        if(isNan(arg1)||((gid0+i)>=";
+    ss <<pCurDVR1->GetArrayLength();
+    ss <<"))\n";
+    ss <<"        {\n";
+    ss <<"            continue;\n";
+    ss <<"        }\n";
+#endif
+#ifdef ISNAN
+    ss << "        if(isNan(arg2)||((gid0+i)>=";
+    ss <<pCurDVR2->GetArrayLength();
+    ss <<"))\n";
+    ss <<"        {\n";
+    ss <<"            continue;\n";
+    ss <<"        }\n";
+#endif
+    ss <<"        fSumDeltaXDeltaY+=(arg2 - fMeanX) * (arg1 - fMeanY);\n";
+    ss <<"        fSumSqrDeltaX+=(arg2 - fMeanX) * (arg2 - fMeanX);\n";
+    ss <<"    }\n";
+    ss <<"    tmp =fMeanY + fSumDeltaXDeltaY / fSumSqrDeltaX *";
+    ss <<" (arg0 - fMeanX);\n";
+    ss <<"    return tmp;\n";
+    ss << "}";
+}
 
 }}
 
diff --git a/sc/source/core/opencl/op_statistical.hxx b/sc/source/core/opencl/op_statistical.hxx
index 19ad6a5..73f7ece 100644
--- a/sc/source/core/opencl/op_statistical.hxx
+++ b/sc/source/core/opencl/op_statistical.hxx
@@ -211,6 +211,13 @@ public:
 
     virtual std::string BinFuncName(void) const { return "CritBinom"; }
 };
+class OpForecast: public Normal
+{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments);
+    virtual std::string BinFuncName(void) const { return "Forecast"; }
+};
 }}
 
 #endif
commit 975e946f04cd39aa620d7c7d61833fdb40572355
Author: yangzhang <yangzhang at multicorewareinc.com>
Date:   Thu Nov 7 13:45:48 2013 +0800

    GPU Calc: unit test cases for BITAND
    
    Need open macro NO_FALLBACK_TO_SWINTERP in formulagroupcl.cxx for test
    
    AMLOEXT-149 BUG
    
    Change-Id: Iad20b76cc627768421bb3523388deeaa3584439e
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/qa/unit/data/ods/opencl/math/BitAnd.ods b/sc/qa/unit/data/ods/opencl/math/BitAnd.ods
new file mode 100644
index 0000000..cf848ba
Binary files /dev/null and b/sc/qa/unit/data/ods/opencl/math/BitAnd.ods differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index bf14e11..4755b9b 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -172,6 +172,7 @@ public:
     void testMathFormulaArcSinHyp();
     void testMathFormulaArcTan();
     void testMathFormulaArcTanHyp();
+    void testMathFormulaBitAnd();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -275,6 +276,7 @@ public:
     CPPUNIT_TEST(testMathFormulaArcSinHyp);
     CPPUNIT_TEST(testMathFormulaArcTan);
     CPPUNIT_TEST(testMathFormulaArcTanHyp);
+    CPPUNIT_TEST(testMathFormulaBitAnd);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2964,6 +2966,31 @@ void ScOpenclTest::testMathFormulaArcTanHyp()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-149]
+void ScOpenclTest::testMathFormulaBitAnd()
+{
+    if (!detectOpenCLDevice())
+        return;
+    ScDocShellRef xDocSh =
+        loadDoc("opencl/math/BitAnd.", ODS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+    ScDocShellRef xDocShRes =
+        loadDoc("opencl/math/BitAnd.", ODS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Verify BitAnd Function
+    for (SCROW i = 1; i <= 1000; ++i)
+    {
+        double fLibre = pDoc->GetValue(ScAddress(2,i,0));
+        double fExcel = pDocRes->GetValue(ScAddress(2,i,0));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
+    }
+    xDocSh->DoClose();
+    xDocShRes->DoClose();
+}
 ScOpenclTest::ScOpenclTest()
       : ScBootstrapFixture( "/sc/qa/unit/data" )
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 1ab1b58..f9c5806 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1406,6 +1406,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocArcSinHyp:
             case ocArcTan:
             case ocArcTanHyp:
+            case ocBitAnd:
             // Don't change the state.
             break;
             default:
commit d767355e1f3cda3d2eec5140abad2d26e6f70ce2
Author: yangzhang <yangzhang at multicorewareinc.com>
Date:   Thu Nov 7 13:50:49 2013 +0800

    GPU Calc: implemented BITAND
    
    AMLOEXT-149 FIX
    
    Change-Id: I4d7061993348c93bef929d0fe5484fa06e700230
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index 02ef787..ddaa107 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1176,6 +1176,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                     ft->Children[i], new OpArcTanH));
                 break;
+            case ocBitAnd:
+                mvSubArguments.push_back(SoPHelper(ts,
+                    ft->Children[i], new OpBitAnd));
+                break;
             case ocExternal:
                 if ( !(pChild->GetExternal().compareTo(OUString(
                     "com.sun.star.sheet.addin.Analysis.getEffect"))))
diff --git a/sc/source/core/opencl/op_math.cxx b/sc/source/core/opencl/op_math.cxx
index 2aa4b08..9b8b179 100644
--- a/sc/source/core/opencl/op_math.cxx
+++ b/sc/source/core/opencl/op_math.cxx
@@ -568,6 +568,45 @@ void OpArcTanH::GenSlidingWindowFunction(std::stringstream &ss,
     ss << "    return atanh(tmp);\n";
     ss << "}";
 }
+void OpBitAnd::GenSlidingWindowFunction(std::stringstream &ss,
+    const std::string sSymName, SubArguments &vSubArguments)
+{
+    ss << "\ndouble " << sSymName;
+    ss << "_"<< BinFuncName() <<"(";
+    for (unsigned i = 0; i < vSubArguments.size(); i++)
+    {
+        if (i) ss << ",";
+        vSubArguments[i]->GenSlidingWindowDecl(ss);
+    }
+    ss << ") {\n";
+    ss << "    int gid0 = get_global_id(0);\n";
+    ss << "    double num1 = " << GetBottom() << ";\n";
+    ss << "    double num2 = " << GetBottom() << ";\n";
+#ifdef ISNAN
+    FormulaToken *iNum1 = vSubArguments[0]->GetFormulaToken();
+    const formula::SingleVectorRefToken* tmpCurDVRNum1=
+        dynamic_cast<const formula::SingleVectorRefToken *>(iNum1);
+    FormulaToken *iNum2 = vSubArguments[1]->GetFormulaToken();
+    const formula::SingleVectorRefToken* tmpCurDVRNum2=
+        dynamic_cast<const formula::SingleVectorRefToken *>(iNum2);
+    ss << "    int buffer_num1_len = "<<tmpCurDVRNum1->GetArrayLength()<<";\n";
+    ss << "    int buffer_num2_len = "<<tmpCurDVRNum2->GetArrayLength()<<";\n";
+    ss << "    if((gid0)>=buffer_num1_len || isNan(";
+    ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+    ss << "        num1 = " << GetBottom() << ";\n";
+    ss << "    else \n    ";
+#endif
+    ss << "    num1 = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef ISNAN
+    ss << "    if((gid0)>=buffer_num2_len || isNan(";
+    ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+    ss << "        num2 = " << GetBottom() << ";\n";
+    ss << "    else \n    ";
+#endif
+    ss << "    num2 = " << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+    ss << "    return (int)num1 & (int)num2;\n";
+    ss << "}";
+}
 }}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_math.hxx b/sc/source/core/opencl/op_math.hxx
index cdbafed..008d7fa 100644
--- a/sc/source/core/opencl/op_math.hxx
+++ b/sc/source/core/opencl/op_math.hxx
@@ -146,6 +146,13 @@ public:
     virtual std::string GetBottom(void) { return "0.0"; }
     virtual std::string BinFuncName(void) const { return "ScATanH"; }
 };
+class OpBitAnd:public Normal{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+        const std::string sSymName, SubArguments &vSubArguments);
+        virtual std::string GetBottom(void) { return "0.0"; }
+    virtual std::string BinFuncName(void) const { return "ScBitAnd"; }
+};
 }}
 
 #endif
commit 7e4bbdd944810b0a095d5797b37c007834fe3f37
Author: yangzhang <yangzhang at multicorewareinc.com>
Date:   Thu Nov 7 13:25:57 2013 +0800

    GPU Calc: unit test cases for ATANH
    
    Need open macro NO_FALLBACK_TO_SWINTERP in formulagroupcl.cxx for test
    
    AMLOEXT-145 BUG
    
    Change-Id: I4f4da7dc73836c4c28a81eb8bcc43e471adc40ac
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/qa/unit/data/ods/opencl/math/ArcTanHyp.ods b/sc/qa/unit/data/ods/opencl/math/ArcTanHyp.ods
new file mode 100644
index 0000000..5045027
Binary files /dev/null and b/sc/qa/unit/data/ods/opencl/math/ArcTanHyp.ods differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index 9e73d73..bf14e11 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -171,6 +171,7 @@ public:
     void testMathFormulaArcSin();
     void testMathFormulaArcSinHyp();
     void testMathFormulaArcTan();
+    void testMathFormulaArcTanHyp();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -273,6 +274,7 @@ public:
     CPPUNIT_TEST(testMathFormulaArcSin);
     CPPUNIT_TEST(testMathFormulaArcSinHyp);
     CPPUNIT_TEST(testMathFormulaArcTan);
+    CPPUNIT_TEST(testMathFormulaArcTanHyp);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2937,6 +2939,31 @@ void ScOpenclTest::testMathFormulaArcTan()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-145]
+void ScOpenclTest::testMathFormulaArcTanHyp()
+{
+    if (!detectOpenCLDevice())
+        return;
+    ScDocShellRef xDocSh =
+        loadDoc("opencl/math/ArcTanHyp.", ODS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+    ScDocShellRef xDocShRes =
+        loadDoc("opencl/math/ArcTanHyp.", ODS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Verify ATanH Function
+    for (SCROW i = 1; i <= 1000; ++i)
+    {
+        double fLibre = pDoc->GetValue(ScAddress(1,i,0));
+        double fExcel = pDocRes->GetValue(ScAddress(1,i,0));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
+    }
+    xDocSh->DoClose();
+    xDocShRes->DoClose();
+}
 ScOpenclTest::ScOpenclTest()
       : ScBootstrapFixture( "/sc/qa/unit/data" )
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index af67716..1ab1b58 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1405,6 +1405,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocArcSin:
             case ocArcSinHyp:
             case ocArcTan:
+            case ocArcTanHyp:
             // Don't change the state.
             break;
             default:
commit 308f73a1f018ab79b2f8a0fa5a66777c9244adbb
Author: yangzhang <yangzhang at multicorewareinc.com>
Date:   Thu Nov 7 13:36:45 2013 +0800

    GPU Calc: implemented for ATANH
    
    AMLOEXT-145 FIX
    
    Change-Id: I5bc9f5d6e94df018725691ed365db332a067cc43
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index 07499ad..02ef787 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1172,6 +1172,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                     ft->Children[i], new OpArcTan));
                 break;
+            case ocArcTanHyp:
+                mvSubArguments.push_back(SoPHelper(ts,
+                    ft->Children[i], new OpArcTanH));
+                break;
             case ocExternal:
                 if ( !(pChild->GetExternal().compareTo(OUString(
                     "com.sun.star.sheet.addin.Analysis.getEffect"))))
diff --git a/sc/source/core/opencl/op_math.cxx b/sc/source/core/opencl/op_math.cxx
index 54114e7..2aa4b08 100644
--- a/sc/source/core/opencl/op_math.cxx
+++ b/sc/source/core/opencl/op_math.cxx
@@ -541,6 +541,33 @@ void OpArcTan::GenSlidingWindowFunction(std::stringstream &ss,
     ss << "    return atan(tmp);\n";
     ss << "}";
 }
+void OpArcTanH::GenSlidingWindowFunction(std::stringstream &ss,
+    const std::string sSymName, SubArguments &vSubArguments)
+{
+    ss << "\ndouble " << sSymName;
+    ss << "_"<< BinFuncName() <<"(";
+    for (unsigned i = 0; i < vSubArguments.size(); i++)
+    {
+        if (i) ss << ",";
+        vSubArguments[i]->GenSlidingWindowDecl(ss);
+    }
+    ss << ") {\n";
+    ss << "    int gid0 = get_global_id(0);\n";
+    ss << "    double tmp = " << GetBottom() << ";\n";
+#ifdef ISNAN
+    FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+    const formula::SingleVectorRefToken*tmpCurDVR0=
+        dynamic_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+    ss << "    int buffer_len = " << tmpCurDVR0->GetArrayLength() << ";\n";
+    ss << "    if((gid0)>=buffer_len || isNan(";
+    ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+    ss << "        tmp = " << GetBottom() << ";\n";
+    ss << "    else \n    ";
+#endif
+    ss << "    tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+    ss << "    return atanh(tmp);\n";
+    ss << "}";
+}
 }}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_math.hxx b/sc/source/core/opencl/op_math.hxx
index edbab10..cdbafed 100644
--- a/sc/source/core/opencl/op_math.hxx
+++ b/sc/source/core/opencl/op_math.hxx
@@ -139,6 +139,13 @@ public:
     virtual std::string GetBottom(void) { return "0.0"; }
     virtual std::string BinFuncName(void) const { return "ScATan"; }
 };
+class OpArcTanH:public Normal{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+        const std::string sSymName, SubArguments &vSubArguments);
+    virtual std::string GetBottom(void) { return "0.0"; }
+    virtual std::string BinFuncName(void) const { return "ScATanH"; }
+};
 }}
 
 #endif
commit de08508db3d7785aa72be55268514708497fc7d3
Author: yangzhang <yangzhang at multicorewareinc.com>
Date:   Thu Nov 7 12:47:03 2013 +0800

    GPU Calc: unit test cases for ATAN
    
    Need open macro NO_FALLBACK_TO_SWINTERP in formulagroupcl.cxx for test
    
    AMLOEXT-144 BUG
    
    Change-Id: I2e0664cdd9a557666652fcf5d77dac2d93a0aa79
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/qa/unit/data/ods/opencl/math/ArcTan.ods b/sc/qa/unit/data/ods/opencl/math/ArcTan.ods
new file mode 100644
index 0000000..70737f8
Binary files /dev/null and b/sc/qa/unit/data/ods/opencl/math/ArcTan.ods differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index 8fa9117..9e73d73 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -170,6 +170,7 @@ public:
     void testMathFormulaArcCotHyp();
     void testMathFormulaArcSin();
     void testMathFormulaArcSinHyp();
+    void testMathFormulaArcTan();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -271,6 +272,7 @@ public:
     CPPUNIT_TEST(testMathFormulaArcCotHyp);
     CPPUNIT_TEST(testMathFormulaArcSin);
     CPPUNIT_TEST(testMathFormulaArcSinHyp);
+    CPPUNIT_TEST(testMathFormulaArcTan);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2910,6 +2912,31 @@ void ScOpenclTest::testMathFormulaArcSinHyp()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-144]
+void ScOpenclTest::testMathFormulaArcTan()
+{
+    if (!detectOpenCLDevice())
+        return;
+    ScDocShellRef xDocSh =
+        loadDoc("opencl/math/ArcTan.", ODS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+    ScDocShellRef xDocShRes =
+        loadDoc("opencl/math/ArcTan.", ODS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Verify ATan Function
+    for (SCROW i = 1; i <= 1000; ++i)
+    {
+        double fLibre = pDoc->GetValue(ScAddress(1,i,0));
+        double fExcel = pDocRes->GetValue(ScAddress(1,i,0));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
+    }
+    xDocSh->DoClose();
+    xDocShRes->DoClose();
+}
 ScOpenclTest::ScOpenclTest()
       : ScBootstrapFixture( "/sc/qa/unit/data" )
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 9265db0..af67716 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1404,6 +1404,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocArcCotHyp:
             case ocArcSin:
             case ocArcSinHyp:
+            case ocArcTan:
             // Don't change the state.
             break;
             default:
commit 44b2e2f6b6d2f11829b0d98de7606ee01ec17cac
Author: yangzhang <yangzhang at multicorewareinc.com>
Date:   Thu Nov 7 13:01:31 2013 +0800

    GPU Calc: implemented ATAN
    
    AMLOEXT-144 FIX
    
    Change-Id: Ib94a4fbdcdf928c9a943d5b57449e7335d82b016
    Refactoring: fix compile warnning in op_statistical.cxx
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index 595b733..07499ad 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1168,6 +1168,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                     ft->Children[i], new OpArcSinHyp));
                 break;
+            case ocArcTan:
+                mvSubArguments.push_back(SoPHelper(ts,
+                    ft->Children[i], new OpArcTan));
+                break;
             case ocExternal:
                 if ( !(pChild->GetExternal().compareTo(OUString(
                     "com.sun.star.sheet.addin.Analysis.getEffect"))))
diff --git a/sc/source/core/opencl/op_math.cxx b/sc/source/core/opencl/op_math.cxx
index 43c6591..54114e7 100644
--- a/sc/source/core/opencl/op_math.cxx
+++ b/sc/source/core/opencl/op_math.cxx
@@ -514,6 +514,33 @@ void OpArcSinHyp::GenSlidingWindowFunction(std::stringstream &ss,
     ss << "    return asinh(tmp);\n";
     ss << "}";
 }
+void OpArcTan::GenSlidingWindowFunction(std::stringstream &ss,
+    const std::string sSymName, SubArguments &vSubArguments)
+{
+    ss << "\ndouble " << sSymName;
+    ss << "_"<< BinFuncName() <<"(";
+    for (unsigned i = 0; i < vSubArguments.size(); i++)
+    {
+        if (i) ss << ",";
+        vSubArguments[i]->GenSlidingWindowDecl(ss);
+    }
+    ss << ") {\n";
+    ss << "    int gid0 = get_global_id(0);\n";
+    ss << "    double tmp = " << GetBottom() << ";\n";
+#ifdef ISNAN
+    FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+    const formula::SingleVectorRefToken*tmpCurDVR0=
+        dynamic_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+    ss << "    int buffer_len = " << tmpCurDVR0->GetArrayLength() << ";\n";
+    ss << "    if((gid0)>=buffer_len || isNan(";
+    ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+    ss << "        tmp = " << GetBottom() << ";\n";
+    ss << "    else\n    ";
+#endif
+    ss << "    tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+    ss << "    return atan(tmp);\n";
+    ss << "}";
+}
 }}
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_math.hxx b/sc/source/core/opencl/op_math.hxx
index 9178415..edbab10 100644
--- a/sc/source/core/opencl/op_math.hxx
+++ b/sc/source/core/opencl/op_math.hxx
@@ -132,6 +132,13 @@ public:
     virtual std::string GetBottom(void) { return "0.0"; }
     virtual std::string BinFuncName(void) const { return "ScASinH"; }
 };
+class OpArcTan:public Normal{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+        const std::string sSymName, SubArguments &vSubArguments);
+    virtual std::string GetBottom(void) { return "0.0"; }
+    virtual std::string BinFuncName(void) const { return "ScATan"; }
+};
 }}
 
 #endif
diff --git a/sc/source/core/opencl/op_statistical.cxx b/sc/source/core/opencl/op_statistical.cxx
index 6bc1f21..5cf6854 100644
--- a/sc/source/core/opencl/op_statistical.cxx
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -939,6 +939,7 @@ void OpCritBinom::BinInlineFun(std::set<std::string>& decls,
     std::set<std::string>& funs)
 {
     decls.insert(MinDecl);
+    funs.insert("");
 }
 
 void OpCritBinom::GenSlidingWindowFunction(std::stringstream& ss,
commit 84901d03c44da80ece47758e8af44178037d2aca
Author: yangzhang <yangzhang at multicorewareinc.com>
Date:   Thu Nov 7 11:52:20 2013 +0800

    GPU Calc: unit test cases for ASINH
    
    Need open macro NO_FALLBACK_TO_SWINTERP in formulagroupcl.cxx for test
    
    AMLOEXT-143 BUG
    
    Change-Id: Ib5b0d65d0dc88e5ea45679f9aba3ce4f55944daf
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/qa/unit/data/ods/opencl/math/ArcSinHyp.ods b/sc/qa/unit/data/ods/opencl/math/ArcSinHyp.ods
new file mode 100644
index 0000000..0d0525a
Binary files /dev/null and b/sc/qa/unit/data/ods/opencl/math/ArcSinHyp.ods differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index 50f41f1..8fa9117 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -169,6 +169,7 @@ public:
     void testStatisticalFormulaCritBinom();
     void testMathFormulaArcCotHyp();
     void testMathFormulaArcSin();
+    void testMathFormulaArcSinHyp();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -269,6 +270,7 @@ public:
     CPPUNIT_TEST(testStatisticalFormulaCritBinom);
     CPPUNIT_TEST(testMathFormulaArcCotHyp);
     CPPUNIT_TEST(testMathFormulaArcSin);
+    CPPUNIT_TEST(testMathFormulaArcSinHyp);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -2883,6 +2885,31 @@ void ScOpenclTest::testStatisticalFormulaCritBinom()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-143]
+void ScOpenclTest::testMathFormulaArcSinHyp()
+{
+    if (!detectOpenCLDevice())
+        return;
+    ScDocShellRef xDocSh =
+        loadDoc("opencl/math/ArcSinHyp.", ODS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+    ScDocShellRef xDocShRes =
+        loadDoc("opencl/math/ArcSinHyp.", ODS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Verify ASinH Function
+    for (SCROW i = 1; i <= 1000; ++i)
+    {
+        double fLibre = pDoc->GetValue(ScAddress(1,i,0));
+        double fExcel = pDocRes->GetValue(ScAddress(1,i,0));
+        CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel));
+    }
+    xDocSh->DoClose();
+    xDocShRes->DoClose();
+}
 ScOpenclTest::ScOpenclTest()
       : ScBootstrapFixture( "/sc/qa/unit/data" )
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 56f9433..9265db0 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1403,6 +1403,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocKritBinom:
             case ocArcCotHyp:
             case ocArcSin:
+            case ocArcSinHyp:
             // Don't change the state.
             break;
             default:
commit 8a8c128a9ee711f701c7caa750f491324e64fe54
Author: yangzhang <yangzhang at multicorewareinc.com>
Date:   Thu Nov 7 12:29:20 2013 +0800

    GPU Calc: implemented ASINH
    
    AMLOEXT-143 FIX
    
    Change-Id: Ib6d408a18881252271718715de4fdbb9e6068c06
    Signed-off-by: haochen <haochen at multicorewareinc.com>
    Signed-off-by: I-Jui (Ray) Sung <ray at multicorewareinc.com>

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index a2f4906..595b733 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1164,6 +1164,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                         ft->Children[i], new OpArcSin));
                 break;
+            case ocArcSinHyp:
+                mvSubArguments.push_back(SoPHelper(ts,
+                    ft->Children[i], new OpArcSinHyp));
+                break;
             case ocExternal:
                 if ( !(pChild->GetExternal().compareTo(OUString(
                     "com.sun.star.sheet.addin.Analysis.getEffect"))))
diff --git a/sc/source/core/opencl/op_math.cxx b/sc/source/core/opencl/op_math.cxx
index a532284..43c6591 100644
--- a/sc/source/core/opencl/op_math.cxx
+++ b/sc/source/core/opencl/op_math.cxx
@@ -487,6 +487,33 @@ void OpArcSin::GenSlidingWindowFunction(std::stringstream &ss,
     ss << "    return asin(tmp);\n";
     ss << "}";
 }
+void OpArcSinHyp::GenSlidingWindowFunction(std::stringstream &ss,
+    const std::string sSymName, SubArguments &vSubArguments)
+{
+    ss << "\ndouble " << sSymName;
+    ss << "_"<< BinFuncName() <<"(";
+    for (unsigned i = 0; i < vSubArguments.size(); i++)
+    {
+        if (i) ss << ",";
+        vSubArguments[i]->GenSlidingWindowDecl(ss);
+    }
+    ss << ") {\n";
+    ss << "    int gid0   = get_global_id(0);\n";
+    ss << "    double tmp = " << GetBottom() << ";\n";
+#ifdef ISNAN
+    FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+    const formula::SingleVectorRefToken*tmpCurDVR0=
+        dynamic_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+    ss << "    int buffer_len = " << tmpCurDVR0->GetArrayLength() << ";\n";
+    ss << "    if((gid0)>=buffer_len || isNan(";
+    ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+    ss << "        tmp = " << GetBottom() << ";\n";
+    ss << "    else \n    ";

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list