sc/source/core/opencl/op_financial.cxx   |  318 ---
 sc/source/core/opencl/op_financial.hxx   |    5 
 sc/source/core/opencl/op_math.cxx        |  257 --
 sc/source/core/opencl/op_math.hxx        |    2 
 sc/source/core/opencl/op_statistical.cxx | 2888 ++++---------------------------
 sc/source/core/opencl/op_statistical.hxx |   31 
 sc/source/core/opencl/opbase.cxx         |    6 
 sc/source/core/opencl/opbase.hxx         |    2 
 8 files changed, 508 insertions(+), 3001 deletions(-)

New commits:
commit 4797becd04ccd8447f933b8aa3de4477c740a273
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Mon Sep 19 17:43:22 2022 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Tue Sep 20 08:44:50 2022 +0200

    reduce opencl copy&paste WRT simple loops with svDoubleVectorRef
    
    Change-Id: Id68808d5b390c0771e82bf391930a840f423c1e1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140188
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/sc/source/core/opencl/op_financial.cxx 
b/sc/source/core/opencl/op_financial.cxx
index 4d80efb53751..3073ba33195a 100644
--- a/sc/source/core/opencl/op_financial.cxx
+++ b/sc/source/core/opencl/op_financial.cxx
@@ -341,31 +341,17 @@ void Fvschedule::GenSlidingWindowFunction(
     outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
 {
     CHECK_PARAMETER_COUNT( 2, 2 );
-    FormulaToken* pCur = vSubArguments[1]->GetFormulaToken();
-    assert(pCur);
-    if(vSubArguments[0]->GetFormulaToken()->GetType() != 
formula::svDoubleVectorRef)
-        throw Unhandled( __FILE__, __LINE__ );
-    const formula::DoubleVectorRefToken* pCurDVR =
-        static_cast<const formula::DoubleVectorRefToken *>(pCur);
-    size_t nCurWindowSize = pCurDVR->GetRefRowSize();
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n\t";
     ss << "double tmp = 1.0;\n\t";
-    ss << "int gid0 = get_global_id(0);\n\t";
-    ss << "double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
-    ss << ";\n\t";
-    ss << "if (isnan(arg0))\n\t\t";
-    ss << "arg0 = 0;\n\t";
-    ss << "double arg1;\n\t";
-    ss << "int arrayLength = " << pCurDVR->GetArrayLength() << ";\n\t";
-    ss << "for (int i = 0; i + gid0 < arrayLength &&";
-    ss << " i < " << nCurWindowSize << "; i++){\n\t\t";
-    ss << "arg1 = ";
-    ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n\t\t\t";
-    ss << "if (isnan(arg1))\n\t\t\t\t";
-    ss << "arg1 = 0;\n\t\t\t";
-    ss << "tmp *= arg1 + 1.0;\n\t\t";
-    ss << "}\n\t";
+    ss << "int gid0 = get_global_id(0);\n";
+    GenerateArg( 0, vSubArguments, ss );
+    ss << "\t";
+    GenerateRangeArg( 1, vSubArguments, ss,
+        "        if(!isnan(arg))\n"
+        "            tmp *= arg + 1;\n"
+        );
+    ss << "\t";
     ss << "return (double)tmp * arg0";
     ss << ";\n}";
 }
@@ -727,41 +713,12 @@ void MIRR::GenSlidingWindowFunction(
     outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
 {
     CHECK_PARAMETER_COUNT( 3, 3 );
-    FormulaToken* pCur = vSubArguments[0]->GetFormulaToken();
-    assert(pCur);
-    const formula::DoubleVectorRefToken* pCurDVR =
-    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-    size_t nCurWindowSize = pCurDVR->GetRefRowSize();
-    FormulaToken* pCur1 = vSubArguments[1]->GetFormulaToken();
-    assert(pCur1);
-    const formula::SingleVectorRefToken* pSVR1 =
-        static_cast< const formula::SingleVectorRefToken* >(pCur1);
-    assert(pSVR1);
-    FormulaToken* pCur2 = vSubArguments[2]->GetFormulaToken();
-    assert(pCur2);
-    const formula::SingleVectorRefToken* pSVR2 =
-        static_cast< const formula::SingleVectorRefToken* >(pCur2);
-    assert(pSVR2);
-
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n\t";
     ss << "double tmp = " << GetBottom() <<";\n\t";
     ss << "int gid0 = get_global_id(0);\n\t";
-    ss << "double arg0, arg1, arg2;\n\t";
-    ss << "arg1 = " << vSubArguments[1]->GenSlidingWindowDeclRef();
-    ss << ";\n\t";
-    ss << "arg2 = " << vSubArguments[2]->GenSlidingWindowDeclRef();
-    ss << ";\n\t";
-    ss << "int argLen1 = " << pSVR1->GetArrayLength() << ";\n\t";
-    ss << "int argLen2 = " << pSVR2->GetArrayLength() << ";\n\t";
-    ss << "if (gid0 >= argLen1)\n\t\t";
-    ss << "arg1 = 0.0;\n\t";
-    ss << "if (gid0 >= argLen2)\n\t\t";
-    ss << "arg2 = 0.0;\n\t";
-    ss << "if (isnan(arg1))\n\t\t";
-    ss << "arg1 = 0.0;\n\t";
-    ss << "if (isnan(arg2))\n\t\t";
-    ss << "arg2 = 0.0;\n\t";
+    GenerateArg( 1, vSubArguments, ss );
+    GenerateArg( 2, vSubArguments, ss );
     ss << "double invest = arg1 + 1.0;\n\t";
     ss << "double reinvest = arg2 + 1.0;\n\t";
     ss << "double NPV_invest = 0.0;\n\t";
@@ -769,21 +726,18 @@ void MIRR::GenSlidingWindowFunction(
     ss << "double NPV_reinvest = 0.0;\n\t";
     ss << "double Pow_reinvest = 1.0;\n\t";
     ss << "int nCount = 0;\n\t";
-    ss << "int arrayLength = " << pCurDVR->GetArrayLength() << ";\n\t";
-    ss << "for (int i = 0; i + gid0 < arrayLength &&";
-    ss << " i < " << nCurWindowSize << "; i++){\n\t\t";
-    ss << "arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
-    ss << ";\n\t\t";
-    ss << "if (isnan(arg0))\n\t\t\t";
-    ss << "continue;\n\t\t";
-    ss << "if (arg0 > 0.0)\n\t\t\t";
-    ss << "NPV_reinvest += arg0 * Pow_reinvest;\n\t\t";
-    ss << "else if (arg0 < 0.0)\n\t\t\t";
-    ss << "NPV_invest += arg0 * Pow_invest;\n\t\t";
-    ss << "Pow_reinvest /= reinvest;\n\t\t";
-    ss << "Pow_invest /= invest;\n\t\t";
-    ss << "nCount++;\n\t";
-    ss << "}\n\t";
+    GenerateRangeArg( 0, vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "            {\n"
+        "            if (arg > 0.0)\n"
+        "                NPV_reinvest += arg * Pow_reinvest;\n"
+        "            else if (arg < 0.0)\n"
+        "                NPV_invest += arg * Pow_invest;\n"
+        "            Pow_reinvest /= reinvest;\n"
+        "            Pow_invest /= invest;\n"
+        "            nCount++;\n"
+        "            }\n"
+        );
     ss << "tmp = ";
     ss << "-NPV_reinvest /NPV_invest * pow(reinvest,(double)nCount-1);\n\t";
     ss << "tmp =  pow(tmp, 1.0 / (nCount - 1)) - 1.0;\n\t";
@@ -1090,77 +1044,18 @@ void OpNPV::GenSlidingWindowFunction(outputstream &ss,
     ss << "    int gid0 = get_global_id(0);\n";
     ss << "    int nCount = 1;\n";
     GenerateArg( 0, vSubArguments, ss );
-    //while (i-- > 1)
-    for (size_t i = 1; i < vSubArguments.size(); i++)
-    {
-        FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
-        assert(pCur);
-        if (pCur->GetType() == formula::svDoubleVectorRef)
-        {
-            const formula::DoubleVectorRefToken* pDVR =
-            static_cast<const formula::DoubleVectorRefToken *>(pCur);
-            size_t nCurWindowSize = pDVR->GetRefRowSize();
-            ss << "    for (int i = ";
-            if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) {
-                ss << "gid0; i < " << pDVR->GetArrayLength();
-                ss << " && i < " << nCurWindowSize  << "; i++){\n";
-            } else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) {
-                ss << "0; i < " << pDVR->GetArrayLength();
-                ss << " && i < gid0+"<< nCurWindowSize << "; i++){\n";
-            } else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()){
-                ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                ss << " &&  i < "<< nCurWindowSize << "; i++){\n";
-            }
-            else {
-                ss << "0; i < "<< nCurWindowSize << "; i++){\n";
-            }
-        }
-        else if (pCur->GetType() == formula::svSingleVectorRef)
-        {
-            const formula::SingleVectorRefToken* pSVR =
-            static_cast< const formula::SingleVectorRefToken* >(pCur);
-            ss << "    if (gid0 < " << pSVR->GetArrayLength() << "){\n";
-        }
-        else if (pCur->GetType() == formula::svDouble)
-        {
-            ss << "{\n";
-        }
-        else
-        {
-            ss << "nCount += 1;\n";
-        }
-        if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
-        {
-            ss << "        double temp=";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss << ";\n";
-            ss << "        double temp1=1.0;";
-            ss << "        if (isnan(temp)){\n";
-            ss << "            tmp += 0;}\n";
-            ss << "        else{\n";
-            ss << "            for(int i=1;i<nCount;i+=2)\n";
-            ss << "                temp1*=pow(1.0f+ arg0 ,2);\n";
-            ss << "            if(nCount%2)\n";
-            ss << "                temp1*=1.0f+ arg0;\n";
-            ss << "            tmp +=temp/ temp1;\n";
-            ss << "        nCount += 1;\n";
-            ss << "        }\n";
-            ss << "    }\n";
-        }
-        else
-        {
-            ss << "        double temp=";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss << ";\n";
-            ss << "    double temp1=1.0;";
-            ss << "            for(int i=1;i<nCount;i+=2)";
-            ss << "                temp1*=pow(1.0f+ arg0 ,2);\n";
-            ss << "            if(nCount%2)";
-            ss << "                temp1*=1.0f+ arg0;\n";
-            ss << "            tmp +=temp/ temp1;\n";
-            ss << "        nCount += 1;\n";
-        }
-    }
+    GenerateRangeArgs( 1, vSubArguments.size() - 1, vSubArguments, ss,
+        "        double temp1=1.0;\n"
+        "        if (!isnan(arg))\n"
+        "        {\n"
+        "            for(int i=1;i<nCount;i+=2)\n"
+        "                temp1*=pow(1.0f + arg0,2);\n"
+        "            if(nCount%2)\n"
+        "                temp1*=1.0f + arg0;\n"
+        "            tmp += arg / temp1;\n"
+        "        nCount += 1;\n"
+        "        }\n"
+        );
     ss << "    return tmp;\n";
     ss << "}";
 }
@@ -1240,73 +1135,19 @@ void OpOddlprice::BinInlineFun(std::set<std::string>& 
decls,
 void OpOddlprice::GenSlidingWindowFunction(outputstream &ss,
           const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT( 7, 8 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
     ss <<"    double tmp = 0;\n";
     ss <<"    int gid0 = get_global_id(0);\n";
-    ss <<"    double tmp0=0;\n";
-    ss <<"    double tmp1=0;\n";
-    ss <<"    double tmp2=0;\n";
-    ss <<"    double tmp3=0;\n";
-    ss <<"    double tmp4=0;\n";
-    ss <<"    double tmp5=0;\n";
-    ss <<"    double tmp6=0;\n";
-    ss <<"    double tmp7=0;\n";
-    ss <<"    \n";
-    for (size_t i = 0; i < vSubArguments.size(); i++)
-    {
-        FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
-        assert(pCur);
-        if (pCur->GetType() == formula::svDoubleVectorRef)
-        {
-            const formula::DoubleVectorRefToken* pDVR =
-            static_cast<const formula::DoubleVectorRefToken *>(pCur);
-            size_t nCurWindowSize = pDVR->GetRefRowSize();
-            ss << "    for (int i = ";
-            if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) {
-                ss << "gid0; i < " << pDVR->GetArrayLength();
-                ss << " && i < " << nCurWindowSize  << "; i++){\n";
-            } else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) {
-                ss << "0; i < " << pDVR->GetArrayLength();
-                ss << " && i < gid0+"<< nCurWindowSize << "; i++){\n";
-            } else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()){
-                ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                ss << " &&  i < "<< nCurWindowSize << "; i++){\n";
-            }
-            else {
-                ss << "0; i < "<< nCurWindowSize << "; i++){\n";
-            }
-        }
-        else if (pCur->GetType() == formula::svSingleVectorRef)
-        {
-            const formula::SingleVectorRefToken* pSVR =
-            static_cast< const formula::SingleVectorRefToken* >(pCur);
-            ss << "    if (gid0 < " << pSVR->GetArrayLength() << "){\n";
-        }
-        else if (pCur->GetType() == formula::svDouble)
-        {
-            ss << "{\n";
-        }
-
-        if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
-        {
-            ss << "        if (isnan(";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss << "))\n";
-            ss << "            tmp"<<i<<"= 0;\n";
-            ss << "        else\n";
-            ss << "            tmp"<<i<<"=";
-            ss <<vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss << ";\n";
-            ss <<"    }\n";
-        }
-        else
-        {
-            ss << "        tmp"<<i<<"=";
-            ss <<vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss <<";\n";
-        }
-    }
+    GenerateArg( "tmp0", 0, vSubArguments, ss );
+    GenerateArg( "tmp1", 1, vSubArguments, ss );
+    GenerateArg( "tmp2", 2, vSubArguments, ss );
+    GenerateArg( "tmp3", 3, vSubArguments, ss );
+    GenerateArg( "tmp4", 4, vSubArguments, ss );
+    GenerateArg( "tmp5", 5, vSubArguments, ss );
+    GenerateArg( "tmp6", 6, vSubArguments, ss );
+    GenerateArgWithDefault( "tmp7", 7, 0, vSubArguments, ss );
     ss <<"    int nNullDate = GetNullDate();\n";
     ss <<"    tmp = GetOddlprice(nNullDate,tmp0,tmp1,";
     ss <<"tmp2,tmp3,tmp4,tmp5,tmp6,tmp7);\n";
@@ -1330,74 +1171,19 @@ void OpOddlyield::BinInlineFun(std::set<std::string>& 
decls,
 void OpOddlyield::GenSlidingWindowFunction(outputstream &ss,
           const std::string &sSymName, SubArguments &vSubArguments)
 {
-    CHECK_PARAMETER_COUNT( 8, 8 );
+    CHECK_PARAMETER_COUNT( 7, 8 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
     ss <<"    double tmp = 0;\n";
     ss <<"    int gid0 = get_global_id(0);\n";
-    ss <<"    double tmp0=0;\n";
-    ss <<"    double tmp1=0;\n";
-    ss <<"    double tmp2=0;\n";
-    ss <<"    double tmp3=0;\n";
-    ss <<"    double tmp4=0;\n";
-    ss <<"    double tmp5=0;\n";
-    ss <<"    double tmp6=0;\n";
-    ss <<"    double tmp7=0;\n";
-    ss <<"    \n";
-    for (size_t i = 0; i < vSubArguments.size(); i++)
-    {
-        FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
-        assert(pCur);
-        if (pCur->GetType() == formula::svDoubleVectorRef)
-        {
-            const formula::DoubleVectorRefToken* pDVR =
-            static_cast<const formula::DoubleVectorRefToken *>(pCur);
-            size_t nCurWindowSize = pDVR->GetRefRowSize();
-            ss << "    for (int i = ";
-            if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) {
-                ss << "gid0; i < " << pDVR->GetArrayLength();
-                ss << " && i < " << nCurWindowSize  << "; i++){\n";
-            } else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) {
-                ss << "0; i < " << pDVR->GetArrayLength();
-                ss << " && i < gid0+"<< nCurWindowSize << "; i++){\n";
-            } else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()){
-                ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                ss << " &&  i < "<< nCurWindowSize << "; i++){\n";
-            }
-            else {
-                ss << "0; i < "<< nCurWindowSize << "; i++){\n";
-            }
-        }
-        else if (pCur->GetType() == formula::svSingleVectorRef)
-        {
-            const formula::SingleVectorRefToken* pSVR =
-            static_cast< const formula::SingleVectorRefToken* >(pCur);
-            ss << "    if (gid0 < " << pSVR->GetArrayLength() << "){\n";
-        }
-        else if (pCur->GetType() == formula::svDouble)
-        {
-            ss << "{\n";
-        }
-
-        if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
-        {
-            ss << "        if (isnan(";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss << "))\n";
-            ss << "            tmp"<<i<<"= 0;\n";
-            ss << "        else\n";
-            ss << "            tmp"<<i<<"=";
-            ss <<vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss << ";\n";
-            ss <<"    }\n";
-        }
-        else
-        {
-            ss << "        tmp"<<i<<"=";
-            ss <<vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss <<";\n";
-        }
-    }
+    GenerateArg( "tmp0", 0, vSubArguments, ss );
+    GenerateArg( "tmp1", 1, vSubArguments, ss );
+    GenerateArg( "tmp2", 2, vSubArguments, ss );
+    GenerateArg( "tmp3", 3, vSubArguments, ss );
+    GenerateArg( "tmp4", 4, vSubArguments, ss );
+    GenerateArg( "tmp5", 5, vSubArguments, ss );
+    GenerateArg( "tmp6", 6, vSubArguments, ss );
+    GenerateArgWithDefault( "tmp7", 7, 0, vSubArguments, ss );
     ss <<"    int nNullDate = GetNullDate();\n";
     ss <<"    tmp = GetOddlyield(nNullDate,tmp0,tmp1";
     ss <<",tmp2,tmp3,tmp4,tmp5,tmp6,tmp7);\n";
diff --git a/sc/source/core/opencl/op_financial.hxx 
b/sc/source/core/opencl/op_financial.hxx
index a485e09fa349..92f27430d513 100644
--- a/sc/source/core/opencl/op_financial.hxx
+++ b/sc/source/core/opencl/op_financial.hxx
@@ -167,6 +167,8 @@ class Fvschedule: public Normal
 public:
     virtual void GenSlidingWindowFunction(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments) override;
+    virtual std::string BinFuncName() const override {return "Fvschedule"; }
+    virtual bool canHandleMultiVector() const override { return true; }
 };
 
 class Cumipmt: public Normal
@@ -219,6 +221,8 @@ class MIRR: public Normal
 public:
     virtual void GenSlidingWindowFunction(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments) override;
+    virtual bool canHandleMultiVector() const override { return true; }
+    virtual std::string BinFuncName() const override { return "MIRR"; }
 };
 
 class OpEffective:public Normal
@@ -331,6 +335,7 @@ public:
     virtual void GenSlidingWindowFunction(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments) override;
     virtual std::string BinFuncName() const override { return "NPV"; }
+    virtual bool canHandleMultiVector() const override { return true; }
 };
 
 class OpPrice: public Normal
diff --git a/sc/source/core/opencl/op_math.cxx 
b/sc/source/core/opencl/op_math.cxx
index 7c501fc1e5f7..7c44d7b1e462 100644
--- a/sc/source/core/opencl/op_math.cxx
+++ b/sc/source/core/opencl/op_math.cxx
@@ -1224,82 +1224,15 @@ void OpFloor::GenSlidingWindowFunction(
 void OpSumSQ::GenSlidingWindowFunction(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT( 1, 30 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
     ss << "    int gid0=get_global_id(0);\n";
     ss << "    double sum = 0.0f, arg;\n";
-    for(const DynamicKernelArgumentRef & rArg : vSubArguments)
-    {
-        FormulaToken *tmpCur = rArg->GetFormulaToken();
-        assert(tmpCur);
-        if(ocPush == rArg->GetFormulaToken()->GetOpCode())
-        {
-            if (tmpCur->GetType() == formula::svDoubleVectorRef)
-            {
-                const formula::DoubleVectorRefToken* pDVR =
-                    static_cast<const formula::DoubleVectorRefToken *>(tmpCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; ++i)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+"<< nCurWindowSize << "; ++i)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < "<< nCurWindowSize << "; ++i)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < "<< nCurWindowSize << "; ++i)\n";
-                    ss << "    {\n";
-                }
-                ss << "        arg = ";
-                ss << rArg->GenSlidingWindowDeclRef();
-                ss << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        sum += pown(arg, 2);\n";
-                ss << "    }\n";
-            }
-            else if(tmpCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* tmpCurDVR=
-                      static_cast<
-                      const formula::SingleVectorRefToken *>(tmpCur);
-                ss << "    arg = ";
-                ss << rArg->GenSlidingWindowDeclRef();
-                ss << ";\n";
-                ss << "    if(isnan(arg)||(gid0>=";
-                ss << tmpCurDVR->GetArrayLength();
-                ss << "))\n";
-                ss << "        arg = 0.0f;\n";
-                ss << "    sum += pown(arg, 2);\n";
-            }
-            else if(tmpCur->GetType() == formula::svDouble)
-            {
-                ss << "        arg = ";
-                ss << tmpCur->GetDouble() << ";\n";
-                ss << "        sum += pown(arg, 2);\n";
-            }
-        }
-        else
-        {
-            ss << "        arg = ";
-            ss << rArg->GenSlidingWindowDeclRef();
-            ss << ";\n";
-            ss << "        sum += pown(arg, 2);\n";
-        }
-    }
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "            sum += pown(arg, 2);\n"
+        );
     ss << "    return sum;\n";
     ss << "}";
 }
@@ -1328,74 +1261,19 @@ void OpCeil::GenSlidingWindowFunction(outputstream &ss,
 void OpProduct::GenSlidingWindowFunction(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT( 1, 30 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
     ss << "    int gid0 = get_global_id(0);\n";
-    ss << "    int i = 0;\n";
     ss << "    double product=1.0;\n";
     ss << "    int count = 0;\n\n";
-    for (DynamicKernelArgumentRef & rArg : vSubArguments)
-    {
-        FormulaToken *pCur = rArg->GetFormulaToken();
-        assert(pCur);
-        if (pCur->GetType() == formula::svDoubleVectorRef)
-        {
-            const formula::DoubleVectorRefToken* pDVR =
-            static_cast<const formula::DoubleVectorRefToken *>(pCur);
-            size_t nCurWindowSize = pDVR->GetRefRowSize();
-
-            ss << "    for (int i = ";
-            if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-            {
-                 ss << "gid0; i < " << pDVR->GetArrayLength();
-                 ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                 ss << "    {\n";
-            }
-            else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-            {
-                 ss << "0; i < " << pDVR->GetArrayLength();
-                 ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                 ss << "    {\n";
-            }
-            else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-            {
-                 ss << "0; i + gid0 < " <<  pDVR->GetArrayLength();
-                 ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                 ss << "    {\n";
-            }
-            else if (pDVR->IsStartFixed() && pDVR->IsEndFixed())
-            {
-
-                 ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                 ss << "    {\n";
-            }
-            ss << "        
if(!isnan("<<rArg->GenSlidingWindowDeclRef()<<"))\n";
-            ss << "        {\n";
-            ss << "            product = product*";
-            ss << rArg->GenSlidingWindowDeclRef()<<";\n";
-            ss << "            ++count;\n";
-            ss << "        }\n";
-            ss << "    }\n";
-        }
-        else if (pCur->GetType() == formula::svSingleVectorRef)
-        {
-            ss << "    if(!isnan("<<rArg->GenSlidingWindowDeclRef()<<"))\n";
-            ss << "    {\n";
-            ss << "        product = product*";
-            ss << rArg->GenSlidingWindowDeclRef()<<";\n";
-            ss << "        ++count;\n";
-            ss << "    }\n";
-        }
-        else
-        {
-            ss << "    if(!isnan("<<rArg->GenSlidingWindowDeclRef()<<"))\n";
-            ss << "    {\n";
-            ss << "        product = product*";
-            ss << rArg->GenSlidingWindowDeclRef()<<";\n";
-            ss << "        ++count;\n";
-            ss << "    }\n";
-        }
-    }
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if(!isnan(arg))\n"
+        "        {\n"
+        "            product = product*arg;\n"
+        "            ++count;\n"
+        "        }\n"
+        );
     ss << "    if(count == 0)\n";
     ss << "        return 0;\n";
     ss << "    return product;\n";
@@ -1562,100 +1440,21 @@ void 
OpSeriesSum::GenSlidingWindowFunction(outputstream &ss,
     ss << "{\n";
     ss << "    int gid0=get_global_id(0);\n";
     ss << "    double var[3], coeff, res = 0.0f;\n";
-    FormulaToken *tmpCur;
-    for(int i = 0; i < 3; ++i)
-    {
-        tmpCur = vSubArguments[i]->GetFormulaToken();
-        assert(tmpCur);
-        if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
-        {
-            if(tmpCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* tmpCurDVR=
-                    static_cast<
-                    const formula::SingleVectorRefToken *>(tmpCur);
-                ss << "    var["<<i<<"] = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-                ss << ";\n";
-                ss << "    if(isnan(var["<<i<<"])||(gid0>=";
-                ss << tmpCurDVR->GetArrayLength();
-                ss << "))\n";
-                ss << "        var["<<i<<"] = 0;\n";
-            }
-            else if(tmpCur->GetType() == formula::svDouble)
-            {
-                ss << "    var["<<i<<"] = ";
-                ss << tmpCur->GetDouble() << ";\n";
-            }
-        }
-        else
-        {
-            ss << "    var["<<i<<"] = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss << ";\n";
-        }
-    }
-    tmpCur = vSubArguments[3]->GetFormulaToken();
-    assert(tmpCur);
-    if(ocPush == vSubArguments[3]->GetFormulaToken()->GetOpCode())
-    {
-        //TODO       DoubleVector
-        if (tmpCur->GetType() == formula::svDoubleVectorRef)
-        {
-            const formula::DoubleVectorRefToken* pDVR =
-                static_cast<const formula::DoubleVectorRefToken *>(tmpCur);
-            size_t nCurWindowSize = pDVR->GetRefRowSize();
-            ss << "    int j = 0;\n";
-            ss << "    for (int i = ";
-            if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-            {
-                ss << "gid0; i < " << pDVR->GetArrayLength();
-                ss << " && i < " << nCurWindowSize  << "; ++i)\n";
-                ss << "    {\n";
-            }
-            else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-            {
-                ss << "0; i < " << pDVR->GetArrayLength();
-                ss << " && i < gid0+"<< nCurWindowSize << "; ++i)\n";
-                ss << "    {\n";
-            }
-            else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-            {
-                ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                ss << " &&  i < "<< nCurWindowSize << "; ++i)\n";
-                ss << "    {\n";
-            }
-            else
-            {
-                ss << "0; i < "<< nCurWindowSize << "; ++i)\n";
-                ss << "    {\n";
-            }
-            ss << "        coeff = ";
-            ss << vSubArguments[3]->GenSlidingWindowDeclRef();
-            ss << ";\n";
-            ss << "        if (isnan(coeff))\n";
-            ss << "            continue;\n";
-            ss << "        res = res + coeff * pow(var[0],";
-            ss << " var[1] + j * var[2]);\n";
-            ss << "        ++j;\n";
-            ss << "    }\n";
-        }
-        else if(tmpCur->GetType() == formula::svSingleVectorRef)
-        {
-            const formula::SingleVectorRefToken* tmpCurDVR=
-                static_cast<
-                const formula::SingleVectorRefToken *>(tmpCur);
-            ss << "    coeff = ";
-            ss << vSubArguments[3]->GenSlidingWindowDeclRef();
-            ss << ";\n";
-            ss << "    if(isnan(coeff)||(gid0>=";
-            ss << tmpCurDVR->GetArrayLength();
-            ss << "))\n";
-            ss << "        return 0;\n";
-        }
-        else
-            throw Unhandled(__FILE__, __LINE__);
-    }
+    GenerateArg( "var0", 0, vSubArguments, ss );
+    GenerateArg( "var1", 1, vSubArguments, ss );
+    GenerateArg( "var2", 2, vSubArguments, ss );
+    ss << "    var[0] = var0;\n";
+    ss << "    var[1] = var1;\n";
+    ss << "    var[2] = var2;\n";
+    ss << "    int j = 0;\n";
+    GenerateRangeArg( 3, vSubArguments, ss,
+        "        double coeff = arg;\n"
+        "        if (!isnan(coeff))\n"
+        "        {\n"
+        "            res = res + coeff * pow(var[0], var[1] + j * var[2]);\n"
+        "            ++j;\n"
+        "        }\n"
+        );
     ss << "    return res;\n";
     ss << "}";
 }
diff --git a/sc/source/core/opencl/op_math.hxx 
b/sc/source/core/opencl/op_math.hxx
index a1cfa5de0b61..5e1649a7d6ed 100644
--- a/sc/source/core/opencl/op_math.hxx
+++ b/sc/source/core/opencl/op_math.hxx
@@ -314,6 +314,7 @@ public:
             const std::string &sSymName, SubArguments &vSubArguments) override;
 
     virtual std::string BinFuncName() const override { return "SumSQ"; }
+    virtual bool canHandleMultiVector() const override { return true; }
 };
 
 class OpCoth: public OpMathOneArgument
@@ -480,6 +481,7 @@ public:
     virtual void GenSlidingWindowFunction(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments) override;
     virtual std::string BinFuncName() const override { return "SeriesSum"; }
+    virtual bool canHandleMultiVector() const override { return true; }
 };
 class OpSumIf: public Normal
 {
diff --git a/sc/source/core/opencl/op_statistical.cxx 
b/sc/source/core/opencl/op_statistical.cxx
index aedabb4fc14c..4cb421020ce7 100644
--- a/sc/source/core/opencl/op_statistical.cxx
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -45,6 +45,38 @@ void OpVar::GenSlidingWindowFunction(outputstream &ss,
     ss << "        return vSum / (fCount - 1.0);\n";
     ss << "}\n";
 }
+
+void OpVarP::GenSlidingWindowFunction(outputstream &ss,
+            const std::string &sSymName, SubArguments &vSubArguments)
+{
+    CHECK_PARAMETER_COUNT( 1, 30 );
+    GenerateFunctionDeclaration( sSymName, vSubArguments, 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";
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "        {\n"
+        "            fSum += arg;\n"
+        "            fCount += 1.0;\n"
+        "        }\n"
+        );
+    ss << "    fMean = fSum / fCount;\n";
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "            vSum += (arg - fMean) * (arg - fMean);\n"
+        );
+    ss << "    if (fCount == 0.0)\n";
+    ss << "        return CreateDoubleError(DivisionByZero);\n";
+    ss << "    else\n";
+    ss << "        return vSum / fCount;\n";
+    ss << "}\n";
+}
+
 void OpZTest::BinInlineFun(std::set<std::string>& decls,
     std::set<std::string>& funs)
 {
@@ -58,6 +90,7 @@ void OpZTest::BinInlineFun(std::set<std::string>& decls,
 void OpZTest::GenSlidingWindowFunction(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT( 2, 3 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
     ss << "    int gid0 = get_global_id(0);\n";
@@ -65,223 +98,24 @@ void OpZTest::GenSlidingWindowFunction(outputstream &ss,
     ss << "    double fSumSqr = 0.0;\n";
     ss << "    double mue = 0.0;\n";
     ss << "    double fCount = 0.0;\n";
-    ss << "    double arg = 0.0;\n";
-    ss << "    double sigma = 0.0;\n";
-    ss << "    double mu = 0.0;\n";
-    if(vSubArguments.size() == 1 || vSubArguments.empty())
-    {
-        ss << "    return DBL_MAX;\n";
-        ss << "}\n";
-        return ;
-    }
-    else if(vSubArguments.size() == 2)
-    {
-        FormulaToken *pCur = vSubArguments[0]->GetFormulaToken();
-        FormulaToken *pCur1 = vSubArguments[1]->GetFormulaToken();
-        assert(pCur);
-        assert(pCur1);
-        if(pCur->GetType() == formula::svDoubleVectorRef)
-        {
-            const formula::DoubleVectorRefToken* pDVR =
-                static_cast<const formula::DoubleVectorRefToken *>(pCur);
-            size_t nCurWindowSize = pDVR->GetRefRowSize();
-            ss << "    for (int i = ";
-            if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-            {
-                ss << "gid0; i < " << pDVR->GetArrayLength();
-                ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                ss << "    {\n";
-            }
-            else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-            {
-                ss << "0; i < " << pDVR->GetArrayLength();
-                ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                ss << "    {\n";
-            }
-            else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-            {
-                ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                ss << "    {\n";
-            }
-            else
-            {
-                ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                ss << "    {\n";
-            }
-
-            ss << "        arg = ";
-            ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
-            ss << "        if (isnan(arg))\n";
-            ss << "            continue;\n";
-            ss << "        fSum += arg;\n";
-            ss << "        fSumSqr += arg * arg;\n";
-            ss << "        fCount += 1.0;\n";
-            ss << "    }\n";
-            ss << "    if(fCount <= 1.0)\n";
-            ss << "        return DBL_MAX;\n";
-            ss << "    mue = fSum / fCount;\n";
-            ss << "    sigma = (fSumSqr-fSum*fSum/fCount)/(fCount-1.0);\n";
-        }
-        else
-        {
-            ss << "    return DBL_MAX;\n";
-            ss << "}\n";
-            return ;
-        }
-        if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
-        {
-            if(pCur1->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast<const formula::SingleVectorRefToken* >(pCur1);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        mu = " ;
-                ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(mu))\n";
-                ss << "            mu = 0.0;\n";
-                ss << "    }\n";
-
-            }
-            else if(pCur1->GetType() == formula::svDouble)
-            {
-                ss << "    mu = " << pCur1->GetDouble() << ";\n";
-            }
-            else
-            {
-                ss << "    return DBL_MAX;\n";
-                ss << "}\n";
-                return ;
-            }
-        }
-        else
-        {
-            ss << "    mu = " ;
-            ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
-        }
-        ss << "    return 0.5 - gauss((mue-mu)/sqrt(sigma/fCount));\n";
-        ss << "}\n";
-        return ;
-    }
+    GenerateRangeArg( 0, vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "        {\n"
+        "            fSum += arg;\n"
+        "            fSumSqr += arg * arg;\n"
+        "            fCount += 1.0;\n"
+        "        }\n"
+        );
+    ss << "    if(fCount <= 1.0)\n";
+    ss << "        return CreateDoubleError(DivisionByZero);\n";
+    ss << "    mue = fSum / fCount;\n";
+    GenerateArg( "mu", 1, vSubArguments, ss );
+    if(vSubArguments.size() == 3)
+        GenerateArg( "sigma", 2, vSubArguments, ss );
     else
-    {
-        FormulaToken *pCur = vSubArguments[0]->GetFormulaToken();
-        FormulaToken *pCur1 = vSubArguments[1]->GetFormulaToken();
-        FormulaToken *pCur2 = vSubArguments[2]->GetFormulaToken();
-        assert(pCur);
-        assert(pCur1);
-        assert(pCur2);
-        if(pCur->GetType() == formula::svDoubleVectorRef)
-        {
-            const formula::DoubleVectorRefToken* pDVR =
-                static_cast<const formula::DoubleVectorRefToken *>(pCur);
-            size_t nCurWindowSize = pDVR->GetRefRowSize();
-            ss << "    for (int i = ";
-            if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-            {
-                ss << "gid0; i < " << pDVR->GetArrayLength();
-                ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                ss << "    {\n";
-            }
-            else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-            {
-                ss << "0; i < " << pDVR->GetArrayLength();
-                ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                ss << "    {\n";
-            }
-            else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-            {
-                ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                ss << "    {\n";
-            }
-            else
-            {
-                ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                ss << "    {\n";
-            }
-            ss << "        arg = ";
-            ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
-            ss << "        if (isnan(arg))\n";
-            ss << "            continue;\n";
-            ss << "        fSum += arg;\n";
-            ss << "        fSumSqr += arg * arg;\n";
-            ss << "        fCount += 1.0;\n";
-            ss << "    }\n";
-            ss << "    if(fCount <= 1.0)\n";
-            ss << "        return DBL_MAX;\n";
-            ss << "    mue = fSum / fCount;\n";
-        }
-        else
-        {
-            ss << "    return DBL_MAX;\n";
-            ss << "}\n";
-            return ;
-        }
-        if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
-        {
-            if(pCur1->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR1 =
-                    static_cast<const formula::SingleVectorRefToken* >(pCur1);
-                ss << "    if (gid0 < " << pSVR1->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        mu = " ;
-                ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(mu))\n";
-                ss << "            mu = 0.0;\n";
-                ss << "    }\n";
-            }
-            else if(pCur1->GetType() == formula::svDouble)
-            {
-                ss << "    mu = " << pCur1->GetDouble() << ";\n";
-            }
-            else
-            {
-                ss << "    return DBL_MAX;\n";
-                ss << "}\n";
-                return ;
-            }
-        }
-        else
-        {
-            ss << "    mu=" ;
-            ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
-        }
-        if(ocPush == vSubArguments[2]->GetFormulaToken()->GetOpCode())
-        {
-            if(pCur2->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR2 =
-                    static_cast<const formula::SingleVectorRefToken* >(pCur2);
-                ss << "    if (gid0 < " << pSVR2->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        sigma = " ;
-                ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(sigma))\n";
-                ss << "            sigma = 0.0;\n";
-                ss << "    }\n";
-            }
-            else if(pCur2->GetType() == formula::svDouble)
-            {
-                ss << "    sigma = " << pCur2->GetDouble() << ";\n";
-            }
-            else
-            {
-                ss << "    return DBL_MAX;\n";
-                ss << "}\n";
-                return ;
-            }
-        }
-        else
-        {
-            ss << "    sigma = " ;
-            ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ";\n";
-        }
-        ss << "    return 0.5 - gauss((mue-mu)*sqrt(fCount)/sigma);\n";
-        ss << "}\n";
-    }
+        ss << "    double sigma = (fSumSqr-fSum*fSum/fCount)/(fCount-1.0);\n";
+    ss << "    return 0.5 - gauss((mue-mu)/sqrt(sigma/fCount));\n";
+    ss << "}\n";
 }
 
 void OpTTest::BinInlineFun(std::set<std::string>& decls,
@@ -626,201 +460,33 @@ void OpTTest::GenSlidingWindowFunction(outputstream &ss,
         ss << "}\n";
     }
 }
-void OpVarP::GenSlidingWindowFunction(outputstream &ss,
+
+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(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments)
 {
-    GenerateFunctionDeclaration( sSymName, vSubArguments, 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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-                ss << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        fSum += arg;\n";
-                ss << "        fCount += 1.0;\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken*>(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            fSum += arg;\n";
-                ss << "            fCount += 1.0;\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            else
-            {
-                ss << "    arg = " << pCur->GetDouble() << ";\n";
-                ss << "    fSum += arg;\n";
-                ss << "    fCount += 1.0;\n";
-            }
-        }
-        else
-        {
-            ss << "    arg = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-            ss << "    fSum += arg;\n";
-            ss << "    fCount += 1.0;\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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
-
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-                ss << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        vSum += (arg - fMean) * (arg - fMean);\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken*>(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            vSum += (arg - fMean) * (arg - fMean);\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            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 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(outputstream &ss,
-            const std::string &sSymName, SubArguments &vSubArguments)
-{
-    CHECK_PARAMETER_COUNT( 3, 3 );
+    CHECK_PARAMETER_COUNT( 3, 3 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
     ss << "    int gid0 = get_global_id(0);\n";
@@ -950,6 +616,7 @@ void OpWeibull::GenSlidingWindowFunction(outputstream &ss,
 void OpSkew::GenSlidingWindowFunction(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT( 1, 30 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
     ss << "    int gid0 = get_global_id(0);\n";
@@ -957,249 +624,42 @@ void OpSkew::GenSlidingWindowFunction(outputstream &ss,
     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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
-
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        fSum += arg;\n";
-                ss << "        fCount += 1.0;\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken* >(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            fSum += arg;\n";
-                ss << "            fCount += 1.0;\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            else
-            {
-                ss << "    arg = " << pCur->GetDouble() << ";\n";
-                ss << "    fSum += arg;\n";
-                ss << "    fCount += 1.0;\n";
-            }
-        }
-        else
-        {
-            ss << "    arg = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-            ss << "    fSum += arg;\n";
-            ss << "    fCount += 1.0;\n";
-        }
-
-        if(i == 0)
-        {
-            ss << "    if(fCount <= 2.0)\n";
-            ss << "        return DBL_MAX;\n";
-            ss << "    else\n";
-            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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
-
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        vSum += (arg - fMean) * (arg - fMean);\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken* >(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            vSum += (arg - fMean) * (arg - fMean);\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            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 << "    double fStdDev = sqrt(vSum / (fCount - 1.0));\n";
-    ss << "    double dx = 0.0;\n";
-    ss << "    double xcube = 0.0;\n";
-    ss << "    if(fStdDev == 0.0)\n";
-    ss << "        return DBL_MAX;\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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
-
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        dx = (arg - fMean) / fStdDev;\n";
-                ss << "        xcube = xcube + dx * dx * dx;\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken* >(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            dx = (arg - fMean) / fStdDev;\n";
-                ss << "            xcube = xcube + dx * dx * dx;\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            else
-            {
-                ss << "    arg = " << pCur->GetDouble() << ";\n";
-                ss << "    dx = (arg - fMean) / fStdDev;\n";
-                ss << "    xcube = xcube + dx * dx * dx;\n";
-            }
-        }
-        else
-        {
-            ss << "    arg = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-            ss << "    dx = (arg - fMean) / fStdDev;\n";
-            ss << "    xcube = xcube + dx * dx * dx;\n";
-        }
-    }
-    ss << "    return ((xcube * fCount) / (fCount - 1.0))";
-    ss << " / (fCount - 2.0);\n";
-    ss << "}\n";
-}
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "        {\n"
+        "            fSum += arg;\n"
+        "            fCount += 1.0;\n"
+        "        }\n"
+        );
+    ss << "    if(fCount <= 2.0)\n";
+    ss << "        return CreateDoubleError(DivisionByZero);\n";
+    ss << "    else\n";
+    ss << "        fMean = fSum / fCount;\n";
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "            vSum += (arg - fMean) * (arg - fMean);\n"
+        );
+    ss << "    double fStdDev = sqrt(vSum / (fCount - 1.0));\n";
+    ss << "    double dx = 0.0;\n";
+    ss << "    double xcube = 0.0;\n";
+    ss << "    if(fStdDev == 0.0)\n";
+    ss << "        return CreateDoubleError(IllegalArgument);\n";
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "        {\n"
+        "            dx = (arg - fMean) / fStdDev;\n"
+        "            xcube = xcube + dx * dx * dx;\n"
+        "        }\n"
+        );
+    ss << "    return ((xcube * fCount) / (fCount - 1.0))";
+    ss << " / (fCount - 2.0);\n";
+    ss << "}\n";
+}
 
 void OpSkewp::GenSlidingWindowFunction(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT( 1, 3 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
     ss << "    int gid0 = get_global_id(0);\n";
@@ -1207,241 +667,33 @@ void OpSkewp::GenSlidingWindowFunction(outputstream &ss,
     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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
-
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        fSum += arg;\n";
-                ss << "        fCount += 1.0;\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken* >(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            fSum += arg;\n";
-                ss << "            fCount += 1.0;\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            else
-            {
-                ss << "    arg = " << pCur->GetDouble() << ";\n";
-                ss << "    fSum += arg;\n";
-                ss << "    fCount += 1.0;\n";
-            }
-        }
-        else
-        {
-            ss << "    arg = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-            ss << "    fSum += arg;\n";
-            ss << "    fCount += 1.0;\n";
-        }
-
-        if(i == 0)
-        {
-            ss << "    if(fCount <= 2.0)\n";
-            ss << "        return DBL_MAX;\n";
-            ss << "    else\n";
-            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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
-
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        vSum += (arg - fMean) * (arg - fMean);\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken* >(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            vSum += (arg - fMean) * (arg - fMean);\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            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";
-        }
-    }
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "        {\n"
+        "            fSum += arg;\n"
+        "            fCount += 1.0;\n"
+        "        }\n"
+        );
+    ss << "    if(fCount <= 2.0)\n";
+    ss << "        return CreateDoubleError(DivisionByZero);\n";
+    ss << "    else\n";
+    ss << "        fMean = fSum / fCount;\n";
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "            vSum += (arg - fMean) * (arg - fMean);\n"
+        );
     ss << "    double fStdDev = sqrt(vSum / fCount);\n";
     ss << "    double dx = 0.0;\n";
     ss << "    double xcube = 0.0;\n";
     ss << "    if(fStdDev == 0.0)\n";
-    ss << "        return DBL_MAX;\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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
-
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        dx = (arg - fMean) / fStdDev;\n";
-                ss << "        xcube = xcube + dx * dx * dx;\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken* >(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            dx = (arg - fMean) / fStdDev;\n";
-                ss << "            xcube = xcube + dx * dx * dx;\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            else
-            {
-                ss << "    arg = " << pCur->GetDouble() << ";\n";
-                ss << "    dx = (arg - fMean) / fStdDev;\n";
-                ss << "    xcube = xcube + dx * dx * dx;\n";
-            }
-        }
-        else
-        {
-            ss << "    arg = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-            ss << "    dx = (arg - fMean) / fStdDev;\n";
-            ss << "    xcube = xcube + dx * dx * dx;\n";
-        }
-    }
+    ss << "        return CreateDoubleError(IllegalArgument);\n";
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "        {\n"
+        "            dx = (arg - fMean) / fStdDev;\n"
+        "            xcube = xcube + dx * dx * dx;\n"
+        "        }\n"
+        );
     ss << "    return xcube / fCount;\n";
     ss << "}\n";
 }
@@ -1499,334 +751,58 @@ void OpTInv::GenSlidingWindowFunction(outputstream &ss,
 void OpStDev::GenSlidingWindowFunction(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT( 1, 30 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
-    ss << "    int gid0 = get_global_id(0);\n";
-    ss << "    double fSum = 0.0;\n";
-    ss << "    double vSum = 0.0;\n";
-    ss << "    double fMean = 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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
-
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        fSum += arg;\n";
-                ss << "        fCount += 1.0;\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken* >(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            fSum += arg;\n";
-                ss << "            fCount += 1.0;\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            else
-            {
-                ss << "    arg = " << pCur->GetDouble() << ";\n";
-                ss << "    fSum += arg;\n";
-                ss << "    fCount += 1.0;\n";
-            }
-        }
-        else
-        {
-            ss << "    arg = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-            ss << "    fSum += arg;\n";
-            ss << "    fCount += 1.0;\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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        vSum += (arg - fMean) * (arg - fMean);\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken* >(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            vSum += (arg - fMean) * (arg - fMean);\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            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 <= 1.0)\n";
-    ss << "        return DBL_MAX;\n";
-    ss << "    else\n";
-    ss << "        return sqrt(vSum / (fCount - 1.0));\n";
-    ss << "}\n";
-}
-
-void OpStDevP::GenSlidingWindowFunction(outputstream &ss,
-            const std::string &sSymName, SubArguments &vSubArguments)
-{
-    GenerateFunctionDeclaration( sSymName, vSubArguments, 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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
-
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        fSum += arg;\n";
-                ss << "        fCount += 1.0;\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken* >(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            fSum += arg;\n";
-                ss << "            fCount += 1.0;\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            else
-            {
-                ss << "    arg = " << pCur->GetDouble() << ";\n";
-                ss << "    fSum += arg;\n";
-                ss << "    fCount += 1.0;\n";
-            }
-        }
-        else
-        {
-            ss << "    arg = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-            ss << "    fSum += arg;\n";
-            ss << "    fCount += 1.0;\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 =
-                    static_cast<const formula::DoubleVectorRefToken *>(pCur);
-                size_t nCurWindowSize = pDVR->GetRefRowSize();
-                ss << "    for (int i = ";
-                if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
-                {
-                    ss << "gid0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < " << nCurWindowSize  << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength();
-                    ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
-                {
-                    ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                    ss << " &&  i < " << nCurWindowSize << "; i++)\n";
-                    ss << "    {\n";
-                }
-                else
-                {
-                    ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
-                    ss << "    {\n";
-                }
+    ss << "    int gid0 = get_global_id(0);\n";
+    ss << "    double fSum = 0.0;\n";
+    ss << "    double vSum = 0.0;\n";
+    ss << "    double fMean = 0.0;\n";
+    ss << "    double fCount = 0.0;\n";
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "        {\n"
+        "            fSum += arg;\n"
+        "            fCount += 1.0;\n"
+        "        }\n"
+        );
+    ss << "    fMean = fSum / fCount;\n";
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "            vSum += (arg - fMean) * (arg - fMean);\n"
+        );
+    ss << "    if (fCount <= 1.0)\n";
+    ss << "        return CreateDoubleError(DivisionByZero);\n";
+    ss << "    else\n";
+    ss << "        return sqrt(vSum / (fCount - 1.0));\n";
+    ss << "}\n";
+}
 
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (isnan(arg))\n";
-                ss << "            continue;\n";
-                ss << "        vSum += (arg - fMean) * (arg - fMean);\n";
-                ss << "    }\n";
-            }
-            else if (pCur->GetType() == formula::svSingleVectorRef)
-            {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken* >(pCur);
-                ss << "    if (gid0 < " << pSVR->GetArrayLength() << ")\n";
-                ss << "    {\n";
-                ss << "        arg = ";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
-                ss << "        if (!isnan(arg))\n";
-                ss << "        {\n";
-                ss << "            vSum += (arg - fMean) * (arg - fMean);\n";
-                ss << "        }\n";
-                ss << "    }\n";
-            }
-            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";
+void OpStDevP::GenSlidingWindowFunction(outputstream &ss,
+            const std::string &sSymName, SubArguments &vSubArguments)
+{
+    CHECK_PARAMETER_COUNT( 1, 30 );
+    GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
+    ss << "{\n";
+    ss << "    int gid0 = get_global_id(0);\n";
+    ss << "    double fSum = 0.0;\n";
+    ss << "    double vSum = 0.0;\n";
+    ss << "    double fMean = 0.0;\n";
+    ss << "    double fCount = 0.0;\n";
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "        {\n"
+        "            fSum += arg;\n"
+        "            fCount += 1.0;\n"
+        "        }\n"
+        );
+    ss << "    fMean = fSum / fCount;\n";
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if (!isnan(arg))\n"
+        "            vSum += (arg - fMean) * (arg - fMean);\n"
+        );
+    ss << "    if (fCount <= 1.0)\n";
+    ss << "        return CreateDoubleError(DivisionByZero);\n";
     ss << "    else\n";
     ss << "        return sqrt(vSum / fCount);\n";
     ss << "}\n";
@@ -2119,9 +1095,8 @@ void OpSTEYX::GenSlidingWindowFunction(outputstream &ss,
         ss << "}\n";
     }
 }
-void OpFisher::GenSlidingWindowFunction(
-    outputstream &ss, const std::string &sSymName, SubArguments &
-vSubArguments)
+void OpFisher::GenSlidingWindowFunction( outputstream &ss,
+    const std::string &sSymName, SubArguments &vSubArguments)
 {
     CHECK_PARAMETER_COUNT( 1, 1 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
@@ -2658,6 +1633,7 @@ void OpHarMean::GenSlidingWindowFunction(
     outputstream &ss, const std::string &sSymName, SubArguments &
 vSubArguments)
 {
+    CHECK_PARAMETER_COUNT( 1, 30 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
     ss << "    int gid0 = get_global_id(0);\n";
@@ -2665,59 +1641,13 @@ vSubArguments)
     ss << "    double tmp = 0;\n";
     ss << "    int length;\n";
     ss << "    int totallength=0;\n";
-    for (size_t i = 0; i < vSubArguments.size(); i++)
-    {
-        FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
-        assert(pCur);
-        if (pCur->GetType() == formula::svDoubleVectorRef)
-        {
-            const formula::DoubleVectorRefToken* pDVR =
-                static_cast<const formula::DoubleVectorRefToken *>(pCur);
-            size_t nCurWindowSize = pDVR->GetRefRowSize();
-            ss << "    length="<<nCurWindowSize;
-            ss << ";\n";
-            ss << "    for (int i = ";
-            ss << "0; i < "<< nCurWindowSize << "; i++)\n";
-            ss << "    {\n";
-            ss << "        double arg"<<i<<" = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss << ";\n";
-            ss << "        if(isnan(arg"<<i<<")||((gid0+i)>=";
-            ss << pDVR->GetArrayLength();
-            ss << "))\n";
-            ss << "        {\n";
-            ss << "            length--;\n";
-            ss << "            continue;\n";
-            ss << "        }\n";
-            ss << "        nVal += (1.0 *pow(";
-            ss << " arg"<<i<<",-1));\n";
-            ss << "    }\n";
-            ss << "    totallength +=length;\n";
-        }
-        else if (pCur->GetType() == formula::svSingleVectorRef)
-        {
-            ss << "    tmp = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss << ";\n";
-            ss << "    if(!isnan(tmp))\n";
-            ss << "    {\n";
-            ss << "        nVal += (1.0 / tmp);\n";
-            ss << "        totallength +=1;\n";
-            ss << "    }\n";
-        }
-        else if (pCur->GetType() == formula::svDouble)
-        {
-           ss << "    tmp = ";
-           ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-           ss << ";\n";
-           ss << "    nVal += (1.0 / tmp);\n";
-           ss << "    totallength +=1;\n";
-        }
-        else
-        {
-            ss << "    return DBL_MIN;\n";
-        }
-    }
+    GenerateRangeArgs( vSubArguments, ss,
+        "        if(!isnan(arg))\n"
+        "        {\n"
+        "            nVal += (1.0 / arg);\n"
+        "            ++totallength;\n"
+        "        }\n"
+        );
     ss << "    tmp = totallength/nVal;\n";
     ss << "    return tmp;\n";
     ss << "}";
@@ -2918,71 +1848,24 @@ void OpChiInv::GenSlidingWindowFunction(
     outputstream &ss,const std::string &sSymName,
     SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT( 2, 2 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
-    ss << "    double tmp0,tmp1,tmp;\n";
+    ss << "    double tmp;\n";
     ss << "    int gid0=get_global_id(0);\n";
     ss <<"\n    ";
-    for (size_t i = 0; i < vSubArguments.size(); i++)
-    {
-        FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
-        assert(pCur);
-        if (pCur->GetType() == formula::svDoubleVectorRef)
-        {
-            const formula::DoubleVectorRefToken* pDVR =
-                static_cast<const formula::DoubleVectorRefToken *>(pCur);
-            size_t nCurWindowSize = pDVR->GetRefRowSize();
-            ss << "for (int i = ";
-            if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) {
-                ss << "gid0; i < " << pDVR->GetArrayLength();
-                ss << " && i < " << nCurWindowSize  << "; i++){\n";
-            } else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) {
-                ss << "0; i < " << pDVR->GetArrayLength();
-                ss << " && i < gid0+"<< nCurWindowSize << "; i++){\n";
-            } else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()){
-                ss << "0; i + gid0 < " << pDVR->GetArrayLength();
-                ss << " &&  i < "<< nCurWindowSize << "; i++){\n";
-            } else {
-                ss << "0; i < "<< nCurWindowSize << "; i++){\n";
-            }
-        }
-        else if (pCur->GetType() == formula::svSingleVectorRef)
-        {
-                const formula::SingleVectorRefToken* pSVR =
-                    static_cast< const formula::SingleVectorRefToken* >(pCur);
-                ss << "if (gid0 < " << pSVR->GetArrayLength() << "){\n";
-        }
-        else if (pCur->GetType() == formula::svDouble)
-        {
-            ss << "{\n";
-        }
-
-        if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
-        {
-                ss << "if (isnan(";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-                ss << "))\n";
-                ss << "    tmp"<<i<<"= 0;\n";
-                ss << "else\n";
-                ss 
<<"tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
-                ss << ";\n}\n";
-        }
-        else
-        {
-               ss << 
"tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
-               ss << ";\n";
-        }
-    }
+    GenerateArg( "tmp0", 0, vSubArguments, ss );
+    GenerateArg( "tmp1", 1, vSubArguments, ss );
     ss << "    tmp1 = floor(tmp1);";
     ss << "    if (tmp1 < 1.0 || tmp0 <= 0.0 || tmp0 > 1.0 )\n";
     ss << "    {\n";
-    ss << "        return DBL_MIN;\n";
+    ss << "        return CreateDoubleError(IllegalArgument);\n";
     ss << "    }\n";
     ss << "    bool bConvError;\n";
     ss << "    double fVal = lcl_IterateInverseChiInv";
     ss << "(tmp0, tmp1, tmp1*0.5, tmp1, &bConvError);\n";
     ss << "    if(bConvError)\n";
-    ss << "        return DBL_MIN;\n";
+    ss << "        return CreateDoubleError(NoConvergence);\n";
     ss << "    return fVal;\n";
     ss << "}\n";
 }
@@ -3440,198 +2323,75 @@ void OpMedian::GenSlidingWindowFunction(
             }
             ss << "gid0; endFlag = gid0+"<< nCurWindowSize <<";\n";
         }
-        else
-        {
-            ss<<"startFlag=gid0;endFlag=gid0;\n";
-        }
-    }
-    FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
-    const formula::DoubleVectorRefToken*tmpCurDVR0= static_cast<const
-    formula::DoubleVectorRefToken *>(tmpCur0);
-    ss << "int buffer_fIna_len = ";
-    ss << tmpCurDVR0->GetArrayLength();
-    ss << ";\n";
-    ss<<"if((i+gid0)>=buffer_fIna_len || isnan(";
-    ss << vSubArguments[0]->GenSlidingWindowDeclRef();
-    ss<<"))\n";
-    ss<<"    dataIna = 0;\n";
-    ss << "    int nSize =endFlag- startFlag ;\n";
-    ss << "    if (nSize & 1)\n";
-    ss << "    {\n";
-    ss << "        tmp = "<<vSubArguments[0]->GetName();
-    ss << "        [startFlag+nSize/2];\n";
-    ss << "    }\n";
-    ss << "    else\n";
-    ss << "    {\n";
-    ss << "        tmp =("<<vSubArguments[0]->GetName();
-    ss << "        [startFlag+nSize/2]+";
-    ss <<          vSubArguments[0]->GetName();
-    ss << "        [startFlag+nSize/2-1])/2;\n";
-    ss << "    }\n";
-    ss <<"     return tmp;\n";
-    ss << "}\n";
-}
-void OpKurt:: GenSlidingWindowFunction(outputstream &ss,
-            const std::string &sSymName, SubArguments &vSubArguments)
-{
-    GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
-    ss << "{\n";
-    ss << "    int gid0 = get_global_id(0);\n";
-    ss << "    double fSum = 0.0;\n";
-    ss << "    double vSum = 0.0;\n";
-    ss << "    double length;\n";
-    ss << "    double totallength=0;\n";
-    ss << "    double tmp = 0;\n";
-    for (size_t i = 0; i < vSubArguments.size(); i++)
-    {
-        FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
-        assert(pCur);
-        if (pCur->GetType() == formula::svDoubleVectorRef)
-        {
-            const formula::DoubleVectorRefToken* pDVR =
-                static_cast<const formula::DoubleVectorRefToken *>(pCur);
-            size_t nCurWindowSize = pDVR->GetRefRowSize();
-            ss << "    length="<<nCurWindowSize;
-            ss << ";\n";
-            ss << "    for (int i = ";
-            ss << "0; i < "<< nCurWindowSize << "; i++)\n";
-            ss << "    {\n";
-            ss << "        double arg"<<i<<" = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef(true);
-            ss << ";\n";
-            ss << "        if(isnan(arg"<<i<<")||((gid0+i)>=";
-            ss << pDVR->GetArrayLength();
-            ss << "))\n";
-            ss << "        {\n";
-            ss << "            length-=1.0;\n";
-            ss << "            continue;\n";
-            ss << "        }\n";
-            ss << "        fSum +=  arg"<<i<<";\n";
-            ss << "    }\n";
-            ss << "    totallength +=length;\n";
-        }
-        else if (pCur->GetType() == formula::svSingleVectorRef)
-        {
-            ss << "    tmp = ";
-            ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-            ss << ";\n";
-            ss << "    if(!isnan(tmp))\n";
-            ss << "    {\n";
-            ss << "        fSum += tmp;\n";
-            ss << "        totallength +=1;\n";
-            ss << "    }\n";
-        }
-        else if (pCur->GetType() == formula::svDouble)
-        {
-           ss << "    tmp = ";
-           ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-           ss << ";\n";
-           ss << "    fSum += tmp;\n";
-           ss << "    totallength +=1;\n";
-        }

... etc. - the rest is truncated

Reply via email to