[Libreoffice-commits] core.git: Branch 'feature/calc-group-interpreter-4' - 13 commits - sc/qa sc/source

yiming ju yiming at multicorewareinc.com
Sat Nov 16 21:36:59 PST 2013


 sc/qa/unit/data/xls/opencl/array/SUMXMY2.xls      |binary
 sc/qa/unit/data/xls/opencl/statistical/Covar.xls  |binary
 sc/qa/unit/data/xls/opencl/statistical/StDevP.xls |binary
 sc/qa/unit/data/xls/opencl/statistical/TDist.xls  |binary
 sc/qa/unit/data/xls/opencl/statistical/TInv.xls   |binary
 sc/qa/unit/data/xls/opencl/statistical/TTest.xls  |binary
 sc/qa/unit/opencl-test.cxx                        |  165 +
 sc/source/core/opencl/formulagroupcl.cxx          |   30 
 sc/source/core/opencl/op_array.cxx                |   56 
 sc/source/core/opencl/op_array.hxx                |    7 
 sc/source/core/opencl/op_statistical.cxx          | 2037 +++++++++++++++++-----
 sc/source/core/opencl/op_statistical.hxx          |   40 
 sc/source/core/opencl/opinlinefun_statistical.cxx |   12 
 sc/source/core/tool/token.cxx                     |    6 
 14 files changed, 1929 insertions(+), 424 deletions(-)

New commits:
commit 15e3157b7c44c7ea795d4da8b7eea800c0b7b920
Author: yiming ju <yiming at multicorewareinc.com>
Date:   Sun Nov 17 12:04:32 2013 +0800

    GPU Calc: unit test cases for COVAR
    
    Turn  NO_FALLBACK_TO_SWINTERP on in  formulagroupcl.cxx for test
    
    AMLOEXT-86 BUG
    
    Change-Id: Ie35b4fe1efcdd21e8488ce560c30bd3fca6aa30c
    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/Covar.xls b/sc/qa/unit/data/xls/opencl/statistical/Covar.xls
new file mode 100644
index 0000000..fc559b0
Binary files /dev/null and b/sc/qa/unit/data/xls/opencl/statistical/Covar.xls differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index 01ec9a5..c81b50d 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -240,6 +240,7 @@ public:
     void testStatisticalFormulaTInv();
     void testArrayFormulaSumXMY2();
     void testStatisticalFormulaStDevP();
+    void testStatisticalFormulaCovar();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -409,6 +410,7 @@ public:
     CPPUNIT_TEST(testStatisticalFormulaTInv);
     CPPUNIT_TEST(testArrayFormulaSumXMY2);
     CPPUNIT_TEST(testStatisticalFormulaStDevP);
+    CPPUNIT_TEST(testStatisticalFormulaCovar);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -1953,6 +1955,31 @@ void ScOpenclTest::testMathFormulaCosh()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+void ScOpenclTest::testStatisticalFormulaCovar()
+{
+    if (!detectOpenCLDevice())
+        return;
+
+    ScDocShellRef xDocSh = loadDoc("opencl/statistical/Covar.", XLS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+
+    ScDocShellRef xDocShRes = loadDoc("opencl/statistical/Covar.", XLS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Check the results of formula cells in the shared formula range.
+    for (SCROW i = 0; i <= 16; ++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();
+}
+
 //[AMLOEXT-87]
 void ScOpenclTest::testStatisticalFormulaKurt()
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 56df308..28c0721 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1468,6 +1468,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocTInv:
             case ocSumXMY2:
             case ocStDevP:
+            case ocCovar:
             // Don't change the state.
             break;
             default:
commit 0dc8ccd0fce9deaa7aba9dd5ca5b0fb9a5ac500a
Author: yiming ju <yiming at multicorewareinc.com>
Date:   Sun Nov 17 12:23:39 2013 +0800

    GPU Calc: implemented COVAR
    
    AMLOEXT-86 FIX
    
    Change-Id: I2900d2b8d95412faf7c1b1591a2533327b95a1c2
    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 d76003d..d08c35a 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1788,6 +1788,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                          ft->Children[i], new OpStDevP));
                  break;
+            case ocCovar:
+                mvSubArguments.push_back(SoPHelper(ts,
+                         ft->Children[i], new OpCovar));
+                 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 017cb59..20cb150 100644
--- a/sc/source/core/opencl/op_statistical.cxx
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -7010,6 +7010,269 @@ void OpPoisson::GenSlidingWindowFunction(
     ss << "     }\n";
     ss << "}\n";
 }
+void OpCovar::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 vSum = 0.0;\n";
+        ss << "    double vSum0 = 0.0;\n";
+        ss << "    double vSum1 = 0.0;\n";
+        ss << "    double vMean0 = 0.0;\n";
+        ss << "    double vMean1 = 0.0;\n";
+        ss << "    double arg0 = 0.0;\n";
+        ss << "    double arg1 = 0.0;\n";
+        FormulaToken* pCurX = vSubArguments[0]->GetFormulaToken();
+        FormulaToken* pCurY = vSubArguments[1]->GetFormulaToken();
+        if ((pCurX->GetType() == formula::svDoubleVectorRef)&&
+            (pCurY->GetType() == formula::svDoubleVectorRef)){
+        ss << "    int cnt = 0;\n";
+        const formula::DoubleVectorRefToken* pCurDVRX =
+            dynamic_cast<const formula::DoubleVectorRefToken* >(pCurX);
+        const formula::DoubleVectorRefToken* pCurDVRY =
+            dynamic_cast<const formula::DoubleVectorRefToken* >(pCurY);
+        size_t nCurWindowSizeX = pCurDVRX->GetRefRowSize();
+        size_t nCurWindowSizeY = pCurDVRY->GetRefRowSize();
+        if(nCurWindowSizeX == nCurWindowSizeY)
+        {
+            ss << "    for(int i = ";
+            if (!pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+                ss << "gid0; i < " << nCurWindowSizeX << "; i++) {\n";
+                ss << "        arg0 = ";
+                ss << vSubArguments[0]->GenSlidingWindowDeclRef()<< ";\n";
+                ss << "        arg1 = ";
+                ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef ISNAN
+                ss << "        if(isNan(arg0) || isNan(arg1) || (i >= ";
+                ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+                ss << pCurDVRY->GetArrayLength() << ")) {\n";
+                ss << "            arg0 = 0.0;\n";
+                ss << "            arg1 = 0.0;\n";
+                ss << "            --cnt;\n";
+                ss << "        }\n";
+#endif
+                ss << "        ++cnt;\n";
+                ss << "        vSum0 += arg0;\n";
+                ss << "        vSum1 += arg1;\n";
+                ss << "    }\n";
+            }
+            else if (pCurDVRX->IsStartFixed() && !pCurDVRX->IsEndFixed()) {
+                ss << "0; i < gid0 + " << nCurWindowSizeX << "; i++) {\n";
+                ss << "        arg0 = ";
+                ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "        arg1 = ";
+                ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef ISNAN
+                ss << "        if(isNan(arg0) || isNan(arg1) || (i >= ";
+                ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+                ss << pCurDVRY->GetArrayLength() << ")) {\n";
+                ss << "            arg0 = 0.0;\n";
+                ss << "            arg1 = 0.0;\n";
+                ss << "            --cnt;\n";
+                ss << "        }\n";
+#endif
+                ss << "        ++cnt;\n";
+                ss << "        vSum0 += arg0;\n";
+                ss << "        vSum1 += arg1;\n";
+                ss << "    }\n";
+            }
+            else if (pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+                ss << "0; i < " << nCurWindowSizeX << "; i++) {\n";
+                ss << "        arg0 = ";
+                ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "        arg1 = ";
+                ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef ISNAN
+                ss << "        if(isNan(arg0) || isNan(arg1) || (i >= ";
+                ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+                ss << pCurDVRY->GetArrayLength() << ")) {\n";
+                ss << "            arg0 = 0.0;\n";
+                ss << "            arg1 = 0.0;\n";
+                ss << "            --cnt;\n";
+                ss << "        }\n";
+#endif
+                ss << "        ++cnt;\n";
+                ss << "        vSum0 += arg0;\n";
+                ss << "        vSum1 += arg1;\n";
+                ss << "    }\n";
+            }
+            else {
+                ss << "0; i < " << nCurWindowSizeX << "; i++) {\n";
+                ss << "        arg0 = ";
+                ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "        arg1 = ";
+                ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef ISNAN
+                ss << "        if(isNan(arg0) || isNan(arg1) || (i + gid0 >= ";
+                ss << pCurDVRX->GetArrayLength() << ") || (i + gid0 >=";
+                ss << pCurDVRY->GetArrayLength() << ")) {\n";
+                ss << "            arg0 = 0.0;\n";
+                ss << "            arg1 = 0.0;\n";
+                ss << "            --cnt;\n";
+                ss << "        }\n";
+#endif
+                ss << "        ++cnt;\n";
+                ss << "        vSum0 += arg0;\n";
+                ss << "        vSum1 += arg1;\n";
+                ss << "    }\n";
+            }
+            ss << "    if(cnt < 1) {\n";
+            ss << "        return -DBL_MAX;\n";
+            ss << "    }\n";
+            ss << "    else {\n";
+            ss << "        vMean0 = vSum0 / cnt;\n";
+            ss << "        vMean1 = vSum1 / cnt;\n";
+            ss << "    for(int i = ";
+            if (!pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+                ss << "gid0; i < " << nCurWindowSizeX << "; i++) {\n";
+                ss << "arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef()
+                    << ";\n";
+                ss << "arg1 = " << vSubArguments[1]->GenSlidingWindowDeclRef()
+                    << ";\n";
+#ifdef ISNAN
+                ss << "        if(isNan(arg0) || isNan(arg1) || (i >= ";
+                ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+                ss << pCurDVRY->GetArrayLength() << ")) {\n";
+                ss << "            arg0 = vMean0;\n";
+                ss << "            arg1 = vMean1;\n";
+                ss << "        }\n";
+#endif
+                ss << "        vSum += (arg0 - vMean0) * (arg1 - vMean1);\n";
+                ss << "    }\n";
+            } else if (pCurDVRX->IsStartFixed() && !pCurDVRX->IsEndFixed()) {
+                ss << "0; i < gid0 + " << nCurWindowSizeX << "; i++) {\n";
+                ss << "        arg0 = ";
+                ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "        arg1 = ";
+                ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef ISNAN
+                ss << "        if(isNan(arg0) || isNan(arg1) || (i >= ";
+                ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+                ss << pCurDVRY->GetArrayLength() << ")) {\n";
+                ss << "            arg0 = vMean0;\n";
+                ss << "            arg1 = vMean1;\n";
+                ss << "        }\n";
+#endif
+                ss << "        vSum += (arg0 - vMean0) * (arg1 - vMean1);\n";
+                ss << "    }\n";
+            } else if (pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+                ss << "0; i < " << nCurWindowSizeX << "; i++) {\n";
+                ss << "        arg0 = ";
+                ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "        arg1 = ";
+                ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef ISNAN
+                ss << "        if(isNan(arg0) || isNan(arg1) || (i >= ";
+                ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+                ss << pCurDVRY->GetArrayLength() << ")) {\n";
+                ss << "            arg0 = vMean0;\n";
+                ss << "            arg1 = vMean1;\n";
+                ss << "        }\n";
+#endif
+                ss << "        vSum += (arg0 - vMean0) * (arg1 - vMean1);\n";
+                ss << "    }\n";
+            } else {
+                ss << "0; i < " << nCurWindowSizeX << "; i++) {\n";
+                ss << "        arg0 = ";
+                ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "        arg1 = ";
+                ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef ISNAN
+                ss << "        if(isNan(arg0) || isNan(arg1) || (i + gid0 >= ";
+                ss << pCurDVRX->GetArrayLength() << ") || (i + gid0 >= ";
+                ss << pCurDVRY->GetArrayLength() << ")) {\n";
+                ss << "            arg0 = vMean0;\n";
+                ss << "            arg1 = vMean1;\n";
+                ss << "        }\n";
+#endif
+                ss << "        vSum += (arg0 - vMean0) * (arg1 - vMean1);\n";
+                ss << "    }\n";
+            }
+            ss << "    return vSum / cnt;\n";
+            ss << "    }\n";
+            ss << "}";
+        }
+        }
+        else {
+        ss << "    int cnt0 = 0,cnt1 = 0;\n";
+        for (unsigned i = 0; i < vSubArguments.size(); i++)
+        {
+            FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+            if (pCur->GetType() == formula::svSingleVectorRef){
+#ifdef  ISNAN
+                const formula::SingleVectorRefToken* pTVR =
+                dynamic_cast< const formula::SingleVectorRefToken* >(pCur);
+                ss << "    if(isNan(";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+                ss << ") || gid0 >= " << pTVR->GetArrayLength() << ")\n";
+                ss << "        arg" << i << " = 0;\n    else\n";
+#endif
+                ss << "        arg" << i << " = ";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "    cnt" << i << "++;\n";
+                ss << "    vSum" << i << " += arg" << i << ";\n";
+            }
+            else if (pCur->GetType() == formula::svDouble){
+#ifdef  ISNAN
+                ss << "    if(isNan ( ";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << "))\n";
+                ss << "        arg" << i << " = 0;\n    else\n";
+#endif
+                ss << "        arg" << i << " = ";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "    cnt" << i << "++;\n";
+                ss << "    vSum" << i << " += arg" << i << ";\n";
+            }
+            else {
+                ss << "    arg" << i << " = ";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "    cnt" << i << "++;\n";
+                ss << "    vSum" << i << " += arg" << i << ";\n";
+            }
+        }
+        ss << "        vMean0 = vSum0 / cnt0;\n";
+        ss << "        vMean1 = vSum0 / cnt1;\n";
+        for(unsigned i = 0; i < vSubArguments.size(); i++ ) {
+            FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+            if (pCur->GetType() == formula::svSingleVectorRef) {
+#ifdef  ISNAN
+                const formula::SingleVectorRefToken* pTVR =
+                dynamic_cast< const formula::SingleVectorRefToken* >(pCur);
+                ss << "    if(isNan(";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+                ss << ") || gid0 >= " << pTVR->GetArrayLength() << ")\n";
+                ss << "        arg" << i << " = vMean" << i << ";\n";
+                ss << "    else\n";
+#endif
+                ss << "        arg" << i << " = ";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+            }
+            else if (pCur->GetType() == formula::svDouble) {
+                ss << "    arg" << i << " = ";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef  ISNAN
+                ss << "    if(isNan(arg" << i << "))\n";
+                ss << "        arg" << i << " = vMean" << i << ";\n";
+#endif
+            }
+            else {
+                ss << "    arg" << i << " = ";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+            }
+        }
+        ss << "        vSum += (arg0 - vMean0) * ( arg1 - vMean1 );\n";
+        ss << "    return vSum / cnt0;\n";
+        ss << "}";
+        }
+}
 void OpBetaDist::GenSlidingWindowFunction(std::stringstream &ss,
             const std::string sSymName, SubArguments &vSubArguments)
 {
diff --git a/sc/source/core/opencl/op_statistical.hxx b/sc/source/core/opencl/op_statistical.hxx
index b836609..06929f4 100644
--- a/sc/source/core/opencl/op_statistical.hxx
+++ b/sc/source/core/opencl/op_statistical.hxx
@@ -261,6 +261,14 @@ public:
             const std::string sSymName, SubArguments &vSubArguments);
     virtual std::string BinFuncName(void) const { return "Kurt"; }
 };
+class OpCovar: public Normal
+{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream& ss,
+            const std::string sSymName, SubArguments& vSubArguments);
+    virtual std::string BinFuncName(void) const { return "Covar"; }
+};
+
 class OpVariationen:public Normal{
     public:
     virtual void GenSlidingWindowFunction(std::stringstream &ss,
commit 838e167a58cee6230b653f8f87a9f3b34089527f
Author: shiming zhang <shiming at multicorewareinc.com>
Date:   Sun Nov 17 11:34:17 2013 +0800

    GPU Calc: unit test cases for STDEVP
    
    Turn  NO_FALLBACK_TO_SWINTERP on in  formulagroupcl.cxx for test
    
    AMLOEXT-185 BUG
    
    Change-Id: Icfbc7ff33f9d6fb702353250d29c5166513ff960
    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/StDevP.xls b/sc/qa/unit/data/xls/opencl/statistical/StDevP.xls
new file mode 100644
index 0000000..fff92fc
Binary files /dev/null and b/sc/qa/unit/data/xls/opencl/statistical/StDevP.xls differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index e9446e2..01ec9a5 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -239,6 +239,7 @@ public:
     void testStatisticalFormulaTDist();
     void testStatisticalFormulaTInv();
     void testArrayFormulaSumXMY2();
+    void testStatisticalFormulaStDevP();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -407,6 +408,7 @@ public:
     CPPUNIT_TEST(testStatisticalFormulaTDist);
     CPPUNIT_TEST(testStatisticalFormulaTInv);
     CPPUNIT_TEST(testArrayFormulaSumXMY2);
+    CPPUNIT_TEST(testStatisticalFormulaStDevP);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -4312,6 +4314,31 @@ void ScOpenclTest::testStatisticalFormulaStDev()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-185]
+void ScOpenclTest::testStatisticalFormulaStDevP()
+{
+    if (!detectOpenCLDevice())
+        return;
+
+    ScDocShellRef xDocSh = loadDoc("opencl/statistical/StDevP.", XLS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+
+    ScDocShellRef xDocShRes = loadDoc("opencl/statistical/StDevP.", XLS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Check the results of formula cells in the shared formula range.
+    for (SCROW i = 1; i <= 20; ++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-186]
 void ScOpenclTest::testStatisticalFormulaSlope()
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 44aa263..56df308 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1467,6 +1467,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocTDist:
             case ocTInv:
             case ocSumXMY2:
+            case ocStDevP:
             // Don't change the state.
             break;
             default:
commit 978c5ea0992cfb7d75e7911c127b40319220e5a6
Author: shiming zhang <shiming at multicorewareinc.com>
Date:   Sun Nov 17 11:42:53 2013 +0800

    GPU Calc: implemented STDEVP
    
    AMLOEXT-185 FIX
    
    Change-Id: I09eb45e19db9947a720e72312d5696ecdab67ef6
    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 15de6bf..d76003d 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1784,6 +1784,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                          ft->Children[i],new OpSumXMY2));
                  break;
+            case ocStDevP:
+                mvSubArguments.push_back(SoPHelper(ts,
+                         ft->Children[i], new OpStDevP));
+                 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 a09276c..017cb59 100644
--- a/sc/source/core/opencl/op_statistical.cxx
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -2822,6 +2822,238 @@ void OpStDev::GenSlidingWindowFunction(std::stringstream &ss,
     ss << "        return sqrt(vSum / (fCount - 1.0));\n";
     ss << "}\n";
 }
+void OpStDevP::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 fSum = 0.0;\n";
+    ss << "    double fMean = 0.0;\n";
+    ss << "    double vSum = 0.0;\n";
+    ss << "    double fCount = 0.0;\n";
+    ss << "    double arg = 0.0;\n";
+    unsigned i = vSubArguments.size();
+    while (i--)
+    {
+        FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+        assert(pCur);
+        if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
+        {
+            if (pCur->GetType() == formula::svDoubleVectorRef)
+            {
+                const formula::DoubleVectorRefToken* pDVR =
+                    dynamic_cast<const formula::DoubleVectorRefToken *>(pCur);
+                size_t nCurWindowSize = pDVR->GetRefRowSize();
+                ss << "    for (int i = ";
+                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
+                {
+#ifdef  ISNAN
+                    ss << "gid0; i < " << pDVR->GetArrayLength();
+                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
+                    ss << "    {\n";
+#else
+                    ss << "gid0; i < "<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#endif
+                }
+                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+                {
+#ifdef  ISNAN
+                    ss << "0; i < " << pDVR->GetArrayLength();
+                    ss << " && i < gid0+"<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#else
+                    ss << "0; i < gid0+"<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#endif
+                }
+                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+                {
+#ifdef  ISNAN
+                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
+                    ss << " &&  i < "<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#else
+                    ss << "0; i < "<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#endif
+                }
+                else
+                {
+#ifdef  ISNAN
+                    ss << "0; i < "<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#else
+                    ss << "0; i < "<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#endif
+                }
+
+                ss << "        arg = ";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef  ISNAN
+                ss << "        if (isNan(arg))\n";
+                ss << "            continue;\n";
+#endif
+                ss << "        fSum += arg;\n";
+                ss << "        fCount += 1;\n";
+                ss << "    }\n";
+            }
+            else if (pCur->GetType() == formula::svSingleVectorRef)
+            {
+                const formula::SingleVectorRefToken* pSVR =
+                    dynamic_cast< const formula::SingleVectorRefToken* >(pCur);
+                assert(pSVR);
+#ifdef  ISNAN
+                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+                ss << "    {\n";
+                ss << "        if (!isNan(";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << "))\n";
+                ss << "        {\n";
+#endif
+                ss << "            arg = ";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "            fSum += arg;\n";
+                ss << "            fCount += 1;\n";
+#ifdef ISNAN
+                ss << "        }\n";
+                ss << "    }\n";
+#endif
+            }
+            else
+            {
+                ss << "    arg = " << pCur->GetDouble() << ";\n";
+                ss << "    fSum += arg;\n";
+                ss << "    fCount += 1;\n";
+            }
+        }
+        else
+        {
+            ss << "    arg = ";
+            ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+            ss << "    fSum += arg;\n";
+            ss << "    fCount += 1;\n";
+
+        }
+        if (i == 0)
+        {
+            ss << "    fMean = fSum / " << "fCount" << ";\n";
+        }
+    }
+    i = vSubArguments.size();
+    while (i--)
+    {
+        FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+        assert(pCur);
+        if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
+        {
+            if (pCur->GetType() == formula::svDoubleVectorRef)
+            {
+                const formula::DoubleVectorRefToken* pDVR =
+                    dynamic_cast<const formula::DoubleVectorRefToken *>(pCur);
+                size_t nCurWindowSize = pDVR->GetRefRowSize();
+                ss << "    for (int i = ";
+                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
+                {
+#ifdef  ISNAN
+                    ss << "gid0; i < " << pDVR->GetArrayLength();
+                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
+                    ss << "    {\n";
+#else
+                    ss << "gid0; i < "<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#endif
+                }
+                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+                {
+#ifdef  ISNAN
+                    ss << "0; i < " << pDVR->GetArrayLength();
+                    ss << " && i < gid0+"<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#else
+                    ss << "0; i < gid0+"<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#endif
+                }
+                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+                {
+#ifdef  ISNAN
+                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
+                    ss << " &&  i < "<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#else
+                    ss << "0; i < "<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#endif
+                }
+                else
+                {
+#ifdef  ISNAN
+                    ss << "0; i < "<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#else
+                    ss << "0; i < "<< nCurWindowSize << "; i++)\n";
+                    ss << "    {\n";
+#endif
+                }
+
+                ss << "        arg = ";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef  ISNAN
+                ss << "        if (isNan(arg))\n";
+                ss << "            continue;\n";
+#endif
+                ss << "        vSum += (arg - fMean) * (arg - fMean);\n";
+                ss << "    }\n";
+            }
+            else if (pCur->GetType() == formula::svSingleVectorRef)
+            {
+                const formula::SingleVectorRefToken* pSVR =
+                    dynamic_cast< const formula::SingleVectorRefToken* >(pCur);
+                assert(pSVR);
+#ifdef  ISNAN
+                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+                ss << "    {\n";
+                ss << "        if (!isNan(";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << "))\n";
+                ss << "        {\n";
+#endif
+                ss << "            arg = ";
+                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "            vSum += (arg - fMean) * (arg - fMean);\n";
+#ifdef ISNAN
+                ss << "        }\n";
+                ss << "    }\n";
+#endif
+            }
+            else
+            {
+                ss << "    arg = " << pCur->GetDouble() << ";\n";
+                ss << "    vSum += (arg - fMean) * (arg - fMean);\n";
+            }
+        }
+        else
+        {
+            ss << "    arg = ";
+            ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+            ss << "    vSum += (arg - fMean) * (arg - fMean);\n";
+        }
+    }
+    ss << "    if (fCount == 0.0)\n";
+    ss << "        return DBL_MAX;\n";
+    ss << "    else\n";
+    ss << "        return sqrt(vSum / fCount);\n";
+    ss << "}\n";
+}
+
 void OpSlope::GenSlidingWindowFunction(std::stringstream &ss,
             const std::string sSymName, SubArguments &vSubArguments)
 {
diff --git a/sc/source/core/opencl/op_statistical.hxx b/sc/source/core/opencl/op_statistical.hxx
index b5aa6ac..b836609 100644
--- a/sc/source/core/opencl/op_statistical.hxx
+++ b/sc/source/core/opencl/op_statistical.hxx
@@ -56,6 +56,14 @@ public:
             const std::string sSymName, SubArguments &vSubArguments);
     virtual std::string BinFuncName(void) const { return "ZTest"; }
 };
+class OpStDevP: public Normal
+{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments);
+    virtual std::string BinFuncName(void) const { return "StDevP"; }
+};
+
 class OpStDev: public Normal
 {
 public:
commit a1c6df77dda374c2d6141b27f71b343f8ad52858
Author: yiming ju <yiming at multicorewareinc.com>
Date:   Sun Nov 17 11:16:38 2013 +0800

    GPU Calc: unit test cases for SUMXMY2
    
    Turn  NO_FALLBACK_TO_SWINTERP on in  formulagroupcl.cxx for test
    
    AMLOEXT-204 BUG
    
    Change-Id: Ie9c124ecf8d88915e037c0f36f8e46c4e0e97801
    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/array/SUMXMY2.xls b/sc/qa/unit/data/xls/opencl/array/SUMXMY2.xls
new file mode 100644
index 0000000..b45e2ac
Binary files /dev/null and b/sc/qa/unit/data/xls/opencl/array/SUMXMY2.xls differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index d6c3e47..e9446e2 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -238,6 +238,7 @@ public:
     void testStatisticalFormulaTTest();
     void testStatisticalFormulaTDist();
     void testStatisticalFormulaTInv();
+    void testArrayFormulaSumXMY2();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -405,6 +406,7 @@ public:
     CPPUNIT_TEST(testStatisticalFormulaTTest);
     CPPUNIT_TEST(testStatisticalFormulaTDist);
     CPPUNIT_TEST(testStatisticalFormulaTInv);
+    CPPUNIT_TEST(testArrayFormulaSumXMY2);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -4630,6 +4632,34 @@ void ScOpenclTest::testStatisticalFormulaBetainv()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[  AMLOEXT-204]
+void ScOpenclTest:: testArrayFormulaSumXMY2()
+{
+    if (!detectOpenCLDevice())
+        return;
+    ScDocShellRef xDocSh = loadDoc("opencl/array/SUMXMY2.", XLS);
+    ScDocument *pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+    ScDocShellRef xDocShRes = loadDoc("opencl/array/SUMXMY2.", XLS);
+    ScDocument *pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    for (SCROW i = 0; i <= 9; ++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));
+    }
+    for (SCROW i = 20; i <= 26; ++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 19f7983..44aa263 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1466,6 +1466,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocTTest:
             case ocTDist:
             case ocTInv:
+            case ocSumXMY2:
             // Don't change the state.
             break;
             default:
commit ddbd65f62e6281830af060ae6b37446e5a74abe4
Author: yiming ju <yiming at multicorewareinc.com>
Date:   Sun Nov 17 11:22:28 2013 +0800

    GPU Calc: implemented SUMXMY2
    
    AMLOEXT-204 FIX
    
    Change-Id: Ibb3e61322a0468f1e77fc0e7176116765b53f540
    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 cdfb597..15de6bf 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1780,6 +1780,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                          ft->Children[i], new OpTInv));
                  break;
+            case ocSumXMY2:
+                mvSubArguments.push_back(SoPHelper(ts,
+                         ft->Children[i],new OpSumXMY2));
+                 break;
             case ocExternal:
                 if ( !(pChild->GetExternal().compareTo(OUString(
                     "com.sun.star.sheet.addin.Analysis.getEffect"))))
diff --git a/sc/source/core/opencl/op_array.cxx b/sc/source/core/opencl/op_array.cxx
index e656f7b..a793996 100644
--- a/sc/source/core/opencl/op_array.cxx
+++ b/sc/source/core/opencl/op_array.cxx
@@ -135,6 +135,62 @@ void OpSumX2PY2::GenSlidingWindowFunction(std::stringstream &ss,
     ss << "    return tmp;\n";
     ss << "}";
 }
+void OpSumXMY2::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 << "    double tmp =0;\n";
+    GenTmpVariables(ss,vSubArguments);
+    if(vSubArguments[0]->GetFormulaToken()->GetType() ==
+    formula::svDoubleVectorRef)
+    {
+        FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+        const formula::DoubleVectorRefToken*pCurDVR= dynamic_cast<const
+            formula::DoubleVectorRefToken *>(tmpCur);
+        size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+        pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+        pCurDVR->GetRefRowSize() ;
+         ss << "    int i ;\n";
+         ss << "    for (i = ";
+         if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+            ss << "gid0; i < "<< nCurWindowSize <<"; i++)\n";
+         } else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) {
+            ss << "0; i < gid0+"<< nCurWindowSize <<"; i++)\n";
+         } else {
+            ss << "0; i < "<< nCurWindowSize <<"; i++)\n";
+         }
+         ss << "    {\n";
+         if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+         {
+            ss << "    int doubleIndex =i+gid0;\n";
+         }else
+         {
+            ss << "    int doubleIndex =i;\n";
+         }
+
+        CheckSubArgumentIsNan(ss,vSubArguments,0);
+        CheckSubArgumentIsNan(ss,vSubArguments,1);
+        ss << "     tmp +=pow((tmp0-tmp1),2);\n";
+        ss <<"    }\n";
+    }
+    else
+    {
+        ss << "    int singleIndex =gid0;\n";
+        CheckAllSubArgumentIsNan(ss, vSubArguments);
+        ss << "    tmp = pow((tmp0-tmp1),2);\n";
+    }
+    ss << "    return tmp;\n";
+    ss << "}";
+}
 
 }}
 
diff --git a/sc/source/core/opencl/op_array.hxx b/sc/source/core/opencl/op_array.hxx
index c0eff09..36e7723 100644
--- a/sc/source/core/opencl/op_array.hxx
+++ b/sc/source/core/opencl/op_array.hxx
@@ -30,6 +30,13 @@ public:
     virtual std::string BinFuncName(void) const { return "SumX2PY2"; }
 };
 
+class OpSumXMY2: public CheckVariables
+{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments);
+    virtual std::string BinFuncName(void) const { return "SumXMY2"; }
+};
 }}
 
 #endif
commit 044205022fae6f96a346e980ca38ffee1f1ee7a0
Author: shiming zhang <shiming at multicorewareinc.com>
Date:   Sat Nov 16 19:01:43 2013 +0800

    GPU Calc: unit test cases for TINV
    
    Turn NO_FALLBACK_TO_SWINTERP on in  formulagroupcl.cxx for test
    
    AMLOEXT-191 BUG
    
    Change-Id: Id77552084e755f100b61c7db7daaea7d79747a87
    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/TInv.xls b/sc/qa/unit/data/xls/opencl/statistical/TInv.xls
new file mode 100644
index 0000000..7aa4669
Binary files /dev/null and b/sc/qa/unit/data/xls/opencl/statistical/TInv.xls differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index f77f188..d6c3e47 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -237,6 +237,7 @@ public:
     void testStatisticalFormulaBetainv();
     void testStatisticalFormulaTTest();
     void testStatisticalFormulaTDist();
+    void testStatisticalFormulaTInv();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -403,6 +404,7 @@ public:
     CPPUNIT_TEST(testStatisticalFormulaBetainv);
     CPPUNIT_TEST(testStatisticalFormulaTTest);
     CPPUNIT_TEST(testStatisticalFormulaTDist);
+    CPPUNIT_TEST(testStatisticalFormulaTInv);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -4433,6 +4435,31 @@ void ScOpenclTest::testStatisticalFormulaTDist()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-191]
+void ScOpenclTest::testStatisticalFormulaTInv()
+{
+    if (!detectOpenCLDevice())
+        return;
+
+    ScDocShellRef xDocSh = loadDoc("opencl/statistical/TInv.", XLS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+
+    ScDocShellRef xDocShRes = loadDoc("opencl/statistical/TInv.", XLS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Check the results of formula cells in the shared formula range.
+    for (SCROW i = 1; i <= 20; ++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();
+}
 //[AMLOEXT-192]
 void ScOpenclTest::testStatisticalFormulaBinomDist()
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index efdcda3..19f7983 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1465,6 +1465,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocBetaInv:
             case ocTTest:
             case ocTDist:
+            case ocTInv:
             // Don't change the state.
             break;
             default:
commit 55e1e98ca670ed87e31b53bad2c8fa29122d6945
Author: shiming zhang <shiming at multicorewareinc.com>
Date:   Sat Nov 16 19:09:18 2013 +0800

    GPU Calc: implemented TINV
    
    AMLOEXT-191 FIX
    
    Change-Id: Ieccfbb0b79d55b6630a9dd05bf3c738c42058b53
    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 482a904..cdfb597 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1776,6 +1776,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                          ft->Children[i], new OpTDist));
                  break;
+            case ocTInv:
+                mvSubArguments.push_back(SoPHelper(ts,
+                         ft->Children[i], new OpTInv));
+                 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 a26af8b..a09276c 100644
--- a/sc/source/core/opencl/op_statistical.cxx
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -2466,6 +2466,133 @@ void OpSkewp::GenSlidingWindowFunction(std::stringstream &ss,
     ss << "    return xcube / fCount;\n";
     ss << "}\n";
 }
+void OpTInv::BinInlineFun(std::set<std::string>& decls,
+    std::set<std::string>& funs)
+{
+    decls.insert(fMachEpsDecl);
+    funs.insert("");
+    decls.insert(fMaxGammaArgumentDecl);
+    funs.insert("");
+    decls.insert(lcl_getLanczosSumDecl);
+    funs.insert(lcl_getLanczosSum);
+    decls.insert(GetBetaDecl);
+    funs.insert(GetBeta);
+    decls.insert(GetLogBetaDecl);
+    funs.insert(GetLogBeta);
+    decls.insert(GetBetaDistPDFDecl);
+    funs.insert(GetBetaDistPDF);
+    decls.insert(lcl_GetBetaHelperContFracDecl);
+    funs.insert(lcl_GetBetaHelperContFrac);
+    decls.insert(GetBetaDistDecl);
+    funs.insert(GetBetaDist);
+    decls.insert(GetTDistDecl);
+    funs.insert(GetTDist);
+    decls.insert(GetValueDecl);
+    funs.insert(GetValue);
+    decls.insert(lcl_HasChangeOfSignDecl);
+    funs.insert(lcl_HasChangeOfSign);
+    decls.insert(lcl_IterateInverseDecl);
+    funs.insert(lcl_IterateInverse);
+}
+
+void OpTInv::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 x,fDF;\n";
+    if(vSubArguments.size() != 2)
+    {
+        ss << "    return DBL_MAX;\n" << "}\n";
+        return ;
+    }
+    FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+    assert(tmpCur0);
+    if(ocPush==vSubArguments[0]->GetFormulaToken()->GetOpCode())
+    {
+        if(tmpCur0->GetType() == formula::svSingleVectorRef)
+        {
+            const formula::SingleVectorRefToken*tmpCurDVR0 =
+                dynamic_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+#ifdef ISNAN
+            ss << "    int buffer_x_len = ";
+            ss << tmpCurDVR0->GetArrayLength() << ";\n";
+            ss << "    if(gid0 >= buffer_x_len || isNan(";
+            ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+            ss << "        x = 0.0;\n";
+            ss << "    else\n";
+#endif
+            ss << "        x = ";
+            ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+        }
+        else if(tmpCur0->GetType() == formula::svDouble)
+        {
+            ss << "    x = " << tmpCur0->GetDouble() << ";\n";
+        }
+        else
+        {
+            ss << "    return DBL_MAX;\n" << "}\n";
+            return ;
+        }
+    }
+    else
+    {
+        ss << "    x = ";
+        ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+    }
+    FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+    assert(tmpCur1);
+    if(ocPush==vSubArguments[1]->GetFormulaToken()->GetOpCode())
+    {
+        if(tmpCur1->GetType() == formula::svSingleVectorRef)
+        {
+            const formula::SingleVectorRefToken*tmpCurDVR1 =
+                dynamic_cast<const formula::SingleVectorRefToken *>(tmpCur1);
+#ifdef ISNAN
+            ss << "    int buffer_fDF_len = ";
+            ss << tmpCurDVR1->GetArrayLength() << ";\n";
+            ss << "    if(gid0 >= buffer_fDF_len || isNan(";
+            ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+            ss << "        fDF = 0.0;\n";
+            ss << "    else\n";
+#endif
+            ss << "        fDF = floor(";
+            ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ");\n";
+        }
+        else if(tmpCur1->GetType() == formula::svDouble)
+        {
+            ss << "    fDF = floor(" << tmpCur1->GetDouble() << ");\n";
+        }
+        else
+        {
+            ss << "    return DBL_MAX;\n" << "}\n";
+            return ;
+        }
+    }
+    else
+    {
+        ss << "    fDF = floor(";
+        ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ");\n";
+    }
+    ss << "    if (x > 1.0||fDF < 1.0 || fDF > 1.0E10 || x <= 0.0)\n";
+    ss << "        return DBL_MAX;\n";
+    ss << "    bool bConvError;\n";
+    ss << "    double fVal = lcl_IterateInverse(\n";
+    ss << "        fDF*0.5, fDF, &bConvError,x,fDF );\n";
+    ss << "    if (bConvError)\n";
+    ss << "        return DBL_MAX;\n";
+    ss << "    return fVal;\n";
+    ss << "}\n";
+}
+
 void OpStDev::GenSlidingWindowFunction(std::stringstream &ss,
             const std::string sSymName, SubArguments &vSubArguments)
 {
diff --git a/sc/source/core/opencl/op_statistical.hxx b/sc/source/core/opencl/op_statistical.hxx
index 7f6b017..b5aa6ac 100644
--- a/sc/source/core/opencl/op_statistical.hxx
+++ b/sc/source/core/opencl/op_statistical.hxx
@@ -100,6 +100,14 @@ public:
     virtual std::string BinFuncName(void) const { return "TDist"; }
     virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&);
 };
+class OpTInv: public Normal
+{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments);
+    virtual std::string BinFuncName(void) const { return "TInv"; }
+    virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&);
+};
 class OpTTest: public Normal
 {
 public:
commit 3b506dc21c88b8318dda56066ad5ea948eb335c0
Author: I-Jui (Ray) Sung <ray at multicorewareinc.com>
Date:   Sat Nov 16 22:37:26 2013 -0600

    GPU Calc: temporarily disable parallel sum reduction
    
    Change-Id: I4995f08805ef23d88dc996a54688b5eed9595e3d

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index 68b053d..482a904 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -487,7 +487,8 @@ public:
             if (!bIsStartFixed && !bIsEndFixed)
             {
                 // set 100 as a threshold for invoking reduction kernel
-                if (nCurWindowSize > 100 )
+                // Ray: temporarily turn off parallel sum reduction
+                if (false /*nCurWindowSize > 100*/)
                 {
                     std::string temp = Base::GetName() + "[gid0]";
                     ss << "tmp = ";
@@ -502,7 +503,8 @@ public:
             if (bIsStartFixed && bIsEndFixed)
             {
                 // set 100 as a threshold for invoking reduction kernel
-                if (nCurWindowSize > 100 )
+                // Ray: temporarily turn off parallel sum reduction
+                if (false /* nCurWindowSize > 100 */)
                 {
                     std::string temp = Base::GetName() + "[0]";
                     ss << "tmp = ";
commit 098f50274c2cef0c04973f464ca9b7aa5968b558
Author: shiming zhang <shiming at multicorewareinc.com>
Date:   Sat Nov 16 18:34:14 2013 +0800

    GPU Calc: unit test cases for TDIST
    
    Turn  NO_FALLBACK_TO_SWINTERP on in  formulagroupcl.cxx for test
    
    AMLOEXT-190 BUG
    
    Change-Id: I7d48101f41c592e8c83bd82aa87767e188ce37da
    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/TDist.xls b/sc/qa/unit/data/xls/opencl/statistical/TDist.xls
new file mode 100644
index 0000000..bab2492
Binary files /dev/null and b/sc/qa/unit/data/xls/opencl/statistical/TDist.xls differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index 8bd51dc0..f77f188 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -236,6 +236,7 @@ public:
     void testArrayFormulaSumX2PY2();
     void testStatisticalFormulaBetainv();
     void testStatisticalFormulaTTest();
+    void testStatisticalFormulaTDist();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -401,6 +402,7 @@ public:
     CPPUNIT_TEST(testArrayFormulaSumX2PY2);
     CPPUNIT_TEST(testStatisticalFormulaBetainv);
     CPPUNIT_TEST(testStatisticalFormulaTTest);
+    CPPUNIT_TEST(testStatisticalFormulaTDist);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -4406,6 +4408,31 @@ void ScOpenclTest::testStatisticalFormulaTTest()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-190]
+void ScOpenclTest::testStatisticalFormulaTDist()
+{
+    if (!detectOpenCLDevice())
+        return;
+
+    ScDocShellRef xDocSh = loadDoc("opencl/statistical/TDist.", XLS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+
+    ScDocShellRef xDocShRes = loadDoc("opencl/statistical/TDist.", XLS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Check the results of formula cells in the shared formula range.
+    for (SCROW i = 1; i <= 20; ++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-192]
 void ScOpenclTest::testStatisticalFormulaBinomDist()
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 84c00fb..efdcda3 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1464,6 +1464,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocSumX2DY2:
             case ocBetaInv:
             case ocTTest:
+            case ocTDist:
             // Don't change the state.
             break;
             default:
commit acb3ddef9e2437dfe28e0b96a0482b944a1dd0a4
Author: shiming zhang <shiming at multicorewareinc.com>
Date:   Sat Nov 16 18:54:42 2013 +0800

    GPU Calc: implemented TDIST
    
    AMLOEXT-190 FIX
    
    Change-Id: I9745d4e2b3b25640abfa5ee8165d1335fb52c6b6
    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 bfe7d96..68b053d 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1770,6 +1770,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                          ft->Children[i], new OpTTest));
                  break;
+            case ocTDist:
+                mvSubArguments.push_back(SoPHelper(ts,
+                         ft->Children[i], new OpTDist));
+                 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 8967991..a26af8b 100644
--- a/sc/source/core/opencl/op_statistical.cxx
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -1217,7 +1217,159 @@ void OpVarP::GenSlidingWindowFunction(std::stringstream &ss,
     ss << "        return vSum / fCount;\n";
     ss << "}\n";
 }
+void OpTDist::BinInlineFun(std::set<std::string>& decls,
+    std::set<std::string>& funs)
+{
+    decls.insert(fMachEpsDecl);
+    funs.insert("");
+    decls.insert(fMaxGammaArgumentDecl);
+    funs.insert("");
+    decls.insert(lcl_getLanczosSumDecl);
+    funs.insert(lcl_getLanczosSum);
+    decls.insert(GetBetaDecl);
+    funs.insert(GetBeta);
+    decls.insert(GetLogBetaDecl);
+    funs.insert(GetLogBeta);
+    decls.insert(GetBetaDistPDFDecl);
+    funs.insert(GetBetaDistPDF);
+    decls.insert(lcl_GetBetaHelperContFracDecl);
+    funs.insert(lcl_GetBetaHelperContFrac);
+    decls.insert(GetBetaDistDecl);
+    funs.insert(GetBetaDist);
+    decls.insert(GetTDistDecl);
+    funs.insert(GetTDist);
+}
+void OpTDist::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 x,fDF,fFlag;\n";
+    if(vSubArguments.size() != 3)
+    {
+        ss << "    return DBL_MAX;\n" << "}\n";
+        return ;
+    }
+    FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+    assert(tmpCur0);
+    if(ocPush==vSubArguments[0]->GetFormulaToken()->GetOpCode())
+    {
+        if(tmpCur0->GetType() == formula::svSingleVectorRef)
+        {
+            const formula::SingleVectorRefToken*tmpCurDVR0 =
+                dynamic_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+#ifdef ISNAN
+            ss << "    int buffer_x_len = ";
+            ss << tmpCurDVR0->GetArrayLength() << ";\n";
+            ss << "    if(gid0 >= buffer_x_len || isNan(";
+            ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+            ss << "        x = 0.0;\n";
+            ss << "    else\n";
+#endif
+            ss << "        x = ";
+            ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+        }
+        else if(tmpCur0->GetType() == formula::svDouble)
+        {
+            ss << "    x = " << tmpCur0->GetDouble() << ";\n";
+        }
+        else
+        {
+            ss << "    return DBL_MAX;\n" << "}\n";
+            return ;
+        }
+    }
+    else
+    {
+        ss << "    x = ";
+        ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+    }
+    FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+    assert(tmpCur1);
+    if(ocPush==vSubArguments[1]->GetFormulaToken()->GetOpCode())
+    {
+        if(tmpCur1->GetType() == formula::svSingleVectorRef)
+        {
+            const formula::SingleVectorRefToken*tmpCurDVR1 =
+                dynamic_cast<const formula::SingleVectorRefToken *>(tmpCur1);
+#ifdef ISNAN
+            ss << "    int buffer_fDF_len = ";
+            ss << tmpCurDVR1->GetArrayLength() << ";\n";
+            ss << "    if(gid0 >= buffer_fDF_len || isNan(";
+            ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+            ss << "        fDF = 0.0;\n";
+            ss << "    else\n";
+#endif
+            ss << "        fDF = floor(";
+            ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ");\n";
+        }
+        else if(tmpCur1->GetType() == formula::svDouble)
+        {
+            ss << "    fDF = floor(" << tmpCur1->GetDouble() << ");\n";
+        }
+        else
+        {
+            ss << "    return DBL_MAX;\n" << "}\n";
+            return ;
+        }
+    }
+    else
+    {
+        ss << "    fDF = floor(";
+        ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ");\n";
+    }
 
+    FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+    assert(tmpCur2);
+    if(ocPush==vSubArguments[2]->GetFormulaToken()->GetOpCode())
+    {
+        if(tmpCur2->GetType() == formula::svSingleVectorRef)
+        {
+            const formula::SingleVectorRefToken*tmpCurDVR2 =
+                dynamic_cast<const formula::SingleVectorRefToken *>(tmpCur2);
+#ifdef ISNAN
+            ss << "    int buffer_fFlag_len = ";
+            ss << tmpCurDVR2->GetArrayLength() << ";\n";
+            ss << "    if(gid0>=buffer_fFlag_len || isNan(";
+            ss << vSubArguments[2]->GenSlidingWindowDeclRef() << "))\n";
+            ss << "        fFlag = 0.0;\n";
+            ss << "    else\n";
+#endif
+            ss << "        fFlag = floor(";
+            ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ");\n";
+        }
+        else if(tmpCur2->GetType() == formula::svDouble)
+        {
+            ss << "    fFlag = floor(" << tmpCur2->GetDouble() << ");\n";
+        }
+        else
+        {
+            ss << "    return DBL_MAX;\n" << "}\n";
+            return ;
+        }
+    }
+    else
+    {
+        ss << "    fFlag = floor(";
+        ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ");\n";
+    }
+    ss << "    if(fDF < 1.0 || x < 0.0 || (fFlag != 1.0 && fFlag != 2.0))\n";
+    ss << "        return DBL_MAX;\n";
+    ss << "    double R = GetTDist(x, fDF);\n";
+    ss << "    if (fFlag == 1.0)\n";
+    ss << "        return R;\n";
+    ss << "    else\n";
+    ss << "        return 2.0 * R;\n";
+    ss << "}\n";
+}
 void OpExponDist::GenSlidingWindowFunction(std::stringstream &ss,
         const std::string sSymName, SubArguments &vSubArguments)
 {
diff --git a/sc/source/core/opencl/op_statistical.hxx b/sc/source/core/opencl/op_statistical.hxx
index 6b31ccc..7f6b017 100644
--- a/sc/source/core/opencl/op_statistical.hxx
+++ b/sc/source/core/opencl/op_statistical.hxx
@@ -92,6 +92,14 @@ public:
     virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&);
     virtual std::string BinFuncName(void) const { return "Fdist"; }
 };
+class OpTDist: public Normal
+{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments);
+    virtual std::string BinFuncName(void) const { return "TDist"; }
+    virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&);
+};
 class OpTTest: public Normal
 {
 public:
commit a22c687bfd2b8d9a2ef92097e79298fcb8c98e9b
Author: shiming zhang <shiming at multicorewareinc.com>
Date:   Sat Nov 16 18:04:48 2013 +0800

    GPU Calc: unit test cases for TTEST
    
    Turn  NO_FALLBACK_TO_SWINTERP on in  formulagroupcl.cxx for test
    
    AMLOEXT-189 BUG
    
    Change-Id: I159a9635cb53d962fb16d82ccc2d13c2c4dc41e3
    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/TTest.xls b/sc/qa/unit/data/xls/opencl/statistical/TTest.xls
new file mode 100644
index 0000000..1133a62
Binary files /dev/null and b/sc/qa/unit/data/xls/opencl/statistical/TTest.xls differ
diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx
index 684bab1..8bd51dc0 100644
--- a/sc/qa/unit/opencl-test.cxx
+++ b/sc/qa/unit/opencl-test.cxx
@@ -235,6 +235,7 @@ public:
     void testArrayFormulaSumX2MY2();
     void testArrayFormulaSumX2PY2();
     void testStatisticalFormulaBetainv();
+    void testStatisticalFormulaTTest();
     CPPUNIT_TEST_SUITE(ScOpenclTest);
     CPPUNIT_TEST(testSharedFormulaXLS);
     CPPUNIT_TEST(testFinacialFormula);
@@ -399,6 +400,7 @@ public:
     CPPUNIT_TEST(testArrayFormulaSumX2MY2);
     CPPUNIT_TEST(testArrayFormulaSumX2PY2);
     CPPUNIT_TEST(testStatisticalFormulaBetainv);
+    CPPUNIT_TEST(testStatisticalFormulaTTest);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -4379,6 +4381,31 @@ void ScOpenclTest::testStatisticalFormulaZTest()
     xDocSh->DoClose();
     xDocShRes->DoClose();
 }
+//[AMLOEXT-189]
+void ScOpenclTest::testStatisticalFormulaTTest()
+{
+    if (!detectOpenCLDevice())
+        return;
+
+    ScDocShellRef xDocSh = loadDoc("opencl/statistical/TTest.", XLS);
+    ScDocument* pDoc = xDocSh->GetDocument();
+    CPPUNIT_ASSERT(pDoc);
+    enableOpenCL();
+    pDoc->CalcAll();
+
+    ScDocShellRef xDocShRes = loadDoc("opencl/statistical/TTest.", XLS);
+    ScDocument* pDocRes = xDocShRes->GetDocument();
+    CPPUNIT_ASSERT(pDocRes);
+    // Check the results of formula cells in the shared formula range.
+    for (SCROW i = 1; i <= 20; ++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-192]
 void ScOpenclTest::testStatisticalFormulaBinomDist()
 {
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 310b5f7..84c00fb 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1463,6 +1463,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
             case ocSumX2MY2:
             case ocSumX2DY2:
             case ocBetaInv:
+            case ocTTest:
             // Don't change the state.
             break;
             default:
commit f18a9d6186f097ed5ba3607bdfbd4c09971c1f00
Author: shiming zhang <shiming at multicorewareinc.com>
Date:   Sat Nov 16 18:17:03 2013 +0800

    GPU Calc: implemented TTEST
    
    AMLOEXT-189 FIX
    
    Change-Id: I15a640a9953fa4aef2176fd31242e21ad335abb4
    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 0d63e4c..bfe7d96 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1766,6 +1766,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 mvSubArguments.push_back(SoPHelper(ts,
                          ft->Children[i],new OpBetainv));
                  break;
+            case ocTTest:
+                mvSubArguments.push_back(SoPHelper(ts,
+                         ft->Children[i], new OpTTest));
+                 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 48c015d..8967991 100644
--- a/sc/source/core/opencl/op_statistical.cxx
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -559,7 +559,432 @@ void OpZTest::GenSlidingWindowFunction(std::stringstream &ss,
         ss << "}\n";
     }
 }
+void OpTTest::BinInlineFun(std::set<std::string>& decls,
+    std::set<std::string>& funs)
+{
+    decls.insert(fMachEpsDecl);
+    funs.insert("");
+    decls.insert(fMaxGammaArgumentDecl);
+    funs.insert("");
+    decls.insert(lcl_getLanczosSumDecl);
+    funs.insert(lcl_getLanczosSum);
+    decls.insert(GetBetaDecl);
+    funs.insert(GetBeta);
+    decls.insert(GetLogBetaDecl);
+    funs.insert(GetLogBeta);
+    decls.insert(GetBetaDistPDFDecl);
+    funs.insert(GetBetaDistPDF);
+    decls.insert(lcl_GetBetaHelperContFracDecl);
+    funs.insert(lcl_GetBetaHelperContFrac);
+    decls.insert(GetBetaDistDecl);
+    funs.insert(GetBetaDist);
+    decls.insert(GetTDistDecl);
+    funs.insert(GetTDist);
+}
 
+void OpTTest::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 fSum1=0.0;\n";
+    ss << "    double fSum2=0.0;\n";
+    ss << "    double fSumSqr1=0.0;\n";
+    ss << "    double fSumSqr2=0.0;\n";
+    ss << "    double fCount1=0.0;\n";
+    ss << "    double fCount2=0.0;\n";
+    ss << "    double arg1=0.0;\n";
+    ss << "    double arg2=0.0;\n";
+    ss << "    double mode=0.0;\n";
+    ss << "    double type=0.0;\n";
+    ss << "    double fT=0.0;\n";
+    ss << "    double fF=0.0;\n";
+    if(vSubArguments.size() != 4)
+    {
+        ss << "    return DBL_MAX;\n";
+        ss << "}\n";
+        return ;
+    }
+    if(vSubArguments.size() == 4)
+    {
+        FormulaToken *pCur  = vSubArguments[0]->GetFormulaToken();
+        FormulaToken *pCur1 = vSubArguments[1]->GetFormulaToken();
+        FormulaToken *pCur2 = vSubArguments[2]->GetFormulaToken();
+        FormulaToken *pCur3 = vSubArguments[3]->GetFormulaToken();
+        assert(pCur);
+        assert(pCur1);
+        assert(pCur2);
+        assert(pCur3);
+        if(ocPush==vSubArguments[2]->GetFormulaToken()->GetOpCode())
+        {
+            if(pCur2->GetType() == formula::svSingleVectorRef)
+            {
+                const formula::SingleVectorRefToken* pSVR =
+                    dynamic_cast< const formula::SingleVectorRefToken*>(pCur2);
+                assert(pSVR);
+#ifdef  ISNAN
+                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+                ss << "    {\n";
+                ss << "        if (isNan(";
+                ss << vSubArguments[2]->GenSlidingWindowDeclRef() << "))\n";
+                ss << "            mode = 0.0;\n";
+                ss << "        else\n";
+#endif
+                ss << "            mode = floor(" ;
+                ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ");\n";
+#ifdef ISNAN
+                ss << "    }\n";
+#endif
+            }
+            else if(pCur2->GetType() == formula::svDouble)
+            {
+                ss << "    mode = floor(" << pCur2->GetDouble() << ");\n";
+            }
+            else
+            {
+                ss << "    return DBL_MAX;\n";
+                ss << "}\n";
+                return ;
+            }
+        }
+        else
+        {
+            ss << "    mode = floor(" ;
+            ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ");\n";
+        }
+        ss << "    if(!(mode == 1.0 || mode == 2.0))\n";
+        ss << "        return DBL_MAX;\n";
+        if(ocPush==vSubArguments[3]->GetFormulaToken()->GetOpCode())
+        {
+            if(pCur3->GetType() == formula::svSingleVectorRef)
+            {
+                const formula::SingleVectorRefToken* pSVR =
+                    dynamic_cast< const formula::SingleVectorRefToken*>(pCur3);
+                assert(pSVR);
+#ifdef  ISNAN
+                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+                ss << "    {\n";
+                ss << "        if (isNan(";
+                ss << vSubArguments[3]->GenSlidingWindowDeclRef() << "))\n";
+                ss << "            type=0.0;\n";
+                ss << "        else\n";
+#endif
+                ss << "            type=floor(";
+                ss << vSubArguments[3]->GenSlidingWindowDeclRef() << ");\n";
+#ifdef ISNAN
+                ss << "    }\n";
+#endif
+            }
+            else if(pCur3->GetType() == formula::svDouble)
+            {
+                ss << "    type = floor(" << pCur3->GetDouble() << ");\n";
+            }
+            else
+            {
+                ss << "    return DBL_MAX;\n";
+                ss << "}\n";
+                return ;
+            }
+        }
+        else
+        {
+            ss << "    type=floor(";
+            ss << vSubArguments[3]->GenSlidingWindowDeclRef() << ");\n";
+        }
+        ss << "    if(!(type == 1.0||type == 2.0||type == 3.0))\n";
+        ss << "        return DBL_MAX;\n";
+
+        if(pCur->GetType() == formula::svDoubleVectorRef &&
+               pCur1->GetType() == formula::svDoubleVectorRef)
+        {
+            const formula::DoubleVectorRefToken* pDVR =
+                dynamic_cast<const formula::DoubleVectorRefToken *>(pCur);
+            const formula::DoubleVectorRefToken* pDVR1 =
+                dynamic_cast<const formula::DoubleVectorRefToken *>(pCur1);
+
+            size_t nCurWindowSize  = pDVR->GetRefRowSize();
+            size_t nCurWindowSize1 = pDVR1->GetRefRowSize();
+
+            if(nCurWindowSize == nCurWindowSize1)
+            {
+                ss << "    if(type == 1.0)\n";
+                ss << "    {\n";
+                ss << "        for (int i = ";
+                if ((!pDVR->IsStartFixed() && pDVR->IsEndFixed()) &&
+                         (!pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+                {
+#ifdef  ISNAN
+                    ss << "gid0; i < " << pDVR->GetArrayLength();
+                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
+                    ss << "        {\n";
+#else
+                    ss << "gid0; i < " << nCurWindowSize << "; i++)\n";
+                    ss << "        {\n";
+#endif
+                }
+                else if ((pDVR->IsStartFixed() && !pDVR->IsEndFixed()) &&
+                             (pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+                {
+#ifdef  ISNAN
+                    ss << "0; i < " << pDVR->GetArrayLength();
+                    ss << " && i < gid0+"<< nCurWindowSize << "; i++)\n";
+                    ss << "        {\n";
+#else
+                    ss << "0; i < gid0+" << nCurWindowSize << "; i++)\n";
+                    ss << "        {\n";
+#endif
+                }
+                else if ((!pDVR->IsStartFixed() && !pDVR->IsEndFixed()) &&
+                             (!pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+                {
+#ifdef  ISNAN
+                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
+                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
+                    ss << "        {\n";
+#else
+                    ss << "0; i < " << nCurWindowSize << "; i++)\n";
+                    ss << "        {\n";
+#endif
+                }
+                else if ((pDVR->IsStartFixed() && pDVR->IsEndFixed()) &&
+                             (pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+                {
+#ifdef  ISNAN
+                    ss << "0; i < " << nCurWindowSize << "; i++)\n";
+                    ss << "        {\n";
+#else
+                    ss << "0; i < " << nCurWindowSize << "; i++)\n";
+                    ss << "        {\n";
+#endif
+                }
+                else
+                {
+#ifdef  ISNAN
+                    ss << "0; i < " << nCurWindowSize << "; i++)\n";
+                    ss << "        {\n";
+#else
+                    ss << "0; i < " << nCurWindowSize << "; i++)\n";
+                    ss << "        {\n";
+#endif
+                    ss << "            break;\n";
+                    ss << "        }";
+                    ss << "        return DBL_MAX;\n";
+                    ss << "    }\n";
+                    ss << "}\n";
+                    return ;
+                }
+
+                ss << "            arg1 = ";
+                ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+                ss << "            arg2 = ";
+                ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef  ISNAN
+                ss << "            if (isNan(arg1)||isNan(arg2))\n";
+                ss << "                continue;\n";
+#endif
+                ss << "            fSum1 += arg1;\n";
+                ss << "            fSum2 += arg2;\n";
+                ss << "            fSumSqr1 += (arg1 - arg2)*(arg1 - arg2);\n";
+                ss << "            fCount1 += 1;\n";
+                ss << "        }\n";
+                ss << "        if(fCount1 < 1.0)\n";
+                ss << "            return DBL_MAX;\n";
+                ss << "        fT = sqrt(fCount1-1.0) * fabs(fSum1 - fSum2)\n";
+                ss << "            /sqrt(fCount1 * fSumSqr1 - (fSum1-fSum2)\n";
+                ss << "             *(fSum1-fSum2));\n";
+                ss << "        fF = fCount1 - 1.0;\n";
+            }
+            else
+            {
+                ss << "    return DBL_MAX;\n";
+                ss << "}\n";
+                return ;
+            }
+        }
+        else
+        {
+            ss << "    return DBL_MAX;\n";
+            ss << "}\n";
+            return ;
+        }
+        ss << "    }\n";
+        ss << "    if(type == 2.0 || type == 3.0)\n";
+        ss << "    {\n";
+
+        if(pCur->GetType() == formula::svDoubleVectorRef &&
+               pCur1->GetType() == formula::svDoubleVectorRef)
+        {
+            const formula::DoubleVectorRefToken* pDVR =
+                dynamic_cast<const formula::DoubleVectorRefToken *>(pCur);
+            const formula::DoubleVectorRefToken* pDVR1 =
+                dynamic_cast<const formula::DoubleVectorRefToken *>(pCur1);
+
+            size_t nCurWindowSize  = pDVR->GetRefRowSize();
+            size_t nCurWindowSize1 = pDVR1->GetRefRowSize();
+            ss << "        for (int i = ";
+            if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
+            {
+#ifdef  ISNAN
+                ss << "gid0; i < " << pDVR->GetArrayLength();
+                ss << " && i < " << nCurWindowSize  << "; i++)\n";
+                ss << "        {\n";
+#else
+                ss << "gid0; i < " << nCurWindowSize << "; i++)\n";
+                ss << "        {\n";
+#endif
+            }
+            else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+            {
+#ifdef  ISNAN
+                ss << "0; i < " << pDVR->GetArrayLength();
+                ss << " && i < gid0+"<< nCurWindowSize << "; i++)\n";
+                ss << "        {\n";
+#else
+                ss << "0; i < gid0+" << nCurWindowSize << "; i++)\n";
+                ss << "        {\n";
+#endif
+            }
+            else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+            {
+#ifdef  ISNAN
+                ss << "0; i + gid0 < " << pDVR->GetArrayLength();
+                ss << " &&  i < " << nCurWindowSize << "; i++)\n";
+                ss << "        {\n";
+#else
+                ss << "0; i < " << nCurWindowSize << "; i++)\n";
+                ss << "        {\n";
+#endif
+            }
+            else
+            {
+#ifdef  ISNAN
+                ss << "0; i < " << nCurWindowSize << "; i++)\n";
+                ss << "        {\n";
+#else
+                ss << "0; i < " << nCurWindowSize << "; i++)\n";
+                ss << "        {\n";
+#endif
+            }
+
+            ss << "            arg1 = ";
+            ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef  ISNAN
+            ss << "            if (isNan(arg1))\n";
+            ss << "                continue;\n";
+#endif
+            ss << "            fSum1 += arg1;\n";
+            ss << "            fSumSqr1 += arg1 * arg1;\n";
+            ss << "            fCount1 += 1;\n";
+            ss << "        }\n";
+
+            ss << "        for (int i = ";
+            if (!pDVR1->IsStartFixed() && pDVR1->IsEndFixed())
+            {
+#ifdef  ISNAN
+                ss << "gid0; i < " << pDVR1->GetArrayLength();
+                ss << " && i < " << nCurWindowSize1  << "; i++)\n";
+                ss << "        {\n";
+#else
+                ss << "gid0; i < " << nCurWindowSize1 << "; i++)\n";
+                ss << "        {\n";
+#endif
+            }
+            else if (pDVR1->IsStartFixed() && !pDVR1->IsEndFixed())
+            {
+#ifdef  ISNAN
+                ss << "0; i < " << pDVR1->GetArrayLength();
+                ss << " && i < gid0+"<< nCurWindowSize1 << "; i++)\n";
+                ss << "        {\n";
+#else
+                ss << "0; i < gid0+" << nCurWindowSize1 << "; i++)\n";
+                ss << "        {\n";
+#endif
+            }
+            else if (!pDVR1->IsStartFixed() && !pDVR1->IsEndFixed())
+            {
+#ifdef  ISNAN
+                ss << "0; i + gid0 < " << pDVR1->GetArrayLength();
+                ss << " &&  i < " << nCurWindowSize1 << "; i++)\n";
+                ss << "        {\n";
+#else
+                ss << "0; i < " << nCurWindowSize1 << "; i++)\n";
+                ss << "        {\n";
+#endif
+            }
+            else
+            {
+#ifdef  ISNAN
+                ss << "0; i < " << nCurWindowSize1 << "; i++)\n";
+                ss << "        {\n";
+#else
+                ss << "0; i < " << nCurWindowSize1 << "; i++)\n";
+                ss << "        {\n";
+#endif
+            }
+            ss << "            arg2 = ";
+            ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+#ifdef  ISNAN
+            ss << "            if (isNan(arg2))\n";
+            ss << "                continue;\n";
+#endif
+            ss << "            fSum2 += arg2;\n";
+            ss << "            fSumSqr2 += arg2 * arg2;\n";
+            ss << "            fCount2 += 1;\n";
+            ss << "        }\n";
+        }
+        else
+        {
+            ss << "        return DBL_MAX;\n";
+            ss << "    }\n";
+            ss << "}\n";
+            return ;
+        }
+        ss << "        if (fCount1 < 2.0 || fCount2 < 2.0)\n";
+        ss << "            return DBL_MAX;\n";
+        ss << "    }\n";
+        ss << "    if(type == 3.0)\n";
+        ss << "    {\n";
+        ss << "        double fS1 = (fSumSqr1-fSum1*fSum1/fCount1)\n";
+        ss << "            /(fCount1-1.0)/fCount1;\n";
+        ss << "        double fS2 = (fSumSqr2-fSum2*fSum2/fCount2)\n";
+        ss << "            /(fCount2-1.0)/fCount2;\n";
+        ss << "        if (fS1 + fS2 == 0.0)\n";
+        ss << "            return DBL_MAX;\n";
+        ss << "        fT = fabs(fSum1/fCount1 - fSum2/fCount2)\n";
+        ss << "             /sqrt(fS1+fS2);\n";
+        ss << "        double c = fS1/(fS1+fS2);\n";
+        ss << "        fF = 1.0/(c*c/(fCount1-1.0)+(1.0-c)*(1.0-c)\n";
+        ss << "             /(fCount2-1.0));\n";
+        ss << "    }\n";
+        ss << "    if(type == 2.0)\n";
+        ss << "    {\n";
+        ss << "        double fS1 = (fSumSqr1 - fSum1*fSum1/fCount1)\n";
+        ss << "             /(fCount1 - 1.0);\n";
+        ss << "        double fS2 = (fSumSqr2 - fSum2*fSum2/fCount2)\n";
+        ss << "             /(fCount2 - 1.0);\n";
+        ss << "        fT = fabs( fSum1/fCount1 - fSum2/fCount2 )\n";
+        ss << "            /sqrt( (fCount1-1.0)*fS1 + (fCount2-1.0)*fS2 )\n";
+        ss << "            *sqrt( fCount1*fCount2*(fCount1+fCount2-2)\n";
+        ss << "            /(fCount1+fCount2) );\n";
+        ss << "        fF = fCount1 + fCount2 - 2;\n";
+        ss << "    }\n";
+
+        ss << "    double tdist=GetTDist(fT, fF);\n";
+        ss << "    if (mode==1)\n";
+        ss << "        return tdist;\n";
+        ss << "    else\n";
+        ss << "        return 2.0*tdist;\n";
+        ss << "}\n";
+    }
+}
 void OpVarP::GenSlidingWindowFunction(std::stringstream &ss,
             const std::string sSymName, SubArguments &vSubArguments)
 {
diff --git a/sc/source/core/opencl/op_statistical.hxx b/sc/source/core/opencl/op_statistical.hxx
index 43c829f..6b31ccc 100644
--- a/sc/source/core/opencl/op_statistical.hxx
+++ b/sc/source/core/opencl/op_statistical.hxx
@@ -92,6 +92,14 @@ public:
     virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&);
     virtual std::string BinFuncName(void) const { return "Fdist"; }
 };
+class OpTTest: public Normal
+{
+public:
+    virtual void GenSlidingWindowFunction(std::stringstream &ss,
+            const std::string sSymName, SubArguments &vSubArguments);
+    virtual std::string BinFuncName(void) const { return "TTest"; }
+    virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&);
+};
 class OpSkew: public Normal
 {
 public:
diff --git a/sc/source/core/opencl/opinlinefun_statistical.cxx b/sc/source/core/opencl/opinlinefun_statistical.cxx
index 8aaff82..43d6394 100644
--- a/sc/source/core/opencl/opinlinefun_statistical.cxx
+++ b/sc/source/core/opencl/opinlinefun_statistical.cxx
@@ -15,9 +15,15 @@ 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 fMaxGammaArgumentDecl =
-"#define fMaxGammaArgument  171.624376956302\n";
+std::string fMaxGammaArgumentDecl=
+"#define fMaxGammaArgument 171.624376956302\n";
+std::string GetValueDecl=
+"double  GetValue( double x,double fp,double fDF );";
+std::string GetValue=
+"double  GetValue( double x,double fp,double fDF )\n"
+"{\n"
+"    return fp - 2 * GetTDist(x, fDF);\n"
+"}\n";
 std::string GetGammaSeriesDecl=
 "double GetGammaSeries( double fA, double fX );\n";
 std::string GetGammaSeries =


More information about the Libreoffice-commits mailing list