summaryrefslogtreecommitdiffstats
path: root/sc/source/core/opencl
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/core/opencl')
-rw-r--r--sc/source/core/opencl/cl-test.odsbin0 -> 18569 bytes
-rw-r--r--sc/source/core/opencl/formulagroupcl.cxx4437
-rw-r--r--sc/source/core/opencl/op_addin.cxx236
-rw-r--r--sc/source/core/opencl/op_addin.hxx36
-rw-r--r--sc/source/core/opencl/op_array.cxx191
-rw-r--r--sc/source/core/opencl/op_array.hxx44
-rw-r--r--sc/source/core/opencl/op_database.cxx1642
-rw-r--r--sc/source/core/opencl/op_database.hxx109
-rw-r--r--sc/source/core/opencl/op_financial.cxx4791
-rw-r--r--sc/source/core/opencl/op_financial.hxx582
-rw-r--r--sc/source/core/opencl/op_logical.cxx360
-rw-r--r--sc/source/core/opencl/op_logical.hxx61
-rw-r--r--sc/source/core/opencl/op_math.cxx3207
-rw-r--r--sc/source/core/opencl/op_math.hxx502
-rw-r--r--sc/source/core/opencl/op_spreadsheet.cxx286
-rw-r--r--sc/source/core/opencl/op_spreadsheet.hxx30
-rw-r--r--sc/source/core/opencl/op_statistical.cxx9830
-rw-r--r--sc/source/core/opencl/op_statistical.hxx553
-rw-r--r--sc/source/core/opencl/opbase.cxx391
-rw-r--r--sc/source/core/opencl/opbase.hxx249
-rw-r--r--sc/source/core/opencl/opinlinefun_finacial.cxx1920
-rw-r--r--sc/source/core/opencl/opinlinefun_math.hxx91
-rw-r--r--sc/source/core/opencl/opinlinefun_statistical.cxx1366
23 files changed, 30914 insertions, 0 deletions
diff --git a/sc/source/core/opencl/cl-test.ods b/sc/source/core/opencl/cl-test.ods
new file mode 100644
index 000000000..7e2bae4cb
--- /dev/null
+++ b/sc/source/core/opencl/cl-test.ods
Binary files differ
diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
new file mode 100644
index 000000000..f505e23c9
--- /dev/null
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -0,0 +1,4437 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <formulagroup.hxx>
+#include <formulagroupcl.hxx>
+#include <document.hxx>
+#include <formulacell.hxx>
+#include <tokenarray.hxx>
+#include <compiler.hxx>
+#include <comphelper/random.hxx>
+#include <formula/vectortoken.hxx>
+#include <scmatrix.hxx>
+#include <sal/log.hxx>
+#include <rtl/math.hxx>
+
+#include <opencl/openclwrapper.hxx>
+#include <opencl/OpenCLZone.hxx>
+
+#include "op_financial.hxx"
+#include "op_database.hxx"
+#include "op_math.hxx"
+#include "op_logical.hxx"
+#include "op_statistical.hxx"
+#include "op_array.hxx"
+#include "op_spreadsheet.hxx"
+#include "op_addin.hxx"
+
+#include <com/sun/star/sheet/FormulaLanguage.hpp>
+
+// FIXME: The idea that somebody would bother to (now and then? once a year? once a month?) manually
+// edit a source file and change the value of some #defined constant and run some ill-defined
+// "correctness test" is of course ludicrous. Either things are checked in normal unit tests, in
+// every 'make check', or not at all. The below comments are ridiculous.
+
+#define REDUCE_THRESHOLD 201 // set to 4 for correctness testing. priority 1
+#define UNROLLING_FACTOR 16 // set to 4 for correctness testing (if no reduce)
+
+static const char* const publicFunc =
+ "\n"
+ "#define IllegalArgument 502\n"
+ "#define IllegalFPOperation 503 // #NUM!\n"
+ "#define NoValue 519 // #VALUE!\n"
+ "#define NoConvergence 523\n"
+ "#define DivisionByZero 532 // #DIV/0!\n"
+ "#define NOTAVAILABLE 0x7fff // #N/A\n"
+ "\n"
+ "double CreateDoubleError(ulong nErr)\n"
+ "{\n"
+ // At least nVidia on Linux and Intel on Windows seem to ignore the argument to nan(),
+ // so using that would not propagate the type of error, work that around
+ // by directly constructing the proper IEEE double NaN value
+ // TODO: maybe use a better way to detect such systems?
+ " return as_double(0x7FF8000000000000+nErr);\n"
+// " return nan(nErr);\n"
+ "}\n"
+ "\n"
+ "uint GetDoubleErrorValue(double fVal)\n"
+ "{\n"
+ " if (isfinite(fVal))\n"
+ " return 0;\n"
+ " if (isinf(fVal))\n"
+ " return IllegalFPOperation; // normal INF\n"
+ " if (as_ulong(fVal) & 0XFFFF0000u)\n"
+ " return NoValue; // just a normal NAN\n"
+ " return (as_ulong(fVal) & 0XFFFF); // any other error\n"
+ "}\n"
+ "\n"
+ "double fsum_count(double a, double b, __private int *p) {\n"
+ " bool t = isnan(a);\n"
+ " (*p) += t?0:1;\n"
+ " return t?b:a+b;\n"
+ "}\n"
+ "double fmin_count(double a, double b, __private int *p) {\n"
+ " double result = fmin(a, b);\n"
+ " bool t = isnan(result);\n"
+ " (*p) += t?0:1;\n"
+ " return result;\n"
+ "}\n"
+ "double fmax_count(double a, double b, __private int *p) {\n"
+ " double result = fmax(a, b);\n"
+ " bool t = isnan(result);\n"
+ " (*p) += t?0:1;\n"
+ " return result;\n"
+ "}\n"
+ "double fsum(double a, double b) { return isnan(a)?b:a+b; }\n"
+ "double legalize(double a, double b) { return isnan(a)?b:a;}\n"
+ "double fsub(double a, double b) { return a-b; }\n"
+ "double fdiv(double a, double b) { return a/b; }\n"
+ "double strequal(unsigned a, unsigned b) { return (a==b)?1.0:0; }\n"
+ "int is_representable_integer(double a) {\n"
+ " long kMaxInt = (1L << 53) - 1;\n"
+ " if (a <= as_double(kMaxInt))\n"
+ " {\n"
+ " long nInt = as_long(a);\n"
+ " double fInt;\n"
+ " return (nInt <= kMaxInt &&\n"
+ " (!((fInt = as_double(nInt)) < a) && !(fInt > a)));\n"
+ " }\n"
+ " return 0;\n"
+ "}\n"
+ "int approx_equal(double a, double b) {\n"
+ " double e48 = 1.0 / (16777216.0 * 16777216.0);\n"
+ " double e44 = e48 * 16.0;\n"
+ " if (a == b)\n"
+ " return 1;\n"
+ " if (a == 0.0 || b == 0.0)\n"
+ " return 0;\n"
+ " double d = fabs(a - b);\n"
+ " if (!isfinite(d))\n"
+ " return 0; // Nan or Inf involved\n"
+ " if (d > ((a = fabs(a)) * e44) || d > ((b = fabs(b)) * e44))\n"
+ " return 0;\n"
+ " if (is_representable_integer(d) && is_representable_integer(a) && is_representable_integer(b))\n"
+ " return 0; // special case for representable integers.\n"
+ " return (d < a * e48 && d < b * e48);\n"
+ "}\n"
+ "double fsum_approx(double a, double b) {\n"
+ " if ( ((a < 0.0 && b > 0.0) || (b < 0.0 && a > 0.0))\n"
+ " && approx_equal( a, -b ) )\n"
+ " return 0.0;\n"
+ " return a + b;\n"
+ "}\n"
+ "double fsub_approx(double a, double b) {\n"
+ " if ( ((a < 0.0 && b < 0.0) || (a > 0.0 && b > 0.0)) && approx_equal( a, b ) )\n"
+ " return 0.0;\n"
+ " return a - b;\n"
+ "}\n"
+ ;
+
+#include <vector>
+#include <map>
+#include <iostream>
+#include <algorithm>
+
+#include <rtl/digest.h>
+
+#include <memory>
+
+using namespace formula;
+
+namespace sc::opencl {
+
+namespace {
+
+std::string linenumberify(const std::string& s)
+{
+ std::stringstream ss;
+ int linenumber = 1;
+ size_t start = 0;
+ size_t newline;
+ while ((newline = s.find('\n', start)) != std::string::npos)
+ {
+ ss << "/*" << std::setw(4) << linenumber++ << "*/ " << s.substr(start, newline-start+1);
+ start = newline + 1;
+ }
+ if (start < s.size())
+ ss << "/*" << std::setw(4) << linenumber++ << "*/ " << s.substr(start, std::string::npos);
+ return ss.str();
+}
+
+bool AllStringsAreNull(const rtl_uString* const* pStringArray, size_t nLength)
+{
+ if (pStringArray == nullptr)
+ return true;
+
+ for (size_t i = 0; i < nLength; i++)
+ if (pStringArray[i] != nullptr)
+ return false;
+
+ return true;
+}
+
+OUString LimitedString( const OUString& str )
+{
+ if( str.getLength() < 20 )
+ return "\"" + str + "\"";
+ else
+ return "\"" + str.copy( 0, 20 ) + "\"...";
+}
+
+// Returns formatted contents of the data (possibly shortened), to be used in debug output.
+OUString DebugPeekData(const FormulaToken* ref, int doubleRefIndex = 0)
+{
+ if (ref->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast<const formula::SingleVectorRefToken*>(ref);
+ OUStringBuffer buf = "SingleRef {";
+ for( size_t i = 0; i < std::min< size_t >( 4, pSVR->GetArrayLength()); ++i )
+ {
+ if( i != 0 )
+ buf.append( "," );
+ if( pSVR->GetArray().mpNumericArray != nullptr )
+ buf.append( pSVR->GetArray().mpNumericArray[ i ] );
+ else if( pSVR->GetArray().mpStringArray != nullptr )
+ buf.append( LimitedString( OUString( pSVR->GetArray().mpStringArray[ i ] )));
+ }
+ if( pSVR->GetArrayLength() > 4 )
+ buf.append( ",..." );
+ buf.append( "}" );
+ return buf.makeStringAndClear();
+ }
+ else if (ref->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken*>(ref);
+ OUStringBuffer buf = "DoubleRef {";
+ for( size_t i = 0; i < std::min< size_t >( 4, pDVR->GetArrayLength()); ++i )
+ {
+ if( i != 0 )
+ buf.append( "," );
+ if( pDVR->GetArrays()[doubleRefIndex].mpNumericArray != nullptr )
+ buf.append( pDVR->GetArrays()[doubleRefIndex].mpNumericArray[ i ] );
+ else if( pDVR->GetArrays()[doubleRefIndex].mpStringArray != nullptr )
+ buf.append( LimitedString( OUString( pDVR->GetArrays()[doubleRefIndex].mpStringArray[ i ] )));
+ }
+ if( pDVR->GetArrayLength() > 4 )
+ buf.append( ",..." );
+ buf.append( "}" );
+ return buf.makeStringAndClear();
+ }
+ else if (ref->GetType() == formula::svString)
+ {
+ return "String " + LimitedString( ref->GetString().getString());
+ }
+ else if (ref->GetType() == formula::svDouble)
+ {
+ return OUString::number(ref->GetDouble());
+ }
+ else
+ {
+ return "?";
+ }
+}
+
+// Returns formatted contents of a doubles buffer, to be used in debug output.
+OUString DebugPeekDoubles(const double* data, int size)
+{
+ OUStringBuffer buf = "{";
+ for( int i = 0; i < std::min( 4, size ); ++i )
+ {
+ if( i != 0 )
+ buf.append( "," );
+ buf.append( data[ i ] );
+ }
+ if( size > 4 )
+ buf.append( ",..." );
+ buf.append( "}" );
+ return buf.makeStringAndClear();
+}
+
+} // anonymous namespace
+
+/// Map the buffer used by an argument and do necessary argument setting
+size_t VectorRef::Marshal( cl_kernel k, int argno, int, cl_program )
+{
+ OpenCLZone zone;
+ FormulaToken* ref = mFormulaTree->GetFormulaToken();
+ double* pHostBuffer = nullptr;
+ size_t szHostBuffer = 0;
+ if (ref->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast<const formula::SingleVectorRefToken*>(ref);
+
+ SAL_INFO("sc.opencl", "SingleVectorRef len=" << pSVR->GetArrayLength() << " mpNumericArray=" << pSVR->GetArray().mpNumericArray << " (mpStringArray=" << pSVR->GetArray().mpStringArray << ")");
+
+ pHostBuffer = const_cast<double*>(pSVR->GetArray().mpNumericArray);
+ szHostBuffer = pSVR->GetArrayLength() * sizeof(double);
+ }
+ else if (ref->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken*>(ref);
+
+ SAL_INFO("sc.opencl", "DoubleVectorRef index=" << mnIndex << " len=" << pDVR->GetArrayLength() << " mpNumericArray=" << pDVR->GetArrays()[mnIndex].mpNumericArray << " (mpStringArray=" << pDVR->GetArrays()[mnIndex].mpStringArray << ")");
+
+ pHostBuffer = const_cast<double*>(
+ pDVR->GetArrays()[mnIndex].mpNumericArray);
+ szHostBuffer = pDVR->GetArrayLength() * sizeof(double);
+ }
+ else
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+
+ openclwrapper::KernelEnv kEnv;
+ openclwrapper::setKernelEnv(&kEnv);
+ cl_int err;
+ if (pHostBuffer)
+ {
+ mpClmem = clCreateBuffer(kEnv.mpkContext,
+ cl_mem_flags(CL_MEM_READ_ONLY) | CL_MEM_USE_HOST_PTR,
+ szHostBuffer,
+ pHostBuffer, &err);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clCreateBuffer", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created buffer " << mpClmem << " size " << szHostBuffer << " using host buffer " << pHostBuffer);
+ }
+ else
+ {
+ if (szHostBuffer == 0)
+ szHostBuffer = sizeof(double); // a dummy small value
+ // Marshal as a buffer of NANs
+ mpClmem = clCreateBuffer(kEnv.mpkContext,
+ cl_mem_flags(CL_MEM_READ_ONLY) | CL_MEM_ALLOC_HOST_PTR,
+ szHostBuffer, nullptr, &err);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clCreateBuffer", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created buffer " << mpClmem << " size " << szHostBuffer);
+
+ double* pNanBuffer = static_cast<double*>(clEnqueueMapBuffer(
+ kEnv.mpkCmdQueue, mpClmem, CL_TRUE, CL_MAP_WRITE, 0,
+ szHostBuffer, 0, nullptr, nullptr, &err));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clEnqueueMapBuffer", err, __FILE__, __LINE__);
+
+ for (size_t i = 0; i < szHostBuffer / sizeof(double); i++)
+ rtl::math::setNan(&pNanBuffer[i]);
+ err = clEnqueueUnmapMemObject(kEnv.mpkCmdQueue, mpClmem,
+ pNanBuffer, 0, nullptr, nullptr);
+ // FIXME: Is it intentional to not throw an OpenCLError even if the clEnqueueUnmapMemObject() fails?
+ if (CL_SUCCESS != err)
+ SAL_WARN("sc.opencl", "clEnqueueUnmapMemObject failed: " << openclwrapper::errorString(err));
+ }
+
+ SAL_INFO("sc.opencl", "Kernel " << k << " arg " << argno << ": cl_mem: " << mpClmem << " (" << DebugPeekData(ref, mnIndex) << ")");
+ err = clSetKernelArg(k, argno, sizeof(cl_mem), static_cast<void*>(&mpClmem));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ return 1;
+}
+
+/// Arguments that are actually compile-time constant string
+/// Currently, only the hash is passed.
+/// TBD(IJSUNG): pass also length and the actual string if there is a
+/// hash function collision
+
+/// FIXME: This idea of passing of hashes of uppercased strings into OpenCL code is fairly potent
+/// crack. It is hopefully not used at all any more, but noticing that there are string arguments
+/// automatically disables use of OpenCL for a formula group. If at some point there are resources
+/// to drain the OpenCL swamp, this should go away.
+
+namespace {
+
+class ConstStringArgument : public DynamicKernelArgument
+{
+public:
+ ConstStringArgument( const ScCalcConfig& config, const std::string& s,
+ const FormulaTreeNodeRef& ft ) :
+ DynamicKernelArgument(config, s, ft) { }
+ /// Generate declaration
+ virtual void GenDecl( std::stringstream& ss ) const override
+ {
+ ss << "unsigned " << mSymName;
+ }
+ virtual void GenDeclRef( std::stringstream& ss ) const override
+ {
+ ss << GenSlidingWindowDeclRef();
+ }
+ virtual void GenSlidingWindowDecl( std::stringstream& ss ) const override
+ {
+ GenDecl(ss);
+ }
+ virtual std::string GenSlidingWindowDeclRef( bool = false ) const override
+ {
+ std::stringstream ss;
+ if (GetFormulaToken()->GetType() != formula::svString)
+ throw Unhandled(__FILE__, __LINE__);
+ FormulaToken* Tok = GetFormulaToken();
+ ss << Tok->GetString().getString().toAsciiUpperCase().hashCode() << "U";
+ return ss.str();
+ }
+ virtual size_t GetWindowSize() const override
+ {
+ return 1;
+ }
+ /// Pass the 32-bit hash of the string to the kernel
+ virtual size_t Marshal( cl_kernel k, int argno, int, cl_program ) override
+ {
+ OpenCLZone zone;
+ FormulaToken* ref = mFormulaTree->GetFormulaToken();
+ cl_uint hashCode = 0;
+ if (ref->GetType() != formula::svString)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+
+ const OUString s = ref->GetString().getString().toAsciiUpperCase();
+ hashCode = s.hashCode();
+
+ // Pass the scalar result back to the rest of the formula kernel
+ SAL_INFO("sc.opencl", "Kernel " << k << " arg " << argno << ": cl_uint: " << hashCode << "(" << DebugPeekData(ref) << ")" );
+ cl_int err = clSetKernelArg(k, argno, sizeof(cl_uint), static_cast<void*>(&hashCode));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ return 1;
+ }
+};
+
+/// Arguments that are actually compile-time constants
+class DynamicKernelConstantArgument : public DynamicKernelArgument
+{
+public:
+ DynamicKernelConstantArgument( const ScCalcConfig& config, const std::string& s,
+ const FormulaTreeNodeRef& ft ) :
+ DynamicKernelArgument(config, s, ft) { }
+ /// Generate declaration
+ virtual void GenDecl( std::stringstream& ss ) const override
+ {
+ ss << "double " << mSymName;
+ }
+ virtual void GenDeclRef( std::stringstream& ss ) const override
+ {
+ ss << mSymName;
+ }
+ virtual void GenSlidingWindowDecl( std::stringstream& ss ) const override
+ {
+ GenDecl(ss);
+ }
+ virtual std::string GenSlidingWindowDeclRef( bool = false ) const override
+ {
+ if (GetFormulaToken()->GetType() != formula::svDouble)
+ throw Unhandled(__FILE__, __LINE__);
+ return mSymName;
+ }
+ virtual size_t GetWindowSize() const override
+ {
+ return 1;
+ }
+ double GetDouble() const
+ {
+ FormulaToken* Tok = GetFormulaToken();
+ if (Tok->GetType() != formula::svDouble)
+ throw Unhandled(__FILE__, __LINE__);
+ return Tok->GetDouble();
+ }
+ /// Create buffer and pass the buffer to a given kernel
+ virtual size_t Marshal( cl_kernel k, int argno, int, cl_program ) override
+ {
+ OpenCLZone zone;
+ double tmp = GetDouble();
+ // Pass the scalar result back to the rest of the formula kernel
+ SAL_INFO("sc.opencl", "Kernel " << k << " arg " << argno << ": double: " << tmp);
+ cl_int err = clSetKernelArg(k, argno, sizeof(double), static_cast<void*>(&tmp));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ return 1;
+ }
+};
+
+class DynamicKernelPiArgument : public DynamicKernelArgument
+{
+public:
+ DynamicKernelPiArgument( const ScCalcConfig& config, const std::string& s,
+ const FormulaTreeNodeRef& ft ) :
+ DynamicKernelArgument(config, s, ft) { }
+ /// Generate declaration
+ virtual void GenDecl( std::stringstream& ss ) const override
+ {
+ ss << "double " << mSymName;
+ }
+ virtual void GenDeclRef( std::stringstream& ss ) const override
+ {
+ ss << "3.14159265358979";
+ }
+ virtual void GenSlidingWindowDecl( std::stringstream& ss ) const override
+ {
+ GenDecl(ss);
+ }
+ virtual std::string GenSlidingWindowDeclRef( bool = false ) const override
+ {
+ return mSymName;
+ }
+ virtual size_t GetWindowSize() const override
+ {
+ return 1;
+ }
+ /// Create buffer and pass the buffer to a given kernel
+ virtual size_t Marshal( cl_kernel k, int argno, int, cl_program ) override
+ {
+ OpenCLZone zone;
+ double tmp = 0.0;
+ // Pass the scalar result back to the rest of the formula kernel
+ SAL_INFO("sc.opencl", "Kernel " << k << " arg " << argno << ": double: " << tmp << " (PI)");
+ cl_int err = clSetKernelArg(k, argno, sizeof(double), static_cast<void*>(&tmp));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ return 1;
+ }
+};
+
+class DynamicKernelRandomArgument : public DynamicKernelArgument
+{
+public:
+ DynamicKernelRandomArgument( const ScCalcConfig& config, const std::string& s,
+ const FormulaTreeNodeRef& ft ) :
+ DynamicKernelArgument(config, s, ft) { }
+ /// Generate declaration
+ virtual void GenDecl( std::stringstream& ss ) const override
+ {
+ ss << "double " << mSymName;
+ }
+ virtual void GenDeclRef( std::stringstream& ss ) const override
+ {
+ ss << mSymName;
+ }
+ virtual void GenSlidingWindowDecl( std::stringstream& ss ) const override
+ {
+ ss << "int " << mSymName;
+ }
+ virtual std::string GenSlidingWindowDeclRef( bool = false ) const override
+ {
+ return mSymName + "_Random(" + mSymName + ")";
+ }
+ virtual void GenSlidingWindowFunction( std::stringstream& ss ) override
+ {
+ // This string is from the pi_opencl_kernel.i file as
+ // generated when building the Random123 examples. Unused
+ // stuff has been removed, and the actual kernel is not the
+ // same as in the totally different use case of that example,
+ // of course. Only the code that calculates the counter-based
+ // random number and what it needs is left.
+ ss << "\
+\n\
+#ifndef DEFINED_RANDOM123_STUFF\n\
+#define DEFINED_RANDOM123_STUFF\n\
+\n\
+/*\n\
+Copyright 2010-2011, D. E. Shaw Research.\n\
+All rights reserved.\n\
+\n\
+Redistribution and use in source and binary forms, with or without\n\
+modification, are permitted provided that the following conditions are\n\
+met:\n\
+\n\
+* Redistributions of source code must retain the above copyright\n\
+ notice, this list of conditions, and the following disclaimer.\n\
+\n\
+* Redistributions in binary form must reproduce the above copyright\n\
+ notice, this list of conditions, and the following disclaimer in the\n\
+ documentation and/or other materials provided with the distribution.\n\
+\n\
+* Neither the name of D. E. Shaw Research nor the names of its\n\
+ contributors may be used to endorse or promote products derived from\n\
+ this software without specific prior written permission.\n\
+\n\
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\
+\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n\
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n\
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n\
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n\
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n\
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n\
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n\
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n\
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n\
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\
+*/\n\
+\n\
+typedef uint uint32_t;\n\
+struct r123array2x32\n\
+{\n\
+ uint32_t v[2];\n\
+};\n\
+enum r123_enum_threefry32x2\n\
+{\n\
+ R_32x2_0_0 = 13,\n\
+ R_32x2_1_0 = 15,\n\
+ R_32x2_2_0 = 26,\n\
+ R_32x2_3_0 = 6,\n\
+ R_32x2_4_0 = 17,\n\
+ R_32x2_5_0 = 29,\n\
+ R_32x2_6_0 = 16,\n\
+ R_32x2_7_0 = 24\n\
+};\n\
+inline uint32_t RotL_32 (uint32_t x, unsigned int N)\n\
+ __attribute__ ((always_inline));\n\
+inline uint32_t\n\
+RotL_32 (uint32_t x, unsigned int N)\n\
+{\n\
+ return (x << (N & 31)) | (x >> ((32 - N) & 31));\n\
+}\n\
+\n\
+typedef struct r123array2x32 threefry2x32_ctr_t;\n\
+typedef struct r123array2x32 threefry2x32_key_t;\n\
+typedef struct r123array2x32 threefry2x32_ukey_t;\n\
+inline threefry2x32_key_t\n\
+threefry2x32keyinit (threefry2x32_ukey_t uk)\n\
+{\n\
+ return uk;\n\
+}\n\
+\n\
+inline threefry2x32_ctr_t threefry2x32_R (unsigned int Nrounds,\n\
+ threefry2x32_ctr_t in,\n\
+ threefry2x32_key_t k)\n\
+ __attribute__ ((always_inline));\n\
+inline threefry2x32_ctr_t\n\
+threefry2x32_R (unsigned int Nrounds, threefry2x32_ctr_t in,\n\
+ threefry2x32_key_t k)\n\
+{\n\
+ threefry2x32_ctr_t X;\n\
+ uint32_t ks[2 + 1];\n\
+ int i;\n\
+ ks[2] = 0x1BD11BDA;\n\
+ for (i = 0; i < 2; i++) {\n\
+ ks[i] = k.v[i];\n\
+ X.v[i] = in.v[i];\n\
+ ks[2] ^= k.v[i];\n\
+ }\n\
+ X.v[0] += ks[0];\n\
+ X.v[1] += ks[1];\n\
+ if (Nrounds > 0) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_0_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 1) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_1_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 2) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_2_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 3) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_3_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 3) {\n\
+ X.v[0] += ks[1];\n\
+ X.v[1] += ks[2];\n\
+ X.v[1] += 1;\n\
+ }\n\
+ if (Nrounds > 4) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_4_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 5) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_5_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 6) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_6_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 7) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_7_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 7) {\n\
+ X.v[0] += ks[2];\n\
+ X.v[1] += ks[0];\n\
+ X.v[1] += 2;\n\
+ }\n\
+ if (Nrounds > 8) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_0_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 9) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_1_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 10) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_2_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 11) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_3_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 11) {\n\
+ X.v[0] += ks[0];\n\
+ X.v[1] += ks[1];\n\
+ X.v[1] += 3;\n\
+ }\n\
+ if (Nrounds > 12) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_4_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 13) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_5_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 14) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_6_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 15) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_7_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 15) {\n\
+ X.v[0] += ks[1];\n\
+ X.v[1] += ks[2];\n\
+ X.v[1] += 4;\n\
+ }\n\
+ if (Nrounds > 16) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_0_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 17) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_1_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 18) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_2_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 19) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_3_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 19) {\n\
+ X.v[0] += ks[2];\n\
+ X.v[1] += ks[0];\n\
+ X.v[1] += 5;\n\
+ }\n\
+ if (Nrounds > 20) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_4_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 21) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_5_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 22) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_6_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 23) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_7_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 23) {\n\
+ X.v[0] += ks[0];\n\
+ X.v[1] += ks[1];\n\
+ X.v[1] += 6;\n\
+ }\n\
+ if (Nrounds > 24) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_0_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 25) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_1_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 26) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_2_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 27) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_3_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 27) {\n\
+ X.v[0] += ks[1];\n\
+ X.v[1] += ks[2];\n\
+ X.v[1] += 7;\n\
+ }\n\
+ if (Nrounds > 28) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_4_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 29) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_5_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 30) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_6_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 31) {\n\
+ X.v[0] += X.v[1];\n\
+ X.v[1] = RotL_32 (X.v[1], R_32x2_7_0);\n\
+ X.v[1] ^= X.v[0];\n\
+ }\n\
+ if (Nrounds > 31) {\n\
+ X.v[0] += ks[2];\n\
+ X.v[1] += ks[0];\n\
+ X.v[1] += 8;\n\
+ }\n\
+ return X;\n\
+}\n\
+\n\
+enum r123_enum_threefry2x32\n\
+{ threefry2x32_rounds = 20 };\n\
+inline threefry2x32_ctr_t threefry2x32 (threefry2x32_ctr_t in,\n\
+ threefry2x32_key_t k)\n\
+ __attribute__ ((always_inline));\n\
+inline threefry2x32_ctr_t\n\
+threefry2x32 (threefry2x32_ctr_t in, threefry2x32_key_t k)\n\
+{\n\
+ return threefry2x32_R (threefry2x32_rounds, in, k);\n\
+}\n\
+#endif\n\
+\n\
+";
+ ss << "double " << mSymName << "_Random (int seed)\n\
+{\n\
+ unsigned tid = get_global_id(0);\n\
+ threefry2x32_key_t k = { {tid, 0xdecafbad} };\n\
+ threefry2x32_ctr_t c = { {seed, 0xf00dcafe} };\n\
+ c = threefry2x32_R(threefry2x32_rounds, c, k);\n\
+ const double factor = 1./(" << SAL_MAX_UINT32 << ".0 + 1.0);\n\
+ const double halffactor = 0.5*factor;\n\
+ return c.v[0] * factor + halffactor;\n\
+}\n\
+";
+ }
+ virtual size_t GetWindowSize() const override
+ {
+ return 1;
+ }
+ /// Create buffer and pass the buffer to a given kernel
+ virtual size_t Marshal( cl_kernel k, int argno, int, cl_program ) override
+ {
+ OpenCLZone zone;
+ cl_int seed = comphelper::rng::uniform_int_distribution(0, SAL_MAX_INT32);
+ // Pass the scalar result back to the rest of the formula kernel
+ SAL_INFO("sc.opencl", "Kernel " << k << " arg " << argno << ": cl_int: " << seed << "(RANDOM)");
+ cl_int err = clSetKernelArg(k, argno, sizeof(cl_int), static_cast<void*>(&seed));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ return 1;
+ }
+};
+
+/// A vector of strings
+class DynamicKernelStringArgument : public VectorRef
+{
+public:
+ DynamicKernelStringArgument( const ScCalcConfig& config, const std::string& s,
+ const FormulaTreeNodeRef& ft, int index = 0 ) :
+ VectorRef(config, s, ft, index) { }
+
+ virtual void GenSlidingWindowFunction( std::stringstream& ) override { }
+ /// Generate declaration
+ virtual void GenDecl( std::stringstream& ss ) const override
+ {
+ ss << "__global unsigned int *" << mSymName;
+ }
+ virtual void GenSlidingWindowDecl( std::stringstream& ss ) const override
+ {
+ DynamicKernelStringArgument::GenDecl(ss);
+ }
+ virtual size_t Marshal( cl_kernel, int, int, cl_program ) override;
+};
+
+}
+
+/// Marshal a string vector reference
+size_t DynamicKernelStringArgument::Marshal( cl_kernel k, int argno, int, cl_program )
+{
+ OpenCLZone zone;
+ FormulaToken* ref = mFormulaTree->GetFormulaToken();
+
+ openclwrapper::KernelEnv kEnv;
+ openclwrapper::setKernelEnv(&kEnv);
+ cl_int err;
+ formula::VectorRefArray vRef;
+ size_t nStrings = 0;
+ if (ref->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast<const formula::SingleVectorRefToken*>(ref);
+ nStrings = pSVR->GetArrayLength();
+ vRef = pSVR->GetArray();
+ }
+ else if (ref->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken*>(ref);
+ nStrings = pDVR->GetArrayLength();
+ vRef = pDVR->GetArrays()[mnIndex];
+ }
+ size_t szHostBuffer = nStrings * sizeof(cl_int);
+ cl_uint* pHashBuffer = nullptr;
+
+ if (vRef.mpStringArray != nullptr)
+ {
+ // Marshal strings. Right now we pass hashes of these string
+ mpClmem = clCreateBuffer(kEnv.mpkContext,
+ cl_mem_flags(CL_MEM_READ_ONLY) | CL_MEM_ALLOC_HOST_PTR,
+ szHostBuffer, nullptr, &err);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clCreateBuffer", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created buffer " << mpClmem << " size " << szHostBuffer);
+
+ pHashBuffer = static_cast<cl_uint*>(clEnqueueMapBuffer(
+ kEnv.mpkCmdQueue, mpClmem, CL_TRUE, CL_MAP_WRITE, 0,
+ szHostBuffer, 0, nullptr, nullptr, &err));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clEnqueueMapBuffer", err, __FILE__, __LINE__);
+
+ for (size_t i = 0; i < nStrings; i++)
+ {
+ if (vRef.mpStringArray[i])
+ {
+ const OUString tmp(vRef.mpStringArray[i]);
+ pHashBuffer[i] = tmp.hashCode();
+ }
+ else
+ {
+ pHashBuffer[i] = 0;
+ }
+ }
+ }
+ else
+ {
+ if (nStrings == 0)
+ szHostBuffer = sizeof(cl_int); // a dummy small value
+ // Marshal as a buffer of NANs
+ mpClmem = clCreateBuffer(kEnv.mpkContext,
+ cl_mem_flags(CL_MEM_READ_ONLY) | CL_MEM_ALLOC_HOST_PTR,
+ szHostBuffer, nullptr, &err);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clCreateBuffer", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created buffer " << mpClmem << " size " << szHostBuffer);
+
+ pHashBuffer = static_cast<cl_uint*>(clEnqueueMapBuffer(
+ kEnv.mpkCmdQueue, mpClmem, CL_TRUE, CL_MAP_WRITE, 0,
+ szHostBuffer, 0, nullptr, nullptr, &err));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clEnqueueMapBuffer", err, __FILE__, __LINE__);
+
+ for (size_t i = 0; i < szHostBuffer / sizeof(cl_int); i++)
+ pHashBuffer[i] = 0;
+ }
+ err = clEnqueueUnmapMemObject(kEnv.mpkCmdQueue, mpClmem,
+ pHashBuffer, 0, nullptr, nullptr);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clEnqueueUnmapMemObject", err, __FILE__, __LINE__);
+
+ SAL_INFO("sc.opencl", "Kernel " << k << " arg " << argno << ": cl_mem: " << mpClmem << " (" << DebugPeekData(ref,mnIndex) << ")");
+ err = clSetKernelArg(k, argno, sizeof(cl_mem), static_cast<void*>(&mpClmem));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ return 1;
+}
+
+namespace {
+
+/// A mixed string/numeric vector
+class DynamicKernelMixedArgument : public VectorRef
+{
+public:
+ DynamicKernelMixedArgument( const ScCalcConfig& config, const std::string& s,
+ const FormulaTreeNodeRef& ft ) :
+ VectorRef(config, s, ft), mStringArgument(config, s + "s", ft) { }
+ virtual void GenSlidingWindowDecl( std::stringstream& ss ) const override
+ {
+ VectorRef::GenSlidingWindowDecl(ss);
+ ss << ", ";
+ mStringArgument.GenSlidingWindowDecl(ss);
+ }
+ virtual void GenSlidingWindowFunction( std::stringstream& ) override { }
+ /// Generate declaration
+ virtual void GenDecl( std::stringstream& ss ) const override
+ {
+ VectorRef::GenDecl(ss);
+ ss << ", ";
+ mStringArgument.GenDecl(ss);
+ }
+ virtual void GenDeclRef( std::stringstream& ss ) const override
+ {
+ VectorRef::GenDeclRef(ss);
+ ss << ",";
+ mStringArgument.GenDeclRef(ss);
+ }
+ virtual std::string GenSlidingWindowDeclRef( bool nested ) const override
+ {
+ std::stringstream ss;
+ ss << "(!isnan(" << VectorRef::GenSlidingWindowDeclRef();
+ ss << ")?" << VectorRef::GenSlidingWindowDeclRef();
+ ss << ":" << mStringArgument.GenSlidingWindowDeclRef(nested);
+ ss << ")";
+ return ss.str();
+ }
+ virtual std::string GenDoubleSlidingWindowDeclRef( bool = false ) const override
+ {
+ std::stringstream ss;
+ ss << VectorRef::GenSlidingWindowDeclRef();
+ return ss.str();
+ }
+ virtual std::string GenStringSlidingWindowDeclRef( bool = false ) const override
+ {
+ std::stringstream ss;
+ ss << mStringArgument.GenSlidingWindowDeclRef();
+ return ss.str();
+ }
+ virtual size_t Marshal( cl_kernel k, int argno, int vw, cl_program p ) override
+ {
+ int i = VectorRef::Marshal(k, argno, vw, p);
+ i += mStringArgument.Marshal(k, argno + i, vw, p);
+ return i;
+ }
+
+protected:
+ DynamicKernelStringArgument mStringArgument;
+};
+
+/// Handling a Double Vector that is used as a sliding window input
+/// to either a sliding window average or sum-of-products
+/// Generate a sequential loop for reductions
+template<class Base>
+class DynamicKernelSlidingArgument : public Base
+{
+public:
+ DynamicKernelSlidingArgument(const ScCalcConfig& config, const std::string& s,
+ const FormulaTreeNodeRef& ft,
+ const std::shared_ptr<SlidingFunctionBase>& CodeGen, int index)
+ : Base(config, s, ft, index)
+ , mpCodeGen(CodeGen)
+ {
+ FormulaToken* t = ft->GetFormulaToken();
+ if (t->GetType() != formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ mpDVR = static_cast<const formula::DoubleVectorRefToken*>(t);
+ bIsStartFixed = mpDVR->IsStartFixed();
+ bIsEndFixed = mpDVR->IsEndFixed();
+ }
+
+ // Should only be called by SumIfs. Yikes!
+ virtual bool NeedParallelReduction() const
+ {
+ assert(dynamic_cast<OpSumIfs*>(mpCodeGen.get()));
+ return GetWindowSize() > 100 &&
+ ((GetStartFixed() && GetEndFixed()) ||
+ (!GetStartFixed() && !GetEndFixed()));
+ }
+
+ virtual void GenSlidingWindowFunction( std::stringstream& ) { }
+
+ std::string GenSlidingWindowDeclRef( bool nested = false ) const
+ {
+ size_t nArrayLength = mpDVR->GetArrayLength();
+ std::stringstream ss;
+ if (!bIsStartFixed && !bIsEndFixed)
+ {
+ if (nested)
+ ss << "((i+gid0) <" << nArrayLength << "?";
+ ss << Base::GetName() << "[i + gid0]";
+ if (nested)
+ ss << ":NAN)";
+ }
+ else
+ {
+ if (nested)
+ ss << "(i <" << nArrayLength << "?";
+ ss << Base::GetName() << "[i]";
+ if (nested)
+ ss << ":NAN)";
+ }
+ return ss.str();
+ }
+ /// Controls how the elements in the DoubleVectorRef are traversed
+ size_t GenReductionLoopHeader(
+ std::stringstream& ss, bool& needBody )
+ {
+ assert(mpDVR);
+ size_t nCurWindowSize = mpDVR->GetRefRowSize();
+
+ {
+ if (!mpDVR->IsStartFixed() && mpDVR->IsEndFixed())
+ {
+ ss << "for (int i = ";
+ ss << "gid0; i < " << mpDVR->GetArrayLength();
+ ss << " && i < " << nCurWindowSize << "; i++){\n\t\t";
+ needBody = true;
+ return nCurWindowSize;
+ }
+ else if (mpDVR->IsStartFixed() && !mpDVR->IsEndFixed())
+ {
+ ss << "for (int i = ";
+ ss << "0; i < " << mpDVR->GetArrayLength();
+ ss << " && i < gid0+" << nCurWindowSize << "; i++){\n\t\t";
+ needBody = true;
+ return nCurWindowSize;
+ }
+ else if (!mpDVR->IsStartFixed() && !mpDVR->IsEndFixed())
+ {
+ ss << "tmpBottom = " << mpCodeGen->GetBottom() << ";\n\t";
+ ss << "{int i;\n\t";
+ std::stringstream temp1, temp2;
+ int outLoopSize = UNROLLING_FACTOR;
+ if (nCurWindowSize / outLoopSize != 0)
+ {
+ ss << "for(int outLoop=0; outLoop<" << nCurWindowSize / outLoopSize << "; outLoop++){\n\t";
+ for (int count = 0; count < outLoopSize; count++)
+ {
+ ss << "i = outLoop*" << outLoopSize << "+" << count << ";\n\t";
+ if (count == 0)
+ {
+ temp1 << "if(i + gid0 < " << mpDVR->GetArrayLength();
+ temp1 << "){\n\t\t";
+ temp1 << "tmp = legalize(";
+ temp1 << mpCodeGen->Gen2(GenSlidingWindowDeclRef(), "tmp");
+ temp1 << ", tmp);\n\t\t\t";
+ temp1 << "}\n\t";
+ }
+ ss << temp1.str();
+ }
+ ss << "}\n\t";
+ }
+ // The residual of mod outLoopSize
+ for (size_t count = nCurWindowSize / outLoopSize * outLoopSize; count < nCurWindowSize; count++)
+ {
+ ss << "i = " << count << ";\n\t";
+ if (count == nCurWindowSize / outLoopSize * outLoopSize)
+ {
+ temp2 << "if(i + gid0 < " << mpDVR->GetArrayLength();
+ temp2 << "){\n\t\t";
+ temp2 << "tmp = legalize(";
+ temp2 << mpCodeGen->Gen2(GenSlidingWindowDeclRef(), "tmp");
+ temp2 << ", tmp);\n\t\t\t";
+ temp2 << "}\n\t";
+ }
+ ss << temp2.str();
+ }
+ ss << "}\n";
+ needBody = false;
+ return nCurWindowSize;
+ }
+ // (mpDVR->IsStartFixed() && mpDVR->IsEndFixed())
+ else
+ {
+ ss << "\n\t";
+ ss << "tmpBottom = " << mpCodeGen->GetBottom() << ";\n\t";
+ ss << "{int i;\n\t";
+ std::stringstream temp1, temp2;
+ int outLoopSize = UNROLLING_FACTOR;
+ if (nCurWindowSize / outLoopSize != 0)
+ {
+ ss << "for(int outLoop=0; outLoop<" << nCurWindowSize / outLoopSize << "; outLoop++){\n\t";
+ for (int count = 0; count < outLoopSize; count++)
+ {
+ ss << "i = outLoop*" << outLoopSize << "+" << count << ";\n\t";
+ if (count == 0)
+ {
+ temp1 << "if(i < " << mpDVR->GetArrayLength();
+ temp1 << "){\n\t\t";
+ temp1 << "tmp = legalize(";
+ temp1 << mpCodeGen->Gen2(GenSlidingWindowDeclRef(), "tmp");
+ temp1 << ", tmp);\n\t\t\t";
+ temp1 << "}\n\t";
+ }
+ ss << temp1.str();
+ }
+ ss << "}\n\t";
+ }
+ // The residual of mod outLoopSize
+ for (size_t count = nCurWindowSize / outLoopSize * outLoopSize; count < nCurWindowSize; count++)
+ {
+ ss << "i = " << count << ";\n\t";
+ if (count == nCurWindowSize / outLoopSize * outLoopSize)
+ {
+ temp2 << "if(i < " << mpDVR->GetArrayLength();
+ temp2 << "){\n\t\t";
+ temp2 << "tmp = legalize(";
+ temp2 << mpCodeGen->Gen2(GenSlidingWindowDeclRef(), "tmp");
+ temp2 << ", tmp);\n\t\t\t";
+ temp2 << "}\n\t";
+ }
+ ss << temp2.str();
+ }
+ ss << "}\n";
+ needBody = false;
+ return nCurWindowSize;
+ }
+ }
+ }
+
+ size_t GetArrayLength() const { return mpDVR->GetArrayLength(); }
+
+ size_t GetWindowSize() const { return mpDVR->GetRefRowSize(); }
+
+ bool GetStartFixed() const { return bIsStartFixed; }
+
+ bool GetEndFixed() const { return bIsEndFixed; }
+
+protected:
+ bool bIsStartFixed, bIsEndFixed;
+ const formula::DoubleVectorRefToken* mpDVR;
+ // from parent nodes
+ std::shared_ptr<SlidingFunctionBase> mpCodeGen;
+};
+
+/// A mixed string/numeric vector
+class DynamicKernelMixedSlidingArgument : public VectorRef
+{
+public:
+ DynamicKernelMixedSlidingArgument( const ScCalcConfig& config, const std::string& s,
+ const FormulaTreeNodeRef& ft, const std::shared_ptr<SlidingFunctionBase>& CodeGen,
+ int index ) :
+ VectorRef(config, s, ft),
+ mDoubleArgument(mCalcConfig, s, ft, CodeGen, index),
+ mStringArgument(mCalcConfig, s + "s", ft, CodeGen, index) { }
+ virtual void GenSlidingWindowDecl( std::stringstream& ss ) const override
+ {
+ mDoubleArgument.GenSlidingWindowDecl(ss);
+ ss << ", ";
+ mStringArgument.GenSlidingWindowDecl(ss);
+ }
+ virtual void GenSlidingWindowFunction( std::stringstream& ) override { }
+ /// Generate declaration
+ virtual void GenDecl( std::stringstream& ss ) const override
+ {
+ mDoubleArgument.GenDecl(ss);
+ ss << ", ";
+ mStringArgument.GenDecl(ss);
+ }
+ virtual void GenDeclRef( std::stringstream& ss ) const override
+ {
+ mDoubleArgument.GenDeclRef(ss);
+ ss << ",";
+ mStringArgument.GenDeclRef(ss);
+ }
+ virtual std::string GenSlidingWindowDeclRef( bool nested ) const override
+ {
+ std::stringstream ss;
+ ss << "(!isnan(" << mDoubleArgument.GenSlidingWindowDeclRef();
+ ss << ")?" << mDoubleArgument.GenSlidingWindowDeclRef();
+ ss << ":" << mStringArgument.GenSlidingWindowDeclRef(nested);
+ ss << ")";
+ return ss.str();
+ }
+ virtual std::string GenDoubleSlidingWindowDeclRef( bool = false ) const override
+ {
+ std::stringstream ss;
+ ss << mDoubleArgument.GenSlidingWindowDeclRef();
+ return ss.str();
+ }
+ virtual std::string GenStringSlidingWindowDeclRef( bool = false ) const override
+ {
+ std::stringstream ss;
+ ss << mStringArgument.GenSlidingWindowDeclRef();
+ return ss.str();
+ }
+ virtual size_t Marshal( cl_kernel k, int argno, int vw, cl_program p ) override
+ {
+ int i = mDoubleArgument.Marshal(k, argno, vw, p);
+ i += mStringArgument.Marshal(k, argno + i, vw, p);
+ return i;
+ }
+
+protected:
+ DynamicKernelSlidingArgument<VectorRef> mDoubleArgument;
+ DynamicKernelSlidingArgument<DynamicKernelStringArgument> mStringArgument;
+};
+
+/// Holds the symbol table for a given dynamic kernel
+class SymbolTable
+{
+public:
+ typedef std::map<const formula::FormulaToken*, DynamicKernelArgumentRef> ArgumentMap;
+ // This avoids instability caused by using pointer as the key type
+ SymbolTable() : mCurId(0) { }
+ template <class T>
+ const DynamicKernelArgument* DeclRefArg(const ScCalcConfig& config, const FormulaTreeNodeRef&,
+ std::shared_ptr<SlidingFunctionBase> pCodeGen, int nResultSize);
+ /// Used to generate sliding window helpers
+ void DumpSlidingWindowFunctions( std::stringstream& ss )
+ {
+ for (auto const& argument : mParams)
+ {
+ argument->GenSlidingWindowFunction(ss);
+ ss << "\n";
+ }
+ }
+ /// Memory mapping from host to device and pass buffers to the given kernel as
+ /// arguments
+ void Marshal( cl_kernel, int, cl_program );
+
+private:
+ unsigned int mCurId;
+ ArgumentMap mSymbols;
+ std::vector<DynamicKernelArgumentRef> mParams;
+};
+
+}
+
+void SymbolTable::Marshal( cl_kernel k, int nVectorWidth, cl_program pProgram )
+{
+ int i = 1; //The first argument is reserved for results
+ for (auto const& argument : mParams)
+ {
+ i += argument->Marshal(k, i, nVectorWidth, pProgram);
+ }
+}
+
+namespace {
+
+/// Handling a Double Vector that is used as a sliding window input
+/// Performs parallel reduction based on given operator
+template<class Base>
+class ParallelReductionVectorRef : public Base
+{
+public:
+ ParallelReductionVectorRef(const ScCalcConfig& config, const std::string& s,
+ const FormulaTreeNodeRef& ft,
+ const std::shared_ptr<SlidingFunctionBase>& CodeGen, int index)
+ : Base(config, s, ft, index)
+ , mpCodeGen(CodeGen)
+ , mpClmem2(nullptr)
+ {
+ FormulaToken* t = ft->GetFormulaToken();
+ if (t->GetType() != formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ mpDVR = static_cast<const formula::DoubleVectorRefToken*>(t);
+ bIsStartFixed = mpDVR->IsStartFixed();
+ bIsEndFixed = mpDVR->IsEndFixed();
+ }
+
+ /// Emit the definition for the auxiliary reduction kernel
+ virtual void GenSlidingWindowFunction( std::stringstream& ss );
+
+ virtual std::string GenSlidingWindowDeclRef( bool ) const
+ {
+ std::stringstream ss;
+ if (!bIsStartFixed && !bIsEndFixed)
+ ss << Base::GetName() << "[i + gid0]";
+ else
+ ss << Base::GetName() << "[i]";
+ return ss.str();
+ }
+
+ /// Controls how the elements in the DoubleVectorRef are traversed
+ size_t GenReductionLoopHeader(
+ std::stringstream& ss, int nResultSize, bool& needBody );
+
+ virtual size_t Marshal( cl_kernel k, int argno, int w, cl_program mpProgram );
+
+ ~ParallelReductionVectorRef()
+ {
+ if (mpClmem2)
+ {
+ cl_int err;
+ err = clReleaseMemObject(mpClmem2);
+ SAL_WARN_IF(err != CL_SUCCESS, "sc.opencl", "clReleaseMemObject failed: " << openclwrapper::errorString(err));
+ mpClmem2 = nullptr;
+ }
+ }
+
+ size_t GetArrayLength() const { return mpDVR->GetArrayLength(); }
+
+ size_t GetWindowSize() const { return mpDVR->GetRefRowSize(); }
+
+ bool GetStartFixed() const { return bIsStartFixed; }
+
+ bool GetEndFixed() const { return bIsEndFixed; }
+
+protected:
+ bool bIsStartFixed, bIsEndFixed;
+ const formula::DoubleVectorRefToken* mpDVR;
+ // from parent nodes
+ std::shared_ptr<SlidingFunctionBase> mpCodeGen;
+ // controls whether to invoke the reduction kernel during marshaling or not
+ cl_mem mpClmem2;
+};
+
+class Reduction : public SlidingFunctionBase
+{
+ int mnResultSize;
+public:
+ explicit Reduction(int nResultSize) : mnResultSize(nResultSize) {}
+
+ typedef DynamicKernelSlidingArgument<VectorRef> NumericRange;
+ typedef DynamicKernelSlidingArgument<DynamicKernelStringArgument> StringRange;
+ typedef ParallelReductionVectorRef<VectorRef> ParallelNumericRange;
+
+ virtual bool HandleNaNArgument( std::stringstream&, unsigned, SubArguments& ) const
+ {
+ return false;
+ }
+
+ virtual void GenSlidingWindowFunction( std::stringstream& ss,
+ const std::string& sSymName, SubArguments& vSubArguments ) override
+ {
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << "double tmp = " << GetBottom() << ";\n";
+ ss << "int gid0 = get_global_id(0);\n";
+ if (isAverage() || isMinOrMax())
+ ss << "int nCount = 0;\n";
+ ss << "double tmpBottom;\n";
+ unsigned i = vSubArguments.size();
+ while (i--)
+ {
+ if (NumericRange* NR =
+ dynamic_cast<NumericRange*>(vSubArguments[i].get()))
+ {
+ bool needBody;
+ NR->GenReductionLoopHeader(ss, needBody);
+ if (!needBody)
+ continue;
+ }
+ else if (ParallelNumericRange* PNR =
+ dynamic_cast<ParallelNumericRange*>(vSubArguments[i].get()))
+ {
+ //did not handle yet
+ bool bNeedBody = false;
+ PNR->GenReductionLoopHeader(ss, mnResultSize, bNeedBody);
+ if (!bNeedBody)
+ continue;
+ }
+ else if (StringRange* SR =
+ dynamic_cast<StringRange*>(vSubArguments[i].get()))
+ {
+ //did not handle yet
+ bool needBody;
+ SR->GenReductionLoopHeader(ss, needBody);
+ if (!needBody)
+ continue;
+ }
+ else
+ {
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ assert(pCur->GetType() != formula::svDoubleVectorRef);
+
+ if (pCur->GetType() == formula::svSingleVectorRef ||
+ pCur->GetType() == formula::svDouble)
+ {
+ ss << "{\n";
+ }
+ }
+ if (ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ bool bNanHandled = HandleNaNArgument(ss, i, vSubArguments);
+
+ ss << "tmpBottom = " << GetBottom() << ";\n";
+
+ if (!bNanHandled)
+ {
+ ss << "if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ if (ZeroReturnZero())
+ ss << " return 0;\n";
+ else
+ {
+ ss << " tmp = ";
+ ss << Gen2("tmpBottom", "tmp") << ";\n";
+ }
+ ss << "else\n";
+ }
+ ss << "{";
+ ss << " tmp = ";
+ ss << Gen2(vSubArguments[i]->GenSlidingWindowDeclRef(), "tmp");
+ ss << ";\n";
+ ss << " }\n";
+ ss << "}\n";
+ }
+ else
+ {
+ ss << "tmp = ";
+ ss << Gen2(vSubArguments[i]->GenSlidingWindowDeclRef(), "tmp");
+ ss << ";\n";
+ }
+ }
+ if (isAverage())
+ ss <<
+ "if (nCount==0)\n"
+ " return CreateDoubleError(DivisionByZero);\n";
+ else if (isMinOrMax())
+ ss <<
+ "if (nCount==0)\n"
+ " return 0;\n";
+ ss << "return tmp";
+ if (isAverage())
+ ss << "*pow((double)nCount,-1.0)";
+ ss << ";\n}";
+ }
+ virtual bool isAverage() const { return false; }
+ virtual bool isMinOrMax() const { return false; }
+ virtual bool takeString() const override { return false; }
+ virtual bool takeNumeric() const override { return true; }
+};
+
+// Strictly binary operators
+class Binary : public SlidingFunctionBase
+{
+public:
+ virtual void GenSlidingWindowFunction( std::stringstream& ss,
+ const std::string& sSymName, SubArguments& vSubArguments ) override
+ {
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ assert(vSubArguments.size() == 2);
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << "int gid0 = get_global_id(0), i = 0;\n\t";
+ ss << "double tmp = ";
+ ss << Gen2(vSubArguments[0]->GenSlidingWindowDeclRef(),
+ vSubArguments[1]->GenSlidingWindowDeclRef()) << ";\n\t";
+ ss << "return tmp;\n}";
+ }
+ virtual bool takeString() const override { return true; }
+ virtual bool takeNumeric() const override { return true; }
+};
+
+class SumOfProduct : public SlidingFunctionBase
+{
+public:
+ virtual void GenSlidingWindowFunction( std::stringstream& ss,
+ const std::string& sSymName, SubArguments& vSubArguments ) override
+ {
+ size_t nCurWindowSize = 0;
+ FormulaToken* tmpCur = nullptr;
+ const formula::DoubleVectorRefToken* pCurDVR = nullptr;
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ size_t nCurChildWindowSize = vSubArguments[i]->GetWindowSize();
+ nCurWindowSize = (nCurWindowSize < nCurChildWindowSize) ?
+ nCurChildWindowSize : nCurWindowSize;
+ tmpCur = vSubArguments[i]->GetFormulaToken();
+ if (ocPush == tmpCur->GetOpCode())
+ {
+
+ pCurDVR = static_cast<const formula::DoubleVectorRefToken*>(tmpCur);
+ if (pCurDVR->IsStartFixed() != pCurDVR->IsEndFixed())
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ }
+ ss << ") {\n";
+ ss << " double tmp = 0.0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+
+ ss << "\tint i;\n\t";
+ ss << "int currentCount0;\n";
+ for (size_t i = 0; i < vSubArguments.size() - 1; i++)
+ ss << "int currentCount" << i + 1 << ";\n";
+ std::stringstream temp3, temp4;
+ int outLoopSize = UNROLLING_FACTOR;
+ if (nCurWindowSize / outLoopSize != 0)
+ {
+ ss << "for(int outLoop=0; outLoop<" <<
+ nCurWindowSize / outLoopSize << "; outLoop++){\n\t";
+ for (int count = 0; count < outLoopSize; count++)
+ {
+ ss << "i = outLoop*" << outLoopSize << "+" << count << ";\n";
+ if (count == 0)
+ {
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ tmpCur = vSubArguments[i]->GetFormulaToken();
+ if (ocPush == tmpCur->GetOpCode())
+ {
+ pCurDVR = static_cast<const formula::DoubleVectorRefToken*>(tmpCur);
+ if (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ temp3 << " currentCount";
+ temp3 << i;
+ temp3 << " =i+gid0+1;\n";
+ }
+ else
+ {
+ temp3 << " currentCount";
+ temp3 << i;
+ temp3 << " =i+1;\n";
+ }
+ }
+ }
+
+ temp3 << "tmp = fsum(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ temp3 << "*";
+ if (ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ temp3 << "(";
+ temp3 << "(currentCount";
+ temp3 << i;
+ temp3 << ">";
+ if (vSubArguments[i]->GetFormulaToken()->GetType() ==
+ formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast<const formula::SingleVectorRefToken*>
+ (vSubArguments[i]->GetFormulaToken());
+ temp3 << pSVR->GetArrayLength();
+ temp3 << ")||isnan(" << vSubArguments[i]
+ ->GenSlidingWindowDeclRef();
+ temp3 << ")?0:";
+ temp3 << vSubArguments[i]->GenSlidingWindowDeclRef();
+ temp3 << ")";
+ }
+ else if (vSubArguments[i]->GetFormulaToken()->GetType() ==
+ formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pSVR =
+ static_cast<const formula::DoubleVectorRefToken*>
+ (vSubArguments[i]->GetFormulaToken());
+ temp3 << pSVR->GetArrayLength();
+ temp3 << ")||isnan(" << vSubArguments[i]
+ ->GenSlidingWindowDeclRef(true);
+ temp3 << ")?0:";
+ temp3 << vSubArguments[i]->GenSlidingWindowDeclRef(true);
+ temp3 << ")";
+ }
+
+ }
+ else
+ temp3 << vSubArguments[i]->GenSlidingWindowDeclRef(true);
+ }
+ temp3 << ", tmp);\n\t";
+ }
+ ss << temp3.str();
+ }
+ ss << "}\n\t";
+ }
+ //The residual of mod outLoopSize
+ for (size_t count = nCurWindowSize / outLoopSize * outLoopSize;
+ count < nCurWindowSize; count++)
+ {
+ ss << "i =" << count << ";\n";
+ if (count == nCurWindowSize / outLoopSize * outLoopSize)
+ {
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ tmpCur = vSubArguments[i]->GetFormulaToken();
+ if (ocPush == tmpCur->GetOpCode())
+ {
+ pCurDVR = static_cast<const formula::DoubleVectorRefToken*>(tmpCur);
+ if (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ temp4 << " currentCount";
+ temp4 << i;
+ temp4 << " =i+gid0+1;\n";
+ }
+ else
+ {
+ temp4 << " currentCount";
+ temp4 << i;
+ temp4 << " =i+1;\n";
+ }
+ }
+ }
+
+ temp4 << "tmp = fsum(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ temp4 << "*";
+ if (ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ temp4 << "(";
+ temp4 << "(currentCount";
+ temp4 << i;
+ temp4 << ">";
+ if (vSubArguments[i]->GetFormulaToken()->GetType() ==
+ formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast<const formula::SingleVectorRefToken*>
+ (vSubArguments[i]->GetFormulaToken());
+ temp4 << pSVR->GetArrayLength();
+ temp4 << ")||isnan(" << vSubArguments[i]
+ ->GenSlidingWindowDeclRef();
+ temp4 << ")?0:";
+ temp4 << vSubArguments[i]->GenSlidingWindowDeclRef();
+ temp4 << ")";
+ }
+ else if (vSubArguments[i]->GetFormulaToken()->GetType() ==
+ formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pSVR =
+ static_cast<const formula::DoubleVectorRefToken*>
+ (vSubArguments[i]->GetFormulaToken());
+ temp4 << pSVR->GetArrayLength();
+ temp4 << ")||isnan(" << vSubArguments[i]
+ ->GenSlidingWindowDeclRef(true);
+ temp4 << ")?0:";
+ temp4 << vSubArguments[i]->GenSlidingWindowDeclRef(true);
+ temp4 << ")";
+ }
+
+ }
+ else
+ {
+ temp4 << vSubArguments[i]
+ ->GenSlidingWindowDeclRef(true);
+ }
+ }
+ temp4 << ", tmp);\n\t";
+ }
+ ss << temp4.str();
+ }
+ ss << "return tmp;\n";
+ ss << "}";
+ }
+ virtual bool takeString() const override { return false; }
+ virtual bool takeNumeric() const override { return true; }
+};
+
+/// operator traits
+class OpNop : public Reduction
+{
+public:
+ explicit OpNop(int nResultSize) : Reduction(nResultSize) {}
+
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& ) const override
+ {
+ return lhs;
+ }
+ virtual std::string BinFuncName() const override { return "nop"; }
+};
+
+class OpCount : public Reduction
+{
+public:
+ explicit OpCount(int nResultSize) : Reduction(nResultSize) {}
+
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ std::stringstream ss;
+ ss << "(isnan(" << lhs << ")?" << rhs << ":" << rhs << "+1.0)";
+ return ss.str();
+ }
+ virtual std::string BinFuncName() const override { return "fcount"; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+
+class OpEqual : public Binary
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ std::stringstream ss;
+ ss << "strequal(" << lhs << "," << rhs << ")";
+ return ss.str();
+ }
+ virtual std::string BinFuncName() const override { return "eq"; }
+};
+
+class OpLessEqual : public Binary
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ std::stringstream ss;
+ ss << "(" << lhs << "<=" << rhs << ")";
+ return ss.str();
+ }
+ virtual std::string BinFuncName() const override { return "leq"; }
+};
+
+class OpLess : public Binary
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ std::stringstream ss;
+ ss << "(" << lhs << "<" << rhs << ")";
+ return ss.str();
+ }
+ virtual std::string BinFuncName() const override { return "less"; }
+};
+
+class OpGreater : public Binary
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ std::stringstream ss;
+ ss << "(" << lhs << ">" << rhs << ")";
+ return ss.str();
+ }
+ virtual std::string BinFuncName() const override { return "gt"; }
+};
+
+class OpSum : public Reduction
+{
+public:
+ explicit OpSum(int nResultSize) : Reduction(nResultSize) {}
+
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ std::stringstream ss;
+ ss << "fsum_approx((" << lhs << "),(" << rhs << "))";
+ return ss.str();
+ }
+ virtual std::string BinFuncName() const override { return "fsum"; }
+ // All arguments are simply summed, so it doesn't matter if SvDoubleVector is split.
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+
+class OpAverage : public Reduction
+{
+public:
+ explicit OpAverage(int nResultSize) : Reduction(nResultSize) {}
+
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ std::stringstream ss;
+ ss << "fsum_count(" << lhs << "," << rhs << ", &nCount)";
+ return ss.str();
+ }
+ virtual std::string BinFuncName() const override { return "average"; }
+ virtual bool isAverage() const override { return true; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+
+class OpSub : public Reduction
+{
+public:
+ explicit OpSub(int nResultSize) : Reduction(nResultSize) {}
+
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ return "fsub_approx(" + lhs + "," + rhs + ")";
+ }
+ virtual std::string BinFuncName() const override { return "fsub"; }
+};
+
+class OpMul : public Reduction
+{
+public:
+ explicit OpMul(int nResultSize) : Reduction(nResultSize) {}
+
+ virtual std::string GetBottom() override { return "1"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ return lhs + "*" + rhs;
+ }
+ virtual std::string BinFuncName() const override { return "fmul"; }
+ virtual bool ZeroReturnZero() override { return true; }
+};
+
+/// Technically not a reduction, but fits the framework.
+class OpDiv : public Reduction
+{
+public:
+ explicit OpDiv(int nResultSize) : Reduction(nResultSize) {}
+
+ virtual std::string GetBottom() override { return "1.0"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ return "(" + rhs + "==0 ? CreateDoubleError(DivisionByZero) : (" + lhs + "/" + rhs + ") )";
+ }
+ virtual std::string BinFuncName() const override { return "fdiv"; }
+
+ virtual bool HandleNaNArgument( std::stringstream& ss, unsigned argno, SubArguments& vSubArguments ) const override
+ {
+ if (argno == 1)
+ {
+ ss <<
+ "if (isnan(" << vSubArguments[argno]->GenSlidingWindowDeclRef() << ")) {\n"
+ " return CreateDoubleError(DivisionByZero);\n"
+ "}\n";
+ return true;
+ }
+ else if (argno == 0)
+ {
+ ss <<
+ "if (isnan(" << vSubArguments[argno]->GenSlidingWindowDeclRef() << ") &&\n"
+ " !(isnan(" << vSubArguments[1]->GenSlidingWindowDeclRef() << ") || " << vSubArguments[1]->GenSlidingWindowDeclRef() << " == 0)) {\n"
+ " return 0;\n"
+ "}\n";
+ }
+ return false;
+ }
+
+};
+
+class OpMin : public Reduction
+{
+public:
+ explicit OpMin(int nResultSize) : Reduction(nResultSize) {}
+
+ virtual std::string GetBottom() override { return "NAN"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ return "fmin_count(" + lhs + "," + rhs + ", &nCount)";
+ }
+ virtual std::string BinFuncName() const override { return "min"; }
+ virtual bool isMinOrMax() const override { return true; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+
+class OpMax : public Reduction
+{
+public:
+ explicit OpMax(int nResultSize) : Reduction(nResultSize) {}
+
+ virtual std::string GetBottom() override { return "NAN"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ return "fmax_count(" + lhs + "," + rhs + ", &nCount)";
+ }
+ virtual std::string BinFuncName() const override { return "max"; }
+ virtual bool isMinOrMax() const override { return true; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+
+class OpSumProduct : public SumOfProduct
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override
+ {
+ return lhs + "*" + rhs;
+ }
+ virtual std::string BinFuncName() const override { return "fsop"; }
+};
+
+template<class Base>
+void ParallelReductionVectorRef<Base>::GenSlidingWindowFunction( std::stringstream& ss )
+{
+ if (!dynamic_cast<OpAverage*>(mpCodeGen.get()))
+ {
+ std::string name = Base::GetName();
+ ss << "__kernel void " << name;
+ ss << "_reduction(__global double* A, "
+ "__global double *result,int arrayLength,int windowSize){\n";
+ ss << " double tmp, current_result =" <<
+ mpCodeGen->GetBottom();
+ ss << ";\n";
+ ss << " int writePos = get_group_id(1);\n";
+ ss << " int lidx = get_local_id(0);\n";
+ ss << " __local double shm_buf[256];\n";
+ if (mpDVR->IsStartFixed())
+ ss << " int offset = 0;\n";
+ else // if (!mpDVR->IsStartFixed())
+ ss << " int offset = get_group_id(1);\n";
+ if (mpDVR->IsStartFixed() && mpDVR->IsEndFixed())
+ ss << " int end = windowSize;\n";
+ else if (!mpDVR->IsStartFixed() && !mpDVR->IsEndFixed())
+ ss << " int end = offset + windowSize;\n";
+ else if (mpDVR->IsStartFixed() && !mpDVR->IsEndFixed())
+ ss << " int end = windowSize + get_group_id(1);\n";
+ else if (!mpDVR->IsStartFixed() && mpDVR->IsEndFixed())
+ ss << " int end = windowSize;\n";
+ ss << " end = min(end, arrayLength);\n";
+
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " int loop = arrayLength/512 + 1;\n";
+ ss << " for (int l=0; l<loop; l++){\n";
+ ss << " tmp = " << mpCodeGen->GetBottom() << ";\n";
+ ss << " int loopOffset = l*512;\n";
+ ss << " if((loopOffset + lidx + offset + 256) < end) {\n";
+ ss << " tmp = legalize(" << mpCodeGen->Gen2(
+ "A[loopOffset + lidx + offset]", "tmp") << ", tmp);\n";
+ ss << " tmp = legalize(" << mpCodeGen->Gen2(
+ "A[loopOffset + lidx + offset + 256]", "tmp") << ", tmp);\n";
+ ss << " } else if ((loopOffset + lidx + offset) < end)\n";
+ ss << " tmp = legalize(" << mpCodeGen->Gen2(
+ "A[loopOffset + lidx + offset]", "tmp") << ", tmp);\n";
+ ss << " shm_buf[lidx] = tmp;\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " for (int i = 128; i >0; i/=2) {\n";
+ ss << " if (lidx < i)\n";
+ ss << " shm_buf[lidx] = ";
+ // Special case count
+ if (dynamic_cast<OpCount*>(mpCodeGen.get()))
+ ss << "shm_buf[lidx] + shm_buf[lidx + i];\n";
+ else
+ ss << mpCodeGen->Gen2("shm_buf[lidx]", "shm_buf[lidx + i]") << ";\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " }\n";
+ ss << " if (lidx == 0)\n";
+ ss << " current_result =";
+ if (dynamic_cast<OpCount*>(mpCodeGen.get()))
+ ss << "current_result + shm_buf[0]";
+ else
+ ss << mpCodeGen->Gen2("current_result", "shm_buf[0]");
+ ss << ";\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " }\n";
+ ss << " if (lidx == 0)\n";
+ ss << " result[writePos] = current_result;\n";
+ ss << "}\n";
+ }
+ else
+ {
+ std::string name = Base::GetName();
+ /*sum reduction*/
+ ss << "__kernel void " << name << "_sum";
+ ss << "_reduction(__global double* A, "
+ "__global double *result,int arrayLength,int windowSize){\n";
+ ss << " double tmp, current_result =" <<
+ mpCodeGen->GetBottom();
+ ss << ";\n";
+ ss << " int writePos = get_group_id(1);\n";
+ ss << " int lidx = get_local_id(0);\n";
+ ss << " __local double shm_buf[256];\n";
+ if (mpDVR->IsStartFixed())
+ ss << " int offset = 0;\n";
+ else // if (!mpDVR->IsStartFixed())
+ ss << " int offset = get_group_id(1);\n";
+ if (mpDVR->IsStartFixed() && mpDVR->IsEndFixed())
+ ss << " int end = windowSize;\n";
+ else if (!mpDVR->IsStartFixed() && !mpDVR->IsEndFixed())
+ ss << " int end = offset + windowSize;\n";
+ else if (mpDVR->IsStartFixed() && !mpDVR->IsEndFixed())
+ ss << " int end = windowSize + get_group_id(1);\n";
+ else if (!mpDVR->IsStartFixed() && mpDVR->IsEndFixed())
+ ss << " int end = windowSize;\n";
+ ss << " end = min(end, arrayLength);\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " int loop = arrayLength/512 + 1;\n";
+ ss << " for (int l=0; l<loop; l++){\n";
+ ss << " tmp = " << mpCodeGen->GetBottom() << ";\n";
+ ss << " int loopOffset = l*512;\n";
+ ss << " if((loopOffset + lidx + offset + 256) < end) {\n";
+ ss << " tmp = legalize(";
+ ss << "(A[loopOffset + lidx + offset]+ tmp)";
+ ss << ", tmp);\n";
+ ss << " tmp = legalize((A[loopOffset + lidx + offset + 256]+ tmp)";
+ ss << ", tmp);\n";
+ ss << " } else if ((loopOffset + lidx + offset) < end)\n";
+ ss << " tmp = legalize((A[loopOffset + lidx + offset] + tmp)";
+ ss << ", tmp);\n";
+ ss << " shm_buf[lidx] = tmp;\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " for (int i = 128; i >0; i/=2) {\n";
+ ss << " if (lidx < i)\n";
+ ss << " shm_buf[lidx] = ";
+ ss << "shm_buf[lidx] + shm_buf[lidx + i];\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " }\n";
+ ss << " if (lidx == 0)\n";
+ ss << " current_result =";
+ ss << "current_result + shm_buf[0]";
+ ss << ";\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " }\n";
+ ss << " if (lidx == 0)\n";
+ ss << " result[writePos] = current_result;\n";
+ ss << "}\n";
+ /*count reduction*/
+ ss << "__kernel void " << name << "_count";
+ ss << "_reduction(__global double* A, "
+ "__global double *result,int arrayLength,int windowSize){\n";
+ ss << " double tmp, current_result =" <<
+ mpCodeGen->GetBottom();
+ ss << ";\n";
+ ss << " int writePos = get_group_id(1);\n";
+ ss << " int lidx = get_local_id(0);\n";
+ ss << " __local double shm_buf[256];\n";
+ if (mpDVR->IsStartFixed())
+ ss << " int offset = 0;\n";
+ else // if (!mpDVR->IsStartFixed())
+ ss << " int offset = get_group_id(1);\n";
+ if (mpDVR->IsStartFixed() && mpDVR->IsEndFixed())
+ ss << " int end = windowSize;\n";
+ else if (!mpDVR->IsStartFixed() && !mpDVR->IsEndFixed())
+ ss << " int end = offset + windowSize;\n";
+ else if (mpDVR->IsStartFixed() && !mpDVR->IsEndFixed())
+ ss << " int end = windowSize + get_group_id(1);\n";
+ else if (!mpDVR->IsStartFixed() && mpDVR->IsEndFixed())
+ ss << " int end = windowSize;\n";
+ ss << " end = min(end, arrayLength);\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " int loop = arrayLength/512 + 1;\n";
+ ss << " for (int l=0; l<loop; l++){\n";
+ ss << " tmp = " << mpCodeGen->GetBottom() << ";\n";
+ ss << " int loopOffset = l*512;\n";
+ ss << " if((loopOffset + lidx + offset + 256) < end) {\n";
+ ss << " tmp = legalize((isnan(A[loopOffset + lidx + offset])?tmp:tmp+1.0)";
+ ss << ", tmp);\n";
+ ss << " tmp = legalize((isnan(A[loopOffset + lidx + offset+256])?tmp:tmp+1.0)";
+ ss << ", tmp);\n";
+ ss << " } else if ((loopOffset + lidx + offset) < end)\n";
+ ss << " tmp = legalize((isnan(A[loopOffset + lidx + offset])?tmp:tmp+1.0)";
+ ss << ", tmp);\n";
+ ss << " shm_buf[lidx] = tmp;\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " for (int i = 128; i >0; i/=2) {\n";
+ ss << " if (lidx < i)\n";
+ ss << " shm_buf[lidx] = ";
+ ss << "shm_buf[lidx] + shm_buf[lidx + i];\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " }\n";
+ ss << " if (lidx == 0)\n";
+ ss << " current_result =";
+ ss << "current_result + shm_buf[0];";
+ ss << ";\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " }\n";
+ ss << " if (lidx == 0)\n";
+ ss << " result[writePos] = current_result;\n";
+ ss << "}\n";
+ }
+
+}
+
+template<class Base>
+size_t ParallelReductionVectorRef<Base>::GenReductionLoopHeader(
+ std::stringstream& ss, int nResultSize, bool& needBody )
+{
+ assert(mpDVR);
+ size_t nCurWindowSize = mpDVR->GetRefRowSize();
+ std::string temp = Base::GetName() + "[gid0]";
+ ss << "tmp = ";
+ // Special case count
+ if (dynamic_cast<OpAverage*>(mpCodeGen.get()))
+ {
+ ss << mpCodeGen->Gen2(temp, "tmp") << ";\n";
+ ss << "nCount = nCount-1;\n";
+ ss << "nCount = nCount +"; /*re-assign nCount from count reduction*/
+ ss << Base::GetName() << "[gid0+" << nResultSize << "]" << ";\n";
+ }
+ else if (dynamic_cast<OpCount*>(mpCodeGen.get()))
+ ss << temp << "+ tmp";
+ else
+ ss << mpCodeGen->Gen2(temp, "tmp");
+ ss << ";\n\t";
+ needBody = false;
+ return nCurWindowSize;
+}
+
+template<class Base>
+size_t ParallelReductionVectorRef<Base>::Marshal( cl_kernel k, int argno, int w, cl_program mpProgram )
+{
+ assert(Base::mpClmem == nullptr);
+
+ OpenCLZone zone;
+ openclwrapper::KernelEnv kEnv;
+ openclwrapper::setKernelEnv(&kEnv);
+ cl_int err;
+ size_t nInput = mpDVR->GetArrayLength();
+ size_t nCurWindowSize = mpDVR->GetRefRowSize();
+ // create clmem buffer
+ if (mpDVR->GetArrays()[Base::mnIndex].mpNumericArray == nullptr)
+ throw Unhandled(__FILE__, __LINE__);
+ double* pHostBuffer = const_cast<double*>(
+ mpDVR->GetArrays()[Base::mnIndex].mpNumericArray);
+ size_t szHostBuffer = nInput * sizeof(double);
+ Base::mpClmem = clCreateBuffer(kEnv.mpkContext,
+ cl_mem_flags(CL_MEM_READ_ONLY) | CL_MEM_USE_HOST_PTR,
+ szHostBuffer,
+ pHostBuffer, &err);
+ SAL_INFO("sc.opencl", "Created buffer " << Base::mpClmem << " size " << nInput << "*" << sizeof(double) << "=" << szHostBuffer << " using host buffer " << pHostBuffer);
+
+ mpClmem2 = clCreateBuffer(kEnv.mpkContext,
+ CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
+ sizeof(double) * w, nullptr, nullptr);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clCreateBuffer", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created buffer " << mpClmem2 << " size " << sizeof(double) << "*" << w << "=" << (sizeof(double)*w));
+
+ // reproduce the reduction function name
+ std::string kernelName;
+ if (!dynamic_cast<OpAverage*>(mpCodeGen.get()))
+ kernelName = Base::GetName() + "_reduction";
+ else
+ kernelName = Base::GetName() + "_sum_reduction";
+ cl_kernel redKernel = clCreateKernel(mpProgram, kernelName.c_str(), &err);
+ if (err != CL_SUCCESS)
+ throw OpenCLError("clCreateKernel", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created kernel " << redKernel << " with name " << kernelName << " in program " << mpProgram);
+
+ // set kernel arg of reduction kernel
+ // TODO(Wei Wei): use unique name for kernel
+ cl_mem buf = Base::GetCLBuffer();
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << 0 << ": cl_mem: " << buf);
+ err = clSetKernelArg(redKernel, 0, sizeof(cl_mem),
+ static_cast<void*>(&buf));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << 1 << ": cl_mem: " << mpClmem2);
+ err = clSetKernelArg(redKernel, 1, sizeof(cl_mem), &mpClmem2);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << 2 << ": cl_int: " << nInput);
+ err = clSetKernelArg(redKernel, 2, sizeof(cl_int), static_cast<void*>(&nInput));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << 3 << ": cl_int: " << nCurWindowSize);
+ err = clSetKernelArg(redKernel, 3, sizeof(cl_int), static_cast<void*>(&nCurWindowSize));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+
+ // set work group size and execute
+ size_t global_work_size[] = { 256, static_cast<size_t>(w) };
+ size_t const local_work_size[] = { 256, 1 };
+ SAL_INFO("sc.opencl", "Enqueuing kernel " << redKernel);
+ err = clEnqueueNDRangeKernel(kEnv.mpkCmdQueue, redKernel, 2, nullptr,
+ global_work_size, local_work_size, 0, nullptr, nullptr);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clEnqueueNDRangeKernel", err, __FILE__, __LINE__);
+ err = clFinish(kEnv.mpkCmdQueue);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clFinish", err, __FILE__, __LINE__);
+ if (dynamic_cast<OpAverage*>(mpCodeGen.get()))
+ {
+ /*average need more reduction kernel for count computing*/
+ std::unique_ptr<double[]> pAllBuffer(new double[2 * w]);
+ double* resbuf = static_cast<double*>(clEnqueueMapBuffer(kEnv.mpkCmdQueue,
+ mpClmem2,
+ CL_TRUE, CL_MAP_READ, 0,
+ sizeof(double) * w, 0, nullptr, nullptr,
+ &err));
+ if (err != CL_SUCCESS)
+ throw OpenCLError("clEnqueueMapBuffer", err, __FILE__, __LINE__);
+
+ for (int i = 0; i < w; i++)
+ pAllBuffer[i] = resbuf[i];
+ err = clEnqueueUnmapMemObject(kEnv.mpkCmdQueue, mpClmem2, resbuf, 0, nullptr, nullptr);
+ if (err != CL_SUCCESS)
+ throw OpenCLError("clEnqueueUnmapMemObject", err, __FILE__, __LINE__);
+
+ kernelName = Base::GetName() + "_count_reduction";
+ redKernel = clCreateKernel(mpProgram, kernelName.c_str(), &err);
+ if (err != CL_SUCCESS)
+ throw OpenCLError("clCreateKernel", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created kernel " << redKernel << " with name " << kernelName << " in program " << mpProgram);
+
+ // set kernel arg of reduction kernel
+ buf = Base::GetCLBuffer();
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << 0 << ": cl_mem: " << buf);
+ err = clSetKernelArg(redKernel, 0, sizeof(cl_mem),
+ static_cast<void*>(&buf));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << 1 << ": cl_mem: " << mpClmem2);
+ err = clSetKernelArg(redKernel, 1, sizeof(cl_mem), &mpClmem2);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << 2 << ": cl_int: " << nInput);
+ err = clSetKernelArg(redKernel, 2, sizeof(cl_int), static_cast<void*>(&nInput));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << 3 << ": cl_int: " << nCurWindowSize);
+ err = clSetKernelArg(redKernel, 3, sizeof(cl_int), static_cast<void*>(&nCurWindowSize));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+
+ // set work group size and execute
+ size_t global_work_size1[] = { 256, static_cast<size_t>(w) };
+ size_t const local_work_size1[] = { 256, 1 };
+ SAL_INFO("sc.opencl", "Enqueuing kernel " << redKernel);
+ err = clEnqueueNDRangeKernel(kEnv.mpkCmdQueue, redKernel, 2, nullptr,
+ global_work_size1, local_work_size1, 0, nullptr, nullptr);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clEnqueueNDRangeKernel", err, __FILE__, __LINE__);
+ err = clFinish(kEnv.mpkCmdQueue);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clFinish", err, __FILE__, __LINE__);
+ resbuf = static_cast<double*>(clEnqueueMapBuffer(kEnv.mpkCmdQueue,
+ mpClmem2,
+ CL_TRUE, CL_MAP_READ, 0,
+ sizeof(double) * w, 0, nullptr, nullptr,
+ &err));
+ if (err != CL_SUCCESS)
+ throw OpenCLError("clEnqueueMapBuffer", err, __FILE__, __LINE__);
+ for (int i = 0; i < w; i++)
+ pAllBuffer[i + w] = resbuf[i];
+ err = clEnqueueUnmapMemObject(kEnv.mpkCmdQueue, mpClmem2, resbuf, 0, nullptr, nullptr);
+ // FIXME: Is it intentional to not throw an OpenCLError even if the clEnqueueUnmapMemObject() fails?
+ if (CL_SUCCESS != err)
+ SAL_WARN("sc.opencl", "clEnqueueUnmapMemObject failed: " << openclwrapper::errorString(err));
+ if (mpClmem2)
+ {
+ err = clReleaseMemObject(mpClmem2);
+ SAL_WARN_IF(err != CL_SUCCESS, "sc.opencl", "clReleaseMemObject failed: " << openclwrapper::errorString(err));
+ mpClmem2 = nullptr;
+ }
+ mpClmem2 = clCreateBuffer(kEnv.mpkContext,
+ cl_mem_flags(CL_MEM_READ_WRITE) | CL_MEM_COPY_HOST_PTR,
+ w * sizeof(double) * 2, pAllBuffer.get(), &err);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clCreateBuffer", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created buffer " << mpClmem2 << " size " << w << "*" << sizeof(double) << "=" << (w*sizeof(double)) << " copying host buffer " << pAllBuffer.get());
+ }
+ // set kernel arg
+ SAL_INFO("sc.opencl", "Kernel " << k << " arg " << argno << ": cl_mem: " << mpClmem2);
+ err = clSetKernelArg(k, argno, sizeof(cl_mem), &mpClmem2);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ return 1;
+}
+
+struct SumIfsArgs
+{
+ explicit SumIfsArgs(cl_mem x) : mCLMem(x), mConst(0.0) { }
+ explicit SumIfsArgs(double x) : mCLMem(nullptr), mConst(x) { }
+ cl_mem mCLMem;
+ double mConst;
+};
+
+/// Helper functions that have multiple buffers
+class DynamicKernelSoPArguments : public DynamicKernelArgument
+{
+public:
+ typedef std::vector<DynamicKernelArgumentRef> SubArgumentsType;
+
+ DynamicKernelSoPArguments( const ScCalcConfig& config,
+ const std::string& s, const FormulaTreeNodeRef& ft,
+ std::shared_ptr<SlidingFunctionBase> pCodeGen, int nResultSize );
+
+ /// Create buffer and pass the buffer to a given kernel
+ virtual size_t Marshal( cl_kernel k, int argno, int nVectorWidth, cl_program pProgram ) override
+ {
+ OpenCLZone zone;
+ unsigned i = 0;
+ for (const auto& rxSubArgument : mvSubArguments)
+ {
+ i += rxSubArgument->Marshal(k, argno + i, nVectorWidth, pProgram);
+ }
+ if (dynamic_cast<OpGeoMean*>(mpCodeGen.get()))
+ {
+ openclwrapper::KernelEnv kEnv;
+ openclwrapper::setKernelEnv(&kEnv);
+ cl_int err;
+ cl_mem pClmem2;
+
+ std::vector<cl_mem> vclmem;
+ for (const auto& rxSubArgument : mvSubArguments)
+ {
+ if (VectorRef* VR = dynamic_cast<VectorRef*>(rxSubArgument.get()))
+ vclmem.push_back(VR->GetCLBuffer());
+ else
+ vclmem.push_back(nullptr);
+ }
+ pClmem2 = clCreateBuffer(kEnv.mpkContext, CL_MEM_READ_WRITE,
+ sizeof(double) * nVectorWidth, nullptr, &err);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clCreateBuffer", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created buffer " << pClmem2 << " size " << sizeof(double) << "*" << nVectorWidth << "=" << (sizeof(double)*nVectorWidth));
+
+ std::string kernelName = "GeoMean_reduction";
+ cl_kernel redKernel = clCreateKernel(pProgram, kernelName.c_str(), &err);
+ if (err != CL_SUCCESS)
+ throw OpenCLError("clCreateKernel", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created kernel " << redKernel << " with name " << kernelName << " in program " << pProgram);
+
+ // set kernel arg of reduction kernel
+ for (size_t j = 0; j < vclmem.size(); j++)
+ {
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << j << ": " << (vclmem[j] ? "cl_mem" : "double") << ": " << vclmem[j]);
+ err = clSetKernelArg(redKernel, j,
+ vclmem[j] ? sizeof(cl_mem) : sizeof(double),
+ static_cast<void*>(&vclmem[j]));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ }
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << vclmem.size() << ": cl_mem: " << pClmem2);
+ err = clSetKernelArg(redKernel, vclmem.size(), sizeof(cl_mem), static_cast<void*>(&pClmem2));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+
+ // set work group size and execute
+ size_t global_work_size[] = { 256, static_cast<size_t>(nVectorWidth) };
+ size_t const local_work_size[] = { 256, 1 };
+ SAL_INFO("sc.opencl", "Enqueuing kernel " << redKernel);
+ err = clEnqueueNDRangeKernel(kEnv.mpkCmdQueue, redKernel, 2, nullptr,
+ global_work_size, local_work_size, 0, nullptr, nullptr);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clEnqueueNDRangeKernel", err, __FILE__, __LINE__);
+ err = clFinish(kEnv.mpkCmdQueue);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clFinish", err, __FILE__, __LINE__);
+
+ // Pass pClmem2 to the "real" kernel
+ SAL_INFO("sc.opencl", "Kernel " << k << " arg " << argno << ": cl_mem: " << pClmem2);
+ err = clSetKernelArg(k, argno, sizeof(cl_mem), static_cast<void*>(&pClmem2));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ }
+ if (OpSumIfs* OpSumCodeGen = dynamic_cast<OpSumIfs*>(mpCodeGen.get()))
+ {
+ openclwrapper::KernelEnv kEnv;
+ openclwrapper::setKernelEnv(&kEnv);
+ cl_int err;
+ DynamicKernelArgument* Arg = mvSubArguments[0].get();
+ DynamicKernelSlidingArgument<VectorRef>* slidingArgPtr =
+ static_cast<DynamicKernelSlidingArgument<VectorRef>*>(Arg);
+ mpClmem2 = nullptr;
+
+ if (OpSumCodeGen->NeedReductionKernel())
+ {
+ size_t nInput = slidingArgPtr->GetArrayLength();
+ size_t nCurWindowSize = slidingArgPtr->GetWindowSize();
+ std::vector<SumIfsArgs> vclmem;
+
+ for (const auto& rxSubArgument : mvSubArguments)
+ {
+ if (VectorRef* VR = dynamic_cast<VectorRef*>(rxSubArgument.get()))
+ vclmem.emplace_back(VR->GetCLBuffer());
+ else if (DynamicKernelConstantArgument* CA = dynamic_cast<DynamicKernelConstantArgument*>(rxSubArgument.get()))
+ vclmem.emplace_back(CA->GetDouble());
+ else
+ vclmem.emplace_back(nullptr);
+ }
+ mpClmem2 = clCreateBuffer(kEnv.mpkContext, CL_MEM_READ_WRITE,
+ sizeof(double) * nVectorWidth, nullptr, &err);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clCreateBuffer", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created buffer " << mpClmem2 << " size " << sizeof(double) << "*" << nVectorWidth << "=" << (sizeof(double)*nVectorWidth));
+
+ std::string kernelName = mvSubArguments[0]->GetName() + "_SumIfs_reduction";
+ cl_kernel redKernel = clCreateKernel(pProgram, kernelName.c_str(), &err);
+ if (err != CL_SUCCESS)
+ throw OpenCLError("clCreateKernel", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created kernel " << redKernel << " with name " << kernelName << " in program " << pProgram);
+
+ // set kernel arg of reduction kernel
+ for (size_t j = 0; j < vclmem.size(); j++)
+ {
+ if (vclmem[j].mCLMem)
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << j << ": cl_mem: " << vclmem[j].mCLMem);
+ else
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << j << ": double: " << vclmem[j].mConst);
+ err = clSetKernelArg(redKernel, j,
+ vclmem[j].mCLMem ? sizeof(cl_mem) : sizeof(double),
+ vclmem[j].mCLMem ? static_cast<void*>(&vclmem[j].mCLMem) :
+ static_cast<void*>(&vclmem[j].mConst));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ }
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << vclmem.size() << ": cl_mem: " << mpClmem2);
+ err = clSetKernelArg(redKernel, vclmem.size(), sizeof(cl_mem), static_cast<void*>(&mpClmem2));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << (vclmem.size() + 1) << ": cl_int: " << nInput);
+ err = clSetKernelArg(redKernel, vclmem.size() + 1, sizeof(cl_int), static_cast<void*>(&nInput));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+
+ SAL_INFO("sc.opencl", "Kernel " << redKernel << " arg " << (vclmem.size() + 2) << ": cl_int: " << nCurWindowSize);
+ err = clSetKernelArg(redKernel, vclmem.size() + 2, sizeof(cl_int), static_cast<void*>(&nCurWindowSize));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ // set work group size and execute
+ size_t global_work_size[] = { 256, static_cast<size_t>(nVectorWidth) };
+ size_t const local_work_size[] = { 256, 1 };
+ SAL_INFO("sc.opencl", "Enqueuing kernel " << redKernel);
+ err = clEnqueueNDRangeKernel(kEnv.mpkCmdQueue, redKernel, 2, nullptr,
+ global_work_size, local_work_size, 0, nullptr, nullptr);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clEnqueueNDRangeKernel", err, __FILE__, __LINE__);
+
+ err = clFinish(kEnv.mpkCmdQueue);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clFinish", err, __FILE__, __LINE__);
+
+ SAL_INFO("sc.opencl", "Releasing kernel " << redKernel);
+ err = clReleaseKernel(redKernel);
+ SAL_WARN_IF(err != CL_SUCCESS, "sc.opencl", "clReleaseKernel failed: " << openclwrapper::errorString(err));
+
+ // Pass mpClmem2 to the "real" kernel
+ SAL_INFO("sc.opencl", "Kernel " << k << " arg " << argno << ": cl_mem: " << mpClmem2);
+ err = clSetKernelArg(k, argno, sizeof(cl_mem), static_cast<void*>(&mpClmem2));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ }
+ }
+ return i;
+ }
+
+ virtual void GenSlidingWindowFunction( std::stringstream& ss ) override
+ {
+ for (DynamicKernelArgumentRef & rArg : mvSubArguments)
+ rArg->GenSlidingWindowFunction(ss);
+ mpCodeGen->GenSlidingWindowFunction(ss, mSymName, mvSubArguments);
+ }
+ virtual void GenDeclRef( std::stringstream& ss ) const override
+ {
+ for (size_t i = 0; i < mvSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ mvSubArguments[i]->GenDeclRef(ss);
+ }
+ }
+ virtual void GenDecl( std::stringstream& ss ) const override
+ {
+ for (SubArgumentsType::const_iterator it = mvSubArguments.begin(), e = mvSubArguments.end(); it != e;
+ ++it)
+ {
+ if (it != mvSubArguments.begin())
+ ss << ", ";
+ (*it)->GenDecl(ss);
+ }
+ }
+
+ virtual size_t GetWindowSize() const override
+ {
+ size_t nCurWindowSize = 0;
+ for (const auto & rSubArgument : mvSubArguments)
+ {
+ size_t nCurChildWindowSize = rSubArgument->GetWindowSize();
+ nCurWindowSize = (nCurWindowSize < nCurChildWindowSize) ?
+ nCurChildWindowSize : nCurWindowSize;
+ }
+ return nCurWindowSize;
+ }
+
+ /// When declared as input to a sliding window function
+ virtual void GenSlidingWindowDecl( std::stringstream& ss ) const override
+ {
+ for (SubArgumentsType::const_iterator it = mvSubArguments.begin(), e = mvSubArguments.end(); it != e;
+ ++it)
+ {
+ if (it != mvSubArguments.begin())
+ ss << ", ";
+ (*it)->GenSlidingWindowDecl(ss);
+ }
+ }
+ /// Generate either a function call to each children
+ /// or directly inline it if we are already inside a loop
+ virtual std::string GenSlidingWindowDeclRef( bool nested = false ) const override
+ {
+ std::stringstream ss;
+ if (!nested)
+ {
+ ss << mSymName << "_" << mpCodeGen->BinFuncName() << "(";
+ for (size_t i = 0; i < mvSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ mvSubArguments[i]->GenDeclRef(ss);
+ }
+ ss << ")";
+ }
+ else
+ {
+ if (mvSubArguments.size() != 2)
+ throw Unhandled(__FILE__, __LINE__);
+ bool bArgument1_NeedNested =
+ mvSubArguments[0]->GetFormulaToken()->GetType()
+ != formula::svSingleVectorRef;
+ bool bArgument2_NeedNested =
+ mvSubArguments[1]->GetFormulaToken()->GetType()
+ != formula::svSingleVectorRef;
+ ss << "(";
+ ss << mpCodeGen->
+ Gen2(mvSubArguments[0]
+ ->GenSlidingWindowDeclRef(bArgument1_NeedNested),
+ mvSubArguments[1]
+ ->GenSlidingWindowDeclRef(bArgument2_NeedNested));
+ ss << ")";
+ }
+ return ss.str();
+ }
+ virtual std::string DumpOpName() const override
+ {
+ std::string t = "_" + mpCodeGen->BinFuncName();
+ for (const auto & rSubArgument : mvSubArguments)
+ t += rSubArgument->DumpOpName();
+ return t;
+ }
+ virtual void DumpInlineFun( std::set<std::string>& decls,
+ std::set<std::string>& funs ) const override
+ {
+ mpCodeGen->BinInlineFun(decls, funs);
+ for (const auto & rSubArgument : mvSubArguments)
+ rSubArgument->DumpInlineFun(decls, funs);
+ }
+ virtual bool IsEmpty() const override
+ {
+ for (const auto & rSubArgument : mvSubArguments)
+ if( !rSubArgument->IsEmpty())
+ return false;
+ return true;
+ }
+ virtual ~DynamicKernelSoPArguments() override
+ {
+ if (mpClmem2)
+ {
+ cl_int err;
+ err = clReleaseMemObject(mpClmem2);
+ SAL_WARN_IF(err != CL_SUCCESS, "sc.opencl", "clReleaseMemObject failed: " << openclwrapper::errorString(err));
+ mpClmem2 = nullptr;
+ }
+ }
+
+private:
+ SubArgumentsType mvSubArguments;
+ std::shared_ptr<SlidingFunctionBase> mpCodeGen;
+ cl_mem mpClmem2;
+};
+
+}
+
+static DynamicKernelArgumentRef SoPHelper( const ScCalcConfig& config,
+ const std::string& ts, const FormulaTreeNodeRef& ft, std::shared_ptr<SlidingFunctionBase> pCodeGen,
+ int nResultSize )
+{
+ return std::make_shared<DynamicKernelSoPArguments>(config, ts, ft, std::move(pCodeGen), nResultSize);
+}
+
+template<class Base>
+static std::shared_ptr<DynamicKernelArgument> VectorRefFactory( const ScCalcConfig& config, const std::string& s,
+ const FormulaTreeNodeRef& ft,
+ std::shared_ptr<SlidingFunctionBase>& pCodeGen,
+ int index )
+{
+ //Black lists ineligible classes here ..
+ // SUMIFS does not perform parallel reduction at DoubleVectorRef level
+ if (dynamic_cast<OpSumIfs*>(pCodeGen.get()))
+ {
+ // coverity[identical_branches] - only identical if Base happens to be VectorRef
+ if (index == 0) // the first argument of OpSumIfs cannot be strings anyway
+ return std::make_shared<DynamicKernelSlidingArgument<VectorRef>>(config, s, ft, pCodeGen, index);
+ return std::make_shared<DynamicKernelSlidingArgument<Base>>(config, s, ft, pCodeGen, index);
+ }
+ // AVERAGE is not supported yet
+ //Average has been supported by reduction kernel
+ /*else if (dynamic_cast<OpAverage*>(pCodeGen.get()))
+ {
+ return new DynamicKernelSlidingArgument<Base>(config, s, ft, pCodeGen, index);
+ }*/
+ // MUL is not supported yet
+ else if (dynamic_cast<OpMul*>(pCodeGen.get()))
+ {
+ return std::make_shared<DynamicKernelSlidingArgument<Base>>(config, s, ft, pCodeGen, index);
+ }
+ // Sub is not a reduction per se
+ else if (dynamic_cast<OpSub*>(pCodeGen.get()))
+ {
+ return std::make_shared<DynamicKernelSlidingArgument<Base>>(config, s, ft, pCodeGen, index);
+ }
+ // Only child class of Reduction is supported
+ else if (!dynamic_cast<Reduction*>(pCodeGen.get()))
+ {
+ return std::make_shared<DynamicKernelSlidingArgument<Base>>(config, s, ft, pCodeGen, index);
+ }
+
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken*>(
+ ft->GetFormulaToken());
+ // Window being too small to justify a parallel reduction
+ if (pDVR->GetRefRowSize() < REDUCE_THRESHOLD)
+ return std::make_shared<DynamicKernelSlidingArgument<Base>>(config, s, ft, pCodeGen, index);
+ if (pDVR->IsStartFixed() == pDVR->IsEndFixed())
+ return std::make_shared<ParallelReductionVectorRef<Base>>(config, s, ft, pCodeGen, index);
+ else // Other cases are not supported as well
+ return std::make_shared<DynamicKernelSlidingArgument<Base>>(config, s, ft, pCodeGen, index);
+}
+
+DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config,
+ const std::string& s, const FormulaTreeNodeRef& ft, std::shared_ptr<SlidingFunctionBase> pCodeGen, int nResultSize ) :
+ DynamicKernelArgument(config, s, ft), mpCodeGen(pCodeGen), mpClmem2(nullptr)
+{
+ size_t nChildren = ft->Children.size();
+
+ for (size_t i = 0; i < nChildren; i++)
+ {
+ FormulaTreeNodeRef rChild = ft->Children[i];
+ if (!rChild)
+ throw Unhandled(__FILE__, __LINE__);
+ FormulaToken* pChild = rChild->GetFormulaToken();
+ if (!pChild)
+ throw Unhandled(__FILE__, __LINE__);
+ OpCode opc = pChild->GetOpCode();
+ std::stringstream tmpname;
+ tmpname << s << "_" << i;
+ std::string ts = tmpname.str();
+ switch (opc)
+ {
+ case ocPush:
+ if (pChild->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken*>(pChild);
+
+ // The code below will split one svDoubleVectorRef into one subargument
+ // for each column of data, and then all these subarguments will be later
+ // passed to the code generating the function. Most of the code then
+ // simply treats each subargument as one argument to the function, and thus
+ // could break in this case.
+ // As a simple solution, simply prevent this case, unless the code in question
+ // explicitly claims it will handle this situation properly.
+ if( pDVR->GetArrays().size() > 1 )
+ {
+ if( pCodeGen->canHandleMultiVector())
+ SAL_INFO("sc.opencl", "multi-column DoubleRef");
+ else
+ throw UnhandledToken(("Function '" + pCodeGen->BinFuncName()
+ + "' cannot handle multi-column DoubleRef").c_str(), __FILE__, __LINE__);
+ }
+
+ // FIXME: The Right Thing to do would be to compare the accumulated kernel
+ // parameter size against the CL_DEVICE_MAX_PARAMETER_SIZE of the device, but
+ // let's just do this sanity check for now. The kernel compilation will
+ // hopefully fail anyway if the size of parameters exceeds the limit and this
+ // sanity check is just to make us bail out a bit earlier.
+
+ // The number 50 comes from the fact that the minimum size of
+ // CL_DEVICE_MAX_PARAMETER_SIZE is 256, which for 32-bit code probably means 64
+ // of them. Round down a bit.
+
+ if (pDVR->GetArrays().size() > 50)
+ throw UnhandledToken(("Kernel would have ridiculously many parameters (" + std::to_string(2 + pDVR->GetArrays().size()) + ")").c_str(), __FILE__, __LINE__);
+
+ for (size_t j = 0; j < pDVR->GetArrays().size(); ++j)
+ {
+ SAL_INFO("sc.opencl", "i=" << i << " j=" << j <<
+ " mpNumericArray=" << pDVR->GetArrays()[j].mpNumericArray <<
+ " mpStringArray=" << pDVR->GetArrays()[j].mpStringArray <<
+ " allStringsAreNull=" << (AllStringsAreNull(pDVR->GetArrays()[j].mpStringArray, pDVR->GetArrayLength())?"YES":"NO") <<
+ " takeNumeric=" << (pCodeGen->takeNumeric()?"YES":"NO") <<
+ " takeString=" << (pCodeGen->takeString()?"YES":"NO"));
+
+ if (pDVR->GetArrays()[j].mpNumericArray &&
+ pCodeGen->takeNumeric() &&
+ pDVR->GetArrays()[j].mpStringArray &&
+ pCodeGen->takeString())
+ {
+ // Function takes numbers or strings, there are both
+ SAL_INFO("sc.opencl", "Numbers and strings");
+ mvSubArguments.push_back(
+ std::make_shared<DynamicKernelMixedSlidingArgument>(mCalcConfig,
+ ts, ft->Children[i], mpCodeGen, j));
+ }
+ else if (pDVR->GetArrays()[j].mpNumericArray &&
+ pCodeGen->takeNumeric() &&
+ (AllStringsAreNull(pDVR->GetArrays()[j].mpStringArray, pDVR->GetArrayLength()) || mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO))
+ {
+ // Function takes numbers, and either there
+ // are no strings, or there are strings but
+ // they are to be treated as zero
+ SAL_INFO("sc.opencl", "Numbers (no strings or strings treated as zero)");
+ mvSubArguments.push_back(
+ VectorRefFactory<VectorRef>(mCalcConfig,
+ ts, ft->Children[i], mpCodeGen, j));
+ }
+ else if (pDVR->GetArrays()[j].mpNumericArray == nullptr &&
+ pCodeGen->takeNumeric() &&
+ pDVR->GetArrays()[j].mpStringArray &&
+ mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO)
+ {
+ // Function takes numbers, and there are only
+ // strings, but they are to be treated as zero
+ SAL_INFO("sc.opencl", "Only strings even if want numbers but should be treated as zero");
+ mvSubArguments.push_back(
+ VectorRefFactory<VectorRef>(mCalcConfig,
+ ts, ft->Children[i], mpCodeGen, j));
+ }
+ else if (pDVR->GetArrays()[j].mpStringArray &&
+ pCodeGen->takeString())
+ {
+ // There are strings, and the function takes strings.
+ SAL_INFO("sc.opencl", "Strings only");
+ mvSubArguments.push_back(
+ VectorRefFactory
+ <DynamicKernelStringArgument>(mCalcConfig,
+ ts, ft->Children[i], mpCodeGen, j));
+ }
+ else if (AllStringsAreNull(pDVR->GetArrays()[j].mpStringArray, pDVR->GetArrayLength()) &&
+ pDVR->GetArrays()[j].mpNumericArray == nullptr)
+ {
+ // There are only empty cells. Push as an
+ // array of NANs
+ SAL_INFO("sc.opencl", "Only empty cells");
+ mvSubArguments.push_back(
+ VectorRefFactory<VectorRef>(mCalcConfig,
+ ts, ft->Children[i], mpCodeGen, j));
+ }
+ else
+ {
+ SAL_INFO("sc.opencl", "Unhandled case, rejecting for OpenCL");
+ throw UnhandledToken(("Unhandled numbers/strings combination for '"
+ + pCodeGen->BinFuncName() + "'").c_str(), __FILE__, __LINE__);
+ }
+ }
+ }
+ else if (pChild->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast<const formula::SingleVectorRefToken*>(pChild);
+
+ SAL_INFO("sc.opencl", "i=" << i <<
+ " mpNumericArray=" << pSVR->GetArray().mpNumericArray <<
+ " mpStringArray=" << pSVR->GetArray().mpStringArray <<
+ " allStringsAreNull=" << (AllStringsAreNull(pSVR->GetArray().mpStringArray, pSVR->GetArrayLength())?"YES":"NO") <<
+ " takeNumeric=" << (pCodeGen->takeNumeric()?"YES":"NO") <<
+ " takeString=" << (pCodeGen->takeString()?"YES":"NO"));
+
+ if (pSVR->GetArray().mpNumericArray &&
+ pCodeGen->takeNumeric() &&
+ pSVR->GetArray().mpStringArray &&
+ pCodeGen->takeString())
+ {
+ // Function takes numbers or strings, there are both
+ SAL_INFO("sc.opencl", "Numbers and strings");
+ mvSubArguments.push_back(
+ std::make_shared<DynamicKernelMixedArgument>(mCalcConfig,
+ ts, ft->Children[i]));
+ }
+ else if (pSVR->GetArray().mpNumericArray &&
+ pCodeGen->takeNumeric() &&
+ (AllStringsAreNull(pSVR->GetArray().mpStringArray, pSVR->GetArrayLength()) || mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO))
+ {
+ // Function takes numbers, and either there
+ // are no strings, or there are strings but
+ // they are to be treated as zero
+ SAL_INFO("sc.opencl", "Numbers (no strings or strings treated as zero)");
+ mvSubArguments.push_back(
+ std::make_shared<VectorRef>(mCalcConfig, ts,
+ ft->Children[i]));
+ }
+ else if (pSVR->GetArray().mpNumericArray == nullptr &&
+ pCodeGen->takeNumeric() &&
+ pSVR->GetArray().mpStringArray &&
+ mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO)
+ {
+ // Function takes numbers, and there are only
+ // strings, but they are to be treated as zero
+ SAL_INFO("sc.opencl", "Only strings even if want numbers but should be treated as zero");
+ mvSubArguments.push_back(
+ std::make_shared<VectorRef>(mCalcConfig, ts,
+ ft->Children[i]));
+ }
+ else if (pSVR->GetArray().mpStringArray &&
+ pCodeGen->takeString())
+ {
+ // There are strings, and the function takes strings.
+ SAL_INFO("sc.opencl", "Strings only");
+ mvSubArguments.push_back(
+ std::make_shared<DynamicKernelStringArgument>(mCalcConfig,
+ ts, ft->Children[i]));
+ }
+ else if (AllStringsAreNull(pSVR->GetArray().mpStringArray, pSVR->GetArrayLength()) &&
+ pSVR->GetArray().mpNumericArray == nullptr)
+ {
+ // There are only empty cells. Push as an
+ // array of NANs
+ SAL_INFO("sc.opencl", "Only empty cells");
+ mvSubArguments.push_back(
+ std::make_shared<VectorRef>(mCalcConfig, ts,
+ ft->Children[i]));
+ }
+ else
+ {
+ SAL_INFO("sc.opencl", "Unhandled case, rejecting for OpenCL");
+ throw UnhandledToken(("Unhandled numbers/strings combination for '"
+ + pCodeGen->BinFuncName() + "'").c_str(), __FILE__, __LINE__);
+ }
+ }
+ else if (pChild->GetType() == formula::svDouble)
+ {
+ SAL_INFO("sc.opencl", "Constant number case");
+ mvSubArguments.push_back(
+ std::make_shared<DynamicKernelConstantArgument>(mCalcConfig, ts,
+ ft->Children[i]));
+ }
+ else if (pChild->GetType() == formula::svString
+ && pCodeGen->takeString())
+ {
+ SAL_INFO("sc.opencl", "Constant string case");
+ mvSubArguments.push_back(
+ std::make_shared<ConstStringArgument>(mCalcConfig, ts,
+ ft->Children[i]));
+ }
+ else
+ {
+ SAL_INFO("sc.opencl", "Unhandled operand, rejecting for OpenCL");
+ throw UnhandledToken(("unhandled operand " + StackVarEnumToString(pChild->GetType()) + " for ocPush").c_str(), __FILE__, __LINE__);
+ }
+ break;
+ case ocDiv:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpDiv>(nResultSize), nResultSize));
+ break;
+ case ocMul:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpMul>(nResultSize), nResultSize));
+ break;
+ case ocSub:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpSub>(nResultSize), nResultSize));
+ break;
+ case ocAdd:
+ case ocSum:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpSum>(nResultSize), nResultSize));
+ break;
+ case ocAverage:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpAverage>(nResultSize), nResultSize));
+ break;
+ case ocMin:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpMin>(nResultSize), nResultSize));
+ break;
+ case ocMax:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpMax>(nResultSize), nResultSize));
+ break;
+ case ocCount:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpCount>(nResultSize), nResultSize));
+ break;
+ case ocSumProduct:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpSumProduct>(), nResultSize));
+ break;
+ case ocIRR:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpIRR>(), nResultSize));
+ break;
+ case ocMIRR:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpMIRR>(), nResultSize));
+ break;
+ case ocPMT:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpPMT>(), nResultSize));
+ break;
+ case ocRate:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpIntrate>(), nResultSize));
+ break;
+ case ocRRI:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpRRI>(), nResultSize));
+ break;
+ case ocPpmt:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpPPMT>(), nResultSize));
+ break;
+ case ocFisher:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpFisher>(), nResultSize));
+ break;
+ case ocFisherInv:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpFisherInv>(), nResultSize));
+ break;
+ case ocGamma:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpGamma>(), nResultSize));
+ break;
+ case ocSLN:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpSLN>(), nResultSize));
+ break;
+ case ocGammaLn:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpGammaLn>(), nResultSize));
+ break;
+ case ocGauss:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpGauss>(), nResultSize));
+ break;
+ /*case ocGeoMean:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpGeoMean));
+ break;*/
+ case ocHarMean:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpHarMean>(), nResultSize));
+ break;
+ case ocLessEqual:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpLessEqual>(), nResultSize));
+ break;
+ case ocLess:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpLess>(), nResultSize));
+ break;
+ case ocEqual:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpEqual>(), nResultSize));
+ break;
+ case ocGreater:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpGreater>(), nResultSize));
+ break;
+ case ocSYD:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpSYD>(), nResultSize));
+ break;
+ case ocCorrel:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpCorrel>(), nResultSize));
+ break;
+ case ocCos:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpCos>(), nResultSize));
+ break;
+ case ocNegBinomVert :
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpNegbinomdist>(), nResultSize));
+ break;
+ case ocPearson:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpPearson>(), nResultSize));
+ break;
+ case ocRSQ:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpRsq>(), nResultSize));
+ break;
+ case ocCosecant:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpCsc>(), nResultSize));
+ break;
+ case ocISPMT:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpISPMT>(), nResultSize));
+ break;
+ case ocPDuration:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpPDuration>(), nResultSize));
+ break;
+ case ocSinHyp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSinh>(), nResultSize));
+ break;
+ case ocAbs:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpAbs>(), nResultSize));
+ break;
+ case ocPV:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpPV>(), nResultSize));
+ break;
+ case ocSin:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSin>(), nResultSize));
+ break;
+ case ocTan:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpTan>(), nResultSize));
+ break;
+ case ocTanHyp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpTanH>(), nResultSize));
+ break;
+ case ocStandard:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpStandard>(), nResultSize));
+ break;
+ case ocWeibull:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpWeibull>(), nResultSize));
+ break;
+ /*case ocMedian:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i],std::make_shared<OpMedian));
+ break;*/
+ case ocDDB:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDDB>(), nResultSize));
+ break;
+ case ocFV:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpFV>(), nResultSize));
+ break;
+ case ocSumIfs:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSumIfs>(), nResultSize));
+ break;
+ /*case ocVBD:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i],std::make_shared<OpVDB));
+ break;*/
+ case ocKurt:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpKurt>(), nResultSize));
+ break;
+ /*case ocNper:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpNper));
+ break;*/
+ case ocNormDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpNormdist>(), nResultSize));
+ break;
+ case ocArcCos:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpArcCos>(), nResultSize));
+ break;
+ case ocSqrt:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSqrt>(), nResultSize));
+ break;
+ case ocArcCosHyp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpArcCosHyp>(), nResultSize));
+ break;
+ case ocNPV:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpNPV>(), nResultSize));
+ break;
+ case ocStdNormDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpNormsdist>(), nResultSize));
+ break;
+ case ocNormInv:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpNorminv>(), nResultSize));
+ break;
+ case ocSNormInv:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpNormsinv>(), nResultSize));
+ break;
+ case ocPermut:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpPermut>(), nResultSize));
+ break;
+ case ocPermutationA:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpPermutationA>(), nResultSize));
+ break;
+ case ocPhi:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpPhi>(), nResultSize));
+ break;
+ case ocIpmt:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpIPMT>(), nResultSize));
+ break;
+ case ocConfidence:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpConfidence>(), nResultSize));
+ break;
+ case ocIntercept:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpIntercept>(), nResultSize));
+ break;
+ case ocDB:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpDB>(), nResultSize));
+ break;
+ case ocLogInv:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpLogInv>(), nResultSize));
+ break;
+ case ocArcCot:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpArcCot>(), nResultSize));
+ break;
+ case ocCosHyp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCosh>(), nResultSize));
+ break;
+ case ocCritBinom:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCritBinom>(), nResultSize));
+ break;
+ case ocArcCotHyp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpArcCotHyp>(), nResultSize));
+ break;
+ case ocArcSin:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpArcSin>(), nResultSize));
+ break;
+ case ocArcSinHyp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpArcSinHyp>(), nResultSize));
+ break;
+ case ocArcTan:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpArcTan>(), nResultSize));
+ break;
+ case ocArcTanHyp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpArcTanH>(), nResultSize));
+ break;
+ case ocBitAnd:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpBitAnd>(), nResultSize));
+ break;
+ case ocForecast:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpForecast>(), nResultSize));
+ break;
+ case ocLogNormDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpLogNormDist>(), nResultSize));
+ break;
+ /*case ocGammaDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpGammaDist));
+ break;*/
+ case ocLn:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpLn>(), nResultSize));
+ break;
+ case ocRound:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpRound>(), nResultSize));
+ break;
+ case ocCot:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCot>(), nResultSize));
+ break;
+ case ocCotHyp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCoth>(), nResultSize));
+ break;
+ case ocFDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpFdist>(), nResultSize));
+ break;
+ case ocVar:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpVar>(), nResultSize));
+ break;
+ /*case ocChiDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i],std::make_shared<OpChiDist));
+ break;*/
+ case ocPow:
+ case ocPower:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpPower>(), nResultSize));
+ break;
+ case ocOdd:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpOdd>(), nResultSize));
+ break;
+ /*case ocChiSqDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i],std::make_shared<OpChiSqDist));
+ break;
+ case ocChiSqInv:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i],std::make_shared<OpChiSqInv));
+ break;
+ case ocGammaInv:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpGammaInv));
+ break;*/
+ case ocFloor:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpFloor>(), nResultSize));
+ break;
+ /*case ocFInv:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpFInv));
+ break;*/
+ case ocFTest:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpFTest>(), nResultSize));
+ break;
+ case ocB:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpB>(), nResultSize));
+ break;
+ case ocBetaDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpBetaDist>(), nResultSize));
+ break;
+ case ocCosecantHyp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCscH>(), nResultSize));
+ break;
+ case ocExp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpExp>(), nResultSize));
+ break;
+ case ocLog10:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpLog10>(), nResultSize));
+ break;
+ case ocExpDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpExponDist>(), nResultSize));
+ break;
+ case ocAverageIfs:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpAverageIfs>(), nResultSize));
+ break;
+ case ocCountIfs:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCountIfs>(), nResultSize));
+ break;
+ case ocCombinA:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCombinA>(), nResultSize));
+ break;
+ case ocEven:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpEven>(), nResultSize));
+ break;
+ case ocLog:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpLog>(), nResultSize));
+ break;
+ case ocMod:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpMod>(), nResultSize));
+ break;
+ case ocTrunc:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpTrunc>(), nResultSize));
+ break;
+ case ocSkew:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSkew>(), nResultSize));
+ break;
+ case ocArcTan2:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpArcTan2>(), nResultSize));
+ break;
+ case ocBitOr:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpBitOr>(), nResultSize));
+ break;
+ case ocBitLshift:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpBitLshift>(), nResultSize));
+ break;
+ case ocBitRshift:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpBitRshift>(), nResultSize));
+ break;
+ case ocBitXor:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpBitXor>(), nResultSize));
+ break;
+ /*case ocChiInv:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i],std::make_shared<OpChiInv));
+ break;*/
+ case ocPoissonDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpPoisson>(), nResultSize));
+ break;
+ case ocSumSQ:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSumSQ>(), nResultSize));
+ break;
+ case ocSkewp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSkewp>(), nResultSize));
+ break;
+ case ocBinomDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpBinomdist>(), nResultSize));
+ break;
+ case ocVarP:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpVarP>(), nResultSize));
+ break;
+ case ocCeil:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCeil>(), nResultSize));
+ break;
+ case ocCombin:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCombin>(), nResultSize));
+ break;
+ case ocDevSq:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDevSq>(), nResultSize));
+ break;
+ case ocStDev:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpStDev>(), nResultSize));
+ break;
+ case ocSlope:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSlope>(), nResultSize));
+ break;
+ case ocSTEYX:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSTEYX>(), nResultSize));
+ break;
+ case ocZTest:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpZTest>(), nResultSize));
+ break;
+ case ocPi:
+ mvSubArguments.push_back(
+ std::make_shared<DynamicKernelPiArgument>(mCalcConfig, ts,
+ ft->Children[i]));
+ break;
+ case ocRandom:
+ mvSubArguments.push_back(
+ std::make_shared<DynamicKernelRandomArgument>(mCalcConfig, ts,
+ ft->Children[i]));
+ break;
+ case ocProduct:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpProduct>(), nResultSize));
+ break;
+ /*case ocHypGeomDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i],std::make_shared<OpHypGeomDist));
+ break;*/
+ case ocSumX2MY2:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSumX2MY2>(), nResultSize));
+ break;
+ case ocSumX2DY2:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSumX2PY2>(), nResultSize));
+ break;
+ /*case ocBetaInv:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i],std::make_shared<OpBetainv));
+ break;*/
+ case ocTTest:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpTTest>(), nResultSize));
+ break;
+ case ocTDist:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpTDist>(), nResultSize));
+ break;
+ /*case ocTInv:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpTInv));
+ break;*/
+ case ocSumXMY2:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSumXMY2>(), nResultSize));
+ break;
+ case ocStDevP:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpStDevP>(), nResultSize));
+ break;
+ case ocCovar:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCovar>(), nResultSize));
+ break;
+ case ocAnd:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpAnd>(), nResultSize));
+ break;
+ case ocVLookup:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpVLookup>(), nResultSize));
+ break;
+ case ocOr:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpOr>(), nResultSize));
+ break;
+ case ocNot:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpNot>(), nResultSize));
+ break;
+ case ocXor:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpXor>(), nResultSize));
+ break;
+ case ocDBMax:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDmax>(), nResultSize));
+ break;
+ case ocDBMin:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDmin>(), nResultSize));
+ break;
+ case ocDBProduct:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDproduct>(), nResultSize));
+ break;
+ case ocDBAverage:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDaverage>(), nResultSize));
+ break;
+ case ocDBStdDev:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDstdev>(), nResultSize));
+ break;
+ case ocDBStdDevP:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDstdevp>(), nResultSize));
+ break;
+ case ocDBSum:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDsum>(), nResultSize));
+ break;
+ case ocDBVar:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDvar>(), nResultSize));
+ break;
+ case ocDBVarP:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDvarp>(), nResultSize));
+ break;
+ case ocAverageIf:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpAverageIf>(), nResultSize));
+ break;
+ case ocDBCount:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDcount>(), nResultSize));
+ break;
+ case ocDBCount2:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDcount2>(), nResultSize));
+ break;
+ case ocDeg:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpDeg>(), nResultSize));
+ break;
+ case ocRoundUp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpRoundUp>(), nResultSize));
+ break;
+ case ocRoundDown:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpRoundDown>(), nResultSize));
+ break;
+ case ocInt:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpInt>(), nResultSize));
+ break;
+ case ocRad:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpRadians>(), nResultSize));
+ break;
+ case ocCountIf:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCountIf>(), nResultSize));
+ break;
+ case ocIsEven:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpIsEven>(), nResultSize));
+ break;
+ case ocIsOdd:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpIsOdd>(), nResultSize));
+ break;
+ case ocFact:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpFact>(), nResultSize));
+ break;
+ case ocMinA:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpMinA>(), nResultSize));
+ break;
+ case ocCount2:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpCountA>(), nResultSize));
+ break;
+ case ocMaxA:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpMaxA>(), nResultSize));
+ break;
+ case ocAverageA:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpAverageA>(), nResultSize));
+ break;
+ case ocVarA:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpVarA>(), nResultSize));
+ break;
+ case ocVarPA:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpVarPA>(), nResultSize));
+ break;
+ case ocStDevA:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpStDevA>(), nResultSize));
+ break;
+ case ocStDevPA:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpStDevPA>(), nResultSize));
+ break;
+ case ocSecant:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSec>(), nResultSize));
+ break;
+ case ocSecantHyp:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSecH>(), nResultSize));
+ break;
+ case ocSumIf:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpSumIf>(), nResultSize));
+ break;
+ case ocNegSub:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpNegSub>(), nResultSize));
+ break;
+ case ocAveDev:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpAveDev>(), nResultSize));
+ break;
+ case ocIf:
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpIf>(), nResultSize));
+ break;
+ case ocExternal:
+ if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getEffect")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpEffective>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getCumipmt")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpCumipmt>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getNominal")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpNominal>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getCumprinc")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpCumprinc>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getXnpv")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpXNPV>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getPricemat")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpPriceMat>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getReceived")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpReceived>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getTbilleq")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpTbilleq>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getTbillprice")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpTbillprice>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getTbillyield")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpTbillyield>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getFvschedule")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpFvschedule>(), nResultSize));
+ }
+ /*else if ( pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getYield")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpYield));
+ }*/
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getYielddisc")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpYielddisc>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getYieldmat")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpYieldmat>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getAccrintm")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpAccrintm>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getCoupdaybs")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpCoupdaybs>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getDollarde")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpDollarde>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getDollarfr")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpDollarfr>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getCoupdays")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpCoupdays>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getCoupdaysnc")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpCoupdaysnc>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getDisc")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpDISC>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getIntrate")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpINTRATE>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getPrice")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpPrice>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getCoupnum")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpCoupnum>(), nResultSize));
+ }
+ /*else if pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getDuration"))
+ {
+ mvSubArguments.push_back(
+ SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared<OpDuration_ADD));
+ }*/
+ /*else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getAmordegrc")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpAmordegrc, nResultSize));
+ }*/
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getAmorlinc")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpAmorlinc>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getMduration")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpMDuration>(), nResultSize));
+ }
+ /*else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getXirr")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpXirr, nResultSize));
+ }*/
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getOddlprice")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpOddlprice>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getOddlyield")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpOddlyield>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getPricedisc")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
+ ft->Children[i], std::make_shared<OpPriceDisc>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getCouppcd")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpCouppcd>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getCoupncd")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpCoupncd>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getAccrint")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpAccrint>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getSqrtpi")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpSqrtPi>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getConvert")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpConvert>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getIseven")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpIsEven>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getIsodd")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpIsOdd>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getMround")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpMROUND>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getQuotient")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpQuotient>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getSeriessum")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpSeriesSum>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getBesselj")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpBesselj>(), nResultSize));
+ }
+ else if (pChild->GetExternal() == "com.sun.star.sheet.addin.Analysis.getGestep")
+ {
+ mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
+ std::make_shared<OpGestep>(), nResultSize));
+ }
+ else
+ throw UnhandledToken(OUString("unhandled external " + pChild->GetExternal()).toUtf8().getStr(), __FILE__, __LINE__);
+ break;
+
+ default:
+ throw UnhandledToken(OUString("unhandled opcode "
+ + formula::FormulaCompiler().GetOpCodeMap(com::sun::star::sheet::FormulaLanguage::ENGLISH)->getSymbol(opc)
+ + "(" + OUString::number(opc) + ")").toUtf8().getStr(), __FILE__, __LINE__);
+ }
+ }
+}
+
+namespace {
+
+class DynamicKernel : public CompiledFormula
+{
+public:
+ DynamicKernel( const ScCalcConfig& config, const FormulaTreeNodeRef& r, int nResultSize );
+ virtual ~DynamicKernel() override;
+
+ static std::shared_ptr<DynamicKernel> create( const ScCalcConfig& config, const ScTokenArray& rCode, int nResultSize );
+
+ /// OpenCL code generation
+ void CodeGen();
+
+ /// Produce kernel hash
+ std::string const & GetMD5();
+
+ /// Create program, build, and create kernel
+ /// TODO cache results based on kernel body hash
+ /// TODO: abstract OpenCL part out into OpenCL wrapper.
+ void CreateKernel();
+
+ /// Prepare buffers, marshal them to GPU, and launch the kernel
+ /// TODO: abstract OpenCL part out into OpenCL wrapper.
+ void Launch( size_t nr );
+
+ cl_mem GetResultBuffer() const { return mpResClmem; }
+
+private:
+ ScCalcConfig mCalcConfig;
+ FormulaTreeNodeRef mpRoot;
+ SymbolTable mSyms;
+ std::string mKernelSignature, mKernelHash;
+ std::string mFullProgramSrc;
+ cl_program mpProgram;
+ cl_kernel mpKernel;
+ cl_mem mpResClmem; // Results
+ std::set<std::string> inlineDecl;
+ std::set<std::string> inlineFun;
+
+ int mnResultSize;
+};
+
+}
+
+DynamicKernel::DynamicKernel( const ScCalcConfig& config, const FormulaTreeNodeRef& r, int nResultSize ) :
+ mCalcConfig(config),
+ mpRoot(r),
+ mpProgram(nullptr),
+ mpKernel(nullptr),
+ mpResClmem(nullptr),
+ mnResultSize(nResultSize) {}
+
+DynamicKernel::~DynamicKernel()
+{
+ cl_int err;
+ if (mpResClmem)
+ {
+ err = clReleaseMemObject(mpResClmem);
+ SAL_WARN_IF(err != CL_SUCCESS, "sc.opencl", "clReleaseMemObject failed: " << openclwrapper::errorString(err));
+ }
+ if (mpKernel)
+ {
+ SAL_INFO("sc.opencl", "Releasing kernel " << mpKernel);
+ err = clReleaseKernel(mpKernel);
+ SAL_WARN_IF(err != CL_SUCCESS, "sc.opencl", "clReleaseKernel failed: " << openclwrapper::errorString(err));
+ }
+ // mpProgram is not going to be released here -- it's cached.
+}
+
+void DynamicKernel::CodeGen()
+{
+ // Traverse the tree of expression and declare symbols used
+ const DynamicKernelArgument* DK = mSyms.DeclRefArg<DynamicKernelSoPArguments>(mCalcConfig, mpRoot, std::make_shared<OpNop>(mnResultSize), mnResultSize);
+
+ std::stringstream decl;
+ if (openclwrapper::gpuEnv.mnKhrFp64Flag)
+ {
+ decl << "#if __OPENCL_VERSION__ < 120\n";
+ decl << "#pragma OPENCL EXTENSION cl_khr_fp64: enable\n";
+ decl << "#endif\n";
+ }
+ else if (openclwrapper::gpuEnv.mnAmdFp64Flag)
+ {
+ decl << "#pragma OPENCL EXTENSION cl_amd_fp64: enable\n";
+ }
+ // preambles
+ decl << publicFunc;
+ DK->DumpInlineFun(inlineDecl, inlineFun);
+ for (const auto& rItem : inlineDecl)
+ {
+ decl << rItem;
+ }
+
+ for (const auto& rItem : inlineFun)
+ {
+ decl << rItem;
+ }
+ mSyms.DumpSlidingWindowFunctions(decl);
+ mKernelSignature = DK->DumpOpName();
+ decl << "__kernel void DynamicKernel" << mKernelSignature;
+ decl << "(__global double *result";
+ if( !DK->IsEmpty())
+ {
+ decl << ", ";
+ DK->GenSlidingWindowDecl(decl);
+ }
+ decl << ") {\n\tint gid0 = get_global_id(0);\n\tresult[gid0] = " <<
+ DK->GenSlidingWindowDeclRef() << ";\n}\n";
+ mFullProgramSrc = decl.str();
+ SAL_INFO(
+ "sc.opencl.source",
+ (mKernelSignature[0] == '_'
+ ? mKernelSignature.substr(1, std::string::npos) : mKernelSignature)
+ << " program to be compiled:\n" << linenumberify(mFullProgramSrc));
+}
+
+std::string const & DynamicKernel::GetMD5()
+{
+ if (mKernelHash.empty())
+ {
+ std::stringstream md5s;
+ // Compute MD5SUM of kernel body to obtain the name
+ sal_uInt8 result[RTL_DIGEST_LENGTH_MD5];
+ rtl_digest_MD5(
+ mFullProgramSrc.c_str(),
+ mFullProgramSrc.length(), result,
+ RTL_DIGEST_LENGTH_MD5);
+ for (sal_uInt8 i : result)
+ {
+ md5s << std::hex << static_cast<int>(i);
+ }
+ mKernelHash = md5s.str();
+ }
+ return mKernelHash;
+}
+
+/// Build code
+void DynamicKernel::CreateKernel()
+{
+ if (mpKernel)
+ // already created.
+ return;
+
+ cl_int err;
+ std::string kname = "DynamicKernel" + mKernelSignature;
+ // Compile kernel here!!!
+
+ OpenCLZone zone;
+ openclwrapper::KernelEnv kEnv;
+ openclwrapper::setKernelEnv(&kEnv);
+ const char* src = mFullProgramSrc.c_str();
+ static std::string lastOneKernelHash;
+ static std::string lastSecondKernelHash;
+ static cl_program lastOneProgram = nullptr;
+ static cl_program lastSecondProgram = nullptr;
+ std::string KernelHash = mKernelSignature + GetMD5();
+ if (lastOneKernelHash == KernelHash && lastOneProgram)
+ {
+ mpProgram = lastOneProgram;
+ }
+ else if (lastSecondKernelHash == KernelHash && lastSecondProgram)
+ {
+ mpProgram = lastSecondProgram;
+ }
+ else
+ { // doesn't match the last compiled formula.
+
+ if (lastSecondProgram)
+ {
+ SAL_INFO("sc.opencl", "Releasing program " << lastSecondProgram);
+ err = clReleaseProgram(lastSecondProgram);
+ SAL_WARN_IF(err != CL_SUCCESS, "sc.opencl", "clReleaseProgram failed: " << openclwrapper::errorString(err));
+ lastSecondProgram = nullptr;
+ }
+ if (openclwrapper::buildProgramFromBinary("",
+ &openclwrapper::gpuEnv, KernelHash.c_str(), 0))
+ {
+ mpProgram = openclwrapper::gpuEnv.mpArryPrograms[0];
+ openclwrapper::gpuEnv.mpArryPrograms[0] = nullptr;
+ }
+ else
+ {
+ mpProgram = clCreateProgramWithSource(kEnv.mpkContext, 1,
+ &src, nullptr, &err);
+ if (err != CL_SUCCESS)
+ throw OpenCLError("clCreateProgramWithSource", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created program " << mpProgram);
+
+ err = clBuildProgram(mpProgram, 1,
+ &openclwrapper::gpuEnv.mpDevID, "", nullptr, nullptr);
+ if (err != CL_SUCCESS)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ if (err == CL_BUILD_PROGRAM_FAILURE)
+ {
+ cl_build_status stat;
+ cl_int e = clGetProgramBuildInfo(
+ mpProgram, openclwrapper::gpuEnv.mpDevID,
+ CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status),
+ &stat, nullptr);
+ SAL_WARN_IF(
+ e != CL_SUCCESS, "sc.opencl",
+ "after CL_BUILD_PROGRAM_FAILURE,"
+ " clGetProgramBuildInfo(CL_PROGRAM_BUILD_STATUS)"
+ " fails with " << openclwrapper::errorString(e));
+ if (e == CL_SUCCESS)
+ {
+ size_t n;
+ e = clGetProgramBuildInfo(
+ mpProgram, openclwrapper::gpuEnv.mpDevID,
+ CL_PROGRAM_BUILD_LOG, 0, nullptr, &n);
+ SAL_WARN_IF(
+ e != CL_SUCCESS || n == 0, "sc.opencl",
+ "after CL_BUILD_PROGRAM_FAILURE,"
+ " clGetProgramBuildInfo(CL_PROGRAM_BUILD_LOG)"
+ " fails with " << openclwrapper::errorString(e) << ", n=" << n);
+ if (e == CL_SUCCESS && n != 0)
+ {
+ std::vector<char> log(n);
+ e = clGetProgramBuildInfo(
+ mpProgram, openclwrapper::gpuEnv.mpDevID,
+ CL_PROGRAM_BUILD_LOG, n, log.data(), nullptr);
+ SAL_WARN_IF(
+ e != CL_SUCCESS || n == 0, "sc.opencl",
+ "after CL_BUILD_PROGRAM_FAILURE,"
+ " clGetProgramBuildInfo("
+ "CL_PROGRAM_BUILD_LOG) fails with " << openclwrapper::errorString(e));
+ if (e == CL_SUCCESS)
+ SAL_WARN(
+ "sc.opencl",
+ "CL_BUILD_PROGRAM_FAILURE, status " << stat
+ << ", log \"" << log.data() << "\"");
+ }
+ }
+ }
+#endif
+#ifdef DBG_UTIL
+ SAL_WARN("sc.opencl", "Program failed to build, aborting.");
+ abort(); // make sure errors such as typos don't accidentally go unnoticed
+#else
+ throw OpenCLError("clBuildProgram", err, __FILE__, __LINE__);
+#endif
+ }
+ SAL_INFO("sc.opencl", "Built program " << mpProgram);
+
+ // Generate binary out of compiled kernel.
+ openclwrapper::generatBinFromKernelSource(mpProgram,
+ (mKernelSignature + GetMD5()).c_str());
+ }
+ lastSecondKernelHash = lastOneKernelHash;
+ lastSecondProgram = lastOneProgram;
+ lastOneKernelHash = KernelHash;
+ lastOneProgram = mpProgram;
+ }
+ mpKernel = clCreateKernel(mpProgram, kname.c_str(), &err);
+ if (err != CL_SUCCESS)
+ throw OpenCLError("clCreateKernel", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created kernel " << mpKernel << " with name " << kname << " in program " << mpProgram);
+}
+
+void DynamicKernel::Launch( size_t nr )
+{
+ OpenCLZone zone;
+ openclwrapper::KernelEnv kEnv;
+ openclwrapper::setKernelEnv(&kEnv);
+ cl_int err;
+ // The results
+ mpResClmem = clCreateBuffer(kEnv.mpkContext,
+ cl_mem_flags(CL_MEM_READ_WRITE) | CL_MEM_ALLOC_HOST_PTR,
+ nr * sizeof(double), nullptr, &err);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clCreateBuffer", err, __FILE__, __LINE__);
+ SAL_INFO("sc.opencl", "Created buffer " << mpResClmem << " size " << nr << "*" << sizeof(double) << "=" << (nr*sizeof(double)));
+
+ SAL_INFO("sc.opencl", "Kernel " << mpKernel << " arg " << 0 << ": cl_mem: " << mpResClmem << " (result)");
+ err = clSetKernelArg(mpKernel, 0, sizeof(cl_mem), static_cast<void*>(&mpResClmem));
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__);
+ // The rest of buffers
+ mSyms.Marshal(mpKernel, nr, mpProgram);
+ size_t global_work_size[] = { nr };
+ SAL_INFO("sc.opencl", "Enqueuing kernel " << mpKernel);
+ err = clEnqueueNDRangeKernel(kEnv.mpkCmdQueue, mpKernel, 1, nullptr,
+ global_work_size, nullptr, 0, nullptr, nullptr);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clEnqueueNDRangeKernel", err, __FILE__, __LINE__);
+ err = clFlush(kEnv.mpkCmdQueue);
+ if (CL_SUCCESS != err)
+ throw OpenCLError("clFlush", err, __FILE__, __LINE__);
+}
+
+// Symbol lookup. If there is no such symbol created, allocate one
+// kernel with argument with unique name and return so.
+// The template argument T must be a subclass of DynamicKernelArgument
+template <typename T>
+const DynamicKernelArgument* SymbolTable::DeclRefArg(const ScCalcConfig& config,
+ const FormulaTreeNodeRef& t,
+ std::shared_ptr<SlidingFunctionBase> pCodeGen, int nResultSize)
+{
+ FormulaToken* ref = t->GetFormulaToken();
+ ArgumentMap::iterator it = mSymbols.find(ref);
+ if (it == mSymbols.end())
+ {
+ // Allocate new symbols
+ std::stringstream ss;
+ ss << "tmp" << mCurId++;
+ DynamicKernelArgumentRef new_arg = std::make_shared<T>(config, ss.str(), t, std::move(pCodeGen), nResultSize);
+ mSymbols[ref] = new_arg;
+ mParams.push_back(new_arg);
+ return new_arg.get();
+ }
+ else
+ {
+ return it->second.get();
+ }
+}
+
+FormulaGroupInterpreterOpenCL::FormulaGroupInterpreterOpenCL() :
+ FormulaGroupInterpreter() {}
+
+FormulaGroupInterpreterOpenCL::~FormulaGroupInterpreterOpenCL() {}
+
+ScMatrixRef FormulaGroupInterpreterOpenCL::inverseMatrix( const ScMatrix& )
+{
+ return nullptr;
+}
+
+std::shared_ptr<DynamicKernel> DynamicKernel::create( const ScCalcConfig& rConfig, const ScTokenArray& rCode, int nResultSize )
+{
+ // Constructing "AST"
+ FormulaTokenIterator aCode(rCode);
+ std::vector<FormulaToken*> aTokenVector;
+ std::map<FormulaToken*, FormulaTreeNodeRef> aHashMap;
+ FormulaToken* pCur;
+ while ((pCur = const_cast<FormulaToken*>(aCode.Next())) != nullptr)
+ {
+ OpCode eOp = pCur->GetOpCode();
+ if (eOp != ocPush)
+ {
+ FormulaTreeNodeRef pCurNode = std::make_shared<FormulaTreeNode>(pCur);
+ sal_uInt8 nParamCount = pCur->GetParamCount();
+ for (sal_uInt8 i = 0; i < nParamCount; i++)
+ {
+ if( aTokenVector.empty())
+ return nullptr;
+ FormulaToken* pTempFormula = aTokenVector.back();
+ aTokenVector.pop_back();
+ if (pTempFormula->GetOpCode() != ocPush)
+ {
+ if (aHashMap.find(pTempFormula) == aHashMap.end())
+ return nullptr;
+ pCurNode->Children.push_back(aHashMap[pTempFormula]);
+ }
+ else
+ {
+ FormulaTreeNodeRef pChildTreeNode =
+ std::make_shared<FormulaTreeNode>(pTempFormula);
+ pCurNode->Children.push_back(pChildTreeNode);
+ }
+ }
+ std::reverse(pCurNode->Children.begin(), pCurNode->Children.end());
+ aHashMap[pCur] = pCurNode;
+ }
+ aTokenVector.push_back(pCur);
+ }
+
+ FormulaTreeNodeRef Root = std::make_shared<FormulaTreeNode>(nullptr);
+ Root->Children.push_back(aHashMap[aTokenVector.back()]);
+
+ auto pDynamicKernel = std::make_shared<DynamicKernel>(rConfig, Root, nResultSize);
+
+ // OpenCL source code generation and kernel compilation
+ try
+ {
+ pDynamicKernel->CodeGen();
+ pDynamicKernel->CreateKernel();
+ }
+ catch (const UnhandledToken& ut)
+ {
+ SAL_INFO("sc.opencl", "Dynamic formula compiler: UnhandledToken: " << ut.mMessage << " at " << ut.mFile << ":" << ut.mLineNumber);
+ return nullptr;
+ }
+ catch (const InvalidParameterCount& ipc)
+ {
+ SAL_INFO("sc.opencl", "Dynamic formula compiler: InvalidParameterCount " << ipc.mParameterCount
+ << " at " << ipc.mFile << ":" << ipc.mLineNumber);
+ return nullptr;
+ }
+ catch (const OpenCLError& oce)
+ {
+ // I think OpenCLError exceptions are actually exceptional (unexpected), so do use SAL_WARN
+ // here.
+ SAL_WARN("sc.opencl", "Dynamic formula compiler: OpenCLError from " << oce.mFunction << ": " << openclwrapper::errorString(oce.mError) << " at " << oce.mFile << ":" << oce.mLineNumber);
+
+ // OpenCLError used to go to the catch-all below, and not delete pDynamicKernel. Was that
+ // intentional, should we not do it here then either?
+ openclwrapper::kernelFailures++;
+ return nullptr;
+ }
+ catch (const Unhandled& uh)
+ {
+ SAL_INFO("sc.opencl", "Dynamic formula compiler: Unhandled at " << uh.mFile << ":" << uh.mLineNumber);
+
+ // Unhandled used to go to the catch-all below, and not delete pDynamicKernel. Was that
+ // intentional, should we not do it here then either?
+ openclwrapper::kernelFailures++;
+ return nullptr;
+ }
+ catch (...)
+ {
+ // FIXME: Do we really want to catch random exceptions here?
+ SAL_WARN("sc.opencl", "Dynamic formula compiler: unexpected exception");
+ openclwrapper::kernelFailures++;
+ return nullptr;
+ }
+ return pDynamicKernel;
+}
+
+namespace {
+
+class CLInterpreterResult
+{
+ DynamicKernel* mpKernel;
+
+ SCROW mnGroupLength;
+
+ cl_mem mpCLResBuf;
+ double* mpResBuf;
+
+public:
+ CLInterpreterResult() : mpKernel(nullptr), mnGroupLength(0), mpCLResBuf(nullptr), mpResBuf(nullptr) {}
+ CLInterpreterResult( DynamicKernel* pKernel, SCROW nGroupLength ) :
+ mpKernel(pKernel), mnGroupLength(nGroupLength), mpCLResBuf(nullptr), mpResBuf(nullptr) {}
+
+ bool isValid() const { return mpKernel != nullptr; }
+
+ void fetchResultFromKernel()
+ {
+ if (!isValid())
+ return;
+
+ OpenCLZone zone;
+
+ // Map results back
+ mpCLResBuf = mpKernel->GetResultBuffer();
+
+ openclwrapper::KernelEnv kEnv;
+ openclwrapper::setKernelEnv(&kEnv);
+
+ cl_int err;
+ mpResBuf = static_cast<double*>(clEnqueueMapBuffer(kEnv.mpkCmdQueue,
+ mpCLResBuf,
+ CL_TRUE, CL_MAP_READ, 0,
+ mnGroupLength * sizeof(double), 0, nullptr, nullptr,
+ &err));
+
+ if (err != CL_SUCCESS)
+ {
+ SAL_WARN("sc.opencl", "clEnqueueMapBuffer failed:: " << openclwrapper::errorString(err));
+ mpResBuf = nullptr;
+ return;
+ }
+ SAL_INFO("sc.opencl", "Kernel results: cl_mem: " << mpResBuf << " (" << DebugPeekDoubles(mpResBuf, mnGroupLength) << ")");
+ }
+
+ bool pushResultToDocument( ScDocument& rDoc, const ScAddress& rTopPos )
+ {
+ if (!mpResBuf)
+ return false;
+
+ OpenCLZone zone;
+
+ rDoc.SetFormulaResults(rTopPos, mpResBuf, mnGroupLength);
+
+ openclwrapper::KernelEnv kEnv;
+ openclwrapper::setKernelEnv(&kEnv);
+
+ cl_int err;
+ err = clEnqueueUnmapMemObject(kEnv.mpkCmdQueue, mpCLResBuf, mpResBuf, 0, nullptr, nullptr);
+
+ if (err != CL_SUCCESS)
+ {
+ SAL_WARN("sc.opencl", "clEnqueueUnmapMemObject failed: " << openclwrapper::errorString(err));
+ return false;
+ }
+
+ return true;
+ }
+};
+
+class CLInterpreterContext
+{
+ std::shared_ptr<DynamicKernel> mpKernelStore; /// for managed kernel instance.
+ DynamicKernel* mpKernel;
+
+ SCROW mnGroupLength;
+
+public:
+ explicit CLInterpreterContext(SCROW nGroupLength)
+ : mpKernel(nullptr)
+ , mnGroupLength(nGroupLength) {}
+
+ bool isValid() const
+ {
+ return mpKernel != nullptr;
+ }
+
+ void setManagedKernel( std::shared_ptr<DynamicKernel> pKernel )
+ {
+ mpKernelStore = std::move(pKernel);
+ mpKernel = mpKernelStore.get();
+ }
+
+ CLInterpreterResult launchKernel()
+ {
+ if (!isValid())
+ return CLInterpreterResult();
+
+ try
+ {
+ // Run the kernel.
+ mpKernel->Launch(mnGroupLength);
+ }
+ catch (const UnhandledToken& ut)
+ {
+ SAL_INFO("sc.opencl", "Dynamic formula compiler: UnhandledToken: " << ut.mMessage << " at " << ut.mFile << ":" << ut.mLineNumber);
+ openclwrapper::kernelFailures++;
+ return CLInterpreterResult();
+ }
+ catch (const OpenCLError& oce)
+ {
+ SAL_WARN("sc.opencl", "Dynamic formula compiler: OpenCLError from " << oce.mFunction << ": " << openclwrapper::errorString(oce.mError) << " at " << oce.mFile << ":" << oce.mLineNumber);
+ openclwrapper::kernelFailures++;
+ return CLInterpreterResult();
+ }
+ catch (const Unhandled& uh)
+ {
+ SAL_INFO("sc.opencl", "Dynamic formula compiler: Unhandled at " << uh.mFile << ":" << uh.mLineNumber);
+ openclwrapper::kernelFailures++;
+ return CLInterpreterResult();
+ }
+ catch (...)
+ {
+ SAL_WARN("sc.opencl", "Dynamic formula compiler: unexpected exception");
+ openclwrapper::kernelFailures++;
+ return CLInterpreterResult();
+ }
+
+ return CLInterpreterResult(mpKernel, mnGroupLength);
+ }
+};
+
+
+CLInterpreterContext createCLInterpreterContext( const ScCalcConfig& rConfig,
+ const ScFormulaCellGroupRef& xGroup, const ScTokenArray& rCode )
+{
+ CLInterpreterContext aCxt(xGroup->mnLength);
+
+ aCxt.setManagedKernel(DynamicKernel::create(rConfig, rCode, xGroup->mnLength));
+
+ return aCxt;
+}
+
+void genRPNTokens( ScDocument& rDoc, const ScAddress& rTopPos, ScTokenArray& rCode )
+{
+ ScCompiler aComp(&rDoc, rTopPos, rCode, rDoc.GetGrammar());
+ // Disable special ordering for jump commands for the OpenCL interpreter.
+ aComp.EnableJumpCommandReorder(false);
+ aComp.CompileTokenArray(); // Regenerate RPN tokens.
+}
+
+bool waitForResults()
+{
+ OpenCLZone zone;
+ openclwrapper::KernelEnv kEnv;
+ openclwrapper::setKernelEnv(&kEnv);
+
+ cl_int err = clFinish(kEnv.mpkCmdQueue);
+ if (err != CL_SUCCESS)
+ SAL_WARN("sc.opencl", "clFinish failed: " << openclwrapper::errorString(err));
+
+ return err == CL_SUCCESS;
+}
+
+}
+
+bool FormulaGroupInterpreterOpenCL::interpret( ScDocument& rDoc,
+ const ScAddress& rTopPos, ScFormulaCellGroupRef& xGroup,
+ ScTokenArray& rCode )
+{
+ MergeCalcConfig(rDoc);
+
+ genRPNTokens(rDoc, rTopPos, rCode);
+
+ if( rCode.GetCodeLen() == 0 )
+ return false;
+
+ CLInterpreterContext aCxt = createCLInterpreterContext(maCalcConfig, xGroup, rCode);
+ if (!aCxt.isValid())
+ return false;
+
+ CLInterpreterResult aRes = aCxt.launchKernel();
+ if (!aRes.isValid())
+ return false;
+
+ if (!waitForResults())
+ return false;
+
+ aRes.fetchResultFromKernel();
+
+ return aRes.pushResultToDocument(rDoc, rTopPos);
+}
+
+} // namespace sc::opencl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_addin.cxx b/sc/source/core/opencl/op_addin.cxx
new file mode 100644
index 000000000..8a42de323
--- /dev/null
+++ b/sc/source/core/opencl/op_addin.cxx
@@ -0,0 +1,236 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "op_addin.hxx"
+
+#include <formula/vectortoken.hxx>
+#include <sstream>
+
+using namespace formula;
+
+namespace sc::opencl {
+
+void OpBesselj::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ CHECK_PARAMETER_COUNT( 2, 2 );
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double x = 0.0;\n";
+ ss << " double N = 0.0;\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur0);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurSVR0 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " if (gid0 < " << tmpCurSVR0->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " x = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(x))\n";
+ ss << " x = 0.0;\n";
+ ss << " }\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDouble)
+ {
+ ss << " x = " << tmpCur0->GetDouble() << ";\n";
+ }
+ else
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ }
+ else
+ {
+ ss << " x = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ }
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ assert(tmpCur1);
+ if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurSVR1 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur1);
+ ss << " if (gid0 < " << tmpCurSVR1->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " N = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(N))\n";
+ ss << " N = 0.0;\n";
+ ss << " }\n";
+ }
+ else if(tmpCur1->GetType() == formula::svDouble)
+ {
+ ss << " N = " << tmpCur1->GetDouble() << ";\n";
+ }
+ else
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ }
+ else
+ {
+ ss << " N = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ ss << " double f_PI = 3.1415926535897932385;\n";
+ ss << " double f_2_DIV_PI = 2.0 / f_PI;\n";
+ ss << " double f_PI_DIV_2 = f_PI / 2.0;\n";
+ ss << " double f_PI_DIV_4 = f_PI / 4.0;\n";
+ ss << " if( N < 0.0 )\n";
+ ss << " return CreateDoubleError(IllegalArgument);\n";
+ ss << " if (x == 0.0)\n";
+ ss << " return (N == 0.0) ? 1.0 : 0.0;\n";
+ ss << " double fSign = ((int)N % 2 == 1 && x < 0.0) ? -1.0 : 1.0;\n";
+ ss << " double fX = fabs(x);\n";
+ ss << " double fMaxIteration = 9000000.0;\n";
+ ss << " double fEstimateIteration = fX * 1.5 + N;\n";
+ ss << " bool bAsymptoticPossible = pow(fX,0.4) > N;\n";
+ ss << " if (fEstimateIteration > fMaxIteration)\n";
+ ss << " {\n";
+ ss << " if (bAsymptoticPossible)\n";
+ ss << " return fSign * sqrt(f_2_DIV_PI/fX)";
+ ss << "* cos(fX-N*f_PI_DIV_2-f_PI_DIV_4);\n";
+ ss << " else\n";
+ ss << " return CreateDoubleError(NoConvergence);\n";
+ ss << " }\n";
+ ss << " double epsilon = 1.0e-15;\n";
+ ss << " bool bHasfound = false;\n";
+ ss << " double k= 0.0;\n";
+ ss << " double u ;\n";
+ ss << " double m_bar;\n";
+ ss << " double g_bar;\n";
+ ss << " double g_bar_delta_u;\n";
+ ss << " double g = 0.0;\n";
+ ss << " double delta_u = 0.0;\n";
+ ss << " double f_bar = -1.0;\n";
+ ss << " if (N==0)\n";
+ ss << " {\n";
+ ss << " u = 1.0;\n";
+ ss << " g_bar_delta_u = 0.0;\n";
+ ss << " g_bar = - 2.0/fX; \n";
+ ss << " delta_u = g_bar_delta_u / g_bar;\n";
+ ss << " u = u + delta_u ;\n";
+ ss << " g = -1.0 / g_bar; \n";
+ ss << " f_bar = f_bar * g;\n";
+ ss << " k = 2.0;\n";
+ ss << " }\n";
+ ss << " if (N!=0)\n";
+ ss << " {\n";
+ ss << " u=0.0;\n";
+ ss << " for (k =1.0; k<= N-1; k = k + 1.0)\n";
+ ss << " {\n";
+ ss << " m_bar=2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
+ ss << " g_bar_delta_u = - g * delta_u - m_bar * u;\n";
+ ss << " g_bar = m_bar - 2.0*k/fX + g;\n";
+ ss << " delta_u = g_bar_delta_u / g_bar;\n";
+ ss << " u = u + delta_u;\n";
+ ss << " g = -1.0/g_bar;\n";
+ ss << " f_bar=f_bar * g;\n";
+ ss << " }\n";
+ ss << " m_bar=2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
+ ss << " g_bar_delta_u = f_bar - g * delta_u - m_bar * u;\n";
+ ss << " g_bar = m_bar - 2.0*k/fX + g;\n";
+ ss << " delta_u = g_bar_delta_u / g_bar;\n";
+ ss << " u = u + delta_u;\n";
+ ss << " g = -1.0/g_bar;\n";
+ ss << " f_bar = f_bar * g;\n";
+ ss << " k = k + 1.0;\n";
+ ss << " }\n";
+ ss << " do\n";
+ ss << " {\n";
+ ss << " m_bar = 2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
+ ss << " g_bar_delta_u = - g * delta_u - m_bar * u;\n";
+ ss << " g_bar = m_bar - 2.0*k/fX + g;\n";
+ ss << " delta_u = g_bar_delta_u / g_bar;\n";
+ ss << " u = u + delta_u;\n";
+ ss << " g = -pow(g_bar,-1.0);\n";
+ ss << " f_bar = f_bar * g;\n";
+ ss << " bHasfound = (fabs(delta_u)<=fabs(u)*epsilon);\n";
+ ss << " k = k + 1.0;\n";
+ ss << " }\n";
+ ss << " while (!bHasfound && k <= fMaxIteration);\n";
+ ss << " if (bHasfound)\n";
+ ss << " return u * fSign;\n";
+ ss << " else\n";
+ ss << " return CreateDoubleError(NoConvergence);\n";
+ ss << "}";
+}
+void OpGestep::GenSlidingWindowFunction(
+ std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " double tmp=0,tmp0 =0,tmp1 = 0;\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::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken& rSVR =
+ dynamic_cast< const formula::SingleVectorRefToken& >(*pCur);
+ ss << " if (gid0 < " << rSVR.GetArrayLength() << ")\n";
+ ss << " {\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 }\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<" ="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " tmp =tmp0 >= tmp1 ? 1 : 0;\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_addin.hxx b/sc/source/core/opencl/op_addin.hxx
new file mode 100644
index 000000000..907f53b94
--- /dev/null
+++ b/sc/source/core/opencl/op_addin.hxx
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_CORE_OPENCL_OP_ADDIN_HXX
+#define INCLUDED_SC_SOURCE_CORE_OPENCL_OP_ADDIN_HXX
+
+#include "opbase.hxx"
+
+namespace sc::opencl {
+
+class OpBesselj: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Besselj"; }
+};
+class OpGestep: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Gestep"; }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_array.cxx b/sc/source/core/opencl/op_array.cxx
new file mode 100644
index 000000000..c745ec8a1
--- /dev/null
+++ b/sc/source/core/opencl/op_array.cxx
@@ -0,0 +1,191 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "op_array.hxx"
+
+#include <formula/vectortoken.hxx>
+#include <sstream>
+
+using namespace formula;
+
+namespace sc::opencl {
+
+void OpSumX2MY2::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss << " double tmp =0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ if(vSubArguments[0]->GetFormulaToken()->GetType() ==
+ formula::svDoubleVectorRef)
+ {
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+ pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+ pCurDVR->GetRefRowSize() ;
+ ss << " int i ;\n";
+ ss << " for (i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "gid0; i < "<< nCurWindowSize <<"; i++)\n";
+ } else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) {
+ ss << "0; i < gid0+"<< nCurWindowSize <<"; i++)\n";
+ } else {
+ ss << "0; i < "<< nCurWindowSize <<"; i++)\n";
+ }
+ ss << " {\n";
+ if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << " int doubleIndex =i+gid0;\n";
+ }else
+ {
+ ss << " int doubleIndex =i;\n";
+ }
+
+ CheckSubArgumentIsNan(ss,vSubArguments,0);
+ CheckSubArgumentIsNan(ss,vSubArguments,1);
+ ss << " tmp +=pow(tmp0,2) - pow(tmp1,2);\n";
+ ss <<" }\n";
+ }
+ else
+ {
+ ss << " int singleIndex =gid0;\n";
+ CheckAllSubArgumentIsNan(ss, vSubArguments);
+ ss << " tmp = pow(tmp0,2) - pow(tmp1,2);\n";
+ }
+ ss << "return tmp;\n";
+ ss << "}";
+}
+
+void OpSumX2PY2::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp =0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ if(vSubArguments[0]->GetFormulaToken()->GetType() ==
+ formula::svDoubleVectorRef)
+ {
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+ pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+ pCurDVR->GetRefRowSize() ;
+ ss << " int i ;\n";
+ ss << " for (i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "gid0; i < "<< nCurWindowSize <<"; i++)\n";
+ } else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) {
+ ss << "0; i < gid0+"<< nCurWindowSize <<"; i++)\n";
+ } else {
+ ss << "0; i < "<< nCurWindowSize <<"; i++)\n";
+ }
+ ss << " {\n";
+ if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << " int doubleIndex =i+gid0;\n";
+ }else
+ {
+ ss << " int doubleIndex =i;\n";
+ }
+
+ CheckSubArgumentIsNan(ss,vSubArguments,0);
+ CheckSubArgumentIsNan(ss,vSubArguments,1);
+ ss << " tmp +=pow(tmp0,2) + pow(tmp1,2);\n";
+ ss <<" }\n";
+ }
+ else
+ {
+ ss << " int singleIndex =gid0;\n";
+ CheckAllSubArgumentIsNan(ss, vSubArguments);
+ ss << " tmp = pow(tmp0,2) + pow(tmp1,2);\n";
+ }
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpSumXMY2::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp =0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ if(vSubArguments[0]->GetFormulaToken()->GetType() ==
+ formula::svDoubleVectorRef)
+ {
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+ pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+ pCurDVR->GetRefRowSize() ;
+ ss << " int i ;\n";
+ ss << " for (i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "gid0; i < "<< nCurWindowSize <<"; i++)\n";
+ } else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) {
+ ss << "0; i < gid0+"<< nCurWindowSize <<"; i++)\n";
+ } else {
+ ss << "0; i < "<< nCurWindowSize <<"; i++)\n";
+ }
+ ss << " {\n";
+ if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << " int doubleIndex =i+gid0;\n";
+ }else
+ {
+ ss << " int doubleIndex =i;\n";
+ }
+
+ CheckSubArgumentIsNan(ss,vSubArguments,0);
+ CheckSubArgumentIsNan(ss,vSubArguments,1);
+ ss << " tmp +=pow((tmp0-tmp1),2);\n";
+ ss <<" }\n";
+ }
+ else
+ {
+ ss << " int singleIndex =gid0;\n";
+ CheckAllSubArgumentIsNan(ss, vSubArguments);
+ ss << " tmp = pow((tmp0-tmp1),2);\n";
+ }
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_array.hxx b/sc/source/core/opencl/op_array.hxx
new file mode 100644
index 000000000..b70f3109f
--- /dev/null
+++ b/sc/source/core/opencl/op_array.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_CORE_OPENCL_OP_ARRAY_HXX
+#define INCLUDED_SC_SOURCE_CORE_OPENCL_OP_ARRAY_HXX
+
+#include "opbase.hxx"
+
+namespace sc::opencl {
+
+class OpSumX2MY2: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "SumX2MY2"; }
+};
+
+class OpSumX2PY2: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "SumX2PY2"; }
+};
+
+class OpSumXMY2: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "SumXMY2"; }
+};
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_database.cxx b/sc/source/core/opencl/op_database.cxx
new file mode 100644
index 000000000..b3fc72d40
--- /dev/null
+++ b/sc/source/core/opencl/op_database.cxx
@@ -0,0 +1,1642 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "op_database.hxx"
+
+#include <formula/vectortoken.hxx>
+#include <sstream>
+
+namespace sc::opencl {
+
+void OpDmax::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double max = -1000000000000;\n";
+ ss << " double value=0.0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ int dataCol = 0;
+ int dataRow = 0;
+ if(vSubArguments[0]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ formula::FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ dataCol = pCurDVR->GetArrays().size();
+ dataRow = pCurDVR->GetArrayLength();
+
+ if(vSubArguments[dataCol]->GetFormulaToken()->GetType() !=
+ formula::svSingleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ const formula::SingleVectorRefToken*pTmpDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(vSubArguments[dataCol]->
+ GetFormulaToken());
+ ss << " tmp"<<dataCol<<"=";
+ ss << vSubArguments[dataCol]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(gid0>="<<pTmpDVR1->GetArrayLength()<<" ||isnan(";
+ ss << "tmp"<<dataCol<<"))\n";
+ ss << " tmp"<<dataCol<<"=0;\n";
+
+ int conditionCol = 0;
+ int conditionRow = 0;
+ if(vSubArguments[dataCol + 1]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ tmpCur = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ conditionCol = pCurDVR->GetArrays().size();
+ conditionRow = pCurDVR->GetArrayLength();
+
+ if(dataCol!=conditionCol)
+ throw Unhandled(__FILE__, __LINE__);
+ if(dataCol > 0 && dataRow > 0)
+ {
+ formula::FormulaToken *tmpCur1 = vSubArguments[0]->GetFormulaToken();
+ formula::FormulaToken *tmpCur2 = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+
+ if(pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed() &&
+ pCurDVR2->IsStartFixed() && pCurDVR2->IsEndFixed())
+ {
+ ss << " int i,j,p;\n";
+ ss << " bool flag;\n";
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " if(max<value)\n";
+ ss << " max=value;";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ ss << "max = -1;\n";
+ }
+ else
+ ss << "max = -1;\n";
+ ss << " return max;\n";
+ ss << "}";
+}
+
+void OpDmin::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double min = 1000000000000;\n";
+ ss << " double value=0.0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ int dataCol = 0;
+ int dataRow = 0;
+ if(vSubArguments[0]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ formula::FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ dataCol = pCurDVR->GetArrays().size();
+ dataRow = pCurDVR->GetArrayLength();
+
+ if(vSubArguments[dataCol]->GetFormulaToken()->GetType() !=
+ formula::svSingleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ const formula::SingleVectorRefToken*pTmpDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(vSubArguments[dataCol]->
+ GetFormulaToken());
+ ss << " tmp"<<dataCol<<"=";
+ ss << vSubArguments[dataCol]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(gid0>="<<pTmpDVR1->GetArrayLength()<<" ||isnan(";
+ ss << "tmp"<<dataCol<<"))\n";
+ ss << " tmp"<<dataCol<<"=0;\n";
+
+ int conditionCol = 0;
+ int conditionRow = 0;
+ if(vSubArguments[dataCol + 1]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ tmpCur = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ conditionCol = pCurDVR->GetArrays().size();
+ conditionRow = pCurDVR->GetArrayLength();
+
+ if(dataCol!=conditionCol)
+ throw Unhandled(__FILE__, __LINE__);
+ if(dataCol > 0 && dataRow > 0)
+ {
+ formula::FormulaToken *tmpCur1 = vSubArguments[0]->GetFormulaToken();
+ formula::FormulaToken *tmpCur2 = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+
+ if(pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed() &&
+ pCurDVR2->IsStartFixed() && pCurDVR2->IsEndFixed())
+ {
+ ss << " int i,j,p;\n";
+ ss << " bool flag;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " if(min>value)\n";
+ ss << " min=value;";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ ss << "min = -1;\n";
+ }
+ else
+ ss << "min = -1;\n";
+ ss << " return min;\n";
+ ss << "}";
+}
+
+void OpDproduct::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double product = 1;\n";
+ ss << " double value =0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ int dataCol = 0;
+ int dataRow = 0;
+ if(vSubArguments[0]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ formula::FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ dataCol = pCurDVR->GetArrays().size();
+ dataRow = pCurDVR->GetArrayLength();
+
+ if(vSubArguments[dataCol]->GetFormulaToken()->GetType() !=
+ formula::svSingleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ const formula::SingleVectorRefToken*pTmpDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(vSubArguments[dataCol]->
+ GetFormulaToken());
+ ss << " tmp"<<dataCol<<"=";
+ ss << vSubArguments[dataCol]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(gid0>="<<pTmpDVR1->GetArrayLength()<<" ||isnan(";
+ ss << "tmp"<<dataCol<<"))\n";
+ ss << " tmp"<<dataCol<<"=0;\n";
+
+ int conditionCol = 0;
+ int conditionRow = 0;
+ if(vSubArguments[dataCol + 1]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ tmpCur = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ conditionCol = pCurDVR->GetArrays().size();
+ conditionRow = pCurDVR->GetArrayLength();
+
+ if(dataCol!=conditionCol)
+ throw Unhandled(__FILE__, __LINE__);
+ if(dataCol > 0 && dataRow > 0)
+ {
+ formula::FormulaToken *tmpCur1 = vSubArguments[0]->GetFormulaToken();
+ formula::FormulaToken *tmpCur2 = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+
+ if(pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed() &&
+ pCurDVR2->IsStartFixed() && pCurDVR2->IsEndFixed())
+ {
+ ss << " int i,j,p;\n";
+ ss << " bool flag;\n";
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " product*=value;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ ss << "product = -1;\n";
+ }
+ else
+ ss << "product = -1;\n";
+ ss << " return product;\n";
+ ss << "}";
+}
+
+void OpDaverage::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double sum = 0;\n";
+ ss << " int count = 0;\n";
+ ss << " double value =0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ int dataCol = 0;
+ int dataRow = 0;
+ if(vSubArguments[0]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ formula::FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ dataCol = pCurDVR->GetArrays().size();
+ dataRow = pCurDVR->GetArrayLength();
+
+ if(vSubArguments[dataCol]->GetFormulaToken()->GetType() !=
+ formula::svSingleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ const formula::SingleVectorRefToken*pTmpDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(vSubArguments[dataCol]->
+ GetFormulaToken());
+ ss << " tmp"<<dataCol<<"=";
+ ss << vSubArguments[dataCol]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(gid0>="<<pTmpDVR1->GetArrayLength()<<" ||isnan(";
+ ss << "tmp"<<dataCol<<"))\n";
+ ss << " tmp"<<dataCol<<"=0;\n";
+
+ int conditionCol = 0;
+ int conditionRow = 0;
+ if(vSubArguments[dataCol + 1]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ tmpCur = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ conditionCol = pCurDVR->GetArrays().size();
+ conditionRow = pCurDVR->GetArrayLength();
+
+ if(dataCol!=conditionCol)
+ throw Unhandled(__FILE__, __LINE__);
+ if(dataCol > 0 && dataRow > 0)
+ {
+ formula::FormulaToken *tmpCur1 = vSubArguments[0]->GetFormulaToken();
+ formula::FormulaToken *tmpCur2 = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+
+ if(pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed() &&
+ pCurDVR2->IsStartFixed() && pCurDVR2->IsEndFixed())
+ {
+ ss << " int i,j,p;\n";
+ ss << " bool flag;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ ss << " count++;\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " sum+=value;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ ss << "sum = -1;\n";
+ }
+ else
+ ss << "sum = -1;\n";
+ ss << " if(count==0)\n";
+ ss << " return 0;\n";
+ ss << " return sum/count;\n";
+ ss << "}";
+}
+
+void OpDstdev::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double var = 0;\n";
+ ss << " double mean = 0;\n";
+ ss << " double value =0;\n";
+ ss << " int count = 0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ int dataCol = 0;
+ int dataRow = 0;
+ if(vSubArguments[0]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ formula::FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ dataCol = pCurDVR->GetArrays().size();
+ dataRow = pCurDVR->GetArrayLength();
+
+ if(vSubArguments[dataCol]->GetFormulaToken()->GetType() !=
+ formula::svSingleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ const formula::SingleVectorRefToken*pTmpDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(vSubArguments[dataCol]->
+ GetFormulaToken());
+ ss << " tmp"<<dataCol<<"=";
+ ss << vSubArguments[dataCol]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(gid0>="<<pTmpDVR1->GetArrayLength()<<" ||isnan(";
+ ss << "tmp"<<dataCol<<"))\n";
+ ss << " tmp"<<dataCol<<"=0;\n";
+
+ int conditionCol = 0;
+ int conditionRow = 0;
+ if(vSubArguments[dataCol + 1]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ tmpCur = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ conditionCol = pCurDVR->GetArrays().size();
+ conditionRow = pCurDVR->GetArrayLength();
+
+ if(dataCol!=conditionCol)
+ throw Unhandled(__FILE__, __LINE__);
+ if(dataCol > 0 && dataRow > 0)
+ {
+ formula::FormulaToken *tmpCur1 = vSubArguments[0]->GetFormulaToken();
+ formula::FormulaToken *tmpCur2 = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+
+ if(pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed() &&
+ pCurDVR2->IsStartFixed() && pCurDVR2->IsEndFixed())
+ {
+ ss << " int i,j,p;\n";
+ ss << " bool flag;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ ss << " count++;\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " mean+=value;\n";
+ ss << " }\n";
+ ss << " }\n";
+
+ ss << " if(count<=1)\n";
+ ss << " return 0;\n";
+
+ ss << " mean/=count;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " var+=pow(mean-value,2);\n";
+ ss << " }\n";
+ ss << " }\n";
+
+ ss << " var = sqrt( var/(count-1) );\n";
+ }
+ else
+ ss << "var = -1;\n";
+ }
+ else
+ ss << "var = -1;\n";
+ ss << " return var;\n";
+ ss << "}";
+}
+
+void OpDstdevp::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double var = 0;\n";
+ ss << " double mean = 0;\n";
+ ss << " double value =0;\n";
+ ss << " int count = 0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ int dataCol = 0;
+ int dataRow = 0;
+ if(vSubArguments[0]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ formula::FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ dataCol = pCurDVR->GetArrays().size();
+ dataRow = pCurDVR->GetArrayLength();
+
+ if(vSubArguments[dataCol]->GetFormulaToken()->GetType() !=
+ formula::svSingleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ const formula::SingleVectorRefToken*pTmpDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(vSubArguments[dataCol]->
+ GetFormulaToken());
+ ss << " tmp"<<dataCol<<"=";
+ ss << vSubArguments[dataCol]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(gid0>="<<pTmpDVR1->GetArrayLength()<<" ||isnan(";
+ ss << "tmp"<<dataCol<<"))\n";
+ ss << " tmp"<<dataCol<<"=0;\n";
+
+ int conditionCol = 0;
+ int conditionRow = 0;
+ if(vSubArguments[dataCol + 1]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ tmpCur = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ conditionCol = pCurDVR->GetArrays().size();
+ conditionRow = pCurDVR->GetArrayLength();
+
+ if(dataCol!=conditionCol)
+ throw Unhandled(__FILE__, __LINE__);
+ if(dataCol > 0 && dataRow > 0)
+ {
+ formula::FormulaToken *tmpCur1 = vSubArguments[0]->GetFormulaToken();
+ formula::FormulaToken *tmpCur2 = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+
+ if(pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed() &&
+ pCurDVR2->IsStartFixed() && pCurDVR2->IsEndFixed())
+ {
+ ss << " int i,j,p;\n";
+ ss << " bool flag;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ ss << " count++;\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " mean+=value;\n";
+ ss << " }\n";
+ ss << " }\n";
+
+ ss << " if(count<=1)\n";
+ ss << " return 0;\n";
+
+ ss << " mean/=count;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " var+=pow(mean-value,2);\n";
+ ss << " }\n";
+ ss << " }\n";
+
+ ss << " var = sqrt( var/count );\n";
+ }
+ else
+ ss << "var = -1;\n";
+ }
+ else
+ ss << "var = -1;\n";
+ ss << " return var;\n";
+ ss << "}";
+}
+
+void OpDsum::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double sum = 0;\n";
+ ss << " double value =0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ int dataCol = 0;
+ int dataRow = 0;
+ if(vSubArguments[0]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ formula::FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ dataCol = pCurDVR->GetArrays().size();
+ dataRow = pCurDVR->GetArrayLength();
+
+ if(vSubArguments[dataCol]->GetFormulaToken()->GetType() !=
+ formula::svSingleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ const formula::SingleVectorRefToken*pTmpDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(vSubArguments[dataCol]->
+ GetFormulaToken());
+ ss << " tmp"<<dataCol<<"=";
+ ss << vSubArguments[dataCol]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(gid0>="<<pTmpDVR1->GetArrayLength()<<" ||isnan(";
+ ss << "tmp"<<dataCol<<"))\n";
+ ss << " tmp"<<dataCol<<"=0;\n";
+
+ int conditionCol = 0;
+ int conditionRow = 0;
+ if(vSubArguments[dataCol + 1]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ tmpCur = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ conditionCol = pCurDVR->GetArrays().size();
+ conditionRow = pCurDVR->GetArrayLength();
+
+ if(dataCol!=conditionCol)
+ throw Unhandled(__FILE__, __LINE__);
+ if(dataCol > 0 && dataRow > 0)
+ {
+ formula::FormulaToken *tmpCur1 = vSubArguments[0]->GetFormulaToken();
+ formula::FormulaToken *tmpCur2 = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+
+ if(pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed() &&
+ pCurDVR2->IsStartFixed() && pCurDVR2->IsEndFixed())
+ {
+ ss << " int i,j,p;\n";
+ ss << " bool flag;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " sum+=value;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ ss << "sum = -1;\n";
+ }
+ else
+ ss << "sum = -1;\n";
+ ss << " return sum;\n";
+ ss << "}";
+}
+
+void OpDvar::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double var = 0;\n";
+ ss << " double mean = 0;\n";
+ ss << " double value =0;\n";
+ ss << " int count = 0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ int dataCol = 0;
+ int dataRow = 0;
+ if(vSubArguments[0]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ formula::FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ dataCol = pCurDVR->GetArrays().size();
+ dataRow = pCurDVR->GetArrayLength();
+
+ if(vSubArguments[dataCol]->GetFormulaToken()->GetType() !=
+ formula::svSingleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ const formula::SingleVectorRefToken*pTmpDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(vSubArguments[dataCol]->
+ GetFormulaToken());
+ ss << " tmp"<<dataCol<<"=";
+ ss << vSubArguments[dataCol]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(gid0>="<<pTmpDVR1->GetArrayLength()<<" ||isnan(";
+ ss << "tmp"<<dataCol<<"))\n";
+ ss << " tmp"<<dataCol<<"=0;\n";
+
+ int conditionCol = 0;
+ int conditionRow = 0;
+ if(vSubArguments[dataCol + 1]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ tmpCur = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ conditionCol = pCurDVR->GetArrays().size();
+ conditionRow = pCurDVR->GetArrayLength();
+
+ if(dataCol!=conditionCol)
+ throw Unhandled(__FILE__, __LINE__);
+ if(dataCol > 0 && dataRow > 0)
+ {
+ formula::FormulaToken *tmpCur1 = vSubArguments[0]->GetFormulaToken();
+ formula::FormulaToken *tmpCur2 = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+
+ if(pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed() &&
+ pCurDVR2->IsStartFixed() && pCurDVR2->IsEndFixed())
+ {
+ ss << " int i,j,p;\n";
+ ss << " bool flag;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ ss << " count++;\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " mean+=value;\n";
+ ss << " }\n";
+ ss << " }\n";
+
+ ss << " if(count<=1)\n";
+ ss << " return 0;\n";
+
+ ss << " mean/=count;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " var+=pow(mean-value,2);\n";
+ ss << " }\n";
+ ss << " }\n";
+
+ ss << " var = var/(count-1);\n";
+ }
+ else
+ ss << "var = -1;\n";
+ }
+ else
+ ss << "var = -1;\n";
+ ss << " return var;\n";
+ ss << "}";
+}
+
+void OpDvarp::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double var = 0;\n";
+ ss << " double mean = 0;\n";
+ ss << " double value =0;\n";
+ ss << " int count = 0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ int dataCol = 0;
+ int dataRow = 0;
+ if(vSubArguments[0]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ formula::FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ dataCol = pCurDVR->GetArrays().size();
+ dataRow = pCurDVR->GetArrayLength();
+
+ if(vSubArguments[dataCol]->GetFormulaToken()->GetType() !=
+ formula::svSingleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ const formula::SingleVectorRefToken*pTmpDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(vSubArguments[dataCol]->
+ GetFormulaToken());
+ ss << " tmp"<<dataCol<<"=";
+ ss << vSubArguments[dataCol]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(gid0>="<<pTmpDVR1->GetArrayLength()<<" ||isnan(";
+ ss << "tmp"<<dataCol<<"))\n";
+ ss << " tmp"<<dataCol<<"=0;\n";
+
+ int conditionCol = 0;
+ int conditionRow = 0;
+ if(vSubArguments[dataCol + 1]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ tmpCur = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ conditionCol = pCurDVR->GetArrays().size();
+ conditionRow = pCurDVR->GetArrayLength();
+
+ if(dataCol!=conditionCol)
+ throw Unhandled(__FILE__, __LINE__);
+ if(dataCol > 0 && dataRow > 0)
+ {
+ formula::FormulaToken *tmpCur1 = vSubArguments[0]->GetFormulaToken();
+ formula::FormulaToken *tmpCur2 = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+
+ if(pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed() &&
+ pCurDVR2->IsStartFixed() && pCurDVR2->IsEndFixed())
+ {
+ ss << " int i,j,p;\n";
+ ss << " bool flag;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ ss << " count++;\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " mean+=value;\n";
+ ss << " }\n";
+ ss << " }\n";
+
+ ss << " if(count<=0)\n";
+ ss << " return 0;\n";
+
+ ss << " mean/=count;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " var+=pow(mean-value,2);\n";
+ ss << " }\n";
+ ss << " }\n";
+
+ ss << " var = var/count;\n";
+ }
+ else
+ ss << "var = -1;\n";
+ }
+ else
+ ss << "var = -1;\n";
+ ss << " return var;\n";
+ ss << "}";
+}
+
+void OpDcount::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double value=0;\n";
+ ss << " int count = 0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ int dataCol = 0;
+ int dataRow = 0;
+ if(vSubArguments[0]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ formula::FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ dataCol = pCurDVR->GetArrays().size();
+ dataRow = pCurDVR->GetArrayLength();
+
+ if(vSubArguments[dataCol]->GetFormulaToken()->GetType() !=
+ formula::svSingleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ const formula::SingleVectorRefToken*pTmpDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(vSubArguments[dataCol]
+ ->GetFormulaToken());
+ ss << " tmp"<<dataCol<<"=";
+ ss << vSubArguments[dataCol]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(gid0>="<<pTmpDVR1->GetArrayLength()<<" ||isnan(";
+ ss << "tmp"<<dataCol<<"))\n";
+ ss << " tmp"<<dataCol<<"=DBL_MIN;\n";
+
+ int conditionCol = 0;
+ int conditionRow = 0;
+ if(vSubArguments[dataCol + 1]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ tmpCur = vSubArguments[dataCol + 1]
+ ->GetFormulaToken();
+ pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ conditionCol = pCurDVR->GetArrays().size();
+ conditionRow = pCurDVR->GetArrayLength();
+
+ if(dataCol!=conditionCol)
+ throw Unhandled(__FILE__, __LINE__);
+ if(dataCol > 0 && dataRow > 0)
+ {
+ formula::FormulaToken *tmpCur1 = vSubArguments[0]->GetFormulaToken();
+ formula::FormulaToken *tmpCur2 = vSubArguments[dataCol + 1]
+ ->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+
+ if(pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed() &&
+ pCurDVR2->IsStartFixed() && pCurDVR2->IsEndFixed())
+ {
+ ss << " int i,j,p;\n";
+ ss << " bool flag;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " if(value > DBL_MIN)\n";
+ ss << " count++;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ ss << "count = -1;\n";
+ }
+ else
+ ss << "count = -1;\n";
+ ss << " return count;\n";
+ ss << "}";
+}
+
+void OpDcount2::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double value=0;\n";
+ ss << " int count = 0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ int dataCol = 0;
+ int dataRow = 0;
+ if(vSubArguments[0]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ formula::FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ dataCol = pCurDVR->GetArrays().size();
+ dataRow = pCurDVR->GetArrayLength();
+
+ if(vSubArguments[dataCol]->GetFormulaToken()->GetType() !=
+ formula::svSingleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+
+ const formula::SingleVectorRefToken*pTmpDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(vSubArguments[dataCol]
+ ->GetFormulaToken());
+ ss << " tmp"<<dataCol<<"=";
+ ss << vSubArguments[dataCol]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(gid0>="<<pTmpDVR1->GetArrayLength()<<" ||isnan(";
+ ss << "tmp"<<dataCol<<"))\n";
+ ss << " tmp"<<dataCol<<"=DBL_MIN;\n";
+
+ int conditionCol = 0;
+ int conditionRow = 0;
+ if(vSubArguments[dataCol + 1]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ tmpCur = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ conditionCol = pCurDVR->GetArrays().size();
+ conditionRow = pCurDVR->GetArrayLength();
+
+ if(dataCol!=conditionCol)
+ throw Unhandled(__FILE__, __LINE__);
+ if(dataCol > 0 && dataRow > 0)
+ {
+ formula::FormulaToken *tmpCur1 = vSubArguments[0]->GetFormulaToken();
+ formula::FormulaToken *tmpCur2 = vSubArguments[dataCol + 1]->
+ GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+
+ if(pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed() &&
+ pCurDVR2->IsStartFixed() && pCurDVR2->IsEndFixed())
+ {
+ ss << " int i,j,p;\n";
+ ss << " bool flag;\n";
+
+ ss << " for(p = 1;p < " << dataRow << ";++p)\n";
+ ss << " {\n";
+ ss << " i = p;\n";
+ for(int i = 0; i < dataCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(isnan(tmp"<<i<<"))\n";
+ ss <<" tmp"<<i<<" = 0;\n";
+ }
+ ss << " flag = false;\n";
+ ss << " for(j = 1; j < " << conditionRow << ";++j)\n";
+ ss << " {\n";
+ ss << " i = j;\n";
+ ss << " if (flag)\n";
+ ss << " break;\n";
+ ss << " else{\n";
+ for(int i = dataCol + 1; i < dataCol + 1 + conditionCol; ++i){
+ if(vSubArguments[i]->GetFormulaToken()->GetType() !=
+ formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " if(!isnan(tmp"<<i<<")){\n";
+ ss << " if(tmp"<<(i-dataCol-1)<<"!=tmp";
+ ss << i<<"){\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ ss << " flag=true;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (flag){\n";
+ for(int i = 0; i < dataCol; ++i){
+ ss << " if(tmp"<<dataCol<<"=="<<(i+1)<<"){\n";
+ ss << " value=tmp"<<i<<";\n";
+ ss << " }\n";
+ }
+ ss << " if(value > DBL_MIN)\n";
+ ss << " count++;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ ss << "count = -1;\n";
+ }
+ else
+ ss << "count = -1;\n";
+ ss << " return count;\n";
+ ss << "}";
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_database.hxx b/sc/source/core/opencl/op_database.hxx
new file mode 100644
index 000000000..5488edb32
--- /dev/null
+++ b/sc/source/core/opencl/op_database.hxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_CORE_OPENCL_OP_DATABASE_HXX
+#define INCLUDED_SC_SOURCE_CORE_OPENCL_OP_DATABASE_HXX
+
+#include "opbase.hxx"
+
+namespace sc::opencl {
+
+class OpDmax: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Dmax"; }
+};
+
+class OpDmin: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Dmin"; }
+};
+
+class OpDproduct: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Dproduct"; }
+};
+
+class OpDaverage: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Daverage"; }
+};
+
+class OpDstdev: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Dstdev"; }
+};
+
+class OpDstdevp: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Dstdevp"; }
+};
+
+class OpDsum: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Dsum"; }
+};
+
+class OpDvar: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Dvar"; }
+};
+
+class OpDvarp: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Dvarp"; }
+};
+
+class OpDcount: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Dcount"; }
+};
+
+class OpDcount2: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Dcount2"; }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_financial.cxx b/sc/source/core/opencl/op_financial.cxx
new file mode 100644
index 000000000..6d44271f1
--- /dev/null
+++ b/sc/source/core/opencl/op_financial.cxx
@@ -0,0 +1,4791 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "op_financial.hxx"
+
+#include <formula/vectortoken.hxx>
+#include <sstream>
+
+using namespace formula;
+
+namespace sc::opencl {
+// Definitions of inline functions
+#include "opinlinefun_finacial.cxx"
+
+void RRI::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() <<";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fv;\n";
+ ss << " double pv;\n";
+ ss << " double nper;\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+
+ ss<< " int buffer_nper_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n";
+
+ ss<< " int buffer_pv_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n";
+
+ ss<< " int buffer_fv_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n";
+
+ ss<<" if(gid0>=buffer_nper_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n";
+ ss<<" nper = 0;\n\telse \n";
+ ss<<" nper = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+
+ ss<<" if(gid0>=buffer_pv_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<"))\n";
+ ss<<" pv = 0;\n\telse \n";
+ ss<<" pv = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+
+ ss<<" if(gid0>=buffer_pv_len || isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<"))\n";
+ ss<<" fv = 0;\n\telse \n";
+ ss<<" fv = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+ ss << " tmp = pow(fv*pow(pv,-1),1.0*pow(nper,-1))-1;\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpNominal::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << "double tmp = 0;\n\t";
+ ss << "double temp = 0;\n\t";
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "double tmp0=0,tmp1=0;\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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 <<" temp="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if (isnan(temp))\n";
+ ss <<" tmp"<<i<<"= 0;\n";
+ ss <<" else\n";
+ ss <<" tmp"<<i<<"=temp;\n";
+ ss <<" }\n";
+ }
+ else
+ {
+ ss <<" tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef(
+);
+ ss <<";\n";
+ }
+ }
+ ss<<"if(tmp1==0)\n\t";
+ ss<<"\treturn 0;\n\t";
+ ss<<"tmp=pow( tmp1,-1);\n\t";
+ ss<<"tmp=( pow( tmp0+ 1.0, tmp ) - 1.0 ) *";
+ ss<<"tmp1;\n\t";
+ ss << "return tmp;\n";
+ ss << "}";
+}
+
+void OpDollarde::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << "double tmp = " << GetBottom() <<";\n\t";
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "double fInt = " << GetBottom() <<";\n\t";
+ ss << "double dollar;\n\t";
+ ss << "double fFrac;\n\t";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss<< "int buffer_dollar_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n\t";
+ ss<< "int buffer_frac_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n\t";
+ ss<<"if((gid0)>=buffer_dollar_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"dollar = 0;\n\telse \n\t\t";
+ ss<<"dollar = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss<<"if((gid0)>=buffer_frac_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"fFrac = 0;\n\telse \n\t\t";
+ ss<<"fFrac = (int)(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<");\n\t";
+ ss << "tmp = modf( dollar , &fInt );\n\t";
+ ss << "tmp /= fFrac;\n\t";
+ ss << "tmp *= pow( 10.0 , ceil( log10(fFrac ) ) );\n\t";
+ ss << "tmp += fInt;\t";
+ ss << "\n\treturn tmp;\n";
+ ss << "}";
+}
+
+void OpDollarfr::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << "double tmp = " << GetBottom() <<";\n\t";
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "double fInt = " << GetBottom() <<";\n\t";
+ ss << "double dollar;\n\t";
+ ss << "double fFrac;\n\t";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss<< "int buffer_dollar_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n\t";
+ ss<< "int buffer_frac_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n\t";
+ ss<<"if((gid0)>=buffer_dollar_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"dollar = 0;\n\telse \n\t\t";
+ ss<<"dollar = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss<<"if((gid0)>=buffer_frac_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"fFrac = 0;\n\telse \n\t\t";
+ ss<<"fFrac = (int)(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<");\n\t";
+ ss << "tmp = modf( dollar , &fInt );\n\t";
+ ss << "tmp *= fFrac;\n\t";
+ ss << "tmp *= pow( 10.0 , -ceil( log10(fFrac ) ) );\n\t";
+ ss << "tmp += fInt;\t";
+ ss << "\n\treturn tmp;\n";
+ ss << "}";
+}
+
+void OpDISC::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetYearFrac_newDecl);decls.insert(DaysToDate_newDecl);
+ decls.insert(DaysInMonthDecl);decls.insert(IsLeapYearDecl);
+ funs.insert(GetYearFrac_new);funs.insert(DaysToDate_new);
+ funs.insert(DaysInMonth);funs.insert(IsLeapYear);
+}
+
+void OpDISC::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double arg0 = " << GetBottom() << ";\n";
+ ss << " double arg1 = " << GetBottom() << ";\n";
+ ss << " double arg2 = " << GetBottom() << ";\n";
+ ss << " double arg3 = " << GetBottom() << ";\n";
+ ss << " double arg4 = " << GetBottom() << ";\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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 << " arg" << i << " = 0;\n";
+ ss << " else\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ }
+ ss << " int nNullDate = 693594;\n";
+ ss << " tmp = 1.0 - arg2 / arg3;\n";
+ ss << " tmp /=";
+ ss << " GetYearFrac_new(nNullDate, (int)arg0, (int)arg1, (int)arg4);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpINTRATE::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetYearDiff_newDecl);decls.insert(GetDiffDate_newDecl);
+ decls.insert(DaysToDate_newDecl);decls.insert(GetNullDateDecl);
+ decls.insert(DateToDaysDecl);decls.insert(DaysInMonthDecl);
+ decls.insert(IsLeapYearDecl);
+ funs.insert(GetYearDiff_new);funs.insert(GetDiffDate_new);
+ funs.insert(DaysToDate_new);funs.insert(GetNullDate);
+ funs.insert(DateToDays);funs.insert(DaysInMonth);
+ funs.insert(IsLeapYear);
+}
+
+void OpINTRATE::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double arg0 = " << GetBottom() << ";\n";
+ ss << " double arg1 = " << GetBottom() << ";\n";
+ ss << " double arg2 = " << GetBottom() << ";\n";
+ ss << " double arg3 = " << GetBottom() << ";\n";
+ ss << " double arg4 = " << GetBottom() << ";\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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 << " arg" << i << " = 0;\n";
+ ss << " else\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ }
+ ss << " int nNullDate = GetNullDate();\n";
+ ss << " tmp = ((arg3 / arg2) - 1) / GetYearDiff_new(nNullDate, (int)arg0,";
+ ss << " (int)arg1,(int)arg4);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpFV::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetFVDecl);
+ funs.insert(GetFV);
+}
+
+void OpFV::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double arg0 = " << GetBottom() << ";\n";
+ ss << " double arg1 = " << GetBottom() << ";\n";
+ ss << " double arg2 = " << GetBottom() << ";\n";
+ ss << " double arg3 = " << GetBottom() << ";\n";
+ ss << " double arg4 = " << GetBottom() << ";\n";
+ unsigned j = vSubArguments.size();
+ while (j--)
+ {
+ FormulaToken* pCur = vSubArguments[j]->GetFormulaToken();
+ assert(pCur);
+ if(pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ ss << " if(gid0 >= " << pSVR->GetArrayLength() << " || isnan(";
+ ss << vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg" << j << " = " <<GetBottom() << ";\n";
+ ss << " else\n";
+ ss << " arg" << j << " = ";
+ ss << vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " tmp = GetFV(arg0, arg1, arg2, arg3, arg4);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpIPMT::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetFVDecl);
+ funs.insert(GetFV);
+}
+
+void OpIPMT::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double arg0 = " << GetBottom() << ";\n";
+ ss << " double arg1 = " << GetBottom() << ";\n";
+ ss << " double arg2 = " << GetBottom() << ";\n";
+ ss << " double arg3 = " << GetBottom() << ";\n";
+ ss << " double arg4 = " << GetBottom() << ";\n";
+ ss << " double arg5 = " << GetBottom() << ";\n";
+ unsigned j = vSubArguments.size();
+ while (j--)
+ {
+ FormulaToken* pCur = vSubArguments[j]->GetFormulaToken();
+ assert(pCur);
+ if(pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ ss << " if(gid0 >= " << pSVR->GetArrayLength() << " || isnan(";
+ ss << vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg" << j << " = " <<GetBottom() << ";\n";
+ ss << " else\n";
+ ss << " arg" << j << " = ";
+ ss << vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " double pmt ;\n";
+ ss << " if(arg0 == 0.0)\n";
+ ss << " return 0;\n";
+ ss << " double temp1 = 0;\n";
+ ss << " double abl = pow(1.0 + arg0, arg2);\n";
+ ss << " temp1 -= arg4;\n";
+ ss << " temp1 -= arg3 * abl;\n";
+ ss << " pmt = temp1 / (1.0 + arg0 * arg5) /";
+ ss << " ( (abl - 1.0) / arg0);\n";
+ ss << " double temp = pow( 1 + arg0, arg1 - 2);\n";
+ ss << " if(arg1 == 1.0)\n";
+ ss << " {\n";
+ ss << " if(arg5 > 0.0)\n";
+ ss << " tmp = 0.0;\n";
+ ss << " else\n";
+ ss << " tmp = -arg3;\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " if(arg5 > 0.0)\n";
+ ss << " tmp = GetFV(arg0, arg1 - 2.0, pmt, arg3, 1.0)";
+ ss << " - pmt;\n";
+ ss << " else\n";
+ ss << " tmp = GetFV(arg0, arg1 - 1.0, pmt, arg3, 0.0);\n";
+ ss << " }\n";
+ ss << " tmp = tmp * arg0;\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpISPMT::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double arg0 = " << GetBottom() << ";\n";
+ ss << " double arg1 = " << GetBottom() << ";\n";
+ ss << " double arg2 = " << GetBottom() << ";\n";
+ ss << " double arg3 = " << GetBottom() << ";\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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 << " arg" << i << " = 0;\n";
+ ss << " else\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ }
+ ss << " tmp = arg3 * arg0 * ( arg1 - arg2) * pow(arg2, -1);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpPDuration::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double arg0 = " << GetBottom() << ";\n";
+ ss << " double arg1 = " << GetBottom() << ";\n";
+ ss << " double arg2 = " << GetBottom() << ";\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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 << " arg" << i << " = 0;\n";
+ ss << " else\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ }
+ ss << " tmp = log(arg2 * pow( arg1,-1)) / log(arg0 + 1.0);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpDuration_ADD::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetDurationDecl);decls.insert(lcl_GetcoupnumDecl);
+ decls.insert(GetYearFracDecl);decls.insert(DaysToDateDecl);
+ decls.insert(GetNullDateDecl);decls.insert(DateToDaysDecl);
+ decls.insert(DaysInMonthDecl);decls.insert(IsLeapYearDecl);
+ funs.insert(GetDuration);funs.insert(lcl_Getcoupnum);
+ funs.insert(GetYearFrac);funs.insert(DaysToDate);
+ funs.insert(GetNullDate);funs.insert(DateToDays);
+ funs.insert(DaysInMonth);funs.insert(IsLeapYear);
+}
+
+void OpDuration_ADD::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double arg0 = " << GetBottom() << ";\n";
+ ss << " double arg1 = " << GetBottom() << ";\n";
+ ss << " double arg2 = " << GetBottom() << ";\n";
+ ss << " double arg3 = " << GetBottom() << ";\n";
+ ss << " double arg4 = " << GetBottom() << ";\n";
+ ss << " double arg5 = " << GetBottom() << ";\n";
+ unsigned j = vSubArguments.size();
+ while (j--)
+ {
+ FormulaToken* pCur = vSubArguments[j]->GetFormulaToken();
+ assert(pCur);
+ if(pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ ss << " if(gid0 >= " << pSVR->GetArrayLength() << " || isnan(";
+ ss << vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg" << j << " = " <<GetBottom() << ";\n";
+ ss << " else\n";
+ ss << " arg" << j << " = ";
+ ss << vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " int nNullDate = GetNullDate();\n";
+ ss << " tmp = GetDuration( nNullDate, (int)arg0, (int)arg1, arg2,";
+ ss << " arg3, (int)arg4, (int)arg5);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpMDuration::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetDuration_newDecl);decls.insert(lcl_Getcoupnum_newDecl);
+ decls.insert(addMonthsDecl);decls.insert(checklessthanDecl);
+ decls.insert(setDayDecl);decls.insert(ScaDateDecl);
+ decls.insert(GetYearFracDecl);decls.insert(DaysToDateDecl);
+ decls.insert(DaysInMonthDecl);decls.insert(IsLeapYearDecl);
+ funs.insert(GetDuration_new);funs.insert(lcl_Getcoupnum_new);
+ funs.insert(addMonths);funs.insert(checklessthan);
+ funs.insert(setDay);funs.insert(ScaDate);
+ funs.insert(GetYearFrac);funs.insert(DaysToDate);
+ funs.insert(DaysInMonth);funs.insert(IsLeapYear);
+}
+
+void OpMDuration::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double arg0 = " << GetBottom() << ";\n";
+ ss << " double arg1 = " << GetBottom() << ";\n";
+ ss << " double arg2 = " << GetBottom() << ";\n";
+ ss << " double arg3 = " << GetBottom() << ";\n";
+ ss << " double arg4 = " << GetBottom() << ";\n";
+ ss << " double arg5 = " << GetBottom() << ";\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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 << " arg" << i << " = 0;\n";
+ ss << " else\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ }
+ ss << " int nNullDate = 693594;\n";
+ ss << " tmp = GetDuration_new( nNullDate, (int)arg0, (int)arg1, arg2,";
+ ss << " arg3, (int)arg4, (int)arg5);\n";
+ ss << " tmp = tmp * pow(1.0 + arg3 * pow((int)arg4, -1.0), -1);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void Fvschedule::GenSlidingWindowFunction(
+ std::stringstream &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();
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(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 << "return (double)tmp * arg0";
+ ss << ";\n}";
+}
+void Cumipmt::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetPMT_newDecl); decls.insert(GetFV_newDecl);
+ funs.insert(GetPMT_new);funs.insert(GetFV_new);
+}
+void Cumipmt::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fRate,fVal;\n";
+ ss << " int nStartPer,nEndPer,nNumPeriods,nPayType;\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ FormulaToken *tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ FormulaToken *tmpCur5 = vSubArguments[5]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(gid0 >= "<<tmpCurDVR0->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fRate = 0;\n else\n";
+ }
+ ss <<" fRate = "<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss <<" if(gid0 >= "<<tmpCurDVR1->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nNumPeriods = 0;\n else\n";
+ }
+ ss <<" nNumPeriods = (int)";
+ ss <<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ ss <<" if(gid0 >= "<<tmpCurDVR2->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fVal = 0;\n else\n";
+ }
+ ss <<" fVal = "<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss <<" if(gid0 >= "<<tmpCurDVR3->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nStartPer = 0;\n else\n";
+ }
+ ss <<" nStartPer = (int)";
+ ss <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur4->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+ ss <<" if(gid0 >= "<<tmpCurDVR4->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nEndPer = 0;\n else\n";
+ }
+ ss <<" nEndPer = (int)";
+ ss <<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+
+ if(tmpCur5->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR5= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur5);
+ ss <<" if(gid0 >= "<<tmpCurDVR5->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nPayType = 0;\n else\n";
+ }
+ ss <<" nPayType = (int)"<<vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" double fPmt;\n";
+ ss <<" fPmt = GetPMT_new( fRate, nNumPeriods, fVal, 0.0, nPayType );\n";
+ ss <<" double tmp = 0.0;\n";
+ ss <<" if( nStartPer == 1 )\n";
+ ss <<" {\n";
+ ss <<" if( nPayType <= 0 )\n";
+ ss <<" tmp = -fVal;\n";
+ ss <<" nStartPer++;\n";
+ ss <<" }\n";
+ ss <<" for( ; nStartPer<= nEndPer ; nStartPer++ )\n";
+ ss <<" {\n";
+ ss <<" if( nPayType > 0 )\n";
+ ss <<" tmp += GetFV_new( fRate, nStartPer - 2 , ";
+ ss <<"fPmt, fVal, 1 ) - fPmt;\n";
+ ss <<" else\n";
+ ss <<" tmp += GetFV_new( fRate, nStartPer - 1 , ";
+ ss <<"fPmt, fVal, 0 );\n";
+ ss <<" }\n";
+ ss <<" tmp *= fRate;\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+
+void IRR::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " #define Epsilon 1.0E-7\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ FormulaToken* pSur = vSubArguments[1]->GetFormulaToken();
+ assert(pSur);
+ ss << " double fEstimated = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " double fEps = 1.0;\n";
+ ss << " double x = 0.0, xNew = 0.0, fNumerator = 0.0, fDenominator = 0.0;\n";
+ ss << " double nCount = 0.0;\n";
+ if (pSur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pSur);
+ ss << " if (gid0 >= " << pSVR->GetArrayLength() << ")\n";
+ ss << " fEstimated = 0.1;\n";
+ ss << " if (isnan(fEstimated))\n";
+ ss << " x = 0.1;\n";
+ ss << " else\n";
+ }
+ else if (pSur->GetType() == formula::svDouble)
+ {
+ ss << " if (isnan(fEstimated))\n";
+ ss << " x = 0.1;\n";
+ ss << " else\n";
+ }
+ ss << " x = fEstimated;\n";
+ ss << " unsigned short nItCount = 0;\n";
+ ss << " while (fEps > Epsilon && nItCount < 20){\n";
+ ss << " nCount = 0.0; fNumerator = 0.0; fDenominator = 0.0;\n";
+ ss << " double arg0, arg1;\n";
+ ss << " int i = 0;\n";
+ FormulaToken* pCur = vSubArguments[0]->GetFormulaToken();
+ assert(pCur);
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken* >(pCur);
+ size_t nCurWindowSize = pDVR->GetRefRowSize();
+ ss << " for ( ";
+ if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) {
+ ss << "i = gid0; i < " << pDVR->GetArrayLength();
+ ss << " && i < " << nCurWindowSize << " /2*2; i++){\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " i++;;\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (!isnan(arg0)){\n";
+ ss << " fNumerator += arg0 / pow(1.0 + x, nCount);\n";
+ ss << " fDenominator+=-1*nCount*arg0/pow(1.0+x,nCount+1.0);\n";
+ ss << " nCount += 1;\n";
+ ss << " }\n";
+ ss << " if (!isnan(arg1)){\n";
+ ss << " fNumerator += arg1 / pow(1.0 + x, nCount);\n";
+ ss << " fDenominator+=-1*nCount*arg1/pow(1.0+x,nCount+1.0);\n";
+ ss << " nCount += 1;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << "if(i < " << pDVR->GetArrayLength();
+ ss << " && i < " << nCurWindowSize << ") ;{\n";
+ }
+ else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) {
+ ss << "; i < " << pDVR->GetArrayLength();
+ ss << " && i < (gid0+" << nCurWindowSize << " )/2*2; i++){\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (!isnan(arg0)){\n";
+ ss << " fNumerator += arg0 / pow(1.0 + x, nCount);\n";
+ ss << " fDenominator+=-1*nCount*arg0/pow(1.0+x,nCount+1.0);\n";
+ ss << " nCount += 1;\n";
+ ss << " }\n";
+ ss << " i++;\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (!isnan(arg1)){\n";
+ ss << " fNumerator += arg1 / pow(1.0 + x, nCount);\n";
+ ss << " fDenominator+=-1*nCount*arg1/pow(1.0+x,nCount+1.0);\n";
+ ss << " nCount+=1;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if(i < " << pDVR->GetArrayLength();
+ ss << " && i < gid0+" << nCurWindowSize << "){\n";
+ }
+ else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()){
+ ss << " ; i + gid0 < " << pDVR->GetArrayLength();
+ ss << " && i < " << nCurWindowSize << " /2*2; i++){\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " i++;;\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (!isnan(arg0)){\n";
+ ss << " fNumerator += arg0 / pow(1.0 + x, nCount);\n";
+ ss << " fDenominator+=-1*nCount*arg0/pow(1.0+x,nCount+1.0);\n";
+ ss << " nCount += 1;\n";
+ ss << " }\n";
+ ss << " if (!isnan(arg1)){\n";
+ ss << " fNumerator += arg1 / pow(1.0 + x, nCount);\n";
+ ss << " fDenominator+=-1*nCount*arg1/pow(1.0+x,nCount+1.0);\n";
+ ss << " nCount+=1;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if(i + gid0 < " << pDVR->GetArrayLength() << " &&";
+ ss << " i < " << nCurWindowSize << "){\n";
+
+ } else {
+ ss << "; i < " << nCurWindowSize << " /2*2; i++){\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " i++;;\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (!isnan(arg0)){\n";
+ ss << " fNumerator += arg0 / pow(1.0 + x, nCount);\n";
+ ss << " fDenominator+=-1*nCount*arg0/pow(1.0+x,nCount+1.0);\n";
+ ss << " nCount += 1;\n";
+ ss << " }\n";
+ ss << " if (!isnan(arg1)){\n";
+ ss << " fNumerator += arg1 / pow(1.0 + x, nCount);\n";
+ ss << " fDenominator+=-1*nCount*arg1/pow(1.0+x,nCount+1.0);\n";
+ ss << " nCount+=1;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << "if(i<" << nCurWindowSize << "){\n";
+
+ }
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(arg0))\n";
+ ss << " continue;\n";
+ ss << " fNumerator += arg0 / pow(1.0+x, nCount);\n";
+ ss << " fDenominator += -nCount * arg0 / pow(1.0+x,nCount+1.0);\n";
+ ss << " nCount+=1;\n";
+ ss << " }\n";
+ ss << " xNew = x - fNumerator / fDenominator;\n";
+ ss << " fEps = fabs(xNew - x);\n";
+ ss << " x = xNew;\n";
+ ss << " nItCount++;\n }\n";
+ ss << " if (fEstimated == 0.0 && fabs(x) < Epsilon)\n";
+ ss << " x = 0.0;\n";
+ ss << " if (fEps < Epsilon)\n";
+ ss << " return x;\n";
+ ss << " else\n";
+ // FIXME: This is of course horribly wrong. 523 is the error code NoConvergence, and this should
+ // be CreateDoubleError(523). Ditto for the other occurrences of 523 in the OpenCL code
+ // generated in this file.
+ ss << " return (double)523;\n";
+ ss << "}";
+}
+
+void XNPV::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *pCur = vSubArguments[1]->GetFormulaToken();
+ assert(pCur);
+ const formula::DoubleVectorRefToken* pCurDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur);
+ size_t nCurWindowSize = pCurDVR->GetRefRowSize();
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"( ";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+
+ ss << ") {\n\t";
+ ss << "double result = 0.0;\n\t";
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "int i=0;\n\t";
+ ss << "double date;\n\t";
+ ss << "double value;\n\t";
+ ss << "double rate;\n\t";
+ ss << "double dateNull;\n\t";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+ ss<< "int buffer_rate_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n\t";
+ ss<< "int buffer_value_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n\t";
+ ss<< "int buffer_date_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n\t";
+ ss<<"if((gid0)>=buffer_date_len || isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"return NAN;\n\telse \n";
+ ss<<"dateNull = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss<<"if((gid0)>=buffer_rate_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"return NAN;\n\telse \n";
+ ss<<"rate = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss<<"if(1 == buffer_date_len )\n";
+ ss<<"return ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss << "for (int i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
+ {
+ ss << "gid0; i < "<< nCurWindowSize <<"; i++)\n\t\t";
+ }
+ else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << "0; i < gid0+"<< nCurWindowSize <<"; i++)\n\t\t";
+ }
+ else
+ {
+ ss << "0; i < "<< nCurWindowSize <<"; i++)\n\t\t";
+ }
+ ss << "{\n\t";
+ if (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << "if((i+gid0)>=buffer_value_len || (i+gid0)>=buffer_date_len)\n\t\t";
+ ss << "return result;\n\telse \n\t\t";
+ }
+ else
+ {
+ ss << "if(i>=buffer_value_len || i>=buffer_date_len)\n\t\t";
+ ss << "return result;\n\telse \n\t\t";
+ }
+
+ ss << "value = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef(true);
+ ss << ";\n";
+ ss << " date = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef(true);
+ ss << ";\n";
+ ss << "result += value/(pow((rate+1),(date-dateNull)/365));\n";
+ ss << "}\n";
+ ss << "return result;\n";
+ ss << "}";
+}
+
+ void PriceMat::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetYearFracDecl);decls.insert(GetNullDateDecl);
+ decls.insert(DateToDaysDecl);decls.insert(DaysToDateDecl);
+ decls.insert(DaysInMonthDecl);decls.insert(IsLeapYearDecl);
+
+ funs.insert(GetYearFrac);funs.insert(GetNullDate);
+ funs.insert(DateToDays);funs.insert(DaysToDate);
+ funs.insert(DaysInMonth);funs.insert(IsLeapYear);
+}
+void PriceMat::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "double result=0;\n\t";
+ ss<< "int nNullDate = GetNullDate( );\n\t";
+ ss <<"int settle;\n\t";
+ ss <<"int mat;\n\t";
+ ss <<"int issue;\n\t";
+ ss <<"double rate;\n\t";
+ ss <<"double yield;\n\t";
+ ss <<"int nBase;\n\t";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ FormulaToken *tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+ FormulaToken *tmpCur5 = vSubArguments[5]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR5= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur5);
+
+ ss<< "int buffer_settle_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n\t";
+ ss<< "int buffer_mat_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n\t";
+ ss<< "int buffer_issue_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n\t";
+ ss<< "int buffer_rate_len = ";
+ ss<< tmpCurDVR3->GetArrayLength();
+ ss << ";\n\t";
+ ss<< "int buffer_yield_len = ";
+ ss<< tmpCurDVR4->GetArrayLength();
+ ss << ";\n\t";
+ ss<< "int buffer_base_len = ";
+ ss<< tmpCurDVR5->GetArrayLength();
+ ss << ";\n\t";
+ ss<<"if(gid0>=buffer_settle_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"settle = 0;\n\telse \n\t\t";
+ ss<<"settle = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss<<"if(gid0>=buffer_mat_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"mat = 0;\n\telse \n\t\t";
+ ss<<"mat = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss<<"if(gid0>=buffer_issue_len || isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"issue = 0;\n\telse \n\t\t";
+ ss<<"issue = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss<<"if(gid0>=buffer_rate_len || isnan(";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"rate = 0;\n\telse \n\t\t";
+ ss<<"rate = ";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss<<"if(gid0>=buffer_yield_len || isnan(";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"yield = 0;\n\telse \n\t\t";
+ ss<<"yield = ";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss<<"if(gid0>=buffer_base_len || isnan(";
+ ss << vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"nBase = 0;\n\telse \n\t\t";
+ ss<<"nBase = ";
+ ss << vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss<< "double fIssMat = GetYearFrac( nNullDate, issue, mat, nBase);\n";
+ ss<<"double fIssSet = GetYearFrac( nNullDate, issue, settle,nBase);\n";
+ ss<<"double fSetMat = GetYearFrac( nNullDate, settle, mat, nBase);\n";
+ ss<<"result = 1.0 + fIssMat * rate;\n\t";
+ ss<<"result /= 1.0 + fSetMat * yield;\n\t";
+ ss<<"result -= fIssSet * rate;\n\t";
+ ss<<"result*= 100.0;\n\t";
+ ss<<"return result;\n\t";
+ ss<<"}\n";
+}
+
+void OpSYD::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double result=0;\n";
+ ss << " double cost;\n";
+ ss << " double salvage;\n";
+ ss << " double life;\n";
+ ss << " double period;\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+
+ ss << " int buffer_cost_len = ";
+ ss << tmpCurDVR0->GetArrayLength();
+ ss << ";\n";
+
+ ss << " int buffer_salvage_len = ";
+ ss << tmpCurDVR1->GetArrayLength();
+ ss << ";\n";
+
+ ss << " int buffer_life_len = ";
+ ss << tmpCurDVR2->GetArrayLength();
+ ss << ";\n";
+ ss << " int buffer_period_len = ";
+ ss << tmpCurDVR3->GetArrayLength();
+ ss << ";\n";
+
+ ss <<" if(gid0>=buffer_cost_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" cost = 0;\n\telse \n";
+ ss <<" cost = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0>=buffer_salvage_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" salvage = 0;\n\telse \n";
+ ss <<" salvage = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0>=buffer_life_len || isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" life = 0;\n\telse \n";
+ ss <<" life = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0>=buffer_period_len || isnan(";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" period = 0;\n\telse \n";
+ ss <<" period = ";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" double tmpvalue = ((life*(life+1))*pow(2.0,-1));\n";
+ ss <<" result = ((cost-salvage)*(life-period+1)";
+ ss << "*pow(tmpvalue,-1));\n";
+ ss <<" return result;\n";
+ ss <<"}\n";
+}
+
+void MIRR::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ 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);
+
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(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";
+ ss << "double invest = arg1 + 1.0;\n\t";
+ ss << "double reinvest = arg2 + 1.0;\n\t";
+ ss << "double NPV_invest = 0.0;\n\t";
+ ss << "double Pow_invest = 1.0;\n\t";
+ 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";
+ 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";
+ ss << "return (double)tmp;\n";
+ ss << "}";
+}
+
+void OpEffective::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() <<";\n";
+ ss << " int gid0 = get_global_id(0);\n\t";
+ ss << " double arg0 = " << GetBottom() << ";\n";
+ ss << " double arg1 = " << GetBottom() << ";\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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 << " arg" << i << " = 0;\n";
+ ss << " else\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ }
+ ss << " tmp = pow(1.0 + arg0 * pow(arg1, -1), arg1)-1.0;\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+ void OpTbilleq::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetDiffDate360_Decl);decls.insert(GetDiffDate360Decl);
+ decls.insert(DateToDaysDecl);decls.insert(DaysToDate_LocalBarrierDecl);
+ decls.insert(DaysInMonthDecl);decls.insert(GetNullDateDecl);
+ decls.insert(IsLeapYearDecl);
+ funs.insert(GetDiffDate360_);funs.insert(GetDiffDate360);
+ funs.insert(DateToDays);funs.insert(DaysToDate_LocalBarrier);
+ funs.insert(DaysInMonth);funs.insert(GetNullDate);
+ funs.insert(IsLeapYear);
+}
+void OpTbilleq::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << "double tmp = 0;\n\t";
+ ss << "double tmp000;\n\t";
+ ss << "double tmp001;\n\t";
+ ss << "double tmp002;\n\t";
+
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+
+ ss<< "int buffer_tmp000_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp001_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp002_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp000_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp000 = 0;\n\telse \n\t\t";
+ ss<<"tmp000 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp001_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp001 = 0;\n\telse \n\t\t";
+ ss<<"tmp001 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp002_len || isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp002 = 0;\n\telse \n\t\t";
+ ss<<"tmp002 = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"tmp001+=1.0;\n";
+ ss<<"int nDiff =GetDiffDate360(GetNullDate(),tmp000,tmp001,true);\n";
+ ss<<"tmp =( 365 * tmp002 ) / ( 360 - ( tmp002 * ( nDiff ) ) );\n";
+ ss << "return tmp;\n";
+ ss << "}";
+}
+void OpCumprinc::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetPMT_newDecl); decls.insert(GetFV_newDecl);
+ funs.insert(GetPMT_new);funs.insert(GetFV_new);
+}
+void OpCumprinc::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() <<";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fRate,fVal;\n";
+ ss << " int nStartPer,nEndPer,nNumPeriods,nPayType;\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ FormulaToken *tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ FormulaToken *tmpCur5 = vSubArguments[5]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(gid0 >= "<<tmpCurDVR0->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fRate = 0;\n else\n";
+ }
+ ss <<" fRate = "<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss <<" if(gid0 >= "<<tmpCurDVR1->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nNumPeriods = 0;\n else\n";
+ }
+ ss <<" nNumPeriods = (int)";
+ ss <<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ ss <<" if(gid0 >= "<<tmpCurDVR2->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fVal = 0;\n else\n";
+ }
+ ss <<" fVal = "<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss <<" if(gid0 >= "<<tmpCurDVR3->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nStartPer = 0;\n else\n";
+ }
+ ss <<" nStartPer = (int)";
+ ss <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur4->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+ ss <<" if(gid0 >= "<<tmpCurDVR4->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nEndPer = 0;\n else\n";
+ }
+ ss <<" nEndPer = (int)";
+ ss <<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+
+ if(tmpCur5->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR5= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur5);
+ ss <<" if(gid0 >= "<<tmpCurDVR5->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nPayType = 0;\n else\n";
+ }
+ ss <<" nPayType = (int)";
+ ss <<vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" double fPmt;\n";
+ ss <<" fPmt = GetPMT_new( fRate, nNumPeriods,fVal,0.0,nPayType );\n";
+ ss <<" if(nStartPer == 1)\n";
+ ss <<" {\n";
+ ss <<" if( nPayType <= 0 )\n";
+ ss <<" tmp = fPmt + fVal * fRate;\n";
+ ss <<" else\n";
+ ss <<" tmp = fPmt;\n";
+ ss <<" nStartPer=nStartPer+1;\n";
+ ss <<" }\n";
+ ss <<" for( int i = nStartPer ; i <= nEndPer ; i++ )\n";
+ ss <<" {\n";
+ ss <<" if( nPayType > 0 )\n";
+ ss <<" tmp += fPmt - ( GetFV_new( fRate,i - 2,";
+ ss <<"fPmt,fVal,1)- fPmt ) * fRate;\n";
+ ss <<" else\n";
+ ss <<" tmp += fPmt - GetFV_new( fRate, i - 1,";
+ ss <<"fPmt,fVal,0 ) * fRate;\n";
+ ss <<" }\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+void OpAccrint::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(IsLeapYearDecl); decls.insert(DaysInMonthDecl);
+ decls.insert(DaysToDateDecl); decls.insert(DateToDaysDecl);
+ decls.insert(GetNullDateDecl); decls.insert(GetDiffDateDecl);
+ funs.insert(IsLeapYear);funs.insert(DaysInMonth);
+ funs.insert(DaysToDate);funs.insert(DateToDays);
+ funs.insert(GetNullDate);funs.insert(GetDiffDate);
+}
+void OpAccrint::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = 0;\n";
+ ss << " int nStartDate,nEndDate,mode,freq;\n";
+ ss << " int nDays1stYear=0;\n";
+ ss << " double fVal,fRate;\n";
+ FormulaToken* tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ FormulaToken* tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ FormulaToken* tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ FormulaToken* tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+ FormulaToken* tmpCur5 = vSubArguments[5]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR5= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur5);
+ FormulaToken* tmpCur6 = vSubArguments[6]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR6= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur6);
+ ss<< " int buffer_nIssue_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss<< ";\n";
+ ss<< " int buffer_nSettle_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss<< ";\n";
+ ss<< " int buffer_fRate_len = ";
+ ss<< tmpCurDVR3->GetArrayLength();
+ ss<< ";\n";
+ ss<< " int buffer_fVal_len = ";
+ ss<< tmpCurDVR4->GetArrayLength();
+ ss<< ";\n";
+ ss<< " int buffer_nFreq_len = ";
+ ss<< tmpCurDVR5->GetArrayLength();
+ ss<< ";\n";
+ ss<< " int buffer_nMode_len = ";
+ ss<< tmpCurDVR6->GetArrayLength();
+ ss << ";\n";
+ ss<<" if(gid0 >= buffer_nIssue_len || isnan(";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nStartDate = 0;\n else\n";
+ ss <<" nStartDate=(int)";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_nSettle_len || isnan(";
+ ss <<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nEndDate = 0;\n else\n";
+ ss <<" nEndDate=(int)";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss <<" if(gid0 >= buffer_fRate_len || isnan(";
+ ss <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fRate = 0;\n else\n";
+ ss <<" fRate=";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_fVal_len || isnan(";
+ ss <<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fVal = 0;\n else\n";
+ ss <<" fVal=";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_nFreq_len || isnan(";
+ ss <<vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" freq = 0;\n else\n";
+ ss <<" freq= (int)";
+ ss << vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_nMode_len || isnan(";
+ ss <<vSubArguments[6]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" mode = 0;\n else\n";
+ ss <<" mode = (int)";
+ ss << vSubArguments[6]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" int nNullDate=GetNullDate();\n";
+ ss <<" int nTotalDays = GetDiffDate(nNullDate,nStartDate,";
+ ss <<"nEndDate, mode,&nDays1stYear);\n";
+ ss <<" tmp = fVal*fRate*convert_double(nTotalDays)";
+ ss <<"/convert_double(nDays1stYear);\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+
+void OpAccrintm::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(IsLeapYearDecl); decls.insert(DaysInMonthDecl);
+ decls.insert(DaysToDateDecl); decls.insert(DateToDaysDecl);
+ decls.insert(GetNullDateDecl); decls.insert(GetDiffDateDecl);
+ funs.insert(IsLeapYear);funs.insert(DaysInMonth);
+ funs.insert(DaysToDate);funs.insert(DateToDays);
+ funs.insert(GetNullDate);funs.insert(GetDiffDate);
+}
+void OpAccrintm::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "double tmp = " << GetBottom() <<";\n\t";
+ ss << "int nStartDate,nEndDate,mode;\n\t";
+ ss << "double fRate,fVal;\n\t";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+
+ FormulaToken *tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+ ss<< "int buffer_nIssue_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_nSettle_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_fRate_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_fVal_len = ";
+ ss<< tmpCurDVR3->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_nMode_len = ";
+ ss<< tmpCurDVR4->GetArrayLength();
+ ss << ";\n\t";
+ ss <<"if(gid0 >= buffer_nIssue_len || isnan(";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<"))\n\t\t";
+ ss <<"nStartDate = 0;\n\telse\n\t\t";
+ ss << "nStartDate=(int)";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n\t";
+ ss <<"if(gid0 >= buffer_nSettle_len || isnan(";
+ ss <<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<"))\n\t\t";
+ ss <<"nEndDate = 0;\n\telse\n\t\t";
+ ss << "nEndDate=(int)";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ";\n\t";
+
+ ss <<"if(gid0 >= buffer_fRate_len || isnan(";
+ ss <<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<"))\n\t\t";
+ ss <<"fRate = 0;\n\telse\n\t\t";
+ ss << "fRate=";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n\t";
+ ss <<"if(gid0 >= buffer_fVal_len || isnan(";
+ ss <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<"))\n\t\t";
+ ss <<"fVal = 0;\n\telse\n\t\t";
+ ss << "fVal=";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss << ";\n\t";
+ ss <<"if(gid0 >= buffer_nMode_len || isnan(";
+ ss <<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<"))\n\t\t";
+ ss <<"mode = 0;\n\telse\n\t\t";
+ ss << "mode = (int)";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss << ";\n\t";
+ ss <<"int nDays1stYear=0;\n\t";
+ ss <<"int nNullDate=GetNullDate();\n\t";
+ ss <<"int nTotalDays = GetDiffDate(nNullDate,nStartDate,";
+ ss <<"nEndDate, mode,&nDays1stYear);\n\t";
+ ss <<"tmp = fVal*fRate*convert_double(nTotalDays)";
+ ss <<"/convert_double(nDays1stYear);\n\t";
+ ss << "return tmp;\n";
+ ss << "}";
+}
+
+ void OpYield::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(getYield_Decl);decls.insert(getPrice_Decl);
+ decls.insert(coupnumDecl);decls.insert(coupdaysncDecl);
+ decls.insert(coupdaybsDecl);decls.insert(coupdaysDecl);
+ decls.insert(lcl_GetcoupnumDecl);decls.insert(lcl_GetcoupdaysDecl);
+ decls.insert(lcl_GetcoupdaybsDecl);decls.insert(getDiffDecl);
+ decls.insert(getDaysInYearRangeDecl);decls.insert(GetDaysInYearDecl);
+ decls.insert(GetDaysInYearsDecl);decls.insert(getDaysInMonthRangeDecl);
+ decls.insert(addMonthsDecl);decls.insert(ScaDateDecl);
+ decls.insert(GetNullDateDecl);decls.insert(DateToDaysDecl);
+ decls.insert(DaysToDateDecl);decls.insert(DaysInMonthDecl);
+ decls.insert(IsLeapYearDecl);
+
+ funs.insert(getYield_);funs.insert(getPrice_);
+ funs.insert(coupnum);funs.insert(coupdaysnc);
+ funs.insert(coupdaybs);funs.insert(coupdays);
+ funs.insert(lcl_Getcoupnum);funs.insert(lcl_Getcoupdays);
+ funs.insert(lcl_Getcoupdaybs);funs.insert(getDiff);
+ funs.insert(getDaysInYearRange);funs.insert(GetDaysInYear);
+ funs.insert(GetDaysInYears);funs.insert(getDaysInMonthRange);
+ funs.insert(addMonths);funs.insert(ScaDate);
+ funs.insert(GetNullDate);funs.insert(DateToDays);
+ funs.insert(DaysToDate);funs.insert(DaysInMonth);
+ funs.insert(IsLeapYear);
+}
+
+void OpYield::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << "double tmp = 0;\n\t";
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "double tmp000;\n\t";
+ ss << "double tmp001;\n\t";
+ ss << "double tmp002;\n\t";
+ ss << "double tmp003;\n\t";
+ ss << "double tmp004;\n\t";
+ ss << "double tmp005;\n\t";
+ ss << "double tmp006;\n\t";
+
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+
+ FormulaToken *tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+
+ FormulaToken *tmpCur5 = vSubArguments[5]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR5= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur5);
+
+ FormulaToken *tmpCur6 = vSubArguments[6]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR6= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur6);
+
+ ss<< "int buffer_tmp000_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp001_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp002_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp003_len = ";
+ ss<< tmpCurDVR3->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp004_len = ";
+ ss<< tmpCurDVR4->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp005_len = ";
+ ss<< tmpCurDVR5->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp006_len = ";
+ ss<< tmpCurDVR6->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp000_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp000 = 0;\n\telse \n\t\t";
+ ss<<"tmp000 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp001_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp001 = 0;\n\telse \n\t\t";
+ ss<<"tmp001 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp002_len || isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp002 = 0;\n\telse \n\t\t";
+ ss<<"tmp002 = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp003_len || isnan(";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp003 = 0;\n\telse \n\t\t";
+ ss<<"tmp003 = ";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp004_len || isnan(";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp004 = 0;\n\telse \n\t\t";
+ ss<<"tmp004 = ";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp005_len || isnan(";
+ ss << vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp005 = 0;\n\telse \n\t\t";
+ ss<<"tmp005 = ";
+ ss << vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp006_len || isnan(";
+ ss << vSubArguments[6]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp006 = 0;\n\telse \n\t\t";
+ ss<<"tmp006 = ";
+ ss << vSubArguments[6]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss << "tmp = getYield_(";
+ ss << "GetNullDate(),tmp000,tmp001,tmp002,tmp003,tmp004,tmp005,tmp006);\n\t ";
+ ss << "return tmp;\n";
+ ss << "}";
+}
+
+void OpSLN::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = 0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double cost;\n";
+ ss << " double salvage;\n";
+ ss << " double life;\n";
+
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur1);
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur2);
+ ss<< " int buffer_cost_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n";
+ ss<< " int buffer_salvage_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n";
+ ss<< " int buffer_life_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n";
+ ss<<" if(gid0>=buffer_cost_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n";
+ ss<<" cost = 0;\n\telse \n";
+ ss<<" cost = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+ ss<<" if(gid0>=buffer_salvage_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<"))\n";
+ ss<<" salvage = 0;\n\telse \n";
+ ss<<" salvage = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+ ss<<" if(gid0>=buffer_life_len || isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<"))\n";
+ ss<<" life = 0;\n\telse \n";
+ ss<<" life = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+ ss << " tmp = (cost-salvage)*pow(life,-1);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+ void OpYieldmat::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetYearFrac_newDecl);decls.insert(GetNullDateDecl);
+ decls.insert(DateToDaysDecl);decls.insert(DaysToDate_newDecl);
+ decls.insert(DaysInMonthDecl);decls.insert(IsLeapYearDecl);
+ decls.insert(GetYieldmatDecl);
+
+ funs.insert(GetYearFrac_new);funs.insert(GetNullDate);
+ funs.insert(DateToDays);funs.insert(DaysToDate_new);
+ funs.insert(DaysInMonth);funs.insert(IsLeapYear);
+ funs.insert(GetYieldmat);
+}
+
+void OpYieldmat::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << "double tmp = 0;\n\t";
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "double tmp000;\n\t";
+ ss << "double tmp001;\n\t";
+ ss << "double tmp002;\n\t";
+ ss << "double tmp003;\n\t";
+ ss << "double tmp004;\n\t";
+ ss << "double tmp005;\n\t";
+
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+
+ FormulaToken *tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+
+ FormulaToken *tmpCur5 = vSubArguments[5]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR5= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur5);
+
+ ss<< "int buffer_tmp000_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp001_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp002_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp003_len = ";
+ ss<< tmpCurDVR3->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp004_len = ";
+ ss<< tmpCurDVR4->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp005_len = ";
+ ss<< tmpCurDVR5->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp000_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp000 = 0;\n\telse \n\t\t";
+ ss<<"tmp000 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp001_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp001 = 0;\n\telse \n\t\t";
+ ss<<"tmp001 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp002_len || isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp002 = 0;\n\telse \n\t\t";
+ ss<<"tmp002 = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp003_len || isnan(";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp003 = 0;\n\telse \n\t\t";
+ ss<<"tmp003 = ";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp004_len || isnan(";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp004 = 0;\n\telse \n\t\t";
+ ss<<"tmp004 = ";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp005_len || isnan(";
+ ss << vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp005 = 0;\n\telse \n\t\t";
+ ss<<"tmp005 = ";
+ ss << vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss << "tmp = GetYieldmat(";
+ ss<<"GetNullDate(),tmp000,tmp001,tmp002,tmp003,tmp004,tmp005);\n\t";
+ ss << "return tmp;\n";
+ ss << "}";
+}
+
+void OpPMT::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss<<") {\n";
+ ss<<" double tmp = 0;\n";
+ ss<<" double temp=0.0;\n";
+ ss<<" int gid0 = get_global_id(0);\n";
+ ss<<" double tmp0=0,tmp1=0,tmp2=0;\n";
+ ss<<" double tmp3=0,tmp4=0;\n";
+ ss <<"\n ";
+ //while (i-- > 1)
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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 <<" temp="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if (isnan(temp))\n";
+ ss <<" tmp"<<i<<"= 0;\n";
+ ss <<" else\n";
+ ss <<" tmp"<<i<<"=temp;\n";
+ ss <<" }\n";
+ }
+ else
+ {
+ ss <<" tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss<<" if(tmp0==0.0)\n";
+ ss<<" return -(tmp2+tmp3)/tmp1;\n";
+ ss<<" tmp-=tmp3;\n";
+ ss<<" tmp=tmp-tmp2*pow(1.0+tmp0,tmp1);\n";
+ ss<<" tmp=tmp*pow(( (1.0+tmp0*tmp4)* ";
+ ss<<"( (pow(1.0+tmp0,tmp1)-1.0)/tmp0)),-1);\n";
+ ss<<" return tmp;\n";
+ ss<<"}";
+}
+
+void OpNPV::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = 0.0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int nCount = 1;\n";
+ ss << " double arg0=";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ //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";
+ }
+ }
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+ void OpPrice::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+ {
+ decls.insert(getPrice_new_Decl);
+ decls.insert(IsLeapYearDecl);decls.insert(DaysInMonthDecl);
+ decls.insert(DaysToDateDecl);
+ decls.insert(DateToDaysDecl);
+ decls.insert(ScaDateDecl);
+ decls.insert(setDayDecl);decls.insert(checklessthanDecl);
+ decls.insert(addMonthsDecl);decls.insert(lcl_Getcoupnum_newDecl);
+ decls.insert(coupnum_newDecl);
+ decls.insert(DateToDays_newDecl);
+ decls.insert(getDaysInMonthRangeDecl);
+ decls.insert(GetDaysInYearsDecl); decls.insert(GetDaysInYearDecl);
+ decls.insert(getDaysInYearRangeDecl); decls.insert(getDiffDecl);
+ decls.insert(coupdaybs_newDecl);
+ decls.insert(lcl_Getcoupdays_newDecl);
+ decls.insert(lcl_Getcoupdaybs_newDecl);
+ decls.insert(coupdays_newDecl);
+ decls.insert(coupdaysnc_newDecl);
+ funs.insert(IsLeapYear);funs.insert(DaysInMonth_new);
+ funs.insert(DaysToDate);funs.insert(DateToDays_new);
+ funs.insert(DateToDays);
+ funs.insert(ScaDate);
+ funs.insert(addMonths);funs.insert(getDaysInMonthRange);
+ funs.insert(GetDaysInYears);funs.insert(GetDaysInYear);
+ funs.insert(getDaysInYearRange);funs.insert(getDiff);
+ funs.insert(setDay);funs.insert(checklessthan);
+ funs.insert(lcl_Getcoupdaybs_new);
+ funs.insert(coupdaybs_new);
+ funs.insert(lcl_Getcoupdays_new);
+ funs.insert(coupdaysnc_new);
+ funs.insert(coupdays_new);
+ funs.insert(setDay);funs.insert(checklessthan);
+ funs.insert(lcl_Getcoupnum_new);
+ funs.insert(coupnum_new);funs.insert(getPrice_new);
+ }
+void OpPrice::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ vSubArguments[i]->GenSlidingWindowDecl(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,tmp5=0;\n";
+ ss<<" double tmp6=0;\n";
+ ss<<"\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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 }\n";
+ }
+ else
+ {
+ ss << " tmp"<<i<<"=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " if(tmp4*tmp5 == 0) return NAN;\n";
+ ss << " tmp = getPrice_(tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpOddlprice::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetOddlpriceDecl);decls.insert(GetDiffDateDecl);
+ decls.insert(GetYearDiffDecl);decls.insert(IsLeapYearDecl);
+ decls.insert(GetNullDateDecl);decls.insert(DateToDaysDecl);
+ decls.insert(DaysToDateDecl);decls.insert(DaysInMonthDecl);
+ decls.insert(GetYearFracDecl);
+ funs.insert(GetOddlprice);funs.insert(GetDiffDate);
+ funs.insert(GetYearDiff);funs.insert(IsLeapYear);
+ funs.insert(GetNullDate);funs.insert(DaysInMonth);
+ funs.insert(DaysToDate);funs.insert(DateToDays);
+ funs.insert(GetYearFrac);
+}
+void OpOddlprice::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ vSubArguments[i]->GenSlidingWindowDecl(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";
+ }
+ }
+ ss <<" int nNullDate = GetNullDate();\n";
+ ss <<" tmp = GetOddlprice(nNullDate,tmp0,tmp1,";
+ ss <<"tmp2,tmp3,tmp4,tmp5,tmp6,tmp7);\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+void OpOddlyield::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetDiffDateDecl);decls.insert(DaysToDateDecl);
+ decls.insert(GetYearDiffDecl);decls.insert(IsLeapYearDecl);
+ decls.insert(GetNullDateDecl);decls.insert(DateToDaysDecl);
+ decls.insert(DaysInMonthDecl);
+ decls.insert(GetYearFracDecl);decls.insert(GetOddlyieldDecl);
+ funs.insert(GetDiffDate);funs.insert(DaysToDate);
+ funs.insert(GetYearDiff);funs.insert(IsLeapYear);
+ funs.insert(GetNullDate);funs.insert(DaysInMonth);
+ funs.insert(DateToDays);
+ funs.insert(GetYearFrac);funs.insert(GetOddlyield);
+}
+void OpOddlyield::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ vSubArguments[i]->GenSlidingWindowDecl(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";
+ }
+ }
+ ss <<" int nNullDate = GetNullDate();\n";
+ ss <<" tmp = GetOddlyield(nNullDate,tmp0,tmp1";
+ ss <<",tmp2,tmp3,tmp4,tmp5,tmp6,tmp7);\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+void OpPriceDisc::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetYearDiffDecl);decls.insert(getDiffDecl);
+ decls.insert(getDaysInYearRangeDecl);decls.insert(GetDaysInYearDecl);
+ decls.insert(GetDaysInYearsDecl);decls.insert(getDaysInMonthRangeDecl);
+ decls.insert(addMonthsDecl);decls.insert(ScaDateDecl);
+ decls.insert(GetNullDateDecl);decls.insert(DateToDaysDecl);
+ decls.insert(DaysToDateDecl);decls.insert(DaysInMonthDecl);
+ decls.insert(IsLeapYearDecl);decls.insert(GetDiffDateDecl);
+ funs.insert(GetYearDiff);funs.insert(getDiff);
+ funs.insert(getDaysInYearRange);funs.insert(GetDaysInYear);
+ funs.insert(GetDaysInYears);funs.insert(getDaysInMonthRange);
+ funs.insert(addMonths);funs.insert(ScaDate);
+ funs.insert(GetNullDate);funs.insert(DateToDays);
+ funs.insert(DaysToDate);funs.insert(DaysInMonth);
+ funs.insert(IsLeapYear);funs.insert(GetDiffDate);
+}
+void OpPriceDisc::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ vSubArguments[i]->GenSlidingWindowDecl(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 <<" \n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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";
+ }
+ }
+ ss <<" int nNullDate = GetNullDate();\n";
+ ss <<" tmp=tmp3* ( 1.0 -tmp2*GetYearDiff( nNullDate, ";
+ ss <<"tmp0,tmp1,tmp4));\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+void OpNper::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+ {
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ vSubArguments[i]->GenSlidingWindowDecl(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";
+
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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";
+ }
+ }
+ ss <<" if (tmp0 == 0.0)\n";
+ ss <<" tmp=(-1*(tmp2 + tmp3)/tmp1);\n";
+ ss <<" else if (tmp4 > 0.0)\n";
+ ss <<" tmp=log(-1*(tmp0*tmp3-tmp1*(1.0+tmp0))*";
+ ss <<"pow((tmp0*tmp2+tmp1*(1.0+tmp0)),-1))/log(1.0+tmp0);\n";
+ ss <<" else\n";
+ ss <<" tmp=log(-1*(tmp0*tmp3-tmp1)*pow(tmp0*tmp2+tmp1,-1))";
+ ss <<"/log(1.0+tmp0);\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+ }
+
+void OpPPMT::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetFVDecl);
+ funs.insert(GetFV);
+}
+
+void OpPPMT::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss<<") {\n";
+ ss<<" double tmp = 0;\n";
+ ss<<" int gid0 = get_global_id(0);\n";
+ ss<<" double arg=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,tmp5=0;\n";
+ ss <<"\n ";
+ //while (i-- > 1)
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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 << " arg=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg))\n";
+ ss << " tmp"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " tmp"<<i<<"=arg;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss<<" tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+ }
+ }
+ ss<<" double pmt=0 ;\n";
+ ss<<" if(tmp0==0.0)\n";
+ ss<<" return -(tmp3+tmp4)/tmp2;\n";
+ ss<<" pmt=pmt-tmp4-tmp3*pow(1.0+tmp0,tmp2);\n";
+ ss<<" pmt=pmt*pow(( (1.0+tmp0*tmp5)* ";
+ ss<<"( (pow(1.0+tmp0,tmp2)-1.0)/tmp0)),-1);\n";
+ ss<<" double temp = pow( 1+tmp0,tmp1-2);\n";
+ ss<<" double re;\n";
+ ss<<" if(tmp1==1.0){\n";
+ ss<<" if(tmp5>0.0)\n";
+ ss<<" re=0.0;\n";
+ ss<<" else\n";
+ ss<<" re=-tmp3;\n";
+ ss<<" }\n";
+ ss<<" else\n";
+ ss<<" {\n";
+ ss<<" if(tmp5>0.0)\n ";
+ ss<<" re=GetFV(tmp0, tmp1-2.0, pmt, tmp3, 1.0) - pmt;\n";
+ ss<<" else\n";
+ ss<<" re=GetFV(tmp0, tmp1-1.0, pmt, tmp3, 0.0);\n";
+ ss<<" }\n ";
+ ss<<" re = re * tmp0;\n";
+ ss<<" tmp = pmt - re;\n";
+ ss<<" return tmp;\n";
+ ss<<"}";
+}
+
+void OpCoupdaybs::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(IsLeapYearDecl); decls.insert(DaysInMonthDecl);
+ decls.insert(DaysToDateDecl); decls.insert(DateToDays_newDecl);
+ decls.insert(GetNullDate_newDecl); decls.insert(ScaDateDecl);
+ decls.insert(addMonthsDecl); decls.insert(getDaysInMonthRangeDecl);
+ decls.insert(GetDaysInYearsDecl);
+ decls.insert(getDaysInYearRangeDecl); decls.insert(getDiffDecl);
+ decls.insert(setDayDecl);decls.insert(checklessthanDecl);
+ decls.insert(lcl_Getcoupdaybs_newDecl);
+ decls.insert(coupdaybs_newDecl);
+ funs.insert(IsLeapYear);funs.insert(DaysInMonth);
+ funs.insert(DaysToDate);funs.insert(DateToDays_new);
+ funs.insert(GetNullDate_new);funs.insert(ScaDate);
+ funs.insert(addMonths);funs.insert(getDaysInMonthRange);
+ funs.insert(GetDaysInYears);
+ funs.insert(getDaysInYearRange);funs.insert(getDiff);
+ funs.insert(setDay);funs.insert(checklessthan);
+ funs.insert(lcl_Getcoupdaybs_new);
+ funs.insert(coupdaybs_new);
+}
+void OpCoupdaybs::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = 0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int nSettle,nMat,nFreq,nBase;\n";
+ FormulaToken* tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ FormulaToken* tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken* tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken* tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(isnan("<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR0->GetArrayLength()<<"))\n";
+ ss <<" nSettle = 0;\n else\n";
+ }
+ ss <<" nSettle=(int)";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss <<" if(isnan("<<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR1->GetArrayLength()<<"))\n";
+ ss <<" nMat = 0;\n else\n";
+ }
+ ss <<" nMat=(int)";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ ss <<" if(isnan("<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR2->GetArrayLength()<<"))\n";
+ ss <<" nFreq = 0;\n else\n";
+ }
+ ss << " nFreq=(int)";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss <<" if(isnan(" <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR3->GetArrayLength()<<"))\n";
+ ss <<" nBase = 0;\n else\n";
+ }
+ ss << " nBase=(int)";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss <<" tmp = coupdaybs_new(nSettle,nMat,nFreq,nBase);\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+
+void OpCoupdays::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(IsLeapYearDecl); decls.insert(DaysInMonthDecl);
+ decls.insert(DaysToDateDecl); decls.insert(DateToDays_newDecl);
+ decls.insert(GetNullDate_newDecl); decls.insert(ScaDateDecl);
+ decls.insert(addMonthsDecl); decls.insert(getDaysInMonthRangeDecl);
+ decls.insert(GetDaysInYearsDecl); decls.insert(GetDaysInYearDecl);
+ decls.insert(getDaysInYearRangeDecl); decls.insert(getDiffDecl);
+ decls.insert(setDayDecl);decls.insert(checklessthanDecl);
+ decls.insert(lcl_Getcoupdays_newDecl);
+ decls.insert(coupdays_newDecl);
+ funs.insert(IsLeapYear);funs.insert(DaysInMonth);
+ funs.insert(DaysToDate);funs.insert(DateToDays_new);
+ funs.insert(GetNullDate_new);funs.insert(ScaDate);
+ funs.insert(addMonths);funs.insert(getDaysInMonthRange);
+ funs.insert(GetDaysInYears);funs.insert(GetDaysInYear);
+ funs.insert(getDaysInYearRange);funs.insert(getDiff);
+ funs.insert(lcl_Getcoupdays_new);
+ funs.insert(setDay);funs.insert(checklessthan);
+ funs.insert(coupdays_new);
+}
+void OpCoupdays::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = 0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int nSettle,nMat,nFreq,nBase;\n";
+ FormulaToken* tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ FormulaToken* tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken* tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken* tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(isnan("<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR0->GetArrayLength()<<"))\n";
+ ss <<" nSettle = 0;\n else\n";
+ }
+ ss <<" nSettle=(int)";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss <<" if(isnan("<<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR1->GetArrayLength()<<"))\n";
+ ss <<" nMat = 0;\n else\n";
+ }
+ ss <<" nMat=(int)";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ ss <<" if(isnan("<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR2->GetArrayLength()<<"))\n";
+ ss <<" nFreq = 0;\n else\n";
+ }
+ ss << " nFreq=(int)";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss <<" if(isnan(" <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR3->GetArrayLength()<<"))\n";
+ ss <<" nBase = 0;\n else\n";
+ }
+ ss << " nBase=(int)";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss <<" tmp = coupdays_new(nSettle,nMat,nFreq,nBase);\n";
+ ss <<" return tmp;\n";
+ ss << "}";
+}
+void OpCouppcd::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(IsLeapYearDecl); decls.insert(DaysInMonthDecl);
+ decls.insert(DaysToDateDecl); decls.insert(DateToDaysDecl);
+ decls.insert(GetNullDateDecl);
+ decls.insert(ScaDateDecl);
+ decls.insert(addMonthsDecl);
+ decls.insert(setDayDecl);decls.insert(checklessthanDecl);
+ decls.insert(lcl_GetCouppcdDecl);
+ funs.insert(IsLeapYear);funs.insert(DaysInMonth);
+ funs.insert(DaysToDate);funs.insert(DateToDays);
+ funs.insert(GetNullDate);
+ funs.insert(ScaDate);
+ funs.insert(addMonths);
+ funs.insert(setDay);funs.insert(checklessthan);
+ funs.insert(lcl_GetCouppcd);
+}
+void OpCouppcd::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = 0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int nSettle,nMat,nFreq,nBase;\n";
+ FormulaToken* tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ FormulaToken* tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken* tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken* tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(isnan("<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR0->GetArrayLength()<<"))\n";
+ ss <<" nSettle = 0;\n else\n";
+ }
+ ss <<" nSettle=(int)";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss <<" if(isnan("<<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR1->GetArrayLength()<<"))\n";
+ ss <<" nMat = 0;\n else\n";
+ }
+ ss <<" nMat=(int)";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ ss <<" if(isnan("<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR2->GetArrayLength()<<"))\n";
+ ss <<" nFreq = 0;\n else\n";
+ }
+ ss << " nFreq=(int)";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss <<" if(isnan(" <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR3->GetArrayLength()<<"))\n";
+ ss <<" nBase = 0;\n else\n";
+ }
+ ss << " nBase=(int)";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss <<" int nNullDate=693594;\n";
+ ss <<" tmp = lcl_GetCouppcd(nNullDate,nSettle,nMat,nFreq,nBase);\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+void OpCoupncd::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(IsLeapYearDecl); decls.insert(DaysInMonthDecl);
+ decls.insert(DaysToDateDecl); decls.insert(DateToDaysDecl);
+ decls.insert(GetNullDateDecl);
+ decls.insert(ScaDateDecl);
+ decls.insert(addMonthsDecl);
+ decls.insert(setDayDecl);decls.insert(checklessthanDecl);
+ decls.insert(lcl_GetCoupncdDecl);
+ funs.insert(IsLeapYear);funs.insert(DaysInMonth);
+ funs.insert(DaysToDate);funs.insert(DateToDays);
+ funs.insert(GetNullDate);
+ funs.insert(ScaDate);
+ funs.insert(addMonths);
+ funs.insert(setDay);funs.insert(checklessthan);
+ funs.insert(lcl_GetCoupncd);
+}
+void OpCoupncd::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = 0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int nSettle,nMat,nFreq,nBase;\n";
+ FormulaToken* tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ FormulaToken* tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken* tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken* tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(isnan("<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR0->GetArrayLength()<<"))\n";
+ ss <<" nSettle = 0;\n else\n";
+ }
+ ss <<" nSettle=(int)";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss <<" if(isnan("<<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR1->GetArrayLength()<<"))\n";
+ ss <<" nMat = 0;\n else\n";
+ }
+ ss <<" nMat=(int)";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ ss <<" if(isnan("<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR2->GetArrayLength()<<"))\n";
+ ss <<" nFreq = 0;\n else\n";
+ }
+ ss << " nFreq=(int)";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss <<" if(isnan(" <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR3->GetArrayLength()<<"))\n";
+ ss <<" nBase = 0;\n else\n";
+ }
+ ss << " nBase=(int)";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss <<" int nNullDate=693594;\n";
+ ss <<" tmp = lcl_GetCoupncd(nNullDate,nSettle,nMat,nFreq,nBase);\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+
+void OpCoupdaysnc::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(IsLeapYearDecl); decls.insert(DaysInMonth_newDecl);
+ decls.insert(DaysToDateDecl); decls.insert(DateToDaysDecl);
+ decls.insert(DateToDays_newDecl);
+ decls.insert(ScaDateDecl);
+ decls.insert(addMonthsDecl); decls.insert(getDaysInMonthRangeDecl);
+ decls.insert(GetDaysInYearsDecl); decls.insert(GetDaysInYearDecl);
+ decls.insert(getDaysInYearRangeDecl); decls.insert(getDiffDecl);
+ decls.insert(setDayDecl);decls.insert(checklessthanDecl);
+ decls.insert(coupdaybs_newDecl);
+ decls.insert(lcl_Getcoupdays_newDecl);
+ decls.insert(lcl_Getcoupdaybs_newDecl);
+ decls.insert(coupdays_newDecl);
+ decls.insert(coupdaysnc_newDecl);
+ funs.insert(IsLeapYear);funs.insert(DaysInMonth_new);
+ funs.insert(DaysToDate);funs.insert(DateToDays_new);
+ funs.insert(DateToDays);
+ funs.insert(ScaDate);
+ funs.insert(addMonths);funs.insert(getDaysInMonthRange);
+ funs.insert(GetDaysInYears);funs.insert(GetDaysInYear);
+ funs.insert(getDaysInYearRange);funs.insert(getDiff);
+ funs.insert(setDay);funs.insert(checklessthan);
+ funs.insert(lcl_Getcoupdaybs_new);
+ funs.insert(coupdaybs_new);
+ funs.insert(lcl_Getcoupdays_new);
+ funs.insert(coupdaysnc_new);
+ funs.insert(coupdays_new);
+}
+void OpCoupdaysnc::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = 0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int nSettle,nMat,nFreq,nBase;\n";
+ FormulaToken* tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ FormulaToken* tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken* tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken* tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(isnan("<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR0->GetArrayLength()<<"))\n";
+ ss <<" nSettle = 0;\n else\n";
+ }
+ ss <<" nSettle=(int)";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss <<" if(isnan("<<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR1->GetArrayLength()<<"))\n";
+ ss <<" nMat = 0;\n else\n";
+ }
+ ss <<" nMat=(int)";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ ss <<" if(isnan("<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR2->GetArrayLength()<<"))\n";
+ ss <<" nFreq = 0;\n else\n";
+ }
+ ss << " nFreq=(int)";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss <<" if(isnan(" <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR3->GetArrayLength()<<"))\n";
+ ss <<" nBase = 0;\n else\n";
+ }
+ ss << " nBase=(int)";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss <<" tmp = coupdaysnc_new(nSettle,nMat,nFreq,nBase);\n";
+ ss <<" return tmp;\n";
+ ss << "}";
+}
+
+void OpCoupnum::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(IsLeapYearDecl);decls.insert(DaysInMonthDecl);
+ decls.insert(DaysToDateDecl);
+ decls.insert(DateToDaysDecl);
+ decls.insert(ScaDateDecl);
+ decls.insert(setDayDecl);decls.insert(checklessthanDecl);
+ decls.insert(addMonthsDecl);decls.insert(lcl_Getcoupnum_newDecl);
+ decls.insert(coupnum_newDecl);
+ funs.insert(IsLeapYear);funs.insert(DaysInMonth_new);
+ funs.insert(DaysToDate);
+ funs.insert(DateToDays);
+ funs.insert(ScaDate);
+ funs.insert(setDay);funs.insert(checklessthan);
+ funs.insert(addMonths);funs.insert(lcl_Getcoupnum_new);
+ funs.insert(coupnum_new);
+}
+void OpCoupnum::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = 0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int nSettle,nMat,nFreq,nBase;\n";
+ FormulaToken* tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ FormulaToken* tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken* tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken* tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(isnan("<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR0->GetArrayLength()<<"))\n";
+ ss <<" nSettle = 0;\n else\n";
+ }
+ ss <<" nSettle=(int)";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss <<" if(isnan("<<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR1->GetArrayLength()<<"))\n";
+ ss <<" nMat = 0;\n else\n";
+ }
+ ss <<" nMat=(int)";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ ss <<" if(isnan("<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR2->GetArrayLength()<<"))\n";
+ ss <<" nFreq = 0;\n else\n";
+ }
+ ss << " nFreq=(int)";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss <<" if(isnan(" <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR3->GetArrayLength()<<"))\n";
+ ss <<" nBase = 0;\n else\n";
+ }
+ ss << " nBase=(int)";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss <<" tmp = coupnum_new(nSettle,nMat,nFreq,nBase);\n";
+ ss <<" return tmp;\n";
+ ss << "}";
+}
+void OpAmordegrc::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(nCorrValDecl); decls.insert(RoundDecl);
+ decls.insert(IsLeapYearDecl);decls.insert(DaysInMonthDecl);
+ decls.insert(DaysToDateDecl); decls.insert(DateToDaysDecl);
+ decls.insert(GetNullDateDecl); decls.insert(GetYearFracDecl);
+ funs.insert(Round);
+ funs.insert(IsLeapYear);funs.insert(DaysInMonth);
+ funs.insert(DaysToDate);funs.insert(DateToDays);
+ funs.insert(GetNullDate);funs.insert(GetYearFrac);
+}
+void OpAmordegrc::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n ";
+ ss << "int gid0 = get_global_id(0);\n";
+ ss << " double tmp = " << GetBottom() <<";\n";
+ ss << " double fCost,fRestVal,fPer,fRate;\n";
+ ss << " int nDate,nFirstPer,nBase;\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ FormulaToken *tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ FormulaToken *tmpCur5 = vSubArguments[5]->GetFormulaToken();
+ FormulaToken *tmpCur6 = vSubArguments.size() < 7 ? nullptr : vSubArguments[6]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(isnan("<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR0->GetArrayLength()<<"))\n";
+ ss <<" fCost = 0;\n else\n";
+ }
+ ss << " fCost=";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss <<" if(isnan("<<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR1->GetArrayLength()<<"))\n";
+ ss <<" nDate = 0;\n else\n";
+ }
+ ss << " nDate=(int)";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ ss <<" if(isnan("<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR2->GetArrayLength()<<"))\n";
+ ss <<" nFirstPer = 0;\n else\n";
+ }
+ ss << " nFirstPer=(int)";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss <<" if(isnan(" <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR3->GetArrayLength()<<"))\n";
+ ss <<" fRestVal = 0;\n else\n";
+ }
+ ss << " fRestVal=";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ if(tmpCur4->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+ ss <<" if(isnan(" <<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR4->GetArrayLength()<<"))\n";
+ ss <<" fPer = 0;\n else\n";
+ }
+ ss << " fPer = ";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur5->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR5= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur5);
+ ss <<" if(isnan(" <<vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR5->GetArrayLength()<<"))\n";
+ ss <<" fRate = 0;\n else\n";
+ }
+ ss << " fRate=";
+ ss << vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ if(tmpCur6 == nullptr)
+ {
+ ss << " nBase = 0;\n";
+ }
+ else
+ {
+ if(tmpCur6->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR6=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur6);
+ ss <<" if(isnan(" <<vSubArguments[6]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR6->GetArrayLength()<<"))\n";
+ ss <<" nBase = 0;\n else\n";
+ }
+ ss << " nBase = (int)";
+ ss << vSubArguments[6]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss <<" uint nPer = convert_int( fPer );\n";
+ ss <<" double fUsePer = 1.0 *pow( fRate,-1);\n";
+ ss <<" double fAmorCoeff;\n";
+ ss <<" if( fUsePer < 3.0 )\n";
+ ss <<" fAmorCoeff = 1.0;\n";
+ ss <<" else if( fUsePer < 5.0 )\n";
+ ss <<" fAmorCoeff = 1.5;\n";
+ ss <<" else if( fUsePer <= 6.0 )\n";
+ ss <<" fAmorCoeff = 2.0;\n";
+ ss <<" else\n";
+ ss <<" fAmorCoeff = 2.5;\n";
+ ss <<" fRate *= fAmorCoeff;\n";
+ ss <<" tmp = Round( GetYearFrac( 693594,";
+ ss <<"nDate, nFirstPer, nBase ) * fRate * fCost);\n";
+ ss <<" fCost = fCost-tmp;\n";
+ ss <<" double fRest = fCost - fRestVal;\n";
+ ss <<" for( uint n = 0 ; n < nPer ; n++ )\n";
+ ss <<" {\n";
+ ss <<" tmp = Round( fRate * fCost);\n";
+ ss <<" fRest -= tmp;\n";
+ ss <<" if( fRest < 0.0 )\n";
+ ss <<" {\n";
+ ss <<" switch( nPer - n )\n";
+ ss <<" {\n";
+ ss <<" case 0:\n";
+ ss <<" case 1:\n";
+ ss <<" tmp = Round( fCost * 0.5);\n";
+ ss <<" default:\n";
+ ss <<" tmp = 0.0;\n";
+ ss <<" }\n";
+ ss <<" }\n";
+ ss <<" fCost -= tmp;\n";
+ ss <<" }\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+void OpAmorlinc::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(nCorrValDecl); decls.insert(RoundDecl);
+ decls.insert(IsLeapYearDecl);decls.insert(DaysInMonthDecl);
+ decls.insert(DaysToDateDecl); decls.insert(DateToDaysDecl);
+ decls.insert(GetYearFracDecl);
+ funs.insert(Round);
+ funs.insert(IsLeapYear);funs.insert(DaysInMonth);
+ funs.insert(DaysToDate);funs.insert(DateToDays);
+ funs.insert(GetYearFrac);
+}
+void OpAmorlinc::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = 0;\n";
+ ss << " double fCost,fRestVal,fPer,fRate;\n";
+ ss << " int nDate,nFirstPer,nBase;\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ FormulaToken *tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ FormulaToken *tmpCur5 = vSubArguments[5]->GetFormulaToken();
+ FormulaToken *tmpCur6 = vSubArguments.size() < 7 ? nullptr : vSubArguments[6]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(isnan("<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR0->GetArrayLength()<<"))\n";
+ ss <<" fCost = 0;\n else\n";
+ }
+ ss << " fCost=";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss <<" if(isnan("<<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR1->GetArrayLength()<<"))\n";
+ ss <<" nDate = 0;\n else\n";
+ }
+ ss << " nDate=(int)";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ ss <<" if(isnan("<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR2->GetArrayLength()<<"))\n";
+ ss <<" nFirstPer = 0;\n else\n";
+ }
+ ss << " nFirstPer=(int)";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss <<" if(isnan(" <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR3->GetArrayLength()<<"))\n";
+ ss <<" fRestVal = 0;\n else\n";
+ }
+ ss << " fRestVal=";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ if(tmpCur4->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+ ss <<" if(isnan(" <<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR4->GetArrayLength()<<"))\n";
+ ss <<" fPer = 0;\n else\n";
+ }
+ ss << " fPer = ";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur5->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR5= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur5);
+ ss <<" if(isnan(" <<vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR5->GetArrayLength()<<"))\n";
+ ss <<" fRate = 0;\n else\n";
+ }
+ ss << " fRate=";
+ ss << vSubArguments[5]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ if(tmpCur6 == nullptr)
+ {
+ ss << " nBase = 0;\n";
+ }
+ else
+ {
+ if(tmpCur6->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR6=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur6);
+ ss <<" if(isnan(" <<vSubArguments[6]->GenSlidingWindowDeclRef();
+ ss <<")||(gid0 >="<<tmpCurDVR6->GetArrayLength()<<"))\n";
+ ss <<" nBase = 0;\n else\n";
+ }
+ ss << " nBase = (int)";
+ ss << vSubArguments[6]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss <<" int nPer = convert_int( fPer );\n";
+ ss <<" double fOneRate = fCost * fRate;\n";
+ ss <<" double fCostDelta = fCost - fRestVal;\n";
+ ss <<" double f0Rate = GetYearFrac( 693594,";
+ ss <<"nDate, nFirstPer, nBase )* fRate * fCost;\n";
+ ss <<" int nNumOfFullPeriods = (int)";
+ ss <<"( ( fCost - fRestVal - f0Rate) *pow(fOneRate,-1) );\n";
+ ss <<" if( nPer == 0 )\n";
+ ss <<" tmp = f0Rate;\n";
+ ss <<" else if( nPer <= nNumOfFullPeriods )\n";
+ ss <<" tmp = fOneRate;\n";
+ ss <<" else if( nPer == nNumOfFullPeriods + 1 )\n";
+ ss <<" tmp = fCostDelta - fOneRate * nNumOfFullPeriods - f0Rate;\n";
+ ss <<" else\n";
+ ss <<" tmp = 0.0;\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+void OpReceived::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetYearDiffDecl);decls.insert(GetDiffDateDecl);
+ decls.insert(DaysToDateDecl);decls.insert(DaysInMonthDecl);
+ decls.insert(GetNullDateDecl);decls.insert(IsLeapYearDecl);
+ decls.insert(DateToDaysDecl);
+ funs.insert(GetDiffDate);funs.insert(DaysToDate);
+ funs.insert(DaysInMonth);funs.insert(GetNullDate);
+ funs.insert(DateToDays);funs.insert(IsLeapYear);
+ funs.insert(GetYearDiff);
+}
+
+void OpReceived::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() <<";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int nSettle, nMat;\n";
+ ss << " double fInvest,fDisc;\n";
+ ss << " int rOB;\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ FormulaToken *tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+ ss<< " int buffer_settle_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n";
+ ss<< " int buffer_mat_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n";
+ ss<< " int buffer_invest_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n";
+ ss<< " int buffer_disc_len = ";
+ ss<< tmpCurDVR3->GetArrayLength();
+ ss << ";\n";
+ ss<< " int buffer_rob_len = ";
+ ss<< tmpCurDVR4->GetArrayLength();
+ ss << ";\n";
+ ss <<" if(gid0 >= buffer_settle_len || isnan(";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nSettle = 0;\n\telse\n";
+ ss <<" nSettle = (int)"<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_mat_len || isnan(";
+ ss <<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nMat = 0;\n\telse\n";
+ ss <<" nMat = (int)";
+ ss <<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_invest_len || isnan(";
+ ss <<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fInvest = 0;\n\telse\n";
+ ss <<" fInvest = "<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_disc_len || isnan(";
+ ss <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fDisc = 0;\n\telse\n";
+ ss <<" fDisc = "<<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_rob_len || isnan(";
+ ss <<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" rOB = 0;\n\telse\n";
+ ss <<" rOB = (int)"<<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss << " double tmpvalue = (1.0-(fDisc";
+ ss <<" * GetYearDiff( GetNullDate()";
+ ss <<",nSettle,nMat,rOB)));\n";
+ ss << " tmp = fInvest*pow(tmpvalue,-1);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+ void OpYielddisc::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetYearFracDecl);decls.insert(GetNullDateDecl);
+ decls.insert(DateToDaysDecl);decls.insert(DaysToDateDecl);
+ decls.insert(DaysInMonthDecl);decls.insert(IsLeapYearDecl);
+
+ funs.insert(GetYearFrac);funs.insert(GetNullDate);
+ funs.insert(DateToDays);funs.insert(DaysToDate);
+ funs.insert(DaysInMonth);funs.insert(IsLeapYear);
+}
+void OpYielddisc::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ CHECK_PARAMETER_COUNT(5,5);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << "double tmp = 0;\n\t";
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "double tmp000;\n\t";
+ ss << "double tmp001;\n\t";
+ ss << "double tmp002;\n\t";
+ ss << "double tmp003;\n\t";
+ ss << "double tmp004;\n\t";
+
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+
+ FormulaToken *tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+
+ ss<< "int buffer_tmp000_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp001_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp002_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp003_len = ";
+ ss<< tmpCurDVR3->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp004_len = ";
+ ss<< tmpCurDVR4->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp000_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp000 = 0;\n\telse \n\t\t";
+ ss<<"tmp000 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp001_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp001 = 0;\n\telse \n\t\t";
+ ss<<"tmp001 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp002_len || isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp002 = 0;\n\telse \n\t\t";
+ ss<<"tmp002 = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp003_len || isnan(";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp003 = 0;\n\telse \n\t\t";
+ ss<<"tmp003 = ";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp004_len || isnan(";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp004 = 0;\n\telse \n\t\t";
+ ss<<"tmp004 = ";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<< "if(tmp002 <= 0 || tmp003 <= 0 || tmp000 >= tmp001 )\n";
+ ss<< " return CreateDoubleError(IllegalArgument);\n";
+ ss<< "tmp = (tmp003/tmp002)-1;\n\t";
+ ss << "tmp /= GetYearFrac( GetNullDate(),tmp000,tmp001,tmp004);\n\t";
+ ss << "return tmp;\n";
+ ss << "}";
+}
+
+ void OpTbillprice::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetYearFracDecl);
+ decls.insert(DateToDaysDecl);decls.insert(DaysToDateDecl);
+ decls.insert(DaysInMonthDecl);decls.insert(IsLeapYearDecl);
+
+ funs.insert(GetYearFrac);
+ funs.insert(DateToDays);funs.insert(DaysToDate);
+ funs.insert(DaysInMonth);funs.insert(IsLeapYear);
+}
+
+void OpTbillprice::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = 0;\n";
+
+ ss << " int singleIndex = gid0;\n";
+ ss << " int doubleIndex = gid0;\n";
+ ss << " int i = gid0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+
+ ss << " tmp1+=1.0;\n";
+ ss << " double fFraction =GetYearFrac(693594,tmp0,tmp1,0);\n";
+ ss << " tmp = 100.0 * ( 1.0 - tmp2 * fFraction );\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+ void RATE::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(nCorrValDecl);
+ decls.insert(SCdEpsilonDecl);decls.insert(RoundDecl);
+ funs.insert(Round);
+}
+
+void RATE::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+
+ FormulaToken* pCur = vSubArguments[5]->GetFormulaToken();
+ assert(pCur);
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ assert(pSVR);
+ ss << ") {\n";
+ ss << " double result;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " bool bValid = true, bFound = false;\n";
+ ss << " double fX, fXnew, fTerm, fTermDerivation;\n";
+ ss << " double fGeoSeries, fGeoSeriesDerivation;\n";
+ ss << " int nIterationsMax = 150;\n";
+ ss << " int nCount = 0;\n";
+ ss << " double fEpsilonSmall = 1.0E-14;\n";
+ ss << " double arg0, arg1, arg2, arg3, arg4, arg5;\n";
+ ss << " arg0=" << vSubArguments[0]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " arg1=" << vSubArguments[1]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " arg2=" << vSubArguments[2]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " arg3=" << vSubArguments[3]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " arg4=" << vSubArguments[4]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " arg5=" << vSubArguments[5]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " int guessLen = " << pSVR->GetArrayLength() << ";\n";
+ ss << " if (isnan(arg0) || isnan(arg1) || isnan(arg2)){\n";
+ ss << " result = 523;\n";
+ ss << " return result;\n";
+ ss << " }\n";
+ ss << " if (isnan(arg3))\n";
+ ss << " arg3 = 0.0;\n";
+ ss << " if (isnan(arg4))\n";
+ ss << " arg4 = 0.0;\n";
+ ss << " if (isnan(arg5))\n";
+ ss << " arg5 = 0.1;\n";
+ ss << " if (gid0 >= guessLen)\n";
+ ss << " arg5 = 0.1;\n";
+ ss << " arg3 = arg3 - arg1 * arg4;\n";
+ ss << " arg2 = arg2 + arg1 * arg4;\n";
+ ss << " if (arg0 == Round(arg0)){\n";
+ ss << " fX = arg5;\n";
+ ss << " double fPowN, fPowNminus1;\n";
+ ss << " while (!bFound && nCount < nIterationsMax)\n";
+ ss << " {\n";
+ ss << " fPowNminus1 = pow( 1.0+fX, arg0-1.0);\n";
+ ss << " fPowN = fPowNminus1 * (1.0+fX);\n";
+ ss << " if (fX == 0.0)\n";
+ ss << " {\n";
+ ss << " fGeoSeries = arg0;\n";
+ ss << " fGeoSeriesDerivation = arg0 * (arg0-1.0)";
+ ss << "*pow(2.0,-1);\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " {";
+ ss << " fGeoSeries = (fPowN-1.0)*pow(fX,-1);\n";
+ ss << " fGeoSeriesDerivation =";
+ ss << " arg0 * fPowNminus1 * pow( fX , -1) - fGeoSeries * pow(fX, -1);\n";
+ ss << " }\n";
+ ss << " fTerm = arg3 + arg2 *fPowN+ arg1 * fGeoSeries;\n";
+ ss << " fTermDerivation = arg2 * arg0 * fPowNminus1 +";
+ ss << "arg1 * fGeoSeriesDerivation;\n";
+ ss << " if (fabs(fTerm) < fEpsilonSmall)\n";
+ ss << " bFound = true;\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " if (fTermDerivation == 0.0)\n";
+ ss << " fXnew = fX + 1.1 * SCdEpsilon;\n";
+ ss << " else\n";
+ ss << " fXnew = fX - fTerm ";
+ ss << "*pow( fTermDerivation,-1);\n";
+ ss << " nCount++;\n";
+ ss << " bFound = (fabs(fXnew - fX) < SCdEpsilon);\n";
+ ss << " fX = fXnew;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " {";
+ ss << " fX = (arg5 < -1.0) ? -1.0 : arg5;\n";
+ ss << " while (bValid && !bFound && nCount < nIterationsMax)\n";
+ ss << " {\n";
+ ss << " if (fX == 0.0){\n";
+ ss << " fGeoSeries = arg0;\n";
+ ss << " fGeoSeriesDerivation = arg0 * ";
+ ss << "(arg0-1.0)* pow(2.0,-1);\n";
+ ss << " }else{\n";
+ ss << " fGeoSeries = (pow( 1.0+fX, arg0) - 1.0)";
+ ss << " *pow( fX,-1);\n";
+ ss << " fGeoSeriesDerivation =";
+ ss << " arg0 * pow(1.0+fX,arg0-1.0) *pow(fX,-1)";
+ ss << " - fGeoSeries *pow( fX,-1);\n";
+ ss << " }\n";
+ ss << " fTerm = arg3 + arg2 *pow(1.0+fX, arg0)";
+ ss << "+ arg1 * fGeoSeries;\n";
+ ss << " fTermDerivation =";
+ ss << "arg2*arg0*pow(1.0+fX,arg0-1.0)";
+ ss << "+arg1*fGeoSeriesDerivation;\n";
+ ss << " if (fabs(fTerm) < fEpsilonSmall)\n";
+ ss << " bFound = true;\n";
+ ss << " else{\n";
+ ss << " if (fTermDerivation == 0.0)\n";
+ ss << " fXnew = fX + 1.1 * SCdEpsilon;\n";
+ ss << " else\n";
+ ss << " fXnew = fX - fTerm ";
+ ss << "*pow( fTermDerivation,-1);\n";
+ ss << " nCount++;\n";
+ ss << " bFound = (fabs(fXnew - fX) < SCdEpsilon);\n";
+ ss << " fX = fXnew;\n";
+ ss << " bValid = (fX >= -1.0);\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (bValid && bFound)\n";
+ ss << " result = fX;\n";
+ ss << " else\n";
+ ss << " result = 523;\n";
+ ss << " return result;\n";
+ ss << "}";
+}
+
+ void OpTbillyield::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetDiffDate360Decl);decls.insert(IsLeapYearDecl);
+ decls.insert(DateToDaysDecl);decls.insert(DaysToDate_LocalBarrierDecl);
+ decls.insert(DaysInMonthDecl);decls.insert(GetNullDateDecl);
+ decls.insert(GetDiffDate360_Decl);
+ funs.insert(GetDiffDate360);funs.insert(DateToDays);
+ funs.insert(DaysToDate_LocalBarrier);funs.insert(IsLeapYear);
+ funs.insert(DaysInMonth);funs.insert(GetNullDate);
+ funs.insert(GetDiffDate360_);
+
+}
+
+void OpTbillyield::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "double tmp = 0;\n\t";
+ ss << "double tmp000;\n\t";
+ ss << "double tmp001;\n\t";
+ ss << "double tmp002;\n\t";
+
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+
+ ss<< "int buffer_tmp000_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp001_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<< "int buffer_tmp002_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp000_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp000 = 0;\n\telse \n\t\t";
+ ss<<"tmp000 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp001_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp001 = 0;\n\telse \n\t\t";
+ ss<<"tmp001 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+
+ ss<<"if(gid0>=buffer_tmp002_len || isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<"))\n\t\t";
+ ss<<"tmp002 = 0;\n\telse \n\t\t";
+ ss<<"tmp002 = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<";\n\t";
+ ss <<" int nDiff=GetDiffDate360(GetNullDate(),tmp000,tmp001,true);\n";
+ ss <<" nDiff++;\n";
+ ss <<" tmp=100.0;\n";
+ ss <<" tmp = tmp *pow( tmp002,-1);\n";
+ ss <<" tmp = tmp - 1.0;\n";
+ ss <<" tmp = tmp * pow( nDiff,-1.0 );\n";
+ ss <<" tmp = tmp * 360.0;\n";
+ ss <<" return tmp;\n";
+ ss << "}\n";
+}
+void OpDDB::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = 0;\n";
+ ss << " double fCost, fSalvage, fLife, fPeriod, fFactor;\n";
+ ss << " double fRate, fOldValue, fNewValue;\n";
+
+ FormulaToken* tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ FormulaToken* tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken* tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken* tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ FormulaToken* tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(gid0 >= "<<tmpCurDVR0->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fCost = 0;\n else\n";
+ }
+ ss <<" fCost = "<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss <<" if(gid0 >= "<<tmpCurDVR1->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fSalvage = 0;\n else\n";
+ }
+ ss <<" fSalvage = ";
+ ss <<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ ss <<" if(gid0 >= "<<tmpCurDVR2->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fLife = 0;\n else\n";
+ }
+ ss <<" fLife = ";
+ ss <<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss <<" if(gid0 >= "<<tmpCurDVR3->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fPeriod = 0;\n else\n";
+ }
+ ss <<" fPeriod = "<<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ if(tmpCur4->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+ ss <<" if(gid0 >= "<<tmpCurDVR4->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fFactor = 0;\n else\n";
+ }
+ ss <<" fFactor = "<<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" fRate = fFactor * pow(fLife,-1);\n";
+ ss <<" if (fRate >= 1.0)\n";
+ ss <<" {\n";
+ ss <<" fRate = 1.0;\n";
+ ss <<" if (fPeriod == 1.0)\n";
+ ss <<" fOldValue = fCost;\n";
+ ss <<" else\n";
+ ss <<" fOldValue = 0.0;\n";
+ ss <<" }\n";
+ ss <<" else\n";
+ ss <<" fOldValue = fCost * pow(1.0 - fRate, fPeriod - 1);\n";
+ ss <<" fNewValue = fCost * pow(1.0 - fRate, fPeriod);\n";
+ ss <<" if (fNewValue < fSalvage)\n";
+ ss <<" tmp = fOldValue - fSalvage;\n";
+ ss <<" else\n";
+ ss <<" tmp = fOldValue - fNewValue;\n";
+ ss <<" if (tmp < 0.0)\n";
+ ss <<" tmp = 0.0;\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+void OpPV::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double result = 0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double rate;\n";
+ ss << " double nper;\n";
+ ss << " double pmt;\n";
+ ss << " double fv;\n";
+ ss << " double type;\n";
+
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+
+ if(vSubArguments.size()>3)
+ {
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVR3= static_cast<const formula::SingleVectorRefToken *>(
+tmpCur3);
+ ss<< " int buffer_fv_len = ";
+ ss<< tmpCurDVR3->GetArrayLength();
+ ss << ";\n";
+ }
+
+ if(vSubArguments.size()>4)
+ {
+ FormulaToken *tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVR4= static_cast<const formula::SingleVectorRefToken *>(
+tmpCur4);
+ ss<< " int buffer_type_len = ";
+ ss<< tmpCurDVR4->GetArrayLength();
+ ss << ";\n";
+ }
+
+ ss<< " int buffer_rate_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n";
+
+ ss<< " int buffer_nper_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n";
+
+ ss<< " int buffer_pmt_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n";
+
+ ss<<" if(gid0>=buffer_rate_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<"))\n";
+ ss<<" rate = 0;\n else \n";
+ ss<<" rate = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+
+ ss<<" if(gid0>=buffer_nper_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<"))\n";
+ ss<<" nper = 0;\n else \n";
+ ss<<" nper = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+
+ ss<<" if(gid0>=buffer_pmt_len || isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<"))\n";
+ ss<<" pmt = 0;\n else \n";
+ ss<<" pmt = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+
+ if(vSubArguments.size()>3)
+ {
+ ss<<" if(gid0>=buffer_fv_len || isnan(";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss<<"))\n";
+ ss<<" fv = 0;\n else \n";
+ ss<<" fv = ";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+ }else
+ {
+ ss<<" fv = 0;\n";
+ }
+
+ if(vSubArguments.size()>4)
+ {
+ ss<<" if(gid0>=buffer_type_len || isnan(";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss<<"))\n";
+ ss<<" type = 0;\n else \n";
+ ss<<" type = ";
+ ss << vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+ }else
+ {
+ ss<<" type = 0;\n";
+ }
+ ss << " if(rate == 0)\n";
+ ss << " result=fv+pmt*nper;\n";
+ ss << " else if(type > 0)\n";
+ ss << " result=(fv*pow(1+rate,-nper))+";
+ ss << "(pmt*(1-pow(1+rate,-nper+1))*pow(rate,-1))+pmt;\n";
+ ss << " else\n";
+ ss << " result=(fv*pow(1+rate,-nper))+";
+ ss << "(pmt*(1-pow(1+rate,-nper))*pow(rate,-1));\n";
+ ss << " return -result;\n";
+ ss << "}";
+}
+ void OpVDB::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(ScGetDDBDecl);decls.insert(DblMinDecl);
+ decls.insert(ScInterVDBDecl);decls.insert(VDBImplementDecl);
+ funs.insert(ScGetDDB);funs.insert(DblMin);
+ funs.insert(ScInterVDB);funs.insert(VDBImplement);
+}
+
+void OpVDB::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+ ss << " double result = 0;\n";
+ if(vSubArguments.size()<5)
+ {
+ ss << " result = -DBL_MAX;\n";
+ ss << " return result;\n";
+ }else
+ {
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+ if(vSubArguments.size() <= 6)
+ {
+ ss << " int tmp6 = 0;\n";
+ }
+ if(vSubArguments.size() == 5)
+ {
+ ss << " double tmp5= 2.0;\n";
+ }
+ ss << " if(tmp3 < 0 || tmp4<tmp3 || tmp4>tmp2 || tmp0<0 ||tmp1>tmp0";
+ ss << "|| tmp5 <=0)\n";
+ ss << " result = -DBL_MAX;\n";
+ ss << " else\n";
+ ss << " result =";
+ ss << "VDBImplement(tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6);\n";
+ ss << " return result;\n";
+ ss << "}";
+ }
+
+}
+
+void OpXirr::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+ pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+ pCurDVR->GetRefRowSize() ;
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int doubleIndex = gid0;\n";
+ ss << " int singleIndex = gid0;\n";
+ ss << " double result = 0;\n";
+ ss << " int i=0;\n";
+ if(vSubArguments.size()<2)
+ {
+ ss << " result = -DBL_MAX;\n";
+ ss << " return result;\n";
+ }else
+ {
+ GenTmpVariables(ss,vSubArguments);
+ if(vSubArguments.size() == 2)
+ {
+ ss << " double tmp2 = 0.1;\n";
+ }else
+ {
+ CheckSubArgumentIsNan(ss,vSubArguments,2);
+ }
+ ss << " if(tmp2<=-1)\n";
+ ss << " result = -DBL_MAX;\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " double fMaxEps = 1e-10;\n";
+ ss << " int nMaxIter = 50;\n";
+ ss << " double fNewRate, fRateEps, fResultValue, fResultValue2;\n";
+ ss << " int nIter = 0;\n";
+ ss << " int bContLoop;\n";
+ ss << " int windowsSize = ";
+ ss << nCurWindowSize;
+ ss << ";\n";
+ CheckSubArgumentIsNan(ss,vSubArguments,0);
+ CheckSubArgumentIsNan(ss,vSubArguments,1);
+ ss << " double D_0 = tmp1;\n";
+ ss << " double V_0 = tmp0;\n";
+ ss << " double fResultRate = tmp2;\n";
+ ss << " double r;\n";
+ ss << " double fResult;\n";
+ ss << " do\n";
+ ss << " {\n";
+ ss << " fResultValue = V_0;\n";
+ ss << " r = fResultRate + 1;\n";
+ ss << " for (i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "gid0+1; i < "<< nCurWindowSize <<"; i++)\n";
+ } else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) {
+ ss << "1; i < gid0+"<< nCurWindowSize <<"; i++)\n";
+ } else {
+ ss << "1; i < "<< nCurWindowSize <<"; i++)\n";
+ }
+ ss << " {\n";
+ if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss<< " doubleIndex =i+gid0;\n";
+ }else
+ {
+ ss<< " doubleIndex =i;\n";
+ }
+ CheckSubArgumentIsNan(ss,vSubArguments,0);
+ CheckSubArgumentIsNan(ss,vSubArguments,1);
+ ss << " fResultValue += tmp0/pow(r,(tmp1 - D_0)/365.0);\n";
+ ss << " }\n";
+ ss << " fResultValue2 = 0;\n";
+
+ ss << " for (i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "gid0+1; i < "<< nCurWindowSize <<"; i++)\n";
+ } else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) {
+ ss << "1; i < gid0+"<< nCurWindowSize <<"; i++)\n";
+ } else {
+ ss << "1; i < "<< nCurWindowSize <<"; i++)\n";
+ }
+ ss << " {\n";
+ if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss<< " doubleIndex =i+gid0;\n";
+ }else
+ {
+ ss<< " doubleIndex =i;\n";
+ }
+ CheckSubArgumentIsNan(ss,vSubArguments,0);
+ CheckSubArgumentIsNan(ss,vSubArguments,1);
+ ss << " double E_i = (tmp1 - D_0)/365.0;\n";
+ ss << " fResultValue2 -= E_i * tmp0 / pow(r,E_i + 1.0);\n";
+ ss << " }\n";
+ ss << " fNewRate = fResultRate - fResultValue / fResultValue2;\n";
+ ss << " fRateEps = fabs( fNewRate - fResultRate );\n";
+ ss << " fResultRate = fNewRate;\n";
+ ss << " bContLoop = (fRateEps > fMaxEps) && (fabs( fResultValue ) > fMaxEps);\n";
+ ss << " }\n";
+ ss << " while( bContLoop && (++nIter < nMaxIter) );\n";
+ ss << " if( bContLoop )\n";
+ ss << " result = -DBL_MAX;\n";
+ ss << " result = fResultRate;\n";
+ ss << " }\n";
+ ss << " return result;\n";
+ ss << "}";
+ }
+
+}
+void OpDB::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fCost, fSalvage, fLife, fPeriod;\n";
+ ss << " int nMonths;\n";
+ ss << " double tmp = 0;\n";
+ FormulaToken* tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ FormulaToken* tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ FormulaToken* tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ FormulaToken* tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ FormulaToken* tmpCur4 = vSubArguments[4]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR4= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur4);
+ ss<< " int buffer_cost_len = ";
+ ss<< tmpCurDVR0->GetArrayLength();
+ ss << ";\n";
+ ss<< " int buffer_salvage_len = ";
+ ss<< tmpCurDVR1->GetArrayLength();
+ ss << ";\n";
+ ss<< " int buffer_life_len = ";
+ ss<< tmpCurDVR2->GetArrayLength();
+ ss << ";\n";
+ ss<< " int buffer_period_len = ";
+ ss<< tmpCurDVR3->GetArrayLength();
+ ss << ";\n";
+ ss<< " int buffer_months_len = ";
+ ss<< tmpCurDVR4->GetArrayLength();
+ ss << ";\n";
+ ss <<" if(gid0 >= buffer_cost_len || isnan(";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fCost = 0;\n else\n";
+ ss <<" fCost = "<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_salvage_len || isnan(";
+ ss <<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fSalvage = 0;\n else\n";
+ ss <<" fSalvage = ";
+ ss <<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_life_len || isnan(";
+ ss <<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fLife = 0;\n else\n";
+ ss <<" fLife = "<<vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_period_len || isnan(";
+ ss <<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" fPeriod = 0;\n else\n";
+ ss <<" fPeriod = "<<vSubArguments[3]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" if(gid0 >= buffer_months_len || isnan(";
+ ss <<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" nMonths = 0;\n else\n";
+ ss <<" nMonths = (int)"<<vSubArguments[4]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss <<" double fDeprRate = 1.0 - pow(fSalvage / fCost, 1.0 / fLife);\n";
+ ss <<" fDeprRate = ((int)(fDeprRate * 1000.0 + 0.5)) / 1000.0;\n";
+ ss <<" double fFirstDeprRate = fCost * fDeprRate * nMonths / 12.0;\n";
+ ss <<" double fDb = 0.0;\n";
+ ss <<" if ((int)(fPeriod) == 1)\n";
+ ss <<" fDb = fFirstDeprRate;\n";
+ ss <<" else\n";
+ ss <<" {\n";
+ ss <<" double fSumDeprRate = fFirstDeprRate;\n";
+ ss <<" double fMin = fLife;\n";
+ ss <<" if (fMin > fPeriod) fMin = fPeriod;\n";
+ ss <<" int nMax = (int)fMin;\n";
+ ss <<" for (int i = 2; i <= nMax; i++)\n";
+ ss <<" {\n";
+ ss <<" fDb = (fCost - fSumDeprRate) * fDeprRate;\n";
+ ss <<" fSumDeprRate += fDb;\n";
+ ss <<" }\n";
+ ss <<" if (fPeriod > fLife)\n";
+ ss <<" fDb = ((fCost - fSumDeprRate)";
+ ss <<"* fDeprRate * (12.0 - nMonths)) / 12.0;\n";
+ ss <<" }\n";
+ ss <<" tmp = fDb;\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_financial.hxx b/sc/source/core/opencl/op_financial.hxx
new file mode 100644
index 000000000..1e9db95d9
--- /dev/null
+++ b/sc/source/core/opencl/op_financial.hxx
@@ -0,0 +1,582 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_CORE_OPENCL_OP_FINANCIAL_HXX
+#define INCLUDED_SC_SOURCE_CORE_OPENCL_OP_FINANCIAL_HXX
+
+#include "opbase.hxx"
+
+namespace sc::opencl {
+
+class RRI: public SlidingFunctionBase
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual bool takeString() const override { return false; }
+ virtual bool takeNumeric() const override { return true; }
+};
+
+class OpRRI:public RRI
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string BinFuncName() const override { return "RRI"; }
+};
+
+class OpNominal: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "NOMINAL_ADD"; }
+};
+
+class OpDollarde:public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Dollarde"; }
+
+};
+
+class OpDollarfr:public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Dollarfr"; }
+
+};
+
+class OpDISC: public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+
+ virtual std::string BinFuncName() const override { return "DISC"; }
+};
+
+class OpINTRATE: public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+
+ virtual std::string BinFuncName() const override { return "INTRATE"; }
+};
+
+class OpFV: public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,
+ std::set<std::string>& ) override;
+
+ virtual std::string BinFuncName() const override {
+ return "FV"; }
+};
+
+class OpIPMT: public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,
+ std::set<std::string>& ) override;
+
+ virtual std::string BinFuncName() const override {
+ return "IPMT"; }
+};
+
+class OpISPMT: public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "ISPMT"; }
+};
+
+class OpPDuration: public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Duration"; }
+};
+
+class OpDuration_ADD: public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,
+ std::set<std::string>& ) override;
+
+ virtual std::string BinFuncName() const override {
+ return "Duration_ADD"; }
+};
+class OpMDuration: public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,
+ std::set<std::string>& ) override;
+
+ virtual std::string BinFuncName() const override {return "MDuration"; }
+};
+
+class Fvschedule: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+};
+
+class Cumipmt: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+
+class IRR: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+};
+
+class OpIRR: public IRR
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string BinFuncName() const override { return "IRR"; }
+};
+
+class XNPV: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+};
+
+class PriceMat: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+class OpSYD: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "SYD"; }
+};
+
+class MIRR: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+};
+
+class OpEffective:public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Effect_Add"; }
+};
+
+class OpCumipmt: public Cumipmt
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string BinFuncName() const override { return "Cumipmt"; }
+};
+
+class OpXNPV: public XNPV
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string BinFuncName() const override { return "XNPV"; }
+
+};
+
+class OpTbilleq: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "fTbilleq"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+
+class OpCumprinc: public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "cumprinc"; }
+};
+
+class OpAccrintm: public Normal
+{
+ public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Accrintm"; }
+};
+class OpAccrint: public Normal
+{
+ public:
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Accrint"; }
+};
+
+class OpYield: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Yield"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+
+class OpSLN: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "SLN"; }
+};
+
+class OpFvschedule: public Fvschedule
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string BinFuncName() const override { return "Fvschedule"; }
+};
+
+class OpYieldmat: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Yieldmat"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+
+class OpPMT: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "PMT"; }
+};
+class OpNPV: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "NPV"; }
+};
+
+class OpPrice: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "Price"; }
+};
+
+class OpNper: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "NPER"; }
+};
+class OpOddlprice: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>&,
+ std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "Oddlprice"; }
+};
+class OpOddlyield: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,
+ std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "Oddlyield"; }
+};
+class OpPriceDisc: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>&,
+ std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "PriceDisc"; }
+};
+class OpPPMT: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "PPMT"; }
+};
+
+class OpCoupdaybs:public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0";}
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "Coupdaybs"; }
+
+};
+
+class OpCoupdays:public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0";}
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "Coupdays";}
+
+};
+
+class OpCoupdaysnc:public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0";}
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "Coupdaysnc"; }
+
+};
+
+class OpCouppcd:public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "Couppcd"; }
+
+};
+
+class OpCoupncd:public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual std::string BinFuncName() const override { return "Coupncd"; }
+
+};
+
+class OpCoupnum:public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0";}
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual std::string BinFuncName() const override { return "Coupnum"; }
+
+};
+class OpDDB:public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "DDB"; }
+};
+class OpDB:public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "DB"; }
+};
+class OpAmordegrc:public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0";}
+ virtual void GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual std::string BinFuncName() const override { return "Amordegrc"; }
+};
+class OpAmorlinc:public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0";}
+ virtual void GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual std::string BinFuncName() const override { return "Amorlinc"; }
+};
+
+class OpReceived:public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Received"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+
+class OpYielddisc: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Yielddisc"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+
+class OpTbillprice: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "fTbillprice"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+
+class OpPriceMat:public PriceMat
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string BinFuncName() const override { return "PriceMat"; }
+};
+
+class RATE: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+class OpIntrate: public RATE {
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string BinFuncName() const override { return "rate"; }
+};
+
+class OpTbillyield: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "fTbillyield"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+
+class OpMIRR: public MIRR
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+ virtual std::string BinFuncName() const override { return "MIRR"; }
+};
+
+class OpPV: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "PV"; }
+};
+
+class OpVDB: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "VDB"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+
+class OpXirr: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Xirr"; }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_logical.cxx b/sc/source/core/opencl/op_logical.cxx
new file mode 100644
index 000000000..2d91b1697
--- /dev/null
+++ b/sc/source/core/opencl/op_logical.cxx
@@ -0,0 +1,360 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "op_logical.hxx"
+
+#include <formula/vectortoken.hxx>
+#include <sstream>
+
+using namespace formula;
+
+namespace sc::opencl {
+void OpAnd::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double t = 1,tmp=0;\n";
+ for(size_t j = 0; j< vSubArguments.size(); j++)
+ {
+ ss << " double tmp"<<j<<" = 1;\n";
+ FormulaToken *tmpCur0 = vSubArguments[j]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*pCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss<< " int buffer_len"<<j<<" = "<<pCurDVR->GetArrayLength();
+ ss<< ";\n";
+ ss <<" if(gid0 >= buffer_len"<<j<<" || isnan(";
+ ss <<vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" tmp = 1;\n else\n";
+ ss <<" tmp = ";
+ ss <<vSubArguments[j]->GenSlidingWindowDeclRef()<<";\n";
+ ss <<" tmp"<<j<<" = tmp"<<j<<" && tmp;\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDouble)
+ {
+ ss <<" tmp = ";
+ ss <<vSubArguments[j]->GenSlidingWindowDeclRef()<<";\n";
+ ss <<" tmp"<<j<<" = tmp"<<j<<" && tmp;\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur0);
+ size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+ pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+ pCurDVR->GetRefRowSize() ;
+ ss << " for(int i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "gid0; i < " << nCurWindowSize << "; i++) {\n";
+ }
+ else if(pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()){
+ ss << "0; i < gid0 + " << nCurWindowSize << "; i++) {\n";
+ }
+ else{
+ ss << "0; i < " << nCurWindowSize << "; i++) {\n";
+ }
+ if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss <<" if(isnan("<<vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss <<")||i+gid0>="<<pCurDVR->GetArrayLength();
+ ss <<")\n";
+ ss <<" tmp = 1;\n else\n";
+ }
+ else
+ {
+ ss <<" if(isnan("<<vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss <<")||i>="<<pCurDVR->GetArrayLength();
+ ss <<")\n";
+ ss <<" tmp = 1;\n else\n";
+ }
+ ss <<" tmp = ";
+ ss <<vSubArguments[j]->GenSlidingWindowDeclRef()<<";\n";
+ ss <<" tmp"<<j<<" = tmp"<<j<<" && tmp;\n";
+ ss <<" }\n";
+ }
+ else
+ {
+ ss <<" tmp"<<j<<" = ";
+ ss <<vSubArguments[j]->GenSlidingWindowDeclRef()<<";\n";
+ }
+ ss <<" t = t && tmp"<<j<<";\n";
+ }
+ ss << " return t;\n";
+ ss << "}\n";
+}
+
+void OpOr::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double t = 0,tmp=0;\n";
+ for(size_t j = 0; j< vSubArguments.size(); j++)
+ {
+ ss << " double tmp"<<j<<" = 0;\n";
+ FormulaToken *tmpCur0 = vSubArguments[j]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*pCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss<< " int buffer_len"<<j<<" = "<<pCurDVR->GetArrayLength();
+ ss<< ";\n";
+ ss <<" if(gid0 >= buffer_len"<<j<<" || isnan(";
+ ss <<vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" tmp = 0;\n else\n";
+ ss <<" tmp = ";
+ ss <<vSubArguments[j]->GenSlidingWindowDeclRef()<<";\n";
+ ss <<" tmp"<<j<<" = tmp"<<j<<" || tmp;\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDouble)
+ {
+ ss <<" tmp = ";
+ ss <<vSubArguments[j]->GenSlidingWindowDeclRef()<<";\n";
+ ss <<" tmp"<<j<<" = tmp"<<j<<" || tmp;\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur0);
+ size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+ pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+ pCurDVR->GetRefRowSize() ;
+ ss << " for(int i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "gid0; i < " << nCurWindowSize << "; i++) {\n";
+ }
+ else if(pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()){
+ ss << "0; i < gid0 + " << nCurWindowSize << "; i++) {\n";
+ }
+ else{
+ ss << "0; i < " << nCurWindowSize << "; i++) {\n";
+ }
+ if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss <<" if(isnan("<<vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss <<")||i+gid0>="<<pCurDVR->GetArrayLength();
+ ss <<")\n";
+ ss <<" tmp = 0;\n else\n";
+ }
+ else
+ {
+ ss <<" if(isnan("<<vSubArguments[j]->GenSlidingWindowDeclRef();
+ ss <<")||i>="<<pCurDVR->GetArrayLength();
+ ss <<")\n";
+ ss <<" tmp = 0;\n else\n";
+ }
+ ss <<" tmp = ";
+ ss <<vSubArguments[j]->GenSlidingWindowDeclRef()<<";\n";
+ ss <<" tmp"<<j<<" = tmp"<<j<<" || tmp;\n";
+ ss <<" }\n";
+ }
+ ss <<" t = t || tmp"<<j<<";\n";
+ }
+ ss << " return t;\n";
+ ss << "}\n";
+}
+void OpNot::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp=0;\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*pCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(gid0 >= "<<pCurDVR->GetArrayLength()<<" || isnan(";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" tmp = 0;\n else\n";
+ ss <<" tmp = ";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef()<<";\n";
+ ss <<" tmp = (tmp == 0.0);\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDouble)
+ {
+ ss <<" tmp = ";
+ ss <<vSubArguments[0]->GenSlidingWindowDeclRef()<<";\n";
+ ss <<" tmp = (tmp == 0.0);\n";
+ }
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+
+void OpXor::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int t = 0,tmp0 = 0;\n";
+ ss << " double tmp = 0;\n";
+ for(DynamicKernelArgumentRef & rArg : vSubArguments)
+ {
+ FormulaToken *tmpCur0 = rArg->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*pCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ ss <<" if(gid0 >= "<<pCurDVR->GetArrayLength()<<" || isnan(";
+ ss <<rArg->GenSlidingWindowDeclRef();
+ ss <<"))\n";
+ ss <<" tmp = 0;\n else\n";
+ ss <<" tmp = ";
+ ss <<rArg->GenSlidingWindowDeclRef()<<";\n";
+ ss <<" tmp0 = (tmp != 0);\n";
+ ss <<" t = t ^tmp0;\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDouble)
+ {
+ ss <<" tmp = ";
+ ss <<rArg->GenSlidingWindowDeclRef()<<";\n";
+ ss <<" tmp0 = (tmp != 0);\n";
+ ss <<" t = t ^tmp0;\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur0);
+ size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+ pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+ pCurDVR->GetRefRowSize() ;
+ ss << " for(int i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "gid0; i < " << nCurWindowSize << "; i++) {\n";
+ }
+ else if(pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()){
+ ss << "0; i < gid0 + " << nCurWindowSize << "; i++) {\n";
+ }
+ else{
+ ss << "0; i < " << nCurWindowSize << "; i++) {\n";
+ }
+ if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss <<" if(isnan("<<rArg->GenSlidingWindowDeclRef();
+ ss <<")||i+gid0>="<<pCurDVR->GetArrayLength();
+ ss <<")\n";
+ ss <<" tmp = 0;\n else\n";
+ }
+ else
+ {
+ ss <<" if(isnan("<<rArg->GenSlidingWindowDeclRef();
+ ss <<")||i>="<<pCurDVR->GetArrayLength();
+ ss <<")\n";
+ ss <<" tmp = 0;\n else\n";
+ }
+ ss <<" tmp = ";
+ ss <<rArg->GenSlidingWindowDeclRef()<<";\n";
+ ss <<" tmp0 = (tmp != 0);\n";
+ ss <<" t = t ^tmp0;\n";
+ ss <<" }\n";
+ }
+ }
+ ss << " return t;\n";
+ ss << "}\n";
+}
+void OpIf::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ if(tmpCur0->GetType() == formula::svDoubleVectorRef)
+ {
+ throw UnhandledToken("unknown operand for ocPush", __FILE__, __LINE__);
+ }
+ if(vSubArguments.size()==3)
+ {
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")|| ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " return ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " else";
+ ss <<" return ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ if(vSubArguments.size()==2)
+ {
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")|| ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " return 0;\n";
+ ss << " else";
+ ss <<" return ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ if(vSubArguments.size()==1)
+ {
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")|| ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " return 0;\n";
+ ss << " else";
+ ss <<" return 1;\n";
+ }
+ ss << "}\n";
+}
+
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_logical.hxx b/sc/source/core/opencl/op_logical.hxx
new file mode 100644
index 000000000..89ce39b72
--- /dev/null
+++ b/sc/source/core/opencl/op_logical.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_CORE_OPENCL_OP_LOGICAL_HXX
+#define INCLUDED_SC_SOURCE_CORE_OPENCL_OP_LOGICAL_HXX
+
+#include "opbase.hxx"
+
+namespace sc::opencl {
+
+class OpAnd: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "And"; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+
+class OpOr: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Or"; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+class OpNot: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Not"; }
+};
+class OpXor: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Xor"; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+class OpIf:public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "IF"; }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_math.cxx b/sc/source/core/opencl/op_math.cxx
new file mode 100644
index 000000000..01658ce98
--- /dev/null
+++ b/sc/source/core/opencl/op_math.cxx
@@ -0,0 +1,3207 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "op_math.hxx"
+
+#include <formula/vectortoken.hxx>
+#include "opinlinefun_math.hxx"
+#include <sstream>
+
+using namespace formula;
+
+namespace sc::opencl {
+
+void OpCos::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0 = 0.0f;\n";
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR=
+ static_cast
+ <const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " { arg0 = 0.0f; }\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0=" << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " return cos(arg0);\n";
+ ss << "}";
+
+}
+void OpSec::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss <<" double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss<<" if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg0 = 0;\n";
+ ss << " return pow(cos(arg0),-1 );\n";
+ ss << "}";
+}
+void OpCosh::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(local_coshDecl);
+ funs.insert(local_cosh);
+}
+void OpSecH::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss <<" double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss<<" if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg0 = 0;\n";
+ ss << " return pow(cosh(arg0),-1 );\n";
+ ss << "}";
+}
+void OpMROUND::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ CHECK_PARAMETER_COUNT(2, 2);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ", ";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss<<") {\n";
+ ss<<" double tmp = 0;\n";
+ ss<<" int gid0 = get_global_id(0);\n";
+ ss<<" double arg0=0;\n";
+ ss<<" double arg1=0;\n";
+ ss <<"\n ";
+ //while (i-- > 1)
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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 << " tmp=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(tmp))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"=tmp;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss<<" arg"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss<<";\n";
+ }
+ }
+ ss<<" if(arg1==0)\n";
+ ss<<" return arg1;\n";
+ ss<<" tmp=arg1 * round(arg0 * pow(arg1,-1));\n";
+ ss<<" return tmp;\n";
+ ss<<"}";
+}
+void OpCosh::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss << " double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss<< " if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg0 = 0;\n";
+ ss << " double tmp=local_cosh(arg0);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpCot::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0 = 0.0f;\n";
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR=
+ static_cast
+ <const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " { arg0 = 0.0f; }\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0=";
+ ss << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " arg0 = arg0 * M_1_PI;\n";
+ ss << " return cospi(arg0) * pow(sinpi(arg0), -1);\n";
+ ss << "}";
+}
+
+void OpCoth::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(local_cothDecl);
+ funs.insert(local_coth);
+}
+
+void OpCoth::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss << " double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss<< " if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg0 = 0;\n";
+ ss << " double tmp=local_coth(arg0);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpCombinA::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(bikDecl);
+ funs.insert(bik);
+}
+
+void OpCombinA::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tem;\n";
+ ss << " double arg0,arg1;\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ ss << " arg"<<i<<" = "<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ if(pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ ss << " if(isnan(arg" << i <<")||(gid0 >= ";
+ ss << pSVR->GetArrayLength();
+ ss << "))\n";
+ ss << " arg" << i << " = 0;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " if(isnan(arg" << i <<"))\n";
+ ss << " arg" << i << " = 0;\n";
+ }
+ }
+ ss << " arg0 = trunc(arg0);\n";
+ ss << " arg1 = trunc(arg1);\n";
+ ss << " if(arg0 >= arg1 && arg0 > 0 && arg1 > 0)\n";
+ ss << " tem = bik(arg0+arg1-1,arg1);\n";
+ ss << " else if(arg0 == 0 && arg1 == 0)\n";
+ ss << " tem = 0;\n";
+ ss << " else if(arg0 > 0 && arg1 == 0)\n";
+ ss << " tem = 1;\n";
+ ss << " else\n";
+ ss << " tem = -1;\n";
+ ss << " double i = tem - trunc(tem);\n";
+ ss << " if(i < 0.5)\n";
+ ss << " tem = trunc(tem);\n";
+ ss << " else\n";
+ ss << " tem = trunc(tem) + 1;\n";
+ ss << " return tem;\n";
+ ss << "}";
+}
+void OpEven::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss << " double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss<< " if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg0 = 0;\n";
+ ss << " double tmp;\n";
+ ss << " tmp = fabs(arg0 / 2);\n";
+ ss << " if ( trunc(tmp) == tmp )\n";
+ ss << " tmp = tmp * 2;\n";
+ ss << " else\n";
+ ss << " tmp = (trunc(tmp) + 1) * 2;\n";
+ ss << " if (arg0 < 0)\n";
+ ss << " tmp = tmp * -1.0;\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpMod::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss << " double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " double arg1 =" << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(arg0)||arg0 == 0)\n";
+ ss << " return 0;\n";
+ ss << " if(isnan(arg1) || arg1 ==0)\n";
+ ss << " return NAN;\n";
+ ss << " double tem;\n";
+ ss << " if(arg0 < 0 && arg1 > 0)\n";
+ ss << " while(arg0 < 0)\n";
+ ss << " arg0 += arg1;\n";
+ ss << " else if (arg0 > 0 && arg1 < 0)\n";
+ ss << " while(arg0 > 0)\n";
+ ss << " arg0 += arg1;\n";
+ ss << " tem = fmod(arg0,arg1);\n";
+ ss << " if(arg1 < 0 && tem > 0)\n";
+ ss << " tem = -tem;\n";
+ ss << " return tem;\n";
+ ss << "}";
+}
+void OpLog::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tem;\n";
+ ss << " double arg0,arg1;\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ ss << " arg"<<i<<" = "<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ if(pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ ss << " if(isnan(arg" << i <<")||(gid0 >= ";
+ ss << pSVR->GetArrayLength();
+ ss << "))\n";
+ if( i == 0)
+ ss << " arg0 = 0;\n";
+ else if ( i == 1)
+ ss << " arg1 = 10;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " if(isnan(arg" << i <<"))\n";
+ if( i == 0)
+ ss << " arg0 = 0;\n";
+ else if ( i == 1)
+ ss << " arg1 = 10;\n";
+ }
+ }
+ if (vSubArguments.size() < 2)
+ ss << " arg1 = 10;\n";
+ ss << " tem = log10(arg0)/log10(arg1);;\n";
+ ss << " return tem;\n";
+ ss << "}";
+}
+void OpCsc::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n\t";
+ ss <<"int gid0=get_global_id(0);\n\t";
+ ss << "double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n\t";
+ ss<< "if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n\t\t";
+ ss<<"arg0 = 0;\n\t";
+ ss << "double tmp=1/sin(arg0);\n\t";
+ ss << "return tmp;\n";
+ ss << "}";
+}
+void OpCountIfs::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+ pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+ pCurDVR->GetRefRowSize() ;
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss << " int tmp =0;\n";
+ ss << " int loop;\n";
+ GenTmpVariables(ss,vSubArguments);
+
+ ss<< " int singleIndex =gid0;\n";
+ int m=0;
+
+ std::stringstream tmpss;
+
+ for(size_t j=0;j<vSubArguments.size();j+=2,m++)
+ {
+ CheckSubArgumentIsNan(tmpss,vSubArguments,j);
+ CheckSubArgumentIsNan(ss,vSubArguments,j+1);
+ tmpss <<" if(isequal(";
+ tmpss <<"tmp";
+ tmpss <<j;
+ tmpss <<" , ";
+ tmpss << "tmp";
+ tmpss << j+1;
+ tmpss << ")){\n";
+ }
+ tmpss << " tmp ++;\n";
+ for(size_t j=0;j<vSubArguments.size();j+=2,m--)
+ {
+ for(int n = 0;n<m+1;n++)
+ {
+ tmpss << " ";
+ }
+ tmpss<< "}\n";
+ }
+ UnrollDoubleVector(ss,tmpss,pCurDVR,nCurWindowSize);
+
+ ss << "return tmp;\n";
+ ss << "}";
+}
+void OpSumIfs::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+ pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+ pCurDVR->GetRefRowSize() ;
+
+ mNeedReductionKernel = vSubArguments[0]->NeedParallelReduction();
+ if (mNeedReductionKernel)
+ {
+ // generate reduction functions
+
+ ss << "__kernel void ";
+ ss << vSubArguments[0]->GetName();
+ ss << "_SumIfs_reduction( ";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ", __global double *result,int arrayLength,int windowSize";
+
+ ss << ")\n{\n";
+ ss << " double tmp =0;\n";
+ ss << " int i ;\n";
+
+ GenTmpVariables(ss,vSubArguments);
+ ss << " double current_result = 0.0;\n";
+ ss << " int writePos = get_group_id(1);\n";
+ if (pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
+ ss << " int offset = 0;\n";
+ else if (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ ss << " int offset = get_group_id(1);\n";
+ else
+ throw Unhandled(__FILE__, __LINE__);
+ // actually unreachable
+ ss << " int lidx = get_local_id(0);\n";
+ ss << " __local double shm_buf[256];\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " int loop = arrayLength/512 + 1;\n";
+ ss << " for (int l=0; l<loop; l++){\n";
+ ss << " tmp = 0.0;\n";
+ ss << " int loopOffset = l*512;\n";
+
+ ss << " int p1 = loopOffset + lidx + offset, p2 = p1 + 256;\n";
+ ss << " if (p2 < min(offset + windowSize, arrayLength)) {\n";
+ ss << " tmp0 = 0.0;\n";
+ int mm=0;
+ std::string p1 = "p1";
+ std::string p2 = "p2";
+ for(size_t j=1;j<vSubArguments.size();j+=2,mm++)
+ {
+ CheckSubArgumentIsNan2(ss,vSubArguments,j,p1);
+ CheckSubArgumentIsNan2(ss,vSubArguments,j+1,p1);
+ ss << "";
+ ss <<" if(isequal(";
+ ss <<"tmp";
+ ss <<j;
+ ss <<" , ";
+ ss << "tmp";
+ ss << j+1;
+ ss << "))";
+ ss << "{\n";
+ }
+ CheckSubArgumentIsNan2(ss,vSubArguments,0,p1);
+ ss << " tmp += tmp0;\n";
+ for(size_t j=1;j<vSubArguments.size();j+=2,mm--)
+ {
+ for(int n = 0;n<mm+1;n++)
+ {
+ ss << " ";
+ }
+ ss<< "}\n\n";
+ }
+ mm=0;
+ for(size_t j=1;j<vSubArguments.size();j+=2,mm++)
+ {
+ CheckSubArgumentIsNan2(ss,vSubArguments,j,p2);
+ CheckSubArgumentIsNan2(ss,vSubArguments,j+1,p2);
+ ss <<" if(isequal(";
+ ss <<"tmp";
+ ss <<j;
+ ss <<" , ";
+ ss << "tmp";
+ ss << j+1;
+ ss << ")){\n";
+ }
+ CheckSubArgumentIsNan2(ss,vSubArguments,0,p2);
+ ss << " tmp += tmp0;\n";
+ for(size_t j=1;j< vSubArguments.size();j+=2,mm--)
+ {
+ for(int n = 0;n<mm+1;n++)
+ {
+ ss << " ";
+ }
+ ss<< "}\n";
+ }
+ ss << " }\n";
+
+ ss << " else if (p1 < min(arrayLength, offset + windowSize)) {\n";
+ mm=0;
+ for(size_t j=1;j<vSubArguments.size();j+=2,mm++)
+ {
+ CheckSubArgumentIsNan2(ss,vSubArguments,j,p1);
+ CheckSubArgumentIsNan2(ss,vSubArguments,j+1,p1);
+
+ ss <<" if(isequal(";
+ ss <<"tmp";
+ ss <<j;
+ ss <<" , ";
+ ss << "tmp";
+ ss << j+1;
+ ss << ")){\n";
+ }
+ CheckSubArgumentIsNan2(ss,vSubArguments,0,p1);
+ ss << " tmp += tmp0;\n";
+ for(size_t j=1;j<vSubArguments.size();j+=2,mm--)
+ {
+ for(int n = 0;n<mm+1;n++)
+ {
+ ss << " ";
+ }
+ ss<< "}\n\n";
+ }
+
+ ss << " }\n";
+ ss << " shm_buf[lidx] = tmp;\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " for (int i = 128; i >0; i/=2) {\n";
+ ss << " if (lidx < i)\n";
+ ss << " shm_buf[lidx] += shm_buf[lidx + i];\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " }\n";
+ ss << " if (lidx == 0)\n";
+ ss << " current_result += shm_buf[0];\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " }\n";
+
+ ss << " if (lidx == 0)\n";
+ ss << " result[writePos] = current_result;\n";
+ ss << "}\n";
+ }// finish generate reduction code
+ // generate functions as usual
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss << " double tmp =0;\n";
+ if (!mNeedReductionKernel)
+ {
+ ss << " int i ;\n";
+ GenTmpVariables(ss,vSubArguments);
+ ss << " for (i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "gid0; i < "<< nCurWindowSize <<"; i++)\n";
+ } else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) {
+ ss << "0; i < gid0+"<< nCurWindowSize <<"; i++)\n";
+ } else {
+ ss << "0; i < "<< nCurWindowSize <<"; i++)\n";
+ }
+ ss << " {\n";
+ if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss<< " int doubleIndex =i+gid0;\n";
+ }else
+ {
+ ss<< " int doubleIndex =i;\n";
+ }
+ ss<< " int singleIndex =gid0;\n";
+ int m=0;
+ for(size_t j=1;j<vSubArguments.size();j+=2,m++)
+ {
+ CheckSubArgumentIsNan(ss,vSubArguments,j);
+ CheckSubArgumentIsNan(ss,vSubArguments,j+1);
+ ss <<" if(isequal(";
+ ss <<"tmp";
+ ss <<j;
+ ss <<" , ";
+ ss << "tmp";
+ ss << j+1;
+ ss << ")){\n";
+ }
+ CheckSubArgumentIsNan(ss,vSubArguments,0);
+ ss << " tmp += tmp0;\n";
+ for(size_t j=1;j<=vSubArguments.size();j+=2,m--)
+ {
+ for(int n = 0;n<m+1;n++)
+ {
+ ss << " ";
+ }
+ ss<< "}\n";
+ }
+ }
+ if (mNeedReductionKernel)
+ {
+ ss << "tmp =";
+ vSubArguments[0]->GenDeclRef(ss);
+ ss << "[gid0];\n";
+ }
+ ss << "return tmp;\n";
+ ss << "}";
+}
+void OpCscH::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n\t";
+ ss <<"int gid0=get_global_id(0);\n\t";
+ ss << "double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n\t";
+ ss<< "if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n\t\t";
+ ss<<"arg0 = 0;\n\t";
+ ss << "double tmp=1/sinh(arg0);\n\t";
+ ss << "return tmp;\n";
+ ss << "}";
+}
+void OpExp::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0 = 0.0f;\n";
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR=
+ static_cast
+ <const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " { arg0 = 0.0f; }\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0=" << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " return pow(M_E, arg0);\n";
+ ss << "}";
+}
+
+void OpAverageIfs::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+ pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+ pCurDVR->GetRefRowSize() ;
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss << " double tmp =0;\n";
+ ss << " int count=0;\n";
+ ss << " int loop;";
+ GenTmpVariables(ss,vSubArguments);
+ ss<< " int singleIndex =gid0;\n";
+ int m=0;
+ std::stringstream tmpss;
+ for(size_t j=1;j<vSubArguments.size();j+=2,m++)
+ {
+ CheckSubArgumentIsNan(tmpss,vSubArguments,j);
+ CheckSubArgumentIsNan(ss,vSubArguments,j+1);
+ tmpss <<" if(isequal(";
+ tmpss <<"tmp";
+ tmpss <<j;
+ tmpss <<" , ";
+ tmpss << "tmp";
+ tmpss << j+1;
+ tmpss << ")){\n";
+ }
+ CheckSubArgumentIsNan(tmpss,vSubArguments,0);
+ tmpss << " tmp += tmp0;\n";
+ tmpss << " count++;\n";
+ for(size_t j=1;j<vSubArguments.size();j+=2,m--)
+ {
+ for(int n = 0;n<m+1;n++)
+ {
+ tmpss << " ";
+ }
+ tmpss<< "}\n";
+ }
+
+ UnrollDoubleVector(ss,tmpss,pCurDVR,nCurWindowSize);
+
+ ss << " if(count!=0)\n";
+ ss << " tmp=tmp/count;\n";
+ ss << " else\n";
+ ss << " tmp= 0 ;\n";
+ ss << "return tmp;\n";
+ ss << "}";
+}
+
+void OpLog10::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n\t";
+ ss <<"int gid0=get_global_id(0);\n\t";
+ ss << "double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n\t";
+ ss<< "if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n\t\t";
+ ss<<"arg0 = 0;\n\t";
+ ss << "double tmp=log10(arg0);\n\t";
+ ss << "return tmp;\n";
+ ss << "}";
+}
+
+void OpSinh::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss <<") {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss <<" double arg0 = " <<
+ vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ ss<< " if(isnan(arg0))\n";
+ ss<<" arg0 = 0;\n";
+ ss << " double tmp=( exp(arg0)-exp(-arg0) )/2;\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpSin::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0 = 0.0f;\n";
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR=
+ static_cast
+ <const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " { arg0 = 0.0f; }\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0=" << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " arg0 = arg0 * M_1_PI;\n";
+ ss << " return sinpi(arg0);\n";
+ ss << "}";
+}
+
+void OpAbs::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " int buffer_len = ";
+ ss << tmpCurDVR0->GetArrayLength();
+ ss << ";\n";
+ ss << " if((gid0)>=buffer_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " tmp = " << GetBottom() << ";\n else \n";
+ ss << " tmp = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " return fabs(tmp);\n";
+ ss << "}";
+}
+void OpArcCos::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(atan2Decl);
+ funs.insert(atan2Content);
+}
+void OpArcCos::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " int buffer_len = "<< tmpCurDVR0->GetArrayLength()<< ";\n";
+ ss << " if((gid0)>=buffer_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef()<< "))\n";
+ ss << " tmp = " << GetBottom() << ";\n";
+ ss << " else \n ";
+ ss << " tmp = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef()<< ";\n";
+ ss << " return arctan2(sqrt(1.0 - pow(tmp, 2)), tmp);\n";
+ ss << "}";
+}
+void OpArcCosHyp::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur0);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " int buffer_len = "<<tmpCurDVR0->GetArrayLength()<<";\n";
+ ss << " if((gid0)>=buffer_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " tmp = " << GetBottom() << ";\n";
+ ss << " else \n ";
+ ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDouble)
+ {
+ ss << " tmp = " << tmpCur0->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+
+ ss << " return log( tmp + pow( (pown(tmp, 2) - 1.0), 0.5));\n";
+ ss << "}";
+}
+void OpTan::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0 = 0.0f;\n";
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR=
+ static_cast
+ <const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " { arg0 = 0.0f; }\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0=" << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " arg0 = arg0 * M_1_PI;\n";
+ ss << " return sinpi(arg0) * pow(cospi(arg0), -1);\n";
+ ss << "}";
+}
+void OpTanH::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0 = "<< vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(arg0)||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " arg0 = 0;\n";
+ ss << " double tmp=tanh(arg0);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpPower::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg[2];\n";
+ for( size_t i=0; i < vSubArguments.size(); ++i)
+ {
+ FormulaToken *tmpCur = vSubArguments[i]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* tmpCurDVR =
+ static_cast<
+ const formula::DoubleVectorRefToken *>(tmpCur);
+ ss << " int i = 0;\n";
+ ss << " arg["<<i<<"] = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(arg["<<i;
+ ss << "])||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " arg["<<i;
+ ss << "] = 0;\n";
+ }
+ else if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* tmpCurDVR=
+ static_cast<
+ const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg["<<i<<"] = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(arg["<<i;
+ ss << "])||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " arg["<<i;
+ ss << "] = 0;\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg["<<i<<"] = ";
+ ss << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " arg["<<i<<"] = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " return pow(arg[0],arg[1]);\n";
+ ss << "}";
+}
+void OpSqrt::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0 = 0.0f;\n";
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR=
+ static_cast
+ <const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " { arg0 = 0; }\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0=";
+ ss << tmpCur->GetDouble() << ";\n";
+ }
+ else
+ {
+ throw Unhandled( __FILE__, __LINE__ );
+ }
+ }
+ else
+ {
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " if( arg0 < 0 )\n";
+ ss << " return CreateDoubleError(IllegalArgument);\n";
+ ss << " return sqrt(arg0);\n";
+ ss << "}";
+}
+void OpArcCot::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " int buffer_len = " << tmpCurDVR0->GetArrayLength()<< ";\n";
+ ss << " if((gid0)>=buffer_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " tmp = " << GetBottom() << ";\n";
+ ss << " else \n ";
+ ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef() <<";\n";
+ ss << " return M_PI_2 - atan(tmp);\n";
+ ss << "}";
+}
+void OpArcCotHyp::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0 = 0.0f;\n";
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR=
+ static_cast
+ <const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " { arg0 = 0.0f; }\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0=";
+ ss << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " return 0.5 * log(1 + 2 * pown(arg0 - 1.0, -1));\n";
+ ss << "}";
+}
+void OpArcSin::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(atan2Decl);
+ funs.insert(atan2Content);
+}
+void OpArcSin::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " int buffer_len = " << tmpCurDVR0->GetArrayLength() << ";\n";
+ ss << " if((gid0)>=buffer_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " tmp = " << GetBottom() << ";\n";
+ ss << " else \n ";
+ ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " return arctan2(tmp, sqrt(1.0 - pow(tmp, 2)));\n";
+ ss << "}";
+}
+void OpArcSinHyp::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur0);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " int buffer_len = "<<tmpCurDVR0->GetArrayLength()<<";\n";
+ ss << " if((gid0)>=buffer_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " tmp = " << GetBottom() << ";\n";
+ ss << " else \n ";
+ ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDouble)
+ {
+ ss << " tmp = " << tmpCur0->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " return log( tmp + pow((pown(tmp, 2) + 1.0), 0.5));\n";
+ ss << "}";
+}
+void OpArcTan2::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(atan2Decl);
+ funs.insert(atan2Content);
+}
+void OpArcTan2::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double x_num = " << GetBottom() << ";\n";
+ ss << " double y_num = " << GetBottom() << ";\n";
+ FormulaToken *iXNum = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVRX=
+ static_cast<const formula::SingleVectorRefToken *>(iXNum);
+ FormulaToken *iYNum = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVRY=
+ static_cast<const formula::SingleVectorRefToken *>(iYNum);
+ ss << " int buffer_x_len = " << tmpCurDVRX->GetArrayLength() << ";\n";
+ ss << " int buffer_y_len = " << tmpCurDVRY->GetArrayLength() << ";\n";
+ ss << " if((gid0)>=buffer_x_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " x_num = " << GetBottom() << ";\n";
+ ss << " else \n ";
+ ss << " x_num = "<< vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if((gid0)>=buffer_y_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " y_num = " << GetBottom() << ";\n";
+ ss << " else \n ";
+ ss << " y_num = "<< vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " return arctan2(y_num, x_num);\n";
+ ss << "}";
+}
+void OpArcTan::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0 = 0.0f;\n";
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR=
+ static_cast
+ <const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " { arg0 = 0.0f; }\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0=" << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " return atan(arg0);\n";
+ ss << "}";
+}
+void OpArcTanH::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0=
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " int buffer_len = " << tmpCurDVR0->GetArrayLength() << ";\n";
+ ss << " if((gid0)>=buffer_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " tmp = " << GetBottom() << ";\n";
+ ss << " else \n ";
+ ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " double a = 1.0 + tmp;\n";
+ ss << " double b = 1.0 - tmp;\n";
+ ss << " return log(pow(a/b, 0.5));\n";
+ ss << "}";
+}
+void OpBitAnd::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double num1 = " << GetBottom() << ";\n";
+ ss << " double num2 = " << GetBottom() << ";\n";
+ FormulaToken *iNum1 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVRNum1=
+ static_cast<const formula::SingleVectorRefToken *>(iNum1);
+ FormulaToken *iNum2 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVRNum2=
+ static_cast<const formula::SingleVectorRefToken *>(iNum2);
+ ss << " int buffer_num1_len = "<<tmpCurDVRNum1->GetArrayLength()<<";\n";
+ ss << " int buffer_num2_len = "<<tmpCurDVRNum2->GetArrayLength()<<";\n";
+ ss << " if((gid0)>=buffer_num1_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num1 = " << GetBottom() << ";\n";
+ ss << " else \n ";
+ ss << " num1 = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if((gid0)>=buffer_num2_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num2 = " << GetBottom() << ";\n";
+ ss << " else \n ";
+ ss << " num2 = " << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " return (long)num1 & (long)num2;\n";
+ ss << "}";
+}
+void OpLn::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+
+ ss << " double tmp=log1p(tmp0-1);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpRound::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ CHECK_PARAMETER_COUNT( 1, 2 );
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+ if(vSubArguments.size() ==2)
+ {
+ ss << " for(int i=0;i<tmp1;i++)\n";
+ ss << " tmp0 = tmp0 * 10;\n";
+ ss << " for(int i=0;i>tmp1;i--)\n";
+ ss << " tmp0 = tmp0 / 10;\n";
+ }
+ ss << " double tmp=round(tmp0);\n";
+ if(vSubArguments.size() ==2)
+ {
+ ss << " for(int i=0;i<tmp1;i++)\n";
+ ss << " tmp = tmp / 10;\n";
+ ss << " for(int i=0;i>tmp1;i--)\n";
+ ss << " tmp = tmp * 10;\n";
+ }
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpRoundUp::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+ ss << " int intTmp;\n";
+ ss << " double doubleTmp;\n";
+ ss << " double tmp;\n";
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+ ss << " if(tmp1 >20 || tmp1 < -20)";
+ ss << " {\n";
+ ss << " tmp = NAN;\n";
+ ss << " }else\n";
+ ss << " {\n";
+ ss << " for(int i=0;i<tmp1;i++)\n";
+ ss << " tmp0 = tmp0 * 10;\n";
+ ss << " intTmp = (int)tmp0;\n";
+ ss << " doubleTmp = intTmp;\n";
+ ss << " if(isequal(doubleTmp,tmp0))\n";
+ ss << " tmp = doubleTmp;\n";
+ ss << " else\n";
+ ss << " tmp = doubleTmp + 1;\n";
+ ss << " for(int i=0;i<tmp1;i++)\n";
+ ss << " tmp = tmp / 10;\n";
+ ss << " }\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpRoundDown::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+ ss << " int intTmp;\n";
+ ss << " double tmp;\n";
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+ ss << " if(tmp1 >20 || tmp1 < -20)";
+ ss << " {\n";
+ ss << " tmp = NAN;\n";
+ ss << " }else\n";
+ ss << " {\n";
+ ss << " for(int i=0;i<tmp1;i++)\n";
+ ss << " tmp0 = tmp0 * 10;\n";
+ ss << " intTmp = (int)tmp0;\n";
+ ss << " tmp = intTmp;\n";
+ ss << " for(int i=0;i<tmp1;i++)\n";
+ ss << " tmp = tmp / 10;\n";
+ ss << " }\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpInt::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+ ss << " int intTmp;\n";
+ ss << " double tmp;\n";
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+ ss << " intTmp = (int)tmp0;\n";
+ ss << " tmp = intTmp;\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpNegSub::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+ ss << " return -tmp0;\n";
+ ss << "}";
+}
+
+void OpRadians::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+ ss << " double tmp;\n";
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+ ss << " tmp = tmp0 * 3.14159265358979 * pow(180.0,-1);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpIsEven::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+ ss << " double tmp;\n";
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+ ss << " tmp = (fmod(floor(fabs(tmp0)), 2.0)<0.5);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpIsOdd::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+ ss << " double tmp;\n";
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+ ss << " tmp = !(fmod(floor(fabs(tmp0)), 2.0)<0.5);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpOdd::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << Math_Intg_Str;
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss << " double tmp=0;\n";
+ ss << " double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss<< " if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg0 = 0;\n";
+ ss << " if (arg0 > 0.0 ){\n";
+ ss << " tmp=Intg(arg0);\n";
+ ss << " if(tmp-trunc(tmp/2)*2 == 0)\n";
+ ss << " tmp=tmp+1;\n";
+ ss << " }else if (arg0 < 0.0 ){\n";
+ ss << " tmp=Intg(arg0);\n";
+ ss << " if(tmp-trunc(tmp/2)*2 == 0)\n";
+ ss << " tmp=tmp-1.0;\n";
+ ss << " }else if (arg0 == 0.0 )\n";
+ ss << " tmp=1.0;\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpCountIf::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (unsigned i = 0; i < 2; i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double vara, varb;\n";
+ ss << " int varc = 0;\n";
+ FormulaToken *tmpCur = vSubArguments[1]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* tmpCurDVR=
+ static_cast<
+ const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " varb = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(varb)||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " varb = 0;\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " varb = ";
+ ss << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " varb = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->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 << " 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 << " vara = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(vara))\n";
+ ss << " continue;\n";
+ ss << " (vara == varb) && varc++;\n";
+ ss << " }\n";
+ }
+ else if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* tmpCurDVR=
+ static_cast<
+ const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " vara = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(vara)||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " return 0;\n";
+ ss << " (vara == varb) && varc++;\n";
+ }
+ }
+ ss << " return varc;\n";
+ ss << "}";
+}
+void OpSumIf::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ int flag = 3 == vSubArguments.size() ? 2 : 0;
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double vara, varb, varc, sum = 0.0f;\n";
+ FormulaToken *tmpCur = vSubArguments[1]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* tmpCurDVR=
+ static_cast<
+ const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " varb = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(varb)||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " varb = 0;\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " varb = ";
+ ss << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " varb = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->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 << " 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 << " vara = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(vara))\n";
+ ss << " continue;\n";
+ ss << " varc = ";
+ ss << vSubArguments[flag]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(varc))\n";
+ ss << " varc = 0.0f;\n";
+ ss << " (vara == varb)&&(sum = sum + varc);\n";
+ ss << " }\n";
+ }
+ else if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* tmpCurDVR=
+ static_cast<
+ const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " vara = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(vara)||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " return 0;\n";
+ ss << " int i = 0;\n";
+ ss << " varc = ";
+ ss << vSubArguments[flag]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(varc)||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " varc = 0.0f;\n";
+
+ ss << " (vara == varb)&&(sum = sum + varc);\n";
+
+ }
+ }
+ ss << " return sum;\n";
+ ss << "}";
+}
+void OpTrunc::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg[2];\n";
+ for( size_t i=0; i < vSubArguments.size(); ++i)
+ {
+ FormulaToken *tmpCur = vSubArguments[i]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* tmpCurDVR =
+ static_cast<
+ const formula::DoubleVectorRefToken *>(tmpCur);
+ ss << " int i = 0;\n";
+ ss << " arg["<<i<<"] = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(arg["<<i;
+ ss << "])||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " arg["<<i;
+ ss << "] = 0;\n";
+ }
+ else if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* tmpCurDVR=
+ static_cast<
+ const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg["<<i<<"] = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(arg["<<i;
+ ss << "])||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " arg["<<i;
+ ss << "] = 0;\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg["<<i<<"] = ";
+ ss << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " arg["<<i<<"] = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " double argm = arg[0];\n";
+ ss << " int n = (int)arg[1];\n";
+ ss << " double nn = 1.0f;\n";
+ ss << " for(int i = 0; i < n; ++i)\n";
+ ss << " {\n";
+ ss << " argm = argm * 10;\n";
+ ss << " nn = nn * 10;\n";
+ ss << " }\n";
+ ss << " modf(argm, &argm);\n";
+ ss << " return argm / nn;\n";
+ ss << "}";
+}
+void OpFloor::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0,arg1,arg2=0.0;\n";
+ ss << " arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " arg1 = " << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ if ( 3 == vSubArguments.size() )
+ {
+ ss << " arg2 = " << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " if(isnan(arg0) || isnan(arg1))\n";
+ ss << " return 0;\n";
+ ss << " if(isnan(arg2))\n";
+ ss << " arg2 = 0.0;\n";
+ ss << " if(arg0*arg1<0)\n";
+ ss << " return NAN;\n";
+ ss << " else if(arg2==0.0&&arg0<0.0)\n";
+ ss << " return (trunc(arg0/arg1)+1)*arg1;\n";
+ ss << " else\n";
+ ss << " return trunc(arg0/arg1)*arg1;\n";
+ ss << "}\n";
+}
+void OpBitOr::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double num1 = " << GetBottom() << ";\n";
+ ss << " double num2 = " << GetBottom() << ";\n";
+ FormulaToken *iNum1 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVRNum1=
+ static_cast<const formula::SingleVectorRefToken *>(iNum1);
+ FormulaToken *iNum2 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVRNum2=
+ static_cast<const formula::SingleVectorRefToken *>(iNum2);
+ ss << " int buffer_num1_len = "<<tmpCurDVRNum1->GetArrayLength()<<";\n";
+ ss << " int buffer_num2_len = "<<tmpCurDVRNum2->GetArrayLength()<<";\n";
+ ss << " if((gid0)>=buffer_num1_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num1 = " << GetBottom() << ";\n";
+ ss << " else \n ";
+ ss << " num1 = floor(" << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ");\n";
+ ss << " if((gid0)>=buffer_num2_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num2 = " << GetBottom() << ";\n";
+ ss << " else\n ";
+ ss << " num2 = floor(" << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ");\n";
+ ss << " return (long)num1 | (long)num2;\n";
+ ss << "}";
+}
+void OpBitXor::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double num1 = " << GetBottom() << ";\n";
+ ss << " double num2 = " << GetBottom() << ";\n";
+ FormulaToken *iNum1 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVRNum1=
+ static_cast<const formula::SingleVectorRefToken *>(iNum1);
+ FormulaToken *iNum2 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVRNum2=
+ static_cast<const formula::SingleVectorRefToken *>(iNum2);
+ ss << " int buffer_num1_len = " << tmpCurDVRNum1->GetArrayLength() << ";\n";
+ ss << " int buffer_num2_len = " << tmpCurDVRNum2->GetArrayLength() << ";\n";
+
+ ss << " if((gid0)>=buffer_num1_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num1 = " << GetBottom() << ";\n";
+ ss << " else\n ";
+ ss << " num1 = floor(" << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ");\n";
+ ss << " if((gid0)>=buffer_num2_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num2 = " << GetBottom() << ";\n";
+ ss << " else\n ";
+ ss << " num2 = floor(" << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ");\n";
+ ss << " return (long)num1 ^ (long)num2;\n";
+ ss << "}";
+}
+void OpBitLshift::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double num = " << GetBottom() << ";\n";
+ ss << " double shift_amount = " << GetBottom() << ";\n";
+ FormulaToken *iNum = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVRNum=
+ static_cast<const formula::SingleVectorRefToken*>(iNum);
+ FormulaToken *iShiftAmount = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVRShiftAmount=
+ static_cast<const formula::SingleVectorRefToken*>(iShiftAmount);
+ ss << " int buffer_num_len = "<< tmpCurDVRNum->GetArrayLength()<<";\n";
+ ss << " int buffer_shift_amount_len = ";
+ ss << tmpCurDVRShiftAmount->GetArrayLength() << ";\n";
+ ss << " if((gid0)>=buffer_num_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num = " << GetBottom() << ";\n";
+ ss << " else\n ";
+ ss << " num = floor(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ");\n";
+ ss << " if((gid0)>=buffer_shift_amount_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " shift_amount = " << GetBottom() << ";\n";
+ ss << " else\n ";
+ ss << " shift_amount = floor(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ");\n";
+ ss << " return floor(shift_amount >= 0 ? ";
+ ss << "num * pow(2.0, shift_amount) : ";
+ ss << "num / pow(2.0, fabs(shift_amount)));\n";
+ ss << "}";
+}
+void OpBitRshift::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double num = " << GetBottom() << ";\n";
+ ss << " double shift_amount = " << GetBottom() << ";\n";
+ FormulaToken *iNum = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVRNum=
+ static_cast<const formula::SingleVectorRefToken*>(iNum);
+ FormulaToken *iShiftAmount = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken* tmpCurDVRShiftAmount=
+ static_cast<const formula::SingleVectorRefToken*>(iShiftAmount);
+ ss << " int buffer_num_len = ";
+ ss << tmpCurDVRNum->GetArrayLength() << ";\n";
+ ss << " int buffer_shift_amount_len = ";
+ ss << tmpCurDVRShiftAmount->GetArrayLength() << ";\n";
+
+ ss << " if((gid0)>=buffer_num_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num = " << GetBottom() << ";\n";
+ ss << " else\n ";
+ ss << " num = floor(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ");\n";
+ ss << " if((gid0)>=buffer_shift_amount_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " shift_amount = " <<GetBottom()<< ";\n";
+ ss << " else\n ";
+ ss << " shift_amount = floor(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ");\n";
+ ss << " return floor(";
+ ss << "shift_amount >= 0 ? num / pow(2.0, shift_amount) : ";
+ ss << "num * pow(2.0, fabs(shift_amount)));\n";
+ ss << "}";
+}
+void OpSumSQ::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); ++i)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ 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";
+ }
+ }
+ ss << " return sum;\n";
+ ss << "}";
+}
+void OpSqrtPi::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0 = 0.0f;\n";
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR=
+ static_cast
+ <const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " { arg0 = 0.0f; }\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0=";
+ ss << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " return (double)sqrt(arg0 *";
+ ss << " 3.1415926535897932);\n";
+ ss << "}";
+}
+void OpCeil::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double num = " << GetBottom() << ";\n";
+ ss << " double significance = " << GetBottom() << ";\n";
+ ss << " double bAbs = 0;\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num = " << GetBottom() << ";\n";
+ ss << " else\n ";
+ ss << " num = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " return 0.0;\n";
+ ss << " else\n ";
+ ss << " significance = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ if (vSubArguments.size() > 2)
+ {
+ FormulaToken *bAbs = vSubArguments[2]->GetFormulaToken();
+ if(bAbs->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* tmpCurSVRIsAbs=
+ static_cast<const formula::SingleVectorRefToken*>(bAbs);
+ ss<< " if((gid0)>=" << tmpCurSVRIsAbs->GetArrayLength() << " ||";
+ }
+ if(bAbs->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* tmpCurDVRIsAbs=
+ static_cast<const formula::DoubleVectorRefToken*>(bAbs);
+ ss<< " if((gid0)>=" << tmpCurDVRIsAbs->GetArrayLength() << " ||";
+ }
+ if(bAbs->GetType() == formula::svDouble)
+ {
+ ss<< " if(";
+ }
+ ss << "isnan(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " bAbs = 0;\n";
+ ss << " else\n ";
+ ss << " bAbs = "<<vSubArguments[2]->GenSlidingWindowDeclRef()<<";\n";
+ }
+ ss << " if(significance == 0.0)\n";
+ ss << " return 0.0;\n";
+ ss << " return ";
+ ss << "( !(int)bAbs && num < 0.0 ? floor( num / significance ) : ";
+ ss << "ceil( num / significance ) )";
+ ss << "*significance;\n";
+ ss << "}";
+}
+void OpCombin::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double num = " << GetBottom() << ";\n";
+ ss << " double num_chosen = " << GetBottom() << ";\n";
+ ss << " double result = -1.0;\n";
+ FormulaToken *iNum = vSubArguments[0]->GetFormulaToken();
+ FormulaToken *iNumChosen = vSubArguments[1]->GetFormulaToken();
+
+ assert(iNum);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(iNum->GetType() == formula::svSingleVectorRef &&
+ iNumChosen->GetType() == formula::svSingleVectorRef)
+ {
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num = " << GetBottom() << ";\n";
+ ss << " else\n ";
+ ss << " num = floor(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ");\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num_chosen = " << GetBottom() << ";\n";
+ ss << " else\n ";
+ ss << " num_chosen = floor(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ");\n";
+ }
+ else if(iNum->GetType() == formula::svDouble &&
+ iNumChosen->GetType() == formula::svDouble)
+ {
+ ss << " num = floor(" << iNum->GetDouble() << ");\n";
+ ss << " num_chosen = floor("<< iNumChosen->GetDouble()<< ");\n";
+ }
+ }
+ else
+ {
+ ss << " num = floor(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ");\n";
+ ss << " num_chosen = floor(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ");\n";
+ }
+ ss << " result = select(result, 0.0, (ulong)(num < num_chosen));\n";
+ ss << " result = select(result, 1.0, (ulong)(num_chosen == 0.0));\n";
+ ss << " if(result == 0 || result ==1)\n";
+ ss << " return result;\n";
+ ss << " double4 db4num;\n";
+ ss << " double4 db4num_chosen;\n";
+ ss << " double4 db4result;\n";
+ ss << " double2 db2result;\n";
+ ss << " result = 1.0;\n";
+ ss << " int loop = num_chosen/4;\n";
+ ss << " for(int i=0; i<loop; i++)\n";
+ ss << " {\n";
+ ss << " db4num = (double4){num,\n";
+ ss << " num-1.0,\n";
+ ss << " num-2.0,\n";
+ ss << " num-3.0};\n";
+ ss << " db4num_chosen = (double4){num_chosen,\n";
+ ss << " num_chosen-1.0,\n";
+ ss << " num_chosen-2.0,\n";
+ ss << " num_chosen-3.0};\n";
+ ss << " db4result = db4num * pown(db4num_chosen, -1);\n";
+ ss << " db2result = db4result.xy * db4result.zw;\n";
+ ss << " result *= db2result.x * db2result.y;\n";
+ ss << " num = num - 4.0;\n";
+ ss << " num_chosen = num_chosen - 4.0;\n";
+ ss << " }\n";
+ ss << " while ( num_chosen > 0){\n";
+ ss << " result *= num / num_chosen;\n";
+ ss << " num = num - 1.0;\n";
+ ss << " num_chosen = num_chosen - 1.0;\n";
+ ss << " }\n";
+ ss << " return result;\n";
+ ss << "}\n";
+}
+void OpConvert::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ // The CONVERT function converts a value from one unit of
+ // measurement to another. It takes the units of measurements to
+ // convert between as string arguments. This implementation
+ // handles just a very small subset of such conversions.
+
+ int arg1=vSubArguments[1]->GetFormulaToken()->GetString().
+ getString().toAsciiUpperCase().hashCode();
+ int arg2=vSubArguments[2]->GetFormulaToken()->GetString().
+ getString().toAsciiUpperCase().hashCode();
+
+ // Check if the from and to units are those combinations that the
+ // code below supports.
+ if( !((arg1==5584&&arg2==108)||
+ (arg1==108&&arg2==5584)||
+ (arg1==5665&&arg2==268206)||
+ (arg1==268206&&arg2==5665)) )
+ throw Unhandled(__FILE__, __LINE__);
+
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss << " double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " double arg1 = " << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " double arg2 = " << vSubArguments[2]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss<< " if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg0 = 0;\n";
+ ss<< " if(isnan(arg1)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg1 = 0;\n";
+ ss<< " if(isnan(arg2)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg2 = 0;\n";
+ ss<<" if(arg1==5584U&&arg2==108U)\n";
+ ss<<" return arg0*1000.0;\n";
+ ss<<" else if(arg1==108U&&arg2==3385U)\n";
+ ss<<" return arg0/1000.0;\n";
+ ss<<" else if(arg1==5665U&&arg2==268206U)\n";
+ ss<<" return arg0*60.0;\n";
+ ss<<" else if(arg1==268206U&&arg2==5665U)\n";
+ ss<<" return arg0/60.0;\n";
+ ss<<" else\n";
+ ss<<" return -9999999999;\n";
+ ss << "}\n";
+
+}
+
+void OpProduct::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"( ";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(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";
+ }
+ }
+ ss << " if(count == 0)\n";
+ ss << " return 0;\n";
+ ss << " return product;\n";
+ ss << "}";
+}
+void OpAverageIf::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp =0;\n";
+ ss << " double count=0;\n";
+ ss << " int singleIndex =gid0;\n";
+ ss << " int doubleIndex;\n";
+ ss << " int i ;\n";
+ ss << " int j ;\n";
+ GenTmpVariables(ss,vSubArguments);
+
+ unsigned paraOneIsDoubleVector = 0;
+ unsigned paraOneWidth = 1;
+ unsigned paraTwoWidth = 1;
+ unsigned loopTimes = 0;
+
+ if(vSubArguments[0]->GetFormulaToken()->GetType() == formula::svDoubleVectorRef)
+ {
+ paraOneIsDoubleVector = 1;
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR0= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur0);
+ paraOneWidth = pCurDVR0->GetArrays().size();
+ loopTimes = paraOneWidth;
+ if(paraOneWidth > 1)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ }
+
+ if(vSubArguments[paraOneWidth]->GetFormulaToken()->GetType() ==
+ formula::svDoubleVectorRef)
+
+ {
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR1= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur1);
+ paraTwoWidth = pCurDVR1->GetArrays().size();
+ if(paraTwoWidth > 1)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ ss << " i = ";
+ if (!pCurDVR1->IsStartFixed() && pCurDVR1->IsEndFixed()) {
+ ss << "gid0;\n";
+ } else {
+ ss << "0;\n";
+ }
+ if(!pCurDVR1->IsStartFixed() && !pCurDVR1->IsEndFixed())
+ {
+ ss << " doubleIndex =i+gid0;\n";
+ }else
+ {
+ ss << " doubleIndex =i;\n";
+ }
+ }
+
+ CheckSubArgumentIsNan(ss,vSubArguments,paraOneWidth);
+
+ unsigned paraThreeIndex = paraOneWidth + paraTwoWidth;
+ if(vSubArguments.size() > paraThreeIndex)
+ {
+ if(vSubArguments[paraThreeIndex]->GetFormulaToken()->GetType() ==
+ formula::svDoubleVectorRef)
+ {
+ FormulaToken *tmpCur2 =
+ vSubArguments[paraThreeIndex]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR2= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur2);
+ unsigned paraThreeWidth = pCurDVR2->GetArrays().size();
+ if(paraThreeWidth > 1)
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ }
+ }
+
+ if(paraOneIsDoubleVector)
+ {
+ unsigned loopIndex = 0;
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR0= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur0);
+ size_t nCurWindowSize = pCurDVR0->GetArrayLength() <
+ pCurDVR0->GetRefRowSize() ? pCurDVR0->GetArrayLength():
+ pCurDVR0->GetRefRowSize() ;
+
+ for(loopIndex =0; loopIndex < loopTimes; loopIndex++)
+ {
+ ss << " for (i = ";
+ if (!pCurDVR0->IsStartFixed() && pCurDVR0->IsEndFixed()) {
+ ss << "gid0; i < "<< nCurWindowSize <<"; i++)\n";
+ } else if (pCurDVR0->IsStartFixed() && !pCurDVR0->IsEndFixed()) {
+ ss << "0; i < gid0+"<< nCurWindowSize <<"; i++)\n";
+ } else {
+ ss << "0; i < "<< nCurWindowSize <<"; i++)\n";
+ }
+ ss << " {\n";
+ if(!pCurDVR0->IsStartFixed() && !pCurDVR0->IsEndFixed())
+ {
+ ss << " doubleIndex =i+gid0;\n";
+ }else
+ {
+ ss << " doubleIndex =i;\n";
+ }
+
+ CheckSubArgumentIsNan(ss,vSubArguments, loopIndex);
+
+ ss << " if ( isequal( tmp";
+ ss << loopIndex<<" , tmp"<<paraOneWidth<<") ) \n";
+ ss << " {\n";
+ if(vSubArguments.size() == paraThreeIndex)
+ ss << " tmp += tmp"<<loopIndex<<";\n";
+ else
+ {
+ CheckSubArgumentIsNan(ss,vSubArguments,
+ paraThreeIndex+loopIndex);
+ ss << " tmp += tmp";
+ ss << paraThreeIndex+loopIndex<<";\n";
+ }
+ ss << " count+=1.0;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ }
+ else
+ {
+ CheckSubArgumentIsNan(ss,vSubArguments, 0);
+ ss << " if ( isequal( tmp0 , tmp1 ) ) \n";
+ ss << " {\n";
+ if(vSubArguments.size() == 2)
+ ss << " tmp += tmp0;\n";
+ else
+ {
+ CheckSubArgumentIsNan(ss,vSubArguments,2);
+ ss << " tmp += tmp2;\n";
+ }
+ ss << " count+=1.0;\n";
+ ss << " }\n";
+ }
+
+ ss << " if(count!=0)\n";
+ ss << " tmp=tmp/count;\n";
+ ss << " else\n";
+ ss << " tmp= 0 ;\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpDeg::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0 = 0.0f;\n";
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR=
+ static_cast
+ <const formula::SingleVectorRefToken *>(tmpCur);
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ")||(gid0>=";
+ ss << tmpCurDVR->GetArrayLength();
+ ss << "))\n";
+ ss << " { arg0 = 0.0f; }\n";
+ }
+ else if(tmpCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0=";
+ ss << tmpCur->GetDouble() << ";\n";
+ }
+ }
+ else
+ {
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ ss << " return arg0 * pown(M_PI, -1) * 180;;\n";
+ ss << "}";
+}
+
+void OpFact::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() << ";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double arg0 = " << GetBottom() << ";\n";
+ FormulaToken* pCur = vSubArguments[0]->GetFormulaToken();
+ assert(pCur);
+ 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[0]->GetFormulaToken()->GetOpCode())
+ {
+ ss << " if (isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg0 = 0;\n";
+ ss << " else\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " arg0 = floor(arg0);\n";
+ ss << " if (arg0 < 0.0)\n";
+ ss << " return 0.0;\n";
+ ss << " else if (arg0 == 0.0)\n";
+ ss << " return 1.0;\n";
+ ss << " else if (arg0 <= 170.0)\n";
+ ss << " {\n";
+ ss << " double fTemp = arg0;\n";
+ ss << " while (fTemp > 2.0)\n";
+ ss << " {\n";
+ ss << " fTemp = fTemp - 1;\n";
+ ss << " arg0 = arg0 * fTemp;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " return -DBL_MAX;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ ss << " return arg0;\n";
+ ss << "}";
+}
+void OpQuotient::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i) ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double num1 = 1.0;\n";
+ ss << " double num2 = 1.0;\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num1 = 1.0;\n";
+ ss << " else \n ";
+ ss << " num1 = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " num2 = 1.0;\n";
+ ss << " else \n ";
+ ss << " num2 = " << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " return trunc(num1/num2);\n";
+ ss << "}";
+}
+void OpSeriesSum::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ CHECK_PARAMETER_COUNT(4,4);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ 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__);
+ }
+ ss << " return res;\n";
+ ss << "}";
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_math.hxx b/sc/source/core/opencl/op_math.hxx
new file mode 100644
index 000000000..175703d12
--- /dev/null
+++ b/sc/source/core/opencl/op_math.hxx
@@ -0,0 +1,502 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_CORE_OPENCL_OP_MATH_HXX
+#define INCLUDED_SC_SOURCE_CORE_OPENCL_OP_MATH_HXX
+
+#include "opbase.hxx"
+
+namespace sc::opencl {
+
+class OpCos: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Cos"; }
+};
+class OpSec: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Sec"; }
+};
+class OpSecH: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "SecH"; }
+};
+class OpMROUND: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "MROUND"; }
+};
+
+class OpCsc: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Csc"; }
+};
+class OpSumIfs final : public CheckVariables
+{
+public:
+ OpSumIfs(): CheckVariables(), mNeedReductionKernel(false) {}
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "SumIfs"; }
+ bool NeedReductionKernel() const { return mNeedReductionKernel; }
+private:
+ bool mNeedReductionKernel;
+};
+class OpCosh: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "Cosh"; }
+};
+class OpSinh: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Sinh"; }
+};
+class OpSin: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Sin"; }
+};
+class OpAbs:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScAbs"; }
+};
+class OpArcCos:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScACos"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+};
+class OpArcCosHyp:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "1.0"; }
+ virtual std::string BinFuncName() const override { return "ScACosH"; }
+};
+class OpTan: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Tan"; }
+};
+class OpTanH: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "TanH"; }
+};
+class OpSqrt: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Sqrt"; }
+};
+class OpArcCot:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScACot"; }
+};
+class OpArcCotHyp:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "2.0"; }
+ virtual std::string BinFuncName() const override { return "ScACotH"; }
+};
+class OpArcSin:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScASin"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+};
+class OpArcSinHyp:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScASinH"; }
+};
+class OpTrunc: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Trunc"; }
+};
+class OpArcTan2:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScATan2"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+};
+class OpArcTan:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScATan"; }
+};
+class OpArcTanH:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScATanH"; }
+};
+class OpBitAnd:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScBitAnd"; }
+};
+class OpBitOr:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScBitOr"; }
+};
+class OpBitXor:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScBitXor"; }
+};
+class OpBitLshift:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScBitLshift"; }
+};
+class OpBitRshift:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScBitRshift"; }
+};
+class OpLn: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Ln"; }
+};
+class OpRound: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Round"; }
+};
+class OpRoundUp: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "RoundUp"; }
+};
+class OpRoundDown: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "RoundDown"; }
+};
+class OpInt: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Int"; }
+};
+class OpRadians: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Radians"; }
+};
+class OpIsEven: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "IsEven"; }
+};
+class OpIsOdd: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "IsOdd"; }
+};
+class OpCot: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Cot"; }
+};
+class OpSumSQ: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "SumSQ"; }
+};
+class OpCoth: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,
+ std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "Coth"; }
+};
+class OpPower: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Power"; }
+};
+class OpOdd: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Odd"; }
+};
+class OpFloor: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Floor"; }
+};
+class OpCscH: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "CscH"; }
+};
+class OpCeil:public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScCeil"; }
+};
+class OpExp: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Exp"; }
+};
+class OpLog10: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Log10"; }
+};
+class OpConvert: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Convert"; }
+ virtual bool takeString() const override { return true; }
+
+};
+class OpEven: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Even"; }
+};
+class OpAverageIfs: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "AverageIfs"; }
+};
+class OpCountIfs: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "CountIfs"; }
+};
+class OpMod: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Mod"; }
+};
+class OpProduct: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Product"; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+class OpSqrtPi: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "SqrtPi"; }
+};
+
+class OpCombinA: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Combina"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+class OpLog: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "Log"; }
+};
+class OpCombin: public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "ScCombin"; }
+};
+class OpAverageIf: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+
+ virtual std::string BinFuncName() const override { return "AverageIf"; }
+};
+class OpDeg: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Degrees"; }
+};
+class OpCountIf: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Countif"; }
+};
+class OpFact: public Normal{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments) override;
+ virtual std::string GetBottom() override { return "0.0"; }
+ virtual std::string BinFuncName() const override { return "Fact"; }
+};
+class OpSeriesSum: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "SeriesSum"; }
+};
+class OpSumIf: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "SumIf"; }
+};
+class OpQuotient: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Quotient"; }
+};
+class OpNegSub: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "NegSub"; }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_spreadsheet.cxx b/sc/source/core/opencl/op_spreadsheet.cxx
new file mode 100644
index 000000000..48789d582
--- /dev/null
+++ b/sc/source/core/opencl/op_spreadsheet.cxx
@@ -0,0 +1,286 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "op_spreadsheet.hxx"
+
+#include <rtl/math.hxx>
+#include <formula/vectortoken.hxx>
+
+#include <algorithm>
+#include <sstream>
+
+using namespace formula;
+
+namespace sc::opencl {
+
+void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp = CreateDoubleError(NOTAVAILABLE);\n";
+ ss << " double intermediate = DBL_MAX;\n";
+ ss << " int singleIndex = gid0;\n";
+ ss << " int rowNum = -1;\n";
+
+ GenTmpVariables(ss,vSubArguments);
+ int arg=0;
+ CheckSubArgumentIsNan(ss,vSubArguments,arg++);
+ int secondParaWidth = 1;
+
+ // tdf#99512 - for now only allow non-dynamic indices (the
+ // common-case) to validate consistent return types vs. the input.
+ int index = 0;
+ int indexArg = vSubArguments.size() - 2;
+ if (vSubArguments[indexArg]->GetFormulaToken()->GetType() == formula::svDouble)
+ {
+ const formula::FormulaDoubleToken *dblToken = static_cast<const FormulaDoubleToken *>(vSubArguments[indexArg]->GetFormulaToken());
+ index = ::rtl::math::approxFloor(dblToken->GetDouble());
+ }
+
+ if (vSubArguments[1]->GetFormulaToken()->GetType() != formula::svDoubleVectorRef)
+ throw Unhandled(__FILE__, __LINE__); // unusual vlookup.
+
+ FormulaToken *tmpCur = vSubArguments[1]->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR = static_cast<const formula::DoubleVectorRefToken *>(tmpCur);
+ const std::vector<VectorRefArray> items = pCurDVR->GetArrays();
+
+ secondParaWidth = items.size();
+
+ if (index < 1 || index > secondParaWidth)
+ throw Unhandled(__FILE__, __LINE__); // oob index.
+
+ if (items[index - 1].mpStringArray)
+ {
+ rtl_uString **pStrings = items[index - 1].mpStringArray;
+ for (size_t i = 0; i < pCurDVR->GetArrayLength(); ++i)
+ {
+ if (pStrings[i] != nullptr)
+ { // TODO: the GroupTokenConverter should do better.
+ throw Unhandled(__FILE__, __LINE__); // mixed arguments.
+ }
+ }
+ }
+
+
+ arg += secondParaWidth;
+ CheckSubArgumentIsNan(ss,vSubArguments,arg++);
+
+ if (vSubArguments.size() == static_cast<unsigned int>(3+(secondParaWidth-1)))
+ {
+ ss << " double tmp";
+ ss << 3+(secondParaWidth-1);
+ ss << "= 1;\n";
+ }
+ else
+ {
+ CheckSubArgumentIsNan(ss,vSubArguments,arg++);
+ }
+
+ if (vSubArguments[1]->GetFormulaToken()->GetType() == formula::svDoubleVectorRef)
+ {
+ tmpCur = vSubArguments[1]->GetFormulaToken();
+ pCurDVR = static_cast<const formula::DoubleVectorRefToken *>(tmpCur);
+ size_t nCurWindowSize = std::min(pCurDVR->GetArrayLength(), pCurDVR->GetRefRowSize());
+ int unrollSize = 8;
+ ss << " int loop;\n";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
+ {
+ ss << " loop = ("<<nCurWindowSize<<" - gid0)/";
+ ss << unrollSize<<";\n";
+
+ }
+ else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << " loop = ("<<nCurWindowSize<<" + gid0)/";
+ ss << unrollSize<<";\n";
+
+ }
+ else
+ {
+ ss << " loop = "<<nCurWindowSize<<"/"<< unrollSize<<";\n";
+ }
+
+ for (int i = 0; i < secondParaWidth; i++)
+ {
+ ss << " for ( int j = 0;j< loop; j++)\n";
+ ss << " {\n";
+ ss << " int i = ";
+ if (!pCurDVR->IsStartFixed()&& pCurDVR->IsEndFixed())
+ {
+ ss << "gid0 + j * "<< unrollSize <<";\n";
+ }
+ else
+ {
+ ss << "j * "<< unrollSize <<";\n";
+ }
+ if (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << " int doubleIndex = i+gid0;\n";
+ }
+ else
+ {
+ ss << " int doubleIndex = i;\n";
+ }
+ ss << " if(tmp";
+ ss << 3+(secondParaWidth-1);
+ ss << " == 1)\n";
+ ss << " {\n";
+
+ for (int j = 0;j < unrollSize; j++)
+ {
+ CheckSubArgumentIsNan(ss,vSubArguments,1+i);
+
+ ss << " if((tmp0 - tmp";
+ ss << 1+i;
+ ss << ")>=0 && intermediate > ( tmp0 -tmp";
+ ss << 1+i;
+ ss << "))\n";
+ ss << " {\n";
+ ss << " rowNum = doubleIndex;\n";
+ ss << " intermediate = tmp0 - tmp";
+ ss << 1+i;
+ ss << ";\n";
+ ss << " }\n";
+ ss << " i++;\n";
+ ss << " doubleIndex++;\n";
+ }
+
+ ss << " }else\n";
+ ss << " {\n";
+ for (int j = 0; j < unrollSize; j++)
+ {
+ CheckSubArgumentIsNan(ss,vSubArguments,1+i);
+
+ ss << " if(tmp0 == tmp";
+ ss << 1+i;
+ ss << " && rowNum == -1)\n";
+ ss << " {\n";
+ ss << " rowNum = doubleIndex;\n";
+ ss << " }\n";
+ ss << " i++;\n";
+ ss << " doubleIndex++;\n";
+ }
+ ss << " }\n\n";
+
+ ss << " }\n";
+ ss << " if(rowNum!=-1)\n";
+ ss << " {\n";
+ for (int j = 0; j < secondParaWidth; j++)
+ {
+ ss << " if(tmp";
+ ss << 2+(secondParaWidth-1);
+ ss << " == ";
+ ss << j+1;
+ ss << ")\n";
+ ss << " tmp = ";
+ vSubArguments[1+j]->GenDeclRef(ss);
+ ss << "[rowNum];\n";
+ }
+ ss << " return tmp;\n";
+ ss << " }\n";
+ ss << " for (int i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
+ {
+ ss << "gid0 + loop *"<<unrollSize<<"; i < ";
+ ss << nCurWindowSize <<"; i++)\n";
+ }
+ else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << "0 + loop *"<<unrollSize<<"; i < gid0+";
+ ss << nCurWindowSize <<"; i++)\n";
+ }
+ else
+ {
+ ss << "0 + loop *"<<unrollSize<<"; i < ";
+ ss << nCurWindowSize <<"; i++)\n";
+ }
+ ss << " {\n";
+ if (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << " int doubleIndex = i+gid0;\n";
+ }
+ else
+ {
+ ss << " int doubleIndex = i;\n";
+ }
+ CheckSubArgumentIsNan(ss,vSubArguments,1+i);
+ ss << " if(tmp";
+ ss << 3+(secondParaWidth-1);
+ ss << " == 1)\n";
+ ss << " {\n";
+ ss << " if((tmp0 - tmp";
+ ss << 1+i;
+ ss << ")>=0 && intermediate > ( tmp0 -tmp";
+ ss << 1+i;
+ ss << "))\n";
+ ss << " {\n";
+ ss << " rowNum = doubleIndex;\n";
+ ss << " intermediate = tmp0 - tmp";
+ ss << 1+i;
+ ss << ";\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " if(tmp0 == tmp";
+ ss << 1+i;
+ ss << " && rowNum == -1)\n";
+ ss << " {\n";
+ ss << " rowNum = doubleIndex;\n";
+ ss << " }\n";
+ ss << " }\n";
+
+ ss << " }\n\n";
+ ss << " if(rowNum!=-1)\n";
+ ss << " {\n";
+
+ for (int j = 0; j < secondParaWidth; j++)
+ {
+ ss << " if(tmp";
+ ss << 2+(secondParaWidth-1);
+ ss << " == ";
+ ss << j+1;
+ ss << ")\n";
+ ss << " tmp = ";
+ vSubArguments[1+j]->GenDeclRef(ss);
+ ss << "[rowNum];\n";
+ }
+ ss << " return tmp;\n";
+ ss << " }\n";
+
+ }
+ }
+ else
+ {
+ CheckSubArgumentIsNan(ss,vSubArguments,1);
+ ss << " if(tmp3 == 1)\n";
+ ss << " {\n";
+ ss << " tmp = tmp1;\n";
+ ss << " }else\n";
+ ss << " {\n";
+ ss << " if(tmp0 == tmp1)\n";
+ ss << " tmp = tmp1;\n";
+ ss << " }\n";
+ }
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_spreadsheet.hxx b/sc/source/core/opencl/op_spreadsheet.hxx
new file mode 100644
index 000000000..f057512c2
--- /dev/null
+++ b/sc/source/core/opencl/op_spreadsheet.hxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_CORE_OPENCL_OP_SPREADSHEET_HXX
+#define INCLUDED_SC_SOURCE_CORE_OPENCL_OP_SPREADSHEET_HXX
+
+#include "opbase.hxx"
+
+namespace sc::opencl {
+
+class OpVLookup: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "VLookup"; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_statistical.cxx b/sc/source/core/opencl/op_statistical.cxx
new file mode 100644
index 000000000..94415b39e
--- /dev/null
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -0,0 +1,9830 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "op_statistical.hxx"
+
+#include <formula/vectortoken.hxx>
+#include <sstream>
+#include "opinlinefun_statistical.cxx"
+
+using namespace formula;
+
+namespace sc::opencl {
+void OpVar::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum = 0.0;\n";
+ ss << " double fMean = 0.0;\n";
+ ss << " double vSum = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double arg = 0.0;\n";
+ unsigned i = vSubArguments.size();
+ while (i--)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ 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 * pow(fCount,-1.0);\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 << " if (!isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " {\n";
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\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 CreateDoubleError(DivisionByZero);\n";
+ ss << " else\n";
+ ss << " return vSum * pow(fCount - 1.0,-1.0);\n";
+ ss << "}\n";
+}
+void OpZTest::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(phiDecl);
+ funs.insert(phi);
+ decls.insert(taylorDecl);
+ funs.insert(taylor);
+ decls.insert(gaussDecl);
+ funs.insert(gauss);
+}
+void OpZTest::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum = 0.0;\n";
+ ss << " double 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 *pow(fCount,-1.0);\n";
+ ss << " sigma = (fSumSqr-fSum*fSum*";
+ ss << "pow(fCount,-1.0))*pow(fCount-1.0,-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 ;
+ }
+ 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 * pow(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* 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";
+ }
+}
+
+void OpTTest::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fMachEpsDecl);
+ funs.insert("");
+ decls.insert(fMaxGammaArgumentDecl);
+ funs.insert("");
+ decls.insert(lcl_getLanczosSumDecl);
+ funs.insert(lcl_getLanczosSum);
+ decls.insert(GetBetaDecl);
+ funs.insert(GetBeta);
+ decls.insert(GetLogBetaDecl);
+ funs.insert(GetLogBeta);
+ decls.insert(GetBetaDistPDFDecl);
+ funs.insert(GetBetaDistPDF);
+ decls.insert(lcl_GetBetaHelperContFracDecl);
+ funs.insert(lcl_GetBetaHelperContFrac);
+ decls.insert(GetBetaDistDecl);
+ funs.insert(GetBetaDist);
+ decls.insert(GetTDistDecl);
+ funs.insert(GetTDist);
+}
+
+void OpTTest::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum1 = 0.0;\n";
+ ss << " double fSum2 = 0.0;\n";
+ ss << " double fSumSqr1 = 0.0;\n";
+ ss << " double fSumSqr2 = 0.0;\n";
+ ss << " double fCount1 = 0.0;\n";
+ ss << " double fCount2 = 0.0;\n";
+ ss << " double arg1 = 0.0;\n";
+ ss << " double arg2 = 0.0;\n";
+ ss << " double mode = 0.0;\n";
+ ss << " double type = 0.0;\n";
+ ss << " double fT = 0.0;\n";
+ ss << " double fF = 0.0;\n";
+ if(vSubArguments.size() != 4)
+ {
+ ss << " return DBL_MAX;\n";
+ ss << "}\n";
+ return ;
+ }
+ if(vSubArguments.size() == 4)
+ {
+ FormulaToken *pCur = vSubArguments[0]->GetFormulaToken();
+ FormulaToken *pCur1 = vSubArguments[1]->GetFormulaToken();
+ FormulaToken *pCur2 = vSubArguments[2]->GetFormulaToken();
+ FormulaToken *pCur3 = vSubArguments[3]->GetFormulaToken();
+ assert(pCur);
+ assert(pCur1);
+ assert(pCur2);
+ assert(pCur3);
+ if(ocPush == vSubArguments[2]->GetFormulaToken()->GetOpCode())
+ {
+ if(pCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken*>(pCur2);
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " mode = " ;
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(mode))\n";
+ ss << " mode = 0.0;\n";
+ ss << " else\n";
+ ss << " mode = floor(mode);\n";
+ ss << " }\n";
+ }
+ else if(pCur2->GetType() == formula::svDouble)
+ {
+ ss << " mode = floor(convert_double(";
+ ss << pCur2->GetDouble() << "));\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n";
+ ss << "}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " mode = floor(" ;
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ");\n";
+ }
+ ss << " if(!(mode == 1.0 || mode == 2.0))\n";
+ ss << " return DBL_MAX;\n";
+ if(ocPush==vSubArguments[3]->GetFormulaToken()->GetOpCode())
+ {
+ if(pCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken*>(pCur3);
+ assert(pSVR);
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " if (isnan(";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " type=0.0;\n";
+ ss << " else\n";
+ ss << " type=floor(";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef() << ");\n";
+ ss << " }\n";
+ }
+ else if(pCur3->GetType() == formula::svDouble)
+ {
+ ss << " type = floor(convert_double(" << pCur3->GetDouble() <<
+ "));\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n";
+ ss << "}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " type=floor(";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef() << ");\n";
+ }
+ ss << " if(!(type == 1.0||type == 2.0||type == 3.0))\n";
+ ss << " return DBL_MAX;\n";
+
+ if(pCur->GetType() == formula::svDoubleVectorRef &&
+ pCur1->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur);
+ const formula::DoubleVectorRefToken* pDVR1 =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur1);
+
+ size_t nCurWindowSize = pDVR->GetRefRowSize();
+ size_t nCurWindowSize1 = pDVR1->GetRefRowSize();
+
+ if(nCurWindowSize == nCurWindowSize1)
+ {
+ ss << " if(type == 1.0)\n";
+ ss << " {\n";
+ ss << " for (int i = ";
+ if ((!pDVR->IsStartFixed() && pDVR->IsEndFixed()) &&
+ (!pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+ {
+ ss << "gid0; i < " << pDVR->GetArrayLength();
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((pDVR->IsStartFixed() && !pDVR->IsEndFixed()) &&
+ (pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i < " << pDVR->GetArrayLength();
+ ss << " && i < gid0+"<< nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((!pDVR->IsStartFixed() && !pDVR->IsEndFixed()) &&
+ (!pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i + gid0 < " << pDVR->GetArrayLength();
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((pDVR->IsStartFixed() && pDVR->IsEndFixed()) &&
+ (pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+ {
+ ss << "0; i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else
+ {
+ ss << "0; i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ ss << " break;\n";
+ ss << " }";
+ ss << " return DBL_MAX;\n";
+ ss << " }\n";
+ ss << "}\n";
+ return ;
+ }
+
+ ss << " arg1 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef(true) << ";\n";
+ ss << " arg2 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef(true) << ";\n";
+ ss << " if (isnan(arg1)||isnan(arg2))\n";
+ ss << " continue;\n";
+ ss << " fSum1 += arg1;\n";
+ ss << " fSum2 += arg2;\n";
+ ss << " fSumSqr1 += (arg1 - arg2)*(arg1 - arg2);\n";
+ ss << " fCount1 += 1;\n";
+ ss << " }\n";
+ ss << " if(fCount1 < 1.0)\n";
+ ss << " return DBL_MAX;\n";
+ ss << " fT = sqrt(fCount1-1.0) * fabs(fSum1 - fSum2)\n";
+ ss << " /sqrt(fCount1 * fSumSqr1 - (fSum1-fSum2)\n";
+ ss << " *(fSum1-fSum2));\n";
+ ss << " fF = fCount1 - 1.0;\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n";
+ ss << "}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n";
+ ss << "}\n";
+ return ;
+ }
+ ss << " }\n";
+ ss << " if(type == 2.0 || type == 3.0)\n";
+ ss << " {\n";
+
+ if(pCur->GetType() == formula::svDoubleVectorRef &&
+ pCur1->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur);
+ const formula::DoubleVectorRefToken* pDVR1 =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur1);
+
+ size_t nCurWindowSize = pDVR->GetRefRowSize();
+ size_t nCurWindowSize1 = pDVR1->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 << " arg1 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef(true) << ";\n";
+ ss << " if (isnan(arg1))\n";
+ ss << " continue;\n";
+ ss << " fSum1 += arg1;\n";
+ ss << " fSumSqr1 += arg1 * arg1;\n";
+ ss << " fCount1 += 1;\n";
+ ss << " }\n";
+
+ ss << " for (int i = ";
+ if (!pDVR1->IsStartFixed() && pDVR1->IsEndFixed())
+ {
+ ss << "gid0; i < " << pDVR1->GetArrayLength();
+ ss << " && i < " << nCurWindowSize1 << "; i++)\n";
+ ss << " {\n";
+ }
+ else if (pDVR1->IsStartFixed() && !pDVR1->IsEndFixed())
+ {
+ ss << "0; i < " << pDVR1->GetArrayLength();
+ ss << " && i < gid0+"<< nCurWindowSize1 << "; i++)\n";
+ ss << " {\n";
+ }
+ else if (!pDVR1->IsStartFixed() && !pDVR1->IsEndFixed())
+ {
+ ss << "0; i + gid0 < " << pDVR1->GetArrayLength();
+ ss << " && i < " << nCurWindowSize1 << "; i++)\n";
+ ss << " {\n";
+ }
+ else
+ {
+ ss << "0; i < " << nCurWindowSize1 << "; i++)\n";
+ ss << " {\n";
+ }
+ ss << " arg2 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef(true) << ";\n";
+ ss << " if (isnan(arg2))\n";
+ ss << " continue;\n";
+ ss << " fSum2 += arg2;\n";
+ ss << " fSumSqr2 += arg2 * arg2;\n";
+ ss << " fCount2 += 1;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n";
+ ss << " }\n";
+ ss << "}\n";
+ return ;
+ }
+ ss << " if (fCount1 < 2.0 || fCount2 < 2.0)\n";
+ ss << " return DBL_MAX;\n";
+ ss << " }\n";
+ ss << " if(type == 3.0)\n";
+ ss << " {\n";
+ ss << " double fS1 = (fSumSqr1-fSum1*fSum1/fCount1)\n";
+ ss << " /(fCount1-1.0)/fCount1;\n";
+ ss << " double fS2 = (fSumSqr2-fSum2*fSum2/fCount2)\n";
+ ss << " /(fCount2-1.0)/fCount2;\n";
+ ss << " if (fS1 + fS2 == 0.0)\n";
+ ss << " return DBL_MAX;\n";
+ ss << " fT = fabs(fSum1/fCount1 - fSum2/fCount2)\n";
+ ss << " /sqrt(fS1+fS2);\n";
+ ss << " double c = fS1/(fS1+fS2);\n";
+ ss << " fF = 1.0/(c*c/(fCount1-1.0)+(1.0-c)*(1.0-c)\n";
+ ss << " /(fCount2-1.0));\n";
+ ss << " }\n";
+ ss << " if(type == 2.0)\n";
+ ss << " {\n";
+ ss << " double fS1 = (fSumSqr1 - fSum1*fSum1/fCount1)\n";
+ ss << " /(fCount1 - 1.0);\n";
+ ss << " double fS2 = (fSumSqr2 - fSum2*fSum2/fCount2)\n";
+ ss << " /(fCount2 - 1.0);\n";
+ ss << " fT = fabs( fSum1/fCount1 - fSum2/fCount2 )\n";
+ ss << " /sqrt( (fCount1-1.0)*fS1 + (fCount2-1.0)*fS2 )\n";
+ ss << " *sqrt( fCount1*fCount2*(fCount1+fCount2-2)\n";
+ ss << " /(fCount1+fCount2) );\n";
+ ss << " fF = fCount1 + fCount2 - 2;\n";
+ ss << " }\n";
+
+ ss << " double tdist=GetTDist(fT, fF);\n";
+ ss << " if (mode==1)\n";
+ ss << " return tdist;\n";
+ ss << " else\n";
+ ss << " return 2.0*tdist;\n";
+ ss << "}\n";
+ }
+}
+void OpVarP::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum = 0.0;\n";
+ ss << " double fMean = 0.0;\n";
+ ss << " double vSum = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double arg = 0.0;\n";
+ unsigned i = vSubArguments.size();
+ while (i--)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ 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 * pow(fCount,-1.0);\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 * pow(fCount,-1.0);\n";
+ ss << "}\n";
+}
+
+void OpTDist::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fMachEpsDecl);
+ funs.insert("");
+ decls.insert(fMaxGammaArgumentDecl);
+ funs.insert("");
+ decls.insert(lcl_getLanczosSumDecl);
+ funs.insert(lcl_getLanczosSum);
+ decls.insert(GetBetaDecl);
+ funs.insert(GetBeta);
+ decls.insert(GetLogBetaDecl);
+ funs.insert(GetLogBeta);
+ decls.insert(GetBetaDistPDFDecl);
+ funs.insert(GetBetaDistPDF);
+ decls.insert(lcl_GetBetaHelperContFracDecl);
+ funs.insert(lcl_GetBetaHelperContFrac);
+ decls.insert(GetBetaDistDecl);
+ funs.insert(GetBetaDist);
+ decls.insert(GetTDistDecl);
+ funs.insert(GetTDist);
+}
+void OpTDist::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double x = 0.0;\n";
+ ss << " double fDF = 0.0;\n";
+ ss << " double fFlag = 0.0;\n";
+ if(vSubArguments.size() != 3)
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur0);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " if(gid0 < ";
+ ss << tmpCurDVR0->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " x = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(x))\n";
+ ss << " x = 0.0;\n";
+ ss << " }\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDouble)
+ {
+ ss << " x = " << tmpCur0->GetDouble() << ";\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " x = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ assert(tmpCur1);
+ if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur1);
+ ss << " if(gid0 < ";
+ ss << tmpCurDVR1->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " fDF = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(fDF))\n";
+ ss << " fDF = 0.0;\n";
+ ss << " else\n";
+ ss << " fDF = floor(fDF);\n";
+ ss << " }\n";
+ }
+ else if(tmpCur1->GetType() == formula::svDouble)
+ {
+ ss << " fDF = floor(convert_double(";
+ ss << tmpCur1->GetDouble() << "));\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " fDF = floor(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ");\n";
+ }
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ assert(tmpCur2);
+ if(ocPush == vSubArguments[2]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR2 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur2);
+ ss << " if(gid0 < ";
+ ss << tmpCurDVR2->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " fFlag = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(fFlag))\n";
+ ss << " fFlag = 0.0;\n";
+ ss << " else\n";
+ ss << " fFlag = floor(fFlag);\n";
+ ss << " }\n";
+
+ }
+ else if(tmpCur2->GetType() == formula::svDouble)
+ {
+ ss << " fFlag = floor(convert_double(";
+ ss << tmpCur2->GetDouble() << "));\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " fFlag = floor(";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ");\n";
+ }
+ ss << " if(fDF < 1.0 || x < 0.0 || (fFlag != 1.0 && fFlag != 2.0))\n";
+ ss << " return DBL_MAX;\n";
+ ss << " double R = GetTDist(x, fDF);\n";
+ ss << " if (fFlag == 1.0)\n";
+ ss << " return R;\n";
+ ss << " else\n";
+ ss << " return 2.0 * R;\n";
+ ss << "}\n";
+}
+void OpExponDist::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = 0,tmp0=0,tmp1=0,tmp2=0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double rx,rlambda,rkum;\n";
+ ss <<"\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " rx = tmp0;\n";
+ ss << " rlambda = tmp1;\n";
+ ss << " rkum = tmp2;\n";
+ ss <<" if(rlambda <= 0.0)\n";
+ ss <<" {\n";
+ ss <<" tmp = -DBL_MAX;\n";
+ ss <<" }\n";
+ ss <<" else if(rkum == 0)\n";
+ ss <<" {\n";
+ ss <<" if(rx >= 0)\n";
+ ss <<" tmp = rlambda*exp(-rlambda*rx);\n";
+ ss <<" else\n";
+ ss <<" tmp = 0.0;\n";
+ ss <<" }\n";
+ ss <<" else\n";
+ ss <<" {\n";
+ ss <<" if(rx > 0)\n";
+ ss <<" tmp = 1.0 - exp(-rlambda*rx);\n";
+ ss <<" else\n";
+ ss <<" tmp = 0.0;\n";
+ ss <<" }\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+void OpFdist::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(GetFDistDecl);decls.insert(GetBetaDistDecl);
+ decls.insert(GetBetaDecl);decls.insert(fMaxGammaArgumentDecl);
+ decls.insert(lcl_GetBetaHelperContFracDecl);
+ decls.insert(GetBetaDistPDFDecl);
+ decls.insert(GetLogBetaDecl);decls.insert(lcl_getLanczosSumDecl);
+ decls.insert(fMachEpsDecl);
+ funs.insert(GetFDist);funs.insert(GetBetaDist);
+ funs.insert(GetBeta);
+ funs.insert(lcl_GetBetaHelperContFrac);funs.insert(GetBetaDistPDF);
+ funs.insert(GetLogBeta);
+ funs.insert(lcl_getLanczosSum);
+}
+void OpFdist::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = 0,tmp0=0,tmp1=0,tmp2=0;\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double rF1,rF2,rX;\n";
+ ss <<"\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " rX = tmp0;\n";
+ ss << " rF1 = floor(tmp1);\n";
+ ss << " rF2 = floor(tmp2);\n";
+ ss <<" if (rX < 0.0 || rF1 < 1.0 || rF2 < 1.0 || rF1 >= 1.0E10 ||";
+ ss <<"rF2 >= 1.0E10)\n";
+ ss <<" {\n";
+ ss <<" tmp = -DBL_MAX;\n";
+ ss <<" }\n";
+ ss <<" tmp = GetFDist(rX, rF1, rF2);\n";
+ ss <<" return tmp;\n";
+ ss <<"}";
+}
+
+void OpStandard::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double x = 0.0;\n";
+ ss << " double mu = 0.0;\n";
+ ss << " double sigma = 0.0;\n";
+ if(vSubArguments.size() != 3)
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur0);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurSVR0 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " if (gid0 < " << tmpCurSVR0->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " x = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(x))\n";
+ ss << " x = 0.0;\n";
+ ss << " }\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDouble)
+ {
+ ss << " x = " << tmpCur0->GetDouble() << ";\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " x = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ }
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ assert(tmpCur1);
+ if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurSVR1 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur1);
+ ss << " if (gid0 < " << tmpCurSVR1->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(tmpCur1->GetType() == formula::svDouble)
+ {
+ ss << " mu = " << tmpCur1->GetDouble() << ";\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " mu = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ }
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ assert(tmpCur2);
+ if(ocPush == vSubArguments[2]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurSVR2 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur2);
+ ss << " if (gid0 < " << tmpCurSVR2->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(tmpCur2->GetType() == formula::svDouble)
+ {
+ ss << " sigma = " << tmpCur2->GetDouble() << ";\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n";
+ ss << "}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " sigma = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ";\n";
+ }
+
+ ss << " if(sigma <= 0.0)\n";
+ ss << " return DBL_MAX;\n";
+ ss << " else\n";
+ ss << " return (x - mu)*pow(sigma,-1.0);\n";
+ ss << "}";
+}
+
+void OpWeibull::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double x = 0.0;\n";
+ ss << " double alpha = 0.0;\n";
+ ss << " double beta = 0.0;\n";
+ ss << " double kum = 0.0;\n";
+ if(vSubArguments.size() != 4)
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur0);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurSVR0 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " if (gid0 < " << tmpCurSVR0->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " x = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(x))\n";
+ ss << " x = 0.0;\n";
+ ss << " }\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDouble)
+ {
+ ss << " x = " << tmpCur0->GetDouble() << ";\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " x = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ }
+
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ assert(tmpCur1);
+ if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurSVR1 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur1);
+ ss << " if (gid0 < " << tmpCurSVR1->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " alpha = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(alpha))\n";
+ ss << " alpha = 0.0;\n";
+ ss << " }\n";
+ }
+ else if(tmpCur1->GetType() == formula::svDouble)
+ {
+ ss << " alpha = " << tmpCur1->GetDouble() << ";\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " alpha = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ }
+
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ assert(tmpCur2);
+ if(ocPush == vSubArguments[2]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur2->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurSVR2 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur2);
+ ss << " if (gid0 < " << tmpCurSVR2->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " beta = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(beta))\n";
+ ss << " beta = 0.0;\n";
+ ss << " }\n";
+ }
+ else if(tmpCur2->GetType() == formula::svDouble)
+ {
+ ss << " beta = " << tmpCur2->GetDouble() << ";\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " beta = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef() << ";\n";
+ }
+
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ assert(tmpCur3);
+ if(ocPush == vSubArguments[3]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur3->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurSVR3 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur3);
+ ss << " if (gid0 < " << tmpCurSVR3->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " kum = ";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(kum))\n";
+ ss << " kum = 0.0;\n";
+ ss << " }\n";
+ }
+ else if(tmpCur3->GetType() == formula::svDouble)
+ {
+ ss << " kum = " << tmpCur3->GetDouble() << ";\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " kum = ";
+ ss << vSubArguments[3]->GenSlidingWindowDeclRef() << ";\n";
+ }
+
+ ss << " if(alpha <= 0.0 || beta <=0.0 || kum < 0.0)\n";
+ ss << " return DBL_MAX;\n";
+ ss << " else if(kum == 0.0)\n";
+ ss << " {\n";
+ ss << " return alpha*pow(pow(beta,alpha),-1.0)*pow(x,alpha-1.0)";
+ ss << "*exp(-pow(x*pow(beta,-1.0),alpha));\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " return 1.0-exp(-pow(x*pow(beta,-1.0),alpha));\n";
+ ss << "}\n";
+}
+
+void OpSkew::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum = 0.0;\n";
+ ss << " double fMean = 0.0;\n";
+ ss << " double vSum = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double arg = 0.0;\n";
+ unsigned i = vSubArguments.size();
+ while (i--)
+ {
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ 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 * pow(fCount,-1.0);\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 * pow(fCount - 1.0,-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) * pow(fStdDev,-1.0);\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) * pow(fStdDev,-1.0);\n";
+ ss << " xcube = xcube + dx * dx * dx;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg = " << pCur->GetDouble() << ";\n";
+ ss << " dx = (arg - fMean) * pow(fStdDev,-1.0);\n";
+ ss << " xcube = xcube + dx * dx * dx;\n";
+ }
+ }
+ else
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " dx = (arg - fMean) * pow(fStdDev,-1.0);\n";
+ ss << " xcube = xcube + dx * dx * dx;\n";
+ }
+ }
+ ss << " return ((xcube * fCount) * pow(fCount - 1.0,-1.0))";
+ ss << " * pow(fCount - 2.0,-1.0);\n";
+ ss << "}\n";
+}
+
+void OpSkewp::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum = 0.0;\n";
+ ss << " double fMean = 0.0;\n";
+ ss << " double vSum = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double arg = 0.0;\n";
+ unsigned i = vSubArguments.size();
+ while (i--)
+ {
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ 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 * pow(fCount,-1.0);\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 * pow(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) * pow(fStdDev,-1.0);\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) * pow(fStdDev,-1.0);\n";
+ ss << " xcube = xcube + dx * dx * dx;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg = " << pCur->GetDouble() << ";\n";
+ ss << " dx = (arg - fMean) * pow(fStdDev,-1.0);\n";
+ ss << " xcube = xcube + dx * dx * dx;\n";
+ }
+ }
+ else
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " dx = (arg - fMean) * pow(fStdDev,-1.0);\n";
+ ss << " xcube = xcube + dx * dx * dx;\n";
+ }
+ }
+ ss << " return xcube * pow(fCount,-1.0);\n";
+ ss << "}\n";
+}
+
+void OpTInv::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fMachEpsDecl);
+ funs.insert("");
+ decls.insert(fMaxGammaArgumentDecl);
+ funs.insert("");
+ decls.insert(lcl_getLanczosSumDecl);
+ funs.insert(lcl_getLanczosSum);
+ decls.insert(GetBetaDecl);
+ funs.insert(GetBeta);
+ decls.insert(GetLogBetaDecl);
+ funs.insert(GetLogBeta);
+ decls.insert(GetBetaDistPDFDecl);
+ funs.insert(GetBetaDistPDF);
+ decls.insert(lcl_GetBetaHelperContFracDecl);
+ funs.insert(lcl_GetBetaHelperContFrac);
+ decls.insert(GetBetaDistDecl);
+ funs.insert(GetBetaDist);
+ decls.insert(GetTDistDecl);
+ funs.insert(GetTDist);
+ decls.insert(GetValueDecl);
+ funs.insert(GetValue);
+ decls.insert(lcl_HasChangeOfSignDecl);
+ funs.insert(lcl_HasChangeOfSign);
+ decls.insert(lcl_IterateInverseDecl);
+ funs.insert(lcl_IterateInverse);
+}
+
+void OpTInv::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double x = 0.0;\n";
+ ss << " double fDF = 0.0;\n";
+ if(vSubArguments.size() != 2)
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ assert(tmpCur0);
+ if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur0->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR0 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
+ ss << " if(gid0 < ";
+ ss << tmpCurDVR0->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " x = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(x))\n";
+ ss << " x = 0.0;\n";
+ ss << " }\n";
+ }
+ else if(tmpCur0->GetType() == formula::svDouble)
+ {
+ ss << " x = " << tmpCur0->GetDouble() << ";\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " x = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ assert(tmpCur1);
+ if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
+ {
+ if(tmpCur1->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken*tmpCurDVR1 =
+ static_cast<const formula::SingleVectorRefToken *>(tmpCur1);
+ ss << " if(gid0 < ";
+ ss << tmpCurDVR1->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " fDF = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(fDF))\n";
+ ss << " fDF = 0.0;\n";
+ ss << " else\n";
+ ss << " fDF = floor(fDF);\n";
+ ss << " }\n";
+ }
+ else if(tmpCur1->GetType() == formula::svDouble)
+ {
+ ss << " fDF = floor(convert_double(";
+ ss << tmpCur1->GetDouble() << "));\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n}\n";
+ return ;
+ }
+ }
+ else
+ {
+ ss << " fDF = floor(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ");\n";
+ }
+ ss << " if (x > 1.0||fDF < 1.0 || fDF > 1.0E10 || x <= 0.0)\n";
+ ss << " return DBL_MAX;\n";
+ ss << " bool bConvError;\n";
+ ss << " double fVal = lcl_IterateInverse(\n";
+ ss << " fDF*0.5, fDF, &bConvError,x,fDF );\n";
+ ss << " if (bConvError)\n";
+ ss << " return DBL_MAX;\n";
+ ss << " return fVal;\n";
+ ss << "}\n";
+}
+
+void OpStDev::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum = 0.0;\n";
+ ss << " double 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 * pow(fCount,-1.0);\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 * pow(fCount - 1.0,-1.0));\n";
+ ss << "}\n";
+}
+
+void OpStDevP::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum = 0.0;\n";
+ ss << " double fMean = 0.0;\n";
+ ss << " double vSum = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double arg = 0.0;\n";
+ unsigned i = vSubArguments.size();
+ while (i--)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ 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 * pow(fCount,-1.0);\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 == 0.0)\n";
+ ss << " return DBL_MAX;\n";
+ ss << " else\n";
+ ss << " return sqrt(vSum * pow(fCount,-1.0));\n";
+ ss << "}\n";
+}
+
+void OpSlope::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ CHECK_PARAMETER_COUNT(2,2);
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSumX = 0.0;\n";
+ ss << " double fSumY = 0.0;\n";
+ ss << " double fMeanX = 0.0;\n";
+ ss << " double fMeanY = 0.0;\n";
+ ss << " double fSumDeltaXDeltaY = 0.0;\n";
+ ss << " double fSumSqrDeltaX = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double argX = 0.0;\n";
+ ss << " double argY = 0.0;\n";
+ FormulaToken *pCur = vSubArguments[1]->GetFormulaToken();
+ FormulaToken *pCur1 = vSubArguments[0]->GetFormulaToken();
+ assert(pCur);
+ assert(pCur1);
+ if (pCur->GetType() == formula::svDoubleVectorRef&&
+ pCur1->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur);
+ const formula::DoubleVectorRefToken* pDVR1 =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur1);
+
+ size_t nCurWindowSize = pDVR->GetRefRowSize();
+ size_t nCurWindowSize1 = pDVR1->GetRefRowSize();
+ size_t arrayLength = pDVR->GetArrayLength()<
+ pDVR1->GetArrayLength() ? pDVR->GetArrayLength():
+ pDVR1->GetArrayLength();
+ if(nCurWindowSize != nCurWindowSize1)
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " for (int i = ";
+ if ((!pDVR->IsStartFixed() && pDVR->IsEndFixed())
+ &&(!pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+ {
+ ss << "gid0; i < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+ &&(pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i < " << arrayLength ;
+ ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+ &&(!pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i + gid0 < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((pDVR->IsStartFixed() && pDVR->IsEndFixed())
+ &&(pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+ {
+ ss << "0; i < " << arrayLength << "; i++)\n";
+ ss << " {\n";
+ }
+ else
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+
+ ss << " argX = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " argY = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(argX) || isnan(argY))\n";
+ ss << " continue;\n";
+ ss << " fSumX += argX;\n";
+ ss << " fSumY += argY;\n";
+ ss << " fCount += 1.0;\n";
+ ss << " }\n";
+
+ ss << " if (fCount < 1.0)\n";
+ ss << " return CreateDoubleError(NoValue);\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " fMeanX = fSumX * pow(fCount,-1.0);\n";
+ ss << " fMeanY = fSumY * pow(fCount,-1.0);\n";
+
+ ss << " for (int i = ";
+ if ((!pDVR->IsStartFixed() && pDVR->IsEndFixed())
+ &&(!pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+ {
+ ss << "gid0; i < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+ &&(pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i < " << arrayLength ;
+ ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+ &&(!pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i + gid0 < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else
+ {
+ ss << "0; i < " << arrayLength << "; i++)\n";
+ ss << " {\n";
+ }
+
+ ss << " argX = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " argY = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(argX) || isnan(argY))\n";
+ ss << " continue;\n";
+ ss << " fSumDeltaXDeltaY += (argX-fMeanX)*(argY-fMeanY);\n";
+ ss << " fSumSqrDeltaX += (argX-fMeanX) * (argX-fMeanX);\n";
+ ss << " }\n";
+ ss << " if(fSumSqrDeltaX == 0.0)\n";
+ ss << " return CreateDoubleError(DivisionByZero);\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " return fSumDeltaXDeltaY*pow(fSumSqrDeltaX,-1.0);\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << "}\n";
+ }
+ else
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+}
+void OpSTEYX::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSumX = 0.0;\n";
+ ss << " double fSumY = 0.0;\n";
+ ss << " double fMeanX = 0.0;\n";
+ ss << " double fMeanY = 0.0;\n";
+ ss << " double fSumDeltaXDeltaY = 0.0;\n";
+ ss << " double fSumSqrDeltaX = 0.0;\n";
+ ss << " double fSumSqrDeltaY = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double argX = 0.0;\n";
+ ss << " double argY = 0.0;\n";
+ FormulaToken *pCur = vSubArguments[1]->GetFormulaToken();
+ FormulaToken *pCur1 = vSubArguments[0]->GetFormulaToken();
+ assert(pCur);
+ assert(pCur1);
+ if (pCur->GetType() == formula::svDoubleVectorRef&&
+ pCur1->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur);
+ const formula::DoubleVectorRefToken* pDVR1 =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur1);
+ size_t nCurWindowSize = pDVR->GetRefRowSize();
+ size_t nCurWindowSize1 = pDVR1->GetRefRowSize();
+ size_t arrayLength = pDVR->GetArrayLength()<
+ pDVR1->GetArrayLength() ? pDVR->GetArrayLength():
+ pDVR1->GetArrayLength();
+ if(nCurWindowSize != nCurWindowSize1)
+ {
+ ss << " return DBL_MAX;\n";
+ ss << "}\n";
+ return ;
+ }
+ ss << " for (int i = ";
+ if ((!pDVR->IsStartFixed() && pDVR->IsEndFixed())
+ &&(!pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+ {
+ ss << "gid0; i < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+ &&(pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i < " << arrayLength;
+ ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+ &&(!pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i + gid0 < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((pDVR->IsStartFixed() && pDVR->IsEndFixed())
+ &&(pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+ {
+ ss << "0; i < " << arrayLength << "; i++)\n";
+ ss << " {\n";
+ }
+ else
+ {
+ ss << "0; i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ ss << " break;\n";
+ ss << " }";
+ ss << " return DBL_MAX;\n";
+ ss << "}\n";
+ return ;
+ }
+
+ ss << " argX = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " argY = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(argX) || isnan(argY))\n";
+ ss << " continue;\n";
+ ss << " fSumX += argX;\n";
+ ss << " fSumY += argY;\n";
+ ss << " fCount += 1.0;\n";
+ ss << " }\n";
+
+ ss << " if (fCount < 3.0)\n";
+ ss << " return DBL_MAX;\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " fMeanX = fSumX * pow(fCount,-1.0);\n";
+ ss << " fMeanY = fSumY * pow(fCount,-1.0);\n";
+
+ ss << " for (int i = ";
+ if ((!pDVR->IsStartFixed() && pDVR->IsEndFixed())
+ &&(!pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+ {
+ ss << "gid0; i < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+ &&(pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i < " << arrayLength ;
+ ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((!pDVR->IsStartFixed() && !pDVR->IsEndFixed())&&
+ (!pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i + gid0 < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else
+ {
+ ss << "0; i < " << arrayLength << "; i++)\n";
+ ss << " {\n";
+ }
+
+ ss << " argX = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " argY = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(argX)||isnan(argY))\n";
+ ss << " continue;\n";
+ ss << " fSumDeltaXDeltaY +=(argX-fMeanX)*(argY-fMeanY);\n";
+ ss << " fSumSqrDeltaX += (argX-fMeanX)*(argX-fMeanX);\n";
+ ss << " fSumSqrDeltaY += (argY-fMeanY)*(argY-fMeanY);\n";
+ ss << " }\n";
+ ss << " if(fSumSqrDeltaX == 0.0)\n";
+ ss << " return DBL_MAX;\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " return sqrt((fSumSqrDeltaY - fSumDeltaXDeltaY * \n";
+ ss << " fSumDeltaXDeltaY*pow(fSumSqrDeltaX,-1.0))\n";
+ ss << " *pow(fCount - 2.0,-1.0));\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << "}\n";
+ }
+ else
+ {
+ ss << " return DBL_MAX;\n";
+ ss << "}\n";
+ }
+}
+void OpFisher::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss <<" double arg0;\n";
+ if(vSubArguments.size() != 1)
+ {
+ ss << " return DBL_MAX;\n";
+ return ;
+ }
+ FormulaToken *pCur = vSubArguments[0]->GetFormulaToken();
+ assert(pCur);
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ ss << " return DBL_MAX;\n";
+ return ;
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ ss << " arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss<< " if(isnan(arg0)||(gid0>=";
+ ss<<pSVR->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg0 = 0;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(arg0))\n";
+ ss << " return DBL_MAX;\n";
+ }
+ ss << " if (fabs(arg0) >= 1.0)\n";
+ ss << " return DBL_MAX;\n";
+ ss << " double tmp=0.5*log((1+arg0)*pow((1-arg0),-1));\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+
+void OpFisherInv::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR = static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss <<"int gid0=get_global_id(0);\n\t";
+ ss << "double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n\t";
+ ss<< "if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n\t\t";
+ ss<<"arg0 = 0;\n\t";
+ ss << "double tmp=tanh(arg0);\n\t";
+ ss << "return tmp;\n";
+ ss << "}\n";
+}
+
+void OpGamma::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss <<"int gid0=get_global_id(0);\n\t";
+ ss << "double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n\t";
+ ss << "double tmp=tgamma(arg0);\n\t";
+ ss << "return tmp;\n";
+ ss << "}\n";
+}
+
+void OpCorrel::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ if( vSubArguments.size() !=2 ||vSubArguments[0]->GetFormulaToken()
+ ->GetType() != formula::svDoubleVectorRef||vSubArguments[1]
+ ->GetFormulaToken()->GetType() != formula::svDoubleVectorRef )
+ ///only support DoubleVector in OpCorrelfor GPU calculating.
+ throw Unhandled(__FILE__, __LINE__);
+ const formula::DoubleVectorRefToken* pCurDVRX =
+ static_cast<const formula::DoubleVectorRefToken *>(
+ vSubArguments[0]->GetFormulaToken());
+ const formula::DoubleVectorRefToken* pCurDVRY =
+ static_cast<const formula::DoubleVectorRefToken *>(
+ vSubArguments[1]->GetFormulaToken());
+ if( pCurDVRX->GetRefRowSize() != pCurDVRY->GetRefRowSize() )
+ throw Unhandled(__FILE__, __LINE__);
+
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss << "double vSum = 0.0;\n\t";
+ ss << "double vXSum = 0.0;\n\t";
+ ss << "double vYSum = 0.0;\n\t";
+ ss << "double vXMean = 0.0;\n\t";
+ ss << "double vYMean = 0.0;\n\t";
+
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "double arg0 = 0.0;\n\t";
+ ss << "double arg1 = 0.0;\n\t";
+ ss << "int cnt = 0;\n\t";
+
+ size_t nCurWindowSizeX = pCurDVRY->GetRefRowSize();
+
+ ss << "for (int i = ";
+ if (!pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+ ss << "gid0; i < " << nCurWindowSizeX << "; i++) {\n\t\t";
+ ss << "arg0 = " << vSubArguments[0]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t";
+ ss << "arg1 = " << vSubArguments[1]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t";
+ ss << "if(isnan(arg0) || isnan(arg1) || (i >= ";
+ ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+ ss << pCurDVRY->GetArrayLength() << ")) {\n\t\t\t";
+ ss << "arg0 = 0.0;\n\t\t\t";
+ ss << "arg1 = 0.0;\n\t\t\t";
+ ss << "--cnt;\n\t\t";
+ ss << "}\n\t\t";
+ ss << "++cnt;\n\t\t";
+ ss << "vXSum += arg0;\n\t\t";
+ ss << "vYSum += arg1;\n\t";
+ ss << "}\n\t";
+ } else if (pCurDVRX->IsStartFixed() && !pCurDVRX->IsEndFixed()) {
+ ss << "0; i < gid0 + " << nCurWindowSizeX << "; i++) {\n\t\t";
+ ss << "arg0 = " << vSubArguments[0]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t";
+ ss << "arg1 = " << vSubArguments[1]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t";
+ ss << "if(isnan(arg0) || isnan(arg1) || (i >= ";
+ ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+ ss << pCurDVRY->GetArrayLength() << ")) {\n\t\t\t";
+ ss << "arg0 = 0.0;\n\t\t\t";
+ ss << "arg1 = 0.0;\n\t\t\t";
+ ss << "--cnt;\n\t\t";
+ ss << "}\n\t\t";
+ ss << "++cnt;\n\t\t";
+ ss << "vXSum += arg0;\n\t\t";
+ ss << "vYSum += arg1;\n\t";
+ ss << "}\n\t";
+ }
+ else if (pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+ ss << "0; i < " << nCurWindowSizeX << "; i++) {\n\t\t";
+ ss << "arg0 = " << vSubArguments[0]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t";
+ ss << "arg1 = " << vSubArguments[1]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t";
+ ss << "if(isnan(arg0) || isnan(arg1) || (i >= ";
+ ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+ ss << pCurDVRY->GetArrayLength() << ")) {\n\t\t\t";
+ ss << "arg0 = 0.0;\n\t\t\t";
+ ss << "arg1 = 0.0;\n\t\t\t";
+ ss << "--cnt;\n\t\t";
+ ss << "}\n\t\t";
+ ss << "++cnt;\n\t\t";
+ ss << "vXSum += arg0;\n\t\t";
+ ss << "vYSum += arg1;\n\t";
+ ss << "}\n\t";
+ } else {
+ ss << "0; i < " << nCurWindowSizeX << "; i++) {\n\t\t";
+ ss << "arg0 = " << vSubArguments[0]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t";
+ ss << "arg1 = " << vSubArguments[1]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t";
+ ss << "if(isnan(arg0) || isnan(arg1) || (i + gid0 >= ";
+ ss << pCurDVRX->GetArrayLength() << ") || (i + gid0 >=";
+ ss << pCurDVRY->GetArrayLength() << ")) {\n\t\t\t";
+ ss << "arg0 = 0.0;\n\t\t\t";
+ ss << "arg1 = 0.0;\n\t\t\t";
+ ss << "--cnt;\n\t\t";
+ ss << "}\n\t\t";
+ ss << "++cnt;\n\t\t";
+ ss << "vXSum += arg0;\n\t\t";
+ ss << "vYSum += arg1;\n\t";
+ ss << "}\n\t";
+ }
+
+ ss << "if(cnt < 1) {\n\t\t";
+ ss << "return DBL_MIN;\n\t";
+ ss << "}\n\t";
+ ss << "else {\n\t\t";
+ ss << "vXMean = vXSum/cnt;\n\t\t";
+ ss << "vYMean = vYSum/cnt;\n\t\t";
+ ss << "vXSum = 0.0;\n\t\t";
+ ss << "vYSum = 0.0;\n\t\t";
+
+ ss << "for (int i = ";
+ if (!pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+ ss << "gid0; i < " << nCurWindowSizeX << "; i++) {\n\t\t\t";
+ ss << "arg0 = " << vSubArguments[0]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t\t";
+ ss << "arg1 = " << vSubArguments[1]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t\t";
+ ss << "if(isnan(arg0) || isnan(arg1) || (i >= ";
+ ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+ ss << pCurDVRY->GetArrayLength() << ")) {\n\t\t\t\t";
+ ss << "arg0 = vXMean;\n\t\t\t\t";
+ ss << "arg1 = vYMean;\n\t\t\t";
+ ss << "}\n\t\t\t";
+ ss << "vXSum += pow(arg0 - vXMean, 2);\n\t\t\t";
+ ss << "vYSum += pow(arg1 - vYMean, 2);\n\t\t\t";
+ ss << "vSum += (arg0 - vXMean)*(arg1 - vYMean);\n\t\t";
+ ss << "}\n\t\t";
+ } else if (pCurDVRX->IsStartFixed() && !pCurDVRX->IsEndFixed()) {
+ ss << "0; i < gid0 + " << nCurWindowSizeX << "; i++) {\n\t\t\t";
+ ss << "arg0 = " << vSubArguments[0]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t\t";
+ ss << "arg1 = " << vSubArguments[1]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t\t";
+ ss << "if(isnan(arg0) || isnan(arg1) || (i >= ";
+ ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+ ss << pCurDVRY->GetArrayLength() << ")) {\n\t\t\t\t";
+ ss << "arg0 = vXMean;\n\t\t\t\t";
+ ss << "arg1 = vYMean;\n\t\t\t";
+ ss << "}\n\t\t\t";
+ ss << "vXSum += pow(arg0 - vXMean, 2);\n\t\t\t";
+ ss << "vYSum += pow(arg1 - vYMean, 2);\n\t\t\t";
+ ss << "vSum += (arg0 - vXMean)*(arg1 - vYMean);\n\t\t";
+ ss << "}\n\t\t";
+ } else if (pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+ ss << "0; i < " << nCurWindowSizeX << "; i++) {\n\t\t\t";
+ ss << "arg0 = " << vSubArguments[0]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t\t";
+ ss << "arg1 = " << vSubArguments[1]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t\t";
+ ss << "if(isnan(arg0) || isnan(arg1) || (i >= ";
+ ss << pCurDVRX->GetArrayLength() << ") || (i >=";
+ ss << pCurDVRY->GetArrayLength() << ")) {\n\t\t\t\t";
+ ss << "arg0 = vXMean;\n\t\t\t\t";
+ ss << "arg1 = vYMean;\n\t\t\t";
+ ss << "}\n\t\t\t";
+ ss << "vXSum += pow(arg0 - vXMean, 2);\n\t\t\t";
+ ss << "vYSum += pow(arg1 - vYMean, 2);\n\t\t\t";
+ ss << "vSum += (arg0 - vXMean)*(arg1 - vYMean);\n\t\t";
+ ss << "}\n\t\t";
+ } else {
+ ss << "0; i < " << nCurWindowSizeX << "; i++) {\n\t\t\t";
+ ss << "arg0 = " << vSubArguments[0]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t\t";
+ ss << "arg1 = " << vSubArguments[1]
+ ->GenSlidingWindowDeclRef(true) << ";\n\t\t\t";
+ ss << "if(isnan(arg0) || isnan(arg1) || (i + gid0 >= ";
+ ss << pCurDVRX->GetArrayLength() << ") || (i + gid0 >=";
+ ss << pCurDVRY->GetArrayLength() << ")) {\n\t\t\t\t";
+ ss << "arg0 = vXMean;\n\t\t\t\t";
+ ss << "arg1 = vYMean;\n\t\t\t";
+ ss << "}\n\t\t\t";
+ ss << "vXSum += ((arg0 - vXMean)*(arg0 - vXMean));\n\t\t\t";
+ ss << "vYSum += ((arg1 - vYMean)*(arg1 - vYMean));\n\t\t\t";
+ ss << "vSum += (arg0 - vXMean)*(arg1 - vYMean);\n\t\t";
+ ss << "}\n\t\t";
+ }
+
+ ss << "if(vXSum == 0.0 || vYSum == 0.0) {\n\t\t\t";
+ ss << "return NAN;\n\t\t";
+ ss << "}\n\t\t";
+ ss << "else {\n\t\t\t";
+ ss << "return vSum/pow(vXSum*vYSum, 0.5);\n\t\t";
+ ss << "}\n\t";
+ ss << "}\n";
+ ss << "}";
+}
+
+void OpNegbinomdist::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n\t";
+ ss << "double f,s,p,tmp0,tmp1,tmp2;\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::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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " p = tmp2;\n";
+ ss << " s = tmp1;\n";
+ ss << " f = tmp0;\n";
+ ss << " double q = 1.0 - p;\n\t";
+ ss << " double fFactor = pow(p,s);\n\t";
+ ss << " for(int i=0; i<f; i++)\n\t";
+ ss << " {\n\t";
+ ss << " fFactor *= ((double)i+s)*pow(((double)i+1.0),-1.0)/pow(q,-1);\n";
+ ss << " }\n\t";
+ ss << " double temp=fFactor;\n\t";
+ ss << " return temp;\n";
+ ss << "}\n";
+}
+
+void OpPearson::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ if( vSubArguments.size() !=2 ||vSubArguments[0]->GetFormulaToken()
+ ->GetType() != formula::svDoubleVectorRef||vSubArguments[1]
+ ->GetFormulaToken()->GetType() != formula::svDoubleVectorRef )
+ ///only support DoubleVector in OpPearson for GPU calculating.
+ throw Unhandled(__FILE__, __LINE__);
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(
+ vSubArguments[0]->GetFormulaToken());
+ const formula::DoubleVectorRefToken* pCurDVRY =
+ static_cast<const formula::DoubleVectorRefToken *>(
+ vSubArguments[1]->GetFormulaToken());
+ if( pDVR->GetRefRowSize() != pCurDVRY->GetRefRowSize() )
+ throw Unhandled(__FILE__, __LINE__);
+
+ size_t nCurWindowSize = pDVR->GetRefRowSize();
+
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double fSumX = 0.0;\n";
+ ss << " double fSumY = 0.0;\n";
+ ss << " double fSumDeltaXDeltaY = 0.0;\n";
+ ss << " double fInx;\n";
+ ss << " double fIny;\n";
+ 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";
+ }
+ ss << " fInx = "<<vSubArguments[0]->GenSlidingWindowDeclRef(true);
+ ss << ";\n";
+ ss << " fIny = "<<vSubArguments[1]->GenSlidingWindowDeclRef(true);
+ ss << " ;\n";
+ ss << " if(!isnan(fInx)&&!isnan(fIny)){\n";
+ ss << " fSumX += fInx;\n";
+ ss << " fSumY += fIny;\n";
+ ss << " fCount = fCount + 1;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if(fCount < 1)\n";
+ ss << " return CreateDoubleError(NoValue);\n";
+ ss << " double fMeanX = fSumX / fCount;\n";
+ ss << " double fMeanY = fSumY / fCount;\n";
+ ss << " fSumX = 0.0;\n";
+ ss << " fSumY = 0.0;\n";
+ 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";
+ }
+ ss << " fInx = "<<vSubArguments[0]->GenSlidingWindowDeclRef(true);
+ ss << " ;\n";
+ ss << " fIny = "<<vSubArguments[1]->GenSlidingWindowDeclRef(true);
+ ss << " ;\n";
+ ss << " if(!isnan(fInx)&&!isnan(fIny)){\n";
+ ss << " fSumDeltaXDeltaY += (fInx - fMeanX) * (fIny - fMeanY);\n";
+ ss << " fSumX += (fInx - fMeanX) * (fInx - fMeanX);\n";
+ ss << " fSumY += (fIny - fMeanY) * (fIny - fMeanY);\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " if (fSumX == 0 || fSumY == 0)\n";
+ ss << " return CreateDoubleError(DivisionByZero);\n";
+ ss << " double tmp = ( fSumDeltaXDeltaY / sqrt( fSumX * fSumY));\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+
+void OpGammaLn::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR= static_cast<const
+formula::SingleVectorRefToken *>(tmpCur);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n\t";
+ ss <<"int gid0=get_global_id(0);\n\t";
+ ss << "double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n\t";
+ ss<< "if(isnan(arg0)||(gid0>=";
+ ss<<tmpCurDVR->GetArrayLength();
+ ss<<"))\n\t\t";
+ ss<<"arg0 = 0;\n\t";
+ ss << "double tmp=lgamma(arg0);\n\t";
+ ss << "return tmp;\n";
+ ss << "}\n";
+}
+void OpGauss::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(taylorDecl);decls.insert(phiDecl);
+ decls.insert(gaussDecl);
+ funs.insert(taylor);funs.insert(phi);
+ funs.insert(gauss);
+}
+
+void OpGauss::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss <<" double arg0;\n";
+ if(vSubArguments.size() != 1)
+ {
+ ss << " return DBL_MAX;\n";
+ return ;
+ }
+ FormulaToken *pCur = vSubArguments[0]->GetFormulaToken();
+ assert(pCur);
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ ss << " return DBL_MAX;\n";
+ return ;
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ ss << " arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss<< " if(isnan(arg0)||(gid0>=";
+ ss<<pSVR->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg0 = 0;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(arg0))\n";
+ ss << " return DBL_MAX;\n";
+ }
+ ss << " double tmp=gauss(arg0);\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+
+void OpGeoMean::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "__kernel void ";
+ ss << "GeoMean_reduction( ";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ", __global double *result)\n";
+ ss << "{\n";
+ ss << " double tmp =0;\n";
+ ss << " int count = 0;\n";
+ ss << " int i ;\n";
+ GenTmpVariables(ss,vSubArguments);
+ ss << " double current_sum = 0.0;\n";
+ ss << " int windowSize;\n";
+ ss << " int arrayLength;\n";
+ ss << " int current_count = 0;\n";
+ ss << " int writePos = get_group_id(1);\n";
+ ss << " int lidx = get_local_id(0);\n";
+ ss << " __local double shm_buf[256];\n";
+ ss << " __local int count_buf[256];\n";
+ ss << " int loop;\n";
+ ss << " int offset;\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+
+ for(const DynamicKernelArgumentRef & rArg : vSubArguments)
+ {
+ assert(rArg->GetFormulaToken());
+
+ if(rArg->GetFormulaToken()->GetType() ==
+ formula::svDoubleVectorRef)
+ {
+ FormulaToken *tmpCur = rArg->GetFormulaToken();
+ const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
+ formula::DoubleVectorRefToken *>(tmpCur);
+ size_t nCurWindowSize = pCurDVR->GetArrayLength() <
+ pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
+ pCurDVR->GetRefRowSize() ;
+
+ if (pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
+ ss << " offset = 0;\n";
+ else if (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ ss << " offset = get_group_id(1);\n";
+ else
+ throw Unhandled(__FILE__, __LINE__);
+ ss << " windowSize = ";
+ ss << nCurWindowSize;
+ ss << ";\n";
+ ss << " arrayLength = ";
+ ss << pCurDVR->GetArrayLength();
+ ss << ";\n";
+ ss << " loop = arrayLength/512 + 1;\n";
+ ss << " for (int l=0; l<loop; l++){\n";
+ ss << " tmp = 0.0;\n";
+ ss << " count = 0;\n";
+ ss << " int loopOffset = l*512;\n";
+ ss << " int p1 = loopOffset + lidx + offset, p2 = p1 + 256;\n";
+ ss << " if (p2 < min(offset + windowSize, arrayLength)) {\n";
+ ss << " tmp0 = 0.0;\n";
+ std::string p1 = "p1";
+ std::string p2 = "p2";
+
+ ss << " tmp0 =";
+ rArg->GenDeclRef(ss);
+ ss << "["<<p1.c_str()<<"];\n";
+ ss << " if(!isnan(tmp0))\n";
+ ss << " {\n";
+ ss << " tmp += log(tmp0);\n";
+ ss << " count++;\n";
+ ss << " }\n";
+
+ ss << " tmp0 =";
+ rArg->GenDeclRef(ss);
+ ss << "["<<p2.c_str()<<"];\n";
+ ss << " if(!isnan(tmp0))\n";
+ ss << " {\n";
+ ss << " tmp += log(tmp0);\n";
+ ss << " count++;\n";
+ ss << " }\n";
+
+ ss << " }\n";
+ ss << " else if (p1 < min(arrayLength, offset + windowSize)) {\n";
+
+ ss << " tmp0 =";
+ rArg->GenDeclRef(ss);
+ ss << "["<<p1.c_str()<<"];\n";
+ ss << " if(!isnan(tmp0))\n";
+ ss << " {\n";
+ ss << " tmp += log(tmp0);\n";
+ ss << " count++;\n";
+ ss << " }\n";
+
+ ss << " }\n";
+ ss << " shm_buf[lidx] = tmp;\n";
+ ss << " count_buf[lidx] = count;\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+
+ ss << " for (int i = 128; i >0; i/=2) {\n";
+ ss << " if (lidx < i)\n";
+ ss << " {\n";
+ ss << " shm_buf[lidx] += shm_buf[lidx + i];\n";
+ ss << " count_buf[lidx] += count_buf[lidx + i];\n";
+ ss << " }\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " }\n";
+ ss << " if (lidx == 0)\n";
+ ss << " {\n";
+ ss << " current_sum += shm_buf[0];\n";
+ ss << " current_count += count_buf[0];\n";
+ ss << " }\n";
+ // ss << "if(writePos == 14 && lidx ==0)\n";
+ //ss <<"printf(\"\\n********************sum is %f, count is%d\",current_sum,current_count);\n";
+ ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
+ ss << " }\n";
+ }else
+ {
+ ss << " if (lidx == 0)\n";
+ ss << " {\n";
+ ss << " tmp0 =";
+ if(rArg->GetFormulaToken()->GetType() == formula::svSingleVectorRef)
+ {
+ rArg->GenDeclRef(ss);
+ ss << "[writePos];\n";
+ }
+ else
+ {
+ rArg->GenDeclRef(ss);
+ ss <<";\n";
+ //ss <<"printf(\"\\n********************tmp0 is %f\",tmp0);\n";
+ }
+ ss << " if(!isnan(tmp0))\n";
+ ss << " {\n";
+ ss << " current_sum += log(tmp0);\n";
+ ss << " current_count++;\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ }
+
+ ss << " if (lidx == 0)\n";
+ ss << " result[writePos] = exp(current_sum/current_count);\n";
+ ss << "}\n";
+
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss << " double tmp =0;\n";
+ ss << " tmp =";
+ vSubArguments[0]->GenDeclRef(ss);
+ ss << "[gid0];\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpHarMean::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"( ";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss <<"{\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double nVal=0.0;\n";
+ 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 * pow( tmp,-1));\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 *pow( tmp,-1));\n";
+ ss << " totallength +=1;\n";
+ }
+ else
+ {
+ ss << " return DBL_MIN;\n";
+ }
+ }
+ ss << " tmp = totallength*pow(nVal,-1);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpConfidence::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(gaussinvDecl);
+ funs.insert(gaussinv);
+}
+
+void OpConfidence::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() <<";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double alpha = " << GetBottom() <<";\n";
+ ss << " double sigma = " << GetBottom() <<";\n";
+ ss << " double size = " << GetBottom() <<";\n";
+ ss << " double tmp0,tmp1,tmp2;\n";
+ ss <<"\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " alpha = tmp0;\n";
+ ss << " sigma = tmp1;\n";
+ ss << " size = tmp2;\n";
+ ss << " double rn = floor(size);\n";
+ ss << " if(sigma <= 0.0 || alpha <= 0.0 || alpha >= 1.0";
+ ss << "|| rn < 1.0)\n";
+ ss << " tmp = -DBL_MAX;\n";
+ ss << " else\n";
+ ss << " tmp = gaussinv(1.0 - alpha * pow(2.0,-1.0)) * sigma ";
+ ss << "* pow(sqrt( rn ),-1);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpCritBinom::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(MinDecl);
+ funs.insert("");
+}
+
+void OpCritBinom::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " double tmp = " << GetBottom() <<";\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double n = " << GetBottom() <<";\n";
+ ss << " double p = " << GetBottom() <<";\n";
+ ss << " double alpha = " << GetBottom() <<";\n";
+ ss << " double tmp0 = 0.0,tmp1 = 0.0,tmp2 = 0.0;\n";
+ ss <<"\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " n = tmp0;\n";
+ ss << " p = tmp1;\n";
+ ss << " alpha = tmp2;\n";
+ ss << " double rn = floor(n);\n";
+ ss << " if (rn < 0.0 || alpha <= 0.0 || alpha >= 1.0 || p < 0.0";
+ ss << " || p > 1.0)\n";
+ ss << " tmp = -DBL_MIN;\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " double rq = (0.5 - p) + 0.5;\n";
+ ss << " double fFactor = pow(rq, rn);\n";
+ ss << " if (fFactor <= Min)\n";
+ ss << " {\n";
+ ss << " fFactor = pow(p, rn);\n";
+ ss << " if (fFactor <= Min)\n";
+ ss << " tmp = -DBL_MAX;\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " double fSum = 1.0 - fFactor;\n";
+ ss << " uint max =(uint)(rn), i;\n";
+ ss << " for (i = 0; i < max && fSum >= alpha; i++)\n";
+ ss << " {\n";
+ ss << " fFactor *= (rn - i) * pow((double)(i + 1),-1.0) *";
+ ss << " rq * pow(p, -1.0);\n";
+ ss << " fSum -= fFactor;\n";
+ ss << " }\n";
+ ss << " tmp = (rn - i);\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " double fSum = fFactor;\n";
+ ss << " uint max = (uint)(rn), i;\n";
+ ss << " for (i = 0; i < max && fSum < alpha; i++)\n";
+ ss << " {\n";
+ ss << " fFactor *= (rn - i) * pow((double)(i + 1), -1.0) *";
+ ss << " p * pow(rq, -1.0);\n";
+ ss << " fSum += fFactor;\n";
+ ss << " }\n";
+ ss << " tmp = (i);\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+
+void OpRsq::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ if( vSubArguments.size() !=2 ||vSubArguments[0]->GetFormulaToken()
+ ->GetType() != formula::svDoubleVectorRef||vSubArguments[1]
+ ->GetFormulaToken()->GetType() != formula::svDoubleVectorRef )
+ ///only support DoubleVector in OpRsq for GPU calculating.
+ throw Unhandled(__FILE__, __LINE__);
+ const formula::DoubleVectorRefToken* pCurDVR1 =
+ static_cast<const formula::DoubleVectorRefToken *>(
+ vSubArguments[0]->GetFormulaToken());
+ const formula::DoubleVectorRefToken* pCurDVR2 =
+ static_cast<const formula::DoubleVectorRefToken *>(
+ vSubArguments[1]->GetFormulaToken());
+ if( pCurDVR1->GetRefRowSize() != pCurDVR2->GetRefRowSize() )
+ throw Unhandled(__FILE__, __LINE__);
+
+ size_t nCurWindowSize = pCurDVR1->GetRefRowSize();
+
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double fSumX = 0.0;\n";
+ ss << " double fSumY = 0.0;\n";
+ ss << " double fSumDeltaXDeltaY = 0.0;\n";
+ ss << " double fInx;\n";
+ ss << " double fIny;\n";
+ ss << " double tmp0,tmp1;\n";
+
+ ss <<"\n";
+
+ ss << " for(int i=0; i<"<<nCurWindowSize<<"; i++)\n";
+ ss << " {\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef(true);
+ ss << "))\n";
+ ss << " fInx = 0;\n";
+ ss << " else\n";
+ ss << " fInx = "<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef(true);
+ ss << "))\n";
+ ss << " fIny = 0;\n";
+ ss << " else\n";
+ ss << " fIny = "<<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << " ;\n";
+ ss << " fSumX += fInx;\n";
+ ss << " fSumY += fIny;\n";
+ ss << " fCount = fCount + 1;\n";
+ ss << " }\n";
+ ss << " double fMeanX = fSumX / fCount;\n";
+ ss << " double fMeanY = fSumY / fCount;\n";
+ ss << " fSumX = 0.0;\n";
+ ss << " fSumY = 0.0;\n";
+ ss << " for(int i=0; i<"<<nCurWindowSize<<"; i++)\n";
+ ss << " {\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef(true);
+ ss << "))\n";
+ ss << " fInx = 0;\n";
+ ss << " else\n";
+ ss << " fInx = "<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " fIny = 0;\n";
+ ss << " else\n";
+ ss << " fIny = "<<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << " ;\n";
+ ss << " fSumDeltaXDeltaY += (fInx - fMeanX) * (fIny - fMeanY);\n";
+ ss << " fSumX += pow(fInx - fMeanX,2);\n";
+ ss << " fSumY += pow(fIny - fMeanY,2);\n";
+ ss << " }\n";
+ ss << " double tmp = pow( fSumDeltaXDeltaY,2) / (fSumX * fSumY);\n";
+ ss << " return tmp ;\n";
+ ss << "}\n";
+}
+
+void OpChiInv::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fMachEpsDecl);
+ funs.insert("");
+ decls.insert(fBigInvDecl);
+ funs.insert("");
+ decls.insert(fHalfMachEpsDecl);
+ funs.insert("");
+ decls.insert(lcl_IterateInverseChiInvDecl);
+ funs.insert(lcl_IterateInverseChiInv);
+ decls.insert(GetChiDistDecl);
+ funs.insert(GetChiDist);
+ decls.insert(lcl_HasChangeOfSignDecl);
+ funs.insert(lcl_HasChangeOfSign);
+ decls.insert(GetUpRegIGammaDecl);
+ funs.insert(GetUpRegIGamma);
+ decls.insert(GetGammaContFractionDecl);
+ funs.insert(GetGammaContFraction);
+ decls.insert(GetGammaSeriesDecl);
+ funs.insert(GetGammaSeries);
+}
+void OpChiInv::GenSlidingWindowFunction(
+ std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " double tmp0,tmp1,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";
+ }
+ }
+ ss << " tmp1 = floor(tmp1);";
+ ss << " if (tmp1 < 1.0 || tmp0 <= 0.0 || tmp0 > 1.0 )\n";
+ ss << " {\n";
+ ss << " return DBL_MIN;\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 fVal;\n";
+ ss << "}\n";
+}
+void OpNormdist::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ CHECK_PARAMETER_COUNT(3,4);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " double x,mue,sigma,c;\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp0,tmp1,tmp2;\n";
+ ss << " double tmp3 = 0;\n"; // optional argument
+ ss <<"\n ";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << "x = tmp0;\n";
+ ss << "mue = tmp1;\n";
+ ss << "sigma = tmp2;\n";
+ ss << "c = tmp3;\n";
+ ss << "if(sigma <= 0)\n";
+ ss << " return CreateDoubleError(IllegalArgument);\n";
+ ss << "double mid,tmp;\n";
+ ss << "mid = (x - mue)/sigma;\n";
+ ss << "if(c)\n";
+ ss << " tmp = 0.5 *erfc(-mid * 0.7071067811865475);\n";
+ ss << "else \n";
+ ss <<" tmp=(0.39894228040143268*exp(-pow(mid,2)/2.0))/sigma;\n";
+ ss << "return tmp;\n";
+ ss << "}\n";
+}
+void OpNormsdist::GenSlidingWindowFunction(
+ std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " double x = 0,tmp0 = 0;\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::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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " x = tmp0;\n";
+ ss << " double tmp = 0.5 * erfc((-1)*x * 0.7071067811865475);\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+
+void OpPermut::GenSlidingWindowFunction(
+ std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss <<" double inA;\n";
+ ss <<" double inB;\n";
+ ss <<" double tmp0,tmp1;\n";
+ ss <<" double tmp = 1 ;\n";
+ ss <<"\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " inA = tmp0;\n";
+ ss << " inB = tmp1;\n";
+ ss << " for( int i =0; i<inB; i++)\n";
+ ss << " {\n";
+ ss << " tmp *= inA ;\n";
+ ss << " inA = inA - 1.0;\n";
+ ss << " }\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+void OpPermutationA::GenSlidingWindowFunction(
+ std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss <<" int gid0=get_global_id(0);\n";
+ ss <<" double inA;\n";
+ ss <<" double inB;\n";
+ ss <<" double tmp = 1.0;\n";
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ ss << "int buffer_fIna_len = ";
+ ss << tmpCurDVR0->GetArrayLength();
+ ss << ";\n";
+ ss << " int buffer_fInb_len = ";
+ ss << tmpCurDVR1->GetArrayLength();
+ ss << ";\n";
+ ss << " if((gid0)>=buffer_fIna_len || isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " inA = 0;\nelse \n";
+ ss << " inA = "<<vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << "if((gid0)>=buffer_fInb_len || isnan(";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << "inB = 0;\nelse \n";
+ ss << " inB = "<<vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " for(int i=0; i<inB; i++)\n";
+ ss << " {\n";
+ ss << " tmp *= inA;\n";
+ ss << " }\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+
+void OpPhi::GenSlidingWindowFunction(
+ std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " double x,tmp0;\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::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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " x = tmp0;\n";
+ ss << " double tmp = 0.39894228040143268 * exp((-1)*pow(x,2) / 2.0);\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+
+void OpNorminv::GenSlidingWindowFunction(
+ std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss <<" double q,t,z;\n";
+ ss <<" double x,mue,sigma;\n";
+ ss <<" double tmp0,tmp1,tmp2;\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::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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss <<" x = tmp0;\n";
+ ss <<" mue = tmp1;\n";
+ ss <<" sigma = tmp2;\n";
+ ss <<" q = x -0.5;\n";
+ ss <<" if(fabs(q)<=.425)\n";
+ ss <<" {\n";
+ ss <<" t=0.180625-pow(q,2);\n";
+ ss <<" z=\n"
+ "q*\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*2509.0809287301226727";
+ ss <<"+33430.575583588128105\n"
+ ")\n"
+ "*t+67265.770927008700853\n"
+ ")\n"
+ "*t+45921.953931549871457\n"
+ ")\n"
+ "*t+13731.693765509461125\n"
+ ")\n"
+ "*t+1971.5909503065514427\n"
+ ")\n"
+ "*t+133.14166789178437745\n"
+ ")\n"
+ "*t+3.387132872796366608\n"
+ ")\n"
+ "/\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*5226.495278852854561";
+ ss <<"+28729.085735721942674\n"
+ ")\n"
+ "*t+39307.89580009271061\n"
+ ")\n"
+ "*t+21213.794301586595867\n"
+ ")\n"
+ "*t+5394.1960214247511077\n"
+ ")\n"
+ "*t+687.1870074920579083\n"
+ ")\n"
+ "*t+42.313330701600911252\n"
+ ")\n"
+ "*t+1.0\n"
+ ");\n";
+ ss <<"}\nelse\n{\n";
+ ss <<" if(q>0)\nt=1-x;\n";
+ ss <<"else\nt=x;\n";
+ ss <<"t=sqrt(-log(t));\n";
+ ss <<"if(t<=5.0)\n{\n";
+ ss <<"t+=-1.6;\n";
+ ss <<"z=\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*7.7454501427834140764e-4";
+ ss <<"+0.0227238449892691845833\n"
+ ")\n"
+ "*t+0.24178072517745061177\n"
+ ")\n"
+ "*t+1.27045825245236838258\n"
+ ")\n"
+ "*t+3.64784832476320460504\n"
+ ")\n"
+ "*t+5.7694972214606914055\n"
+ ")\n"
+ "*t+4.6303378461565452959\n"
+ ")\n"
+ "*t+1.42343711074968357734\n"
+ ")\n"
+ "/\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*1.05075007164441684324e-9";
+ ss <<"+5.475938084995344946e-4\n"
+ ")\n"
+ "*t+0.0151986665636164571966\n"
+ ")\n"
+ "*t+0.14810397642748007459\n"
+ ")\n"
+ "*t+0.68976733498510000455\n"
+ ")\n"
+ "*t+1.6763848301838038494\n"
+ ")\n"
+ "*t+2.05319162663775882187\n"
+ ")\n"
+ "*t+1.0\n"
+ ");\n}\n";
+ ss <<"else\n{\n";
+ ss <<"t+=-5.0;\n";
+ ss <<"z=\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*2.01033439929228813265e-7";
+ ss<<"+2.71155556874348757815e-5\n"
+ ")\n"
+ "*t+0.0012426609473880784386\n"
+ ")\n"
+ "*t+0.026532189526576123093\n"
+ ")\n"
+ "*t+0.29656057182850489123\n"
+ ")\n"
+ "*t+1.7848265399172913358\n"
+ ")\n"
+ "*t+5.4637849111641143699\n"
+ ")\n"
+ "*t+6.6579046435011037772\n"
+ ")\n"
+ "/\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*2.04426310338993978564e-15"
+ "+1.4215117583164458887e-7\n"
+ ")\n"
+ "*t+1.8463183175100546818e-5\n"
+ ")\n"
+ "*t+7.868691311456132591e-4\n"
+ ")\n"
+ "*t+0.0148753612908506148525\n"
+ ")\n"
+ "*t+0.13692988092273580531\n"
+ ")\n"
+ "*t+0.59983220655588793769\n"
+ ")\n"
+ "*t+1.0\n"
+ ");\n";
+ ss<<"}\n";
+ ss << "z = q < 0.0 ? (-1)*z : z;\n";
+ ss<<"}\n";
+ ss<<"double tmp = z*sigma + mue;\n";
+ ss<<"return tmp;\n";
+ ss<<"}\n";
+}
+void OpNormsinv:: GenSlidingWindowFunction
+ (std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " double q,t,z,x,tmp0;\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::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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss <<" x = tmp0;\n";
+ ss <<" q = x -0.5;\n";
+ ss <<" if(fabs(q)<=.425)\n";
+ ss <<" {\n";
+ ss <<" t=0.180625-pow(q,2);\n";
+ ss <<" z=\n"
+ "q*\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*2509.0809287301226727";
+ ss <<"+33430.575583588128105\n"
+ ")\n"
+ "*t+67265.770927008700853\n"
+ ")\n"
+ "*t+45921.953931549871457\n"
+ ")\n"
+ "*t+13731.693765509461125\n"
+ ")\n"
+ "*t+1971.5909503065514427\n"
+ ")\n"
+ "*t+133.14166789178437745\n"
+ ")\n"
+ "*t+3.387132872796366608\n"
+ ")\n"
+ "/\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*5226.495278852854561";
+ ss <<"+28729.085735721942674\n"
+ ")\n"
+ "*t+39307.89580009271061\n"
+ ")\n"
+ "*t+21213.794301586595867\n"
+ ")\n"
+ "*t+5394.1960214247511077\n"
+ ")\n"
+ "*t+687.1870074920579083\n"
+ ")\n"
+ "*t+42.313330701600911252\n"
+ ")\n"
+ "*t+1.0\n"
+ ");\n";
+ ss <<"}\nelse\n{\n";
+ ss <<" if(q>0)\nt=1-x;\n";
+ ss <<"else\nt=x;\n";
+ ss <<"t=sqrt(-log(t));\n";
+ ss <<"if(t<=5.0)\n{\n";
+ ss <<"t+=-1.6;\n";
+ ss <<"z=\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*7.7454501427834140764e-4";
+ ss <<"+0.0227238449892691845833\n"
+ ")\n"
+ "*t+0.24178072517745061177\n"
+ ")\n"
+ "*t+1.27045825245236838258\n"
+ ")\n"
+ "*t+3.64784832476320460504\n"
+ ")\n"
+ "*t+5.7694972214606914055\n"
+ ")\n"
+ "*t+4.6303378461565452959\n"
+ ")\n"
+ "*t+1.42343711074968357734\n"
+ ")\n"
+ "/\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*1.05075007164441684324e-9";
+ ss <<"+5.475938084995344946e-4\n"
+ ")\n"
+ "*t+0.0151986665636164571966\n"
+ ")\n"
+ "*t+0.14810397642748007459\n"
+ ")\n"
+ "*t+0.68976733498510000455\n"
+ ")\n"
+ "*t+1.6763848301838038494\n"
+ ")\n"
+ "*t+2.05319162663775882187\n"
+ ")\n"
+ "*t+1.0\n"
+ ");\n}\n";
+ ss <<"else\n{\n";
+ ss <<"t+=-5.0;\n";
+ ss <<"z=\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*2.01033439929228813265e-7";
+ ss <<"+2.71155556874348757815e-5\n"
+ ")\n"
+ "*t+0.0012426609473880784386\n"
+ ")\n"
+ "*t+0.026532189526576123093\n"
+ ")\n"
+ "*t+0.29656057182850489123\n"
+ ")\n"
+ "*t+1.7848265399172913358\n"
+ ")\n"
+ "*t+5.4637849111641143699\n"
+ ")\n"
+ "*t+6.6579046435011037772\n"
+ ")\n"
+ "/\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "(\n"
+ "t*2.04426310338993978564e-15"
+ "+1.4215117583164458887e-7\n"
+ ")\n"
+ "*t+1.8463183175100546818e-5\n"
+ ")\n"
+ "*t+7.868691311456132591e-4\n"
+ ")\n"
+ "*t+0.0148753612908506148525\n"
+ ")\n"
+ "*t+0.13692988092273580531\n"
+ ")\n"
+ "*t+0.59983220655588793769\n"
+ ")\n"
+ "*t+1.0\n"
+ ");\n";
+ ss <<"}\n";
+ ss << "z = q < 0.0 ? (-1)*z : z;\n";
+ ss <<"}\n";
+ ss <<"if (isnan(z))\n";
+ ss <<" return CreateDoubleError(NoValue);\n";
+ ss <<"return z;\n";
+ ss <<"}\n";
+}
+void OpMedian::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double tmp = 0;\n";
+ ss << " int i;\n";
+ ss << " unsigned int startFlag = 0;\n";
+ ss << " unsigned int endFlag = 0;\n";
+ ss << " double dataIna;\n";
+ for (const DynamicKernelArgumentRef & rArg : vSubArguments)
+ {
+ FormulaToken *pCur = rArg->GetFormulaToken();
+ assert(pCur);
+ if (const formula::DoubleVectorRefToken* pCurDVR =
+ dynamic_cast<const formula::DoubleVectorRefToken *>(pCur))
+ {
+ size_t nCurWindowSize = pCurDVR->GetRefRowSize();
+ ss << "startFlag = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
+ {
+ ss << "gid0; endFlag = "<< nCurWindowSize <<"-gid0;\n";
+ }
+ 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(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"( ";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\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 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";
+ }
+ else
+ {
+ ss << " return DBL_MIN;\n";
+ }
+ }
+ ss << " double fMean = fSum * pow(totallength,-1);\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 = ";
+ 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 << " continue;\n";
+ ss << " }\n";
+ ss << " vSum += (arg"<<i<<"-fMean)*(arg"<<i<<"-fMean);\n";
+ ss << " }\n";
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ ss << " tmp = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(!isnan(tmp))\n";
+ ss << " {\n";
+ ss << " vSum += (tmp-fMean)*(tmp-fMean);\n";
+ ss << " }\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " tmp = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " vSum += (tmp-fMean)*(tmp-fMean);\n";
+ }
+ }
+ ss << " double fStdDev = sqrt(vSum / (totallength - 1.0));\n";
+ ss << " double dx = 0.0;\n";
+ ss << " double xpower4 = 0.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 << " 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 << " continue;\n";
+ ss << " }\n";
+ ss<< " dx = (arg"<<i<<" -fMean) / fStdDev;\n";
+ ss<< " xpower4 = xpower4 + (dx * dx * dx * dx);\n";
+ ss << " }\n";
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ ss << " tmp = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(!isnan(tmp))\n";
+ ss << " {\n";
+ ss<< " dx = (tmp -fMean) / fStdDev;\n";
+ ss<< " xpower4 = xpower4 + (dx * dx * dx * dx);\n";
+ ss << " }\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " tmp = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss<< " dx = (tmp -fMean) / fStdDev;\n";
+ ss<< " xpower4 = xpower4 + (dx * dx * dx * dx);\n";
+ }
+ }
+ ss<< " double k_d = (totallength - 2.0) * (totallength - 3.0);\n";
+ ss<< " double k_l = totallength * (totallength + 1.0) /";
+ ss<< "((totallength - 1.0) * k_d);\n";
+ ss<< " double k_t = 3.0 * (totallength - 1.0) * ";
+ ss<< "(totallength - 1.0) / k_d;\n";
+ ss<< " tmp = xpower4 * k_l - k_t;\n";
+ ss<< " return tmp;\n";
+ ss << "}";
+}
+
+void OpIntercept::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSumX = 0.0;\n";
+ ss << " double fSumY = 0.0;\n";
+ ss << " double fMeanX = 0.0;\n";
+ ss << " double fMeanY = 0.0;\n";
+ ss << " double fSumDeltaXDeltaY = 0.0;\n";
+ ss << " double fSumSqrDeltaX = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double argX = 0.0;\n";
+ ss << " double argY = 0.0;\n";
+ if(vSubArguments.size() != 2)
+ {
+ ss << " return NAN;\n";
+ ss << "}\n";
+ return ;
+ }
+ FormulaToken *pCur = vSubArguments[1]->GetFormulaToken();
+ FormulaToken *pCur1 = vSubArguments[0]->GetFormulaToken();
+ assert(pCur);
+ assert(pCur1);
+ if (pCur->GetType() == formula::svDoubleVectorRef&&
+ pCur1->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur);
+ const formula::DoubleVectorRefToken* pDVR1 =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur1);
+
+ size_t nCurWindowSize = pDVR->GetRefRowSize();
+ size_t nCurWindowSize1 = pDVR1->GetRefRowSize();
+ size_t arrayLength = pDVR->GetArrayLength()<
+ pDVR1->GetArrayLength() ? pDVR->GetArrayLength():
+ pDVR1->GetArrayLength();
+ if(nCurWindowSize != nCurWindowSize1)
+ {
+ ss << " return NAN;\n";
+ ss << "}\n";
+ return ;
+ }
+ ss << " for (int i = ";
+ if ((!pDVR->IsStartFixed() && pDVR->IsEndFixed())
+ &&(!pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+ {
+ ss << "gid0; i < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+ &&(pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i < " << arrayLength ;
+ ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+ &&(!pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i + gid0 < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((pDVR->IsStartFixed() && pDVR->IsEndFixed())
+ &&(pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+ {
+ ss << "0; i < " << arrayLength << "; i++)\n";
+ ss << " {\n";
+ }
+ else
+ {
+ ss << "0; i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ ss << " break;\n";
+ ss << " }";
+ ss << " return NAN;\n";
+ ss << "}\n";
+ return ;
+ }
+
+ ss << " argX = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " argY = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(argX) || isnan(argY))\n";
+ ss << " continue;\n";
+ ss << " fSumX += argX;\n";
+ ss << " fSumY += argY;\n";
+ ss << " fCount += 1.0;\n";
+ ss << " }\n";
+
+ ss << " if (fCount < 1.0)\n";
+ ss << " return NAN;\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " fMeanX = fSumX * pow(fCount,-1.0);\n";
+ ss << " fMeanY = fSumY * pow(fCount,-1.0);\n";
+
+ ss << " for (int i = ";
+ if ((!pDVR->IsStartFixed() && pDVR->IsEndFixed())
+ &&(!pDVR1->IsStartFixed() && pDVR1->IsEndFixed()))
+ {
+ ss << "gid0; i < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+ &&(pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i < " << arrayLength ;
+ ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else if ((!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
+ &&(!pDVR1->IsStartFixed() && !pDVR1->IsEndFixed()))
+ {
+ ss << "0; i + gid0 < " << arrayLength;
+ ss << " && i < " << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ }
+ else
+ {
+ ss << "0; i < " << arrayLength << "; i++)\n";
+ ss << " {\n";
+ }
+
+ ss << " argX = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " argY = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if (isnan(argX) || isnan(argY))\n";
+ ss << " continue;\n";
+ ss << " fSumDeltaXDeltaY += (argX-fMeanX)*(argY-fMeanY);\n";
+ ss << " fSumSqrDeltaX += (argX-fMeanX) * (argX-fMeanX);\n";
+ ss << " }\n";
+ ss << " if(fSumSqrDeltaX == 0.0)\n";
+ ss << " return NAN;\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " return fMeanY -";
+ ss << " (fSumDeltaXDeltaY*pow(fSumSqrDeltaX,-1.0))*fMeanX;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << "}\n";
+ }
+ else
+ {
+ ss << " return NAN;\n";
+ ss << "}\n";
+ }
+}
+void OpLogInv:: GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp;\n";
+ ss << " double arg0,arg1,arg2,arg3;\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";
+ ss << " {\n";
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"=";
+ ss<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"= 0;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"=";
+ ss<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss<< " double q,t,z;\n";
+ ss<< " q = arg0 -0.5;\n";
+ ss<< " if(fabs(q)<=.425)\n";
+ ss<< " {\n";
+ ss<< " t=0.180625-pow(q, 2);\n";
+ ss<< " z=\n"
+ " q*\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " t*2509.0809287301226727";
+ ss<<"+33430.575583588128105\n"
+ " )\n"
+ " *t+67265.770927008700853\n"
+ " )\n"
+ " *t+45921.953931549871457\n"
+ " )\n"
+ " *t+13731.693765509461125\n"
+ " )\n"
+ " *t+1971.5909503065514427\n"
+ " )\n"
+ " *t+133.14166789178437745\n"
+ " )\n"
+ " *t+3.387132872796366608\n"
+ " )\n"
+ " /\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " t*5226.495278852854561";
+ ss<<"+28729.085735721942674\n"
+ " )\n"
+ " *t+39307.89580009271061\n"
+ " )\n"
+ " *t+21213.794301586595867\n"
+ " )\n"
+ " *t+5394.1960214247511077\n"
+ " )\n"
+ " *t+687.1870074920579083\n"
+ " )\n"
+ " *t+42.313330701600911252\n"
+ " )\n"
+ " *t+1.0\n"
+ " );\n";
+ ss<<" }\n";
+ ss<<" else\n";
+ ss<<" {\n";
+ ss<<" t = q > 0 ? 1 - arg0 : arg0;\n";
+ ss<<" t=sqrt(-log(t));\n";
+ ss<<" if(t<=5.0)\n";
+ ss<<" {\n";
+ ss<<" t+=-1.6;\n";
+ ss<<" z=\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " t*7.7454501427834140764e-4";
+ ss<<"+0.0227238449892691845833\n"
+ " )\n"
+ " *t+0.24178072517745061177\n"
+ " )\n"
+ " *t+1.27045825245236838258\n"
+ " )\n"
+ " *t+3.64784832476320460504\n"
+ " )\n"
+ " *t+5.7694972214606914055\n"
+ " )\n"
+ " *t+4.6303378461565452959\n"
+ " )\n"
+ " *t+1.42343711074968357734\n"
+ " )\n"
+ " /\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " t*1.05075007164441684324e-9";
+ ss<<"+5.475938084995344946e-4\n"
+ " )\n"
+ " *t+0.0151986665636164571966\n"
+ " )\n"
+ " *t+0.14810397642748007459\n"
+ " )\n"
+ " *t+0.68976733498510000455\n"
+ " )\n"
+ " *t+1.6763848301838038494\n"
+ " )\n"
+ " *t+2.05319162663775882187\n"
+ " )\n"
+ " *t+1.0\n"
+ " );\n";
+ ss<<" }\n";
+ ss<<" else\n";
+ ss<<" {\n";
+ ss<<" t+=-5.0;\n";
+ ss<<" z=\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " t*2.01033439929228813265e-7";
+ ss<<"+2.71155556874348757815e-5\n"
+ " )\n"
+ " *t+0.0012426609473880784386\n"
+ " )\n"
+ " *t+0.026532189526576123093\n"
+ " )\n"
+ " *t+0.29656057182850489123\n"
+ " )\n"
+ " *t+1.7848265399172913358\n"
+ " )\n"
+ " *t+5.4637849111641143699\n"
+ " )\n"
+ " *t+6.6579046435011037772\n"
+ " )\n"
+ " /\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " (\n"
+ " t*2.04426310338993978564e-15"
+ " +1.4215117583164458887e-7\n"
+ " )\n"
+ " *t+1.8463183175100546818e-5\n"
+ " )\n"
+ " *t+7.868691311456132591e-4\n"
+ " )\n"
+ " *t+0.0148753612908506148525\n"
+ " )\n"
+ " *t+0.13692988092273580531\n"
+ " )\n"
+ " *t+0.59983220655588793769\n"
+ " )\n"
+ " *t+1.0\n"
+ " );\n";
+ ss << " }\n";
+ ss << " z = q < 0.0 ? (-1)*z : z;\n";
+ ss << " }\n";
+ ss << " tmp = exp(arg1+arg2*z);\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+
+void OpForecast::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *pCur0 = vSubArguments[0]->GetFormulaToken();
+ assert(pCur0);
+ const formula::SingleVectorRefToken*pCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(pCur0);
+ FormulaToken *pCur1 = vSubArguments[1]->GetFormulaToken();
+ assert(pCur1);
+ const formula::DoubleVectorRefToken* pCurDVR1 =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur1);
+ size_t nCurWindowSize = pCurDVR1->GetRefRowSize();
+ FormulaToken *pCur2 = vSubArguments[2]->GetFormulaToken();
+ assert(pCur2);
+ const formula::DoubleVectorRefToken* pCurDVR2 =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur2);
+ size_t nCurWindowSize1 = pCurDVR2->GetRefRowSize();
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"( ";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSumX = 0.0;\n";
+ ss << " double fSumY = 0.0;\n";
+ ss << " double fSumDeltaXDeltaY = 0.0;\n";
+ ss << " double fSumSqrDeltaX = 0.0;\n";
+ if(pCur0->GetType()== formula::svDouble ||
+ pCur0->GetType() == formula::svSingleVectorRef)
+ {
+ ss << " double arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ else
+ ss << "return HUGE_VAL";
+ if(pCur1->GetType() != formula::svDoubleVectorRef ||
+ pCur2->GetType() != formula::svDoubleVectorRef)
+ ss << "return HUGE_VAL";
+ else
+ {
+ ss<< " if(isnan(arg0)||(gid0>=";
+ ss<<pCurDVR0->GetArrayLength();
+ ss<<"))\n";
+ ss<<" arg0 = 0;\n";
+ ss << " int length="<<nCurWindowSize;
+ ss << ";\n";
+ ss << " int length1= "<<nCurWindowSize1;
+ ss << ";\n";
+ ss << " if(length!=length1)\n";
+ ss << " return 0;\n";
+ ss << " double tmp = 0;\n";
+ ss << " for (int i = 0; i <" << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ ss << " double arg1 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef(true);
+ ss << ";\n";
+ ss << " double arg2 = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef(true);
+ ss << ";\n";
+ ss << " if(isnan(arg1)||((gid0+i)>=";
+ ss << pCurDVR1->GetArrayLength();
+ ss << "))\n";
+ ss << " {\n";
+ ss << " length--;\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " if(isnan(arg2)||((gid0+i)>=";
+ ss << pCurDVR2->GetArrayLength();
+ ss << "))\n";
+ ss << " {\n";
+ ss << " length--;\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " fSumY+=arg1;\n";
+ ss << " fSumX+=arg2;\n";
+ ss << " }\n";
+ ss << " double fMeanX = fSumX / length;\n";
+ ss << " double fMeanY = fSumY / length;\n";
+ ss << " for (int i = 0; i <" << nCurWindowSize << "; i++)\n";
+ ss << " {\n";
+ ss << " double arg1 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef(true);
+ ss << ";\n";
+ ss << " double arg2 = ";
+ ss << vSubArguments[2]->GenSlidingWindowDeclRef(true);
+ ss << ";\n";
+ ss << " if(isnan(arg1)||((gid0+i)>=";
+ ss <<pCurDVR1->GetArrayLength();
+ ss <<"))\n";
+ ss <<" {\n";
+ ss <<" continue;\n";
+ ss <<" }\n";
+ ss << " if(isnan(arg2)||((gid0+i)>=";
+ ss <<pCurDVR2->GetArrayLength();
+ ss <<"))\n";
+ ss <<" {\n";
+ ss <<" continue;\n";
+ ss <<" }\n";
+ ss <<" fSumDeltaXDeltaY+=(arg2 - fMeanX) * (arg1 - fMeanY);\n";
+ ss <<" fSumSqrDeltaX+=pow(arg2 - fMeanX, 2);\n";
+ ss <<" }\n";
+ ss <<" tmp =fMeanY + fSumDeltaXDeltaY / fSumSqrDeltaX *";
+ ss <<" (arg0 - fMeanX);\n";
+ ss <<" return tmp;\n";
+ ss << "}";
+ }
+}
+void OpLogNormDist::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR0= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur0);
+ FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR1= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur1);
+ FormulaToken *tmpCur2 = vSubArguments[2]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR2= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur2);
+ FormulaToken *tmpCur3 = vSubArguments[3]->GetFormulaToken();
+ const formula::SingleVectorRefToken*tmpCurDVR3= static_cast<const
+ formula::SingleVectorRefToken *>(tmpCur3);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0,arg1,arg2,arg3;\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";
+ ss << " {\n";
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"=";
+ ss<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"= 0;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"=";
+ ss <<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " double tmp;\n";
+ ss << " if(isnan(arg0)||(gid0>=";
+ ss << tmpCurDVR0->GetArrayLength();
+ ss << "))\n";
+ ss << " arg0 = 0;\n";
+ ss << " if(isnan(arg1)||(gid0>=";
+ ss << tmpCurDVR1->GetArrayLength();
+ ss << "))\n";
+ ss << " arg1 = 0;\n";
+ ss << " if(isnan(arg2)||(gid0>=";
+ ss << tmpCurDVR2->GetArrayLength();
+ ss << "))\n";
+ ss << " arg2 = 0;\n";
+ ss << " if(isnan(arg3)||(gid0>=";
+ ss << tmpCurDVR3->GetArrayLength();
+ ss << "))\n";
+ ss << " arg3 = 0;\n";
+ ss << " double temp = (log(arg0)-arg1)/arg2;\n";
+ ss << " if(arg3)\n";
+ ss << " {\n";
+ ss << " if(arg0<=0)\n";
+ ss << " tmp = 0.0;\n";
+ ss << " else\n";
+ ss << " tmp = 0.5 * erfc(-temp * 0.7071067811865475);\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " tmp = (0.39894228040143268 * exp((-1)*pow(temp, 2)";
+ ss << " / 2.0))/(arg2*arg0);\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+
+void OpGammaDist::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fBigInvDecl);decls.insert(fLogDblMaxDecl);
+ decls.insert(fHalfMachEpsDecl);decls.insert(fMaxGammaArgumentDecl);
+ decls.insert(GetGammaSeriesDecl);decls.insert(GetGammaContFractionDecl);
+ decls.insert(GetLowRegIGammaDecl);decls.insert(GetGammaDistDecl);
+ decls.insert(GetGammaDistPDFDecl);
+ funs.insert(GetGammaSeries);funs.insert(GetGammaContFraction);
+ funs.insert(GetLowRegIGamma);funs.insert(GetGammaDist);
+ funs.insert(GetGammaDistPDF);
+}
+
+void OpGammaDist::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp;\n";
+ ss << " double arg0,arg1,arg2,arg3;\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";
+ ss << " {\n";
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"=";
+ ss<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"= 0;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"=";
+ ss <<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " if (arg3)\n";
+ ss << " tmp=GetGammaDist( arg0, arg1, arg2);\n";
+ ss << " else\n";
+ ss << " tmp=GetGammaDistPDF( arg0, arg1, arg2);\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+void OpChiDist::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fBigInvDecl);
+ funs.insert("");
+ decls.insert(fHalfMachEpsDecl);
+ funs.insert("");
+ decls.insert(GetUpRegIGammaDecl);
+ funs.insert(GetUpRegIGamma);
+ decls.insert(GetGammaSeriesDecl);
+ funs.insert(GetGammaSeries);
+ decls.insert(GetGammaContFractionDecl);
+ funs.insert(GetGammaContFraction);
+ decls.insert(GetChiDistDecl);
+ funs.insert(GetChiDist);
+}
+void OpChiDist::GenSlidingWindowFunction(
+ std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " double fx,fDF,tmp=0,tmp0=0,tmp1=0;\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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ }
+ ss << " fx = tmp0;\n";
+ ss << " fDF = floor(tmp1);\n";
+ ss << " if(fDF < 1.0)\n";
+ ss << " {\n";
+ ss << " return DBL_MIN;\n";
+ ss << " }\n";
+ ss << " tmp = GetChiDist( fx, fDF);\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+void OpBinomdist::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fMachEpsDecl);
+ funs.insert("");
+ decls.insert(MinDecl);
+ funs.insert("");
+ decls.insert(fMaxGammaArgumentDecl);
+ funs.insert("");
+ decls.insert(GetBinomDistPMFDecl);
+ funs.insert(GetBinomDistPMF);
+ decls.insert(GetBetaDistDecl);
+ funs.insert(GetBetaDist);
+ decls.insert(lcl_GetBinomDistRangeDecl);
+ funs.insert(lcl_GetBinomDistRange);
+ decls.insert(lcl_GetBetaHelperContFracDecl);
+ funs.insert(lcl_GetBetaHelperContFrac);
+ decls.insert(GetBetaDistPDFDecl);
+ funs.insert(GetBetaDistPDF);
+ decls.insert(GetLogBetaDecl);
+ funs.insert(GetLogBeta);
+ decls.insert(GetBetaDecl);
+ funs.insert(GetBeta);
+ decls.insert(lcl_getLanczosSumDecl);
+ funs.insert(lcl_getLanczosSum);
+}
+void OpBinomdist::GenSlidingWindowFunction(
+ std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " double tmp0,tmp1,tmp2,tmp3;\n";
+ ss << " int gid0=get_global_id(0);\n";
+
+ ss <<"\n ";
+ //while (i-- > 1)
+ 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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " tmp0 = floor(tmp0);\n";
+ ss << " tmp1 = floor(tmp1);\n";
+ ss << " double rq = (0.5 - tmp2) + 0.5;\n";
+ ss << " if (tmp1 < 0.0 || tmp0 < 0.0 || tmp0 > tmp1 ||";
+ ss << "tmp2 < 0.0 || tmp2 > 1.0)\n";
+ ss << " {\n";
+ ss << " return DBL_MIN;\n";
+ ss << " }\n";
+ ss << " if(tmp2 == 0.0)\n";
+ ss << " return ( (tmp0 == 0.0 || tmp3) ? 1.0 : 0.0 );\n";
+ ss << " if(tmp2 == 1.0)\n";
+ ss << " return ( (tmp0 == tmp1) ? 1.0 : 0.0);\n";
+ ss << " if(!tmp3)\n";
+ ss << " return ( GetBinomDistPMF(tmp0, tmp1, tmp2));\n";
+ ss << " else \n";
+ ss << " {\n";
+ ss << " if(tmp0 == tmp1)\n";
+ ss << " return 1.0;\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " double fFactor = pow(rq,tmp1);\n";
+ ss << " if(tmp0 == 0.0)\n";
+ ss << " return (fFactor);\n";
+ ss << " else if(fFactor <= Min)\n";
+ ss << " {\n";
+ ss << " fFactor = pow(tmp2,tmp1);\n";
+ ss << " if(fFactor <= Min)\n";
+ ss << " return GetBetaDist";
+ ss << "(rq, tmp1 - tmp0, tmp0 + 1.0);\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " if(fFactor > fMachEps)\n";
+ ss << " {\n";
+ ss << " double fSum = 1.0 - fFactor;\n";
+ ss << " unsigned int max = ";
+ ss << "(unsigned int)((tmp1 - tmp0)-1);\n";
+ ss << " for (uint i = 0; i < max && fFactor > 0.0;";
+ ss << " i++)\n";
+ ss << " {\n";
+ ss << " fFactor *= (tmp1 - i)*pow((i + 1),-1.0)*";
+ ss << "rq*pow(tmp2,-1.0);\n";
+ ss << " fSum -= fFactor;\n";
+ ss << " }\n";
+ ss << " return ( (fSum < 0.0) ? 0.0 : fSum );\n";
+ ss << " }\n";
+ ss << " else \n";
+ ss << " return (lcl_GetBinomDistRange";
+ ss << "(tmp1, tmp1 - tmp0, tmp1, fFactor, rq, tmp2));\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " double rtmp = ( lcl_GetBinomDistRange";
+ ss << "(tmp1, 0.0, tmp0, fFactor, tmp2, rq));\n";
+ ss << " return rtmp;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << "}\n";
+}
+
+void OpChiSqDist::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fMaxGammaArgumentDecl);decls.insert(GetChiSqDistCDFDecl);
+ decls.insert(GetChiSqDistPDFDecl);decls.insert(GetLowRegIGammaDecl);
+ decls.insert(GetGammaContFractionDecl);decls.insert(GetGammaSeriesDecl);
+ decls.insert(fHalfMachEpsDecl);decls.insert(F_PIDecl);
+ decls.insert(fBigInvDecl);
+
+ funs.insert(GetGammaContFraction);funs.insert(GetChiSqDistCDF);
+ funs.insert(GetChiSqDistPDF);funs.insert(GetLowRegIGamma);
+ funs.insert(GetGammaSeries);
+}
+
+void OpChiSqDist::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+ ss << " double result = 0;\n";
+ if(vSubArguments.size()<2)
+ {
+ ss << " result = -DBL_MAX;\n";
+ ss << " return result;\n";
+ }else
+ {
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+ if(vSubArguments.size() == 2)
+ {
+ ss << " int tmp2 = 1;\n";
+ }
+ }
+ ss <<"\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " tmp1 = floor(tmp1);\n";
+ ss << " if(tmp1 < 1.0)\n";
+ ss << " result = -DBL_MAX;\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " if(tmp2)\n";
+ ss << " result =GetChiSqDistCDF(tmp0,tmp1);\n";
+ ss << " else\n";
+ ss << " result =GetChiSqDistPDF(tmp0,tmp1);\n";
+ ss << " }\n";
+ ss << " return result;\n";
+ ss << "}";
+}
+
+ void OpChiSqInv::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fMaxGammaArgumentDecl);decls.insert(GetChiSqDistCDFDecl);
+ decls.insert(GetLowRegIGammaDecl);decls.insert(lcl_IterateInverseChiSQInvDecl);
+ decls.insert(GetGammaContFractionDecl);decls.insert(GetGammaSeriesDecl);
+ decls.insert(fHalfMachEpsDecl);decls.insert(F_PIDecl);
+ decls.insert(fBigInvDecl);decls.insert(lcl_HasChangeOfSignDecl);
+ decls.insert(fMachEpsDecl);
+
+ funs.insert(GetGammaContFraction);funs.insert(GetChiSqDistCDF);
+ funs.insert(GetLowRegIGamma);funs.insert(lcl_HasChangeOfSign);
+ funs.insert(GetGammaSeries);funs.insert(lcl_IterateInverseChiSQInv);
+}
+
+void OpChiSqInv::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " int singleIndex = gid0;\n";
+ ss << " double result = 0;\n";
+ if(vSubArguments.size()!=2)
+ {
+ ss << " result = -DBL_MAX;\n";
+ ss << " return result;\n";
+ }
+ else
+ {
+ GenTmpVariables(ss,vSubArguments);
+ CheckAllSubArgumentIsNan(ss,vSubArguments);
+ ss <<"\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+ 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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " tmp1 = floor(tmp1);\n";
+ ss << " bool bConvError;\n";
+ ss << " if(tmp1 < 1.0 || tmp0 < 0 || tmp0>=1.0)\n";
+ ss << " result = -DBL_MAX;\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " result =lcl_IterateInverseChiSQInv( tmp0, tmp1,";
+ ss << "tmp1*0.5, tmp1, &bConvError );\n";
+ ss << " }\n";
+ ss << " if(bConvError)\n";
+ ss << " result = -DBL_MAX;\n";
+ ss << " return result;\n";
+ ss << "}";
+ }
+
+}
+void OpGammaInv::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fBigInvDecl);decls.insert(fHalfMachEpsDecl);
+ decls.insert(GetGammaSeriesDecl);decls.insert(GetGammaContFractionDecl);
+ decls.insert(GetGammaInvValueDecl);
+ funs.insert(GetGammaSeries);funs.insert(GetGammaContFraction);
+ funs.insert(GetGammaInvValue);
+}
+
+void OpGammaInv::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp;\n";
+ ss << " double arg0,arg1,arg2;\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";
+ ss << " {\n";
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"=";
+ ss <<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"= 0;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"=";
+ ss <<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " if (arg0 == 0.0)\n"
+ " {\n"
+ " tmp=0.0;\n"
+ " return tmp;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " bool bConvError;\n"
+ " double fStart = arg1 * arg2;\n"
+ " double fAx=fStart*0.5;\n"
+ " double fBx=fStart;\n"
+ " bConvError = false;\n"
+ " double fYEps = 1.0E-307;\n"
+ " double fXEps = 2.22045e-016;\n"
+ " double fAy = arg0-GetGammaInvValue(arg1,arg2,fAx);\n"
+ " double fBy = arg0-GetGammaInvValue(arg1,arg2,fBx);\n"
+ " double fTemp;\n"
+ " unsigned short nCount;\n"
+ " for (nCount = 0; nCount < 1000 && !((fAy < 0.0 && fBy > 0.0)"
+ " || (fAy > 0.0 && fBy < 0.0)); nCount++)\n"
+ " {\n"
+ " if (fabs(fAy) <= fabs(fBy))\n"
+ " {\n"
+ " fTemp = fAx;\n"
+ " fAx += 2.0 * (fAx - fBx);\n"
+ " if (fAx < 0.0)\n"
+ " fAx = 0.0;\n"
+ " fBx = fTemp;\n"
+ " fBy = fAy;\n"
+ " fAy = arg0-GetGammaInvValue(arg1,arg2,fAx);\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " fTemp = fBx;\n"
+ " fBx += 2.0 * (fBx - fAx);\n"
+ " fAx = fTemp;\n"
+ " fAy = fBy;\n"
+ " fBy = arg0-GetGammaInvValue(arg1,arg2,fBx);\n"
+ " }\n"
+ " }\n"
+ " if (fAy == 0.0)\n"
+ " {\n"
+ " tmp = fAx;\n"
+ " return tmp;\n"
+ " }\n"
+ " if (fBy == 0.0)\n"
+ " {\n"
+ " tmp = fBx;\n"
+ " return tmp;\n"
+ " }\n"
+ " if (!((fAy < 0.0 && fBy > 0.0) || (fAy > 0.0 && fBy < 0.0)))\n"
+ " {\n"
+ " bConvError = true;\n"
+ " tmp = 0.0;\n"
+ " return tmp;\n"
+ " }\n"
+ " double fPx = fAx;\n"
+ " double fPy = fAy;\n"
+ " double fQx = fBx;\n"
+ " double fQy = fBy;\n"
+ " double fRx = fAx;\n"
+ " double fRy = fAy;\n"
+ " double fSx = 0.5 * (fAx + fBx);\n"
+ " bool bHasToInterpolate = true;\n"
+ " nCount = 0;\n"
+ " while ( nCount < 500 && fabs(fRy) > fYEps &&"
+ "(fBx-fAx) > fmax( fabs(fAx), fabs(fBx)) * fXEps )\n"
+ " {\n"
+ " if (bHasToInterpolate)\n"
+ " {\n"
+ " if (fPy!=fQy && fQy!=fRy && fRy!=fPy)\n"
+ " {\n"
+ " fSx = fPx * fRy * fQy *pow( (fRy-fPy),-1) *pow"
+ "( (fQy-fPy),-1)"
+ "+ fRx * fQy * fPy *pow( (fQy-fRy),-1) *pow( (fPy-fRy),-1)"
+ "+ fQx * fPy * fRy *pow( (fPy-fQy),-1) *pow( (fRy-fQy),-1);\n"
+ " bHasToInterpolate = (fAx < fSx) && (fSx < fBx);\n"
+ " }\n"
+ " else\n"
+ " bHasToInterpolate = false;\n"
+ " }\n"
+ " if(!bHasToInterpolate)\n"
+ " {\n"
+ " fSx = 0.5 * (fAx + fBx);\n"
+ " fPx = fAx; fPy = fAy;\n"
+ " fQx = fBx; fQy = fBy;\n"
+ " bHasToInterpolate = true;\n"
+ " }\n"
+ " fPx = fQx; fQx = fRx; fRx = fSx;\n"
+ " fPy = fQy; fQy = fRy;\n"
+ " fRy = arg0-GetGammaInvValue(arg1,arg2,fSx);\n"
+ " if ((fAy < 0.0 && fRy > 0.0) || (fAy > 0.0 && fRy < 0.0))\n"
+ " {\n"
+ " fBx = fRx;\n"
+ " fBy = fRy;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " fAx = fRx;\n"
+ " fAy = fRy;\n"
+ " }\n"
+ " bHasToInterpolate = bHasToInterpolate && (fabs(fRy)"
+ " * 2.0 <= fabs(fQy));\n"
+ " ++nCount;\n"
+ " }\n"
+ " tmp = fRx;\n"
+ " return tmp;\n"
+ " }\n"
+ "}\n";
+}
+void OpFInv::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fMachEpsDecl);decls.insert(fMaxGammaArgumentDecl);
+ decls.insert(lcl_getLanczosSumDecl);decls.insert(GetBetaDecl);
+ decls.insert(GetLogBetaDecl);decls.insert(GetBetaDistPDFDecl);
+ decls.insert(lcl_GetBetaHelperContFracDecl);decls.insert(GetFInvValueDecl);
+ funs.insert(lcl_getLanczosSum);funs.insert(GetBeta);
+ funs.insert(GetLogBeta);funs.insert(GetBetaDistPDF);
+ funs.insert(lcl_GetBetaHelperContFrac);funs.insert(GetFInvValue);
+}
+
+void OpFInv::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp;\n";
+ ss << " double arg0,arg1,arg2;\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";
+ ss << " {\n";
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"="<<vSubArguments[i]->
+ GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"= 0;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"="<<vSubArguments[i]->
+ GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " double fF2=floor(arg2);\n"
+ " double fF1=floor(arg1);\n"
+ " bool bConvError;\n"
+ " double fAx=fF1*0.5;\n"
+ " double fBx=fF1;\n"
+ " bConvError = false;\n"
+ " const double fYEps = 1.0E-307;\n"
+ " const double fXEps = 2.22045e-016;\n"
+ " double fAy = arg0-GetFInvValue(fF1,fF2,fAx);\n"
+ " double fBy = arg0-GetFInvValue(fF1,fF2,fBx);\n"
+ " double fTemp;\n"
+ " unsigned short nCount;\n"
+ " for (nCount = 0; nCount < 1000 && !((fAy < 0.0 && fBy > 0.0)"
+ " || (fAy > 0.0 && fBy < 0.0)); nCount++)\n"
+ " {\n"
+ " if (fabs(fAy) <= fabs(fBy))\n"
+ " {\n"
+ " fTemp = fAx;\n"
+ " fAx += 2.0 * (fAx - fBx);\n"
+ " if (fAx < 0.0)\n"
+ " fAx = 0.0;\n"
+ " fBx = fTemp;\n"
+ " fBy = fAy;\n"
+ " fAy = arg0-GetFInvValue(fF1,fF2,fAx);\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " fTemp = fBx;\n"
+ " fBx += 2.0 * (fBx - fAx);\n"
+ " fAx = fTemp;\n"
+ " fAy = fBy;\n"
+ " fBy = arg0-GetFInvValue(fF1,fF2,fBx);\n"
+ " }\n"
+ " }\n"
+ " if (fAy == 0.0)\n"
+ " {\n"
+ " tmp = fAx;\n"
+ " return tmp;\n"
+ " }\n"
+ " if (fBy == 0.0)\n"
+ " {\n"
+ " tmp = fBx;\n"
+ " return tmp;\n"
+ " }\n"
+ " if (!((fAy < 0.0 && fBy > 0.0) || (fAy > 0.0 && fBy < 0.0)))\n"
+ " {\n"
+ " bConvError = true;\n"
+ " tmp = 0.0;\n"
+ " return tmp;\n"
+ " }\n"
+ " double fPx = fAx;\n"
+ " double fPy = fAy;\n"
+ " double fQx = fBx;\n"
+ " double fQy = fBy;\n"
+ " double fRx = fAx;\n"
+ " double fRy = fAy;\n"
+ " double fSx = 0.5 * (fAx + fBx);\n"
+ " bool bHasToInterpolate = true;\n"
+ " nCount = 0;\n"
+ " while ( nCount < 500 && fabs(fRy) > fYEps &&"
+ "(fBx-fAx) > fmax( fabs(fAx), fabs(fBx)) * fXEps )\n"
+ " {\n"
+ " if (bHasToInterpolate)\n"
+ " {\n"
+ " if (fPy!=fQy && fQy!=fRy && fRy!=fPy)\n"
+ " {\n"
+ " fSx = fPx * fRy * fQy *pow( (fRy-fPy),-1)"
+ " *pow( (fQy-fPy),-1)+fRx * fQy * fPy*pow( (fQy-fRy),-1) *"
+ "pow( (fPy-fRy),-1)+ fQx * fPy * fRy *pow( (fPy-fQy),-1)"
+ " *pow((fRy-fQy),-1);\n"
+ " bHasToInterpolate = (fAx < fSx) && (fSx < fBx);\n"
+ " }\n"
+ " else\n"
+ " bHasToInterpolate = false;\n"
+ " }\n"
+ " if(!bHasToInterpolate)\n"
+ " {\n"
+ " fSx = 0.5 * (fAx + fBx);\n"
+ " fPx = fAx; fPy = fAy;\n"
+ " fQx = fBx; fQy = fBy;\n"
+ " bHasToInterpolate = true;\n"
+ " }\n"
+ " fPx = fQx; fQx = fRx; fRx = fSx;\n"
+ " fPy = fQy; fQy = fRy;\n"
+ " fRy = arg0-GetFInvValue(fF1,fF2,fSx);\n"
+ " if ((fAy < 0.0 && fRy > 0.0) || (fAy > 0.0 && fRy < 0.0))\n"
+ " {\n"
+ " fBx = fRx; fBy = fRy;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " fAx = fRx; fAy = fRy;\n"
+ " }\n"
+ " bHasToInterpolate = bHasToInterpolate && (fabs(fRy)"
+ " * 2.0 <= fabs(fQy));\n"
+ " ++nCount;\n"
+ " }\n"
+ " tmp = fRx;\n"
+ " return tmp;"
+ "}";
+}
+void OpFTest::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fMachEpsDecl);decls.insert(fMaxGammaArgumentDecl);
+ decls.insert(lcl_getLanczosSumDecl);decls.insert(GetBetaDecl);
+ decls.insert(GetLogBetaDecl);decls.insert(GetBetaDistPDFDecl);
+ decls.insert(lcl_GetBetaHelperContFracDecl);decls.insert(GetBetaDistDecl);
+ decls.insert(GetFDistDecl);
+ funs.insert(lcl_getLanczosSum);funs.insert(GetBeta);
+ funs.insert(GetLogBeta);funs.insert(GetBetaDistPDF);
+ funs.insert(lcl_GetBetaHelperContFrac);funs.insert(GetBetaDist);
+ funs.insert(GetFDist);
+}
+void OpFTest::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ 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::DoubleVectorRefToken* pCurDVR1 =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur1);
+ size_t nCurWindowSize1 = pCurDVR1->GetRefRowSize();
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"( ";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum1 = 0.0;\n";
+ ss << " double fSumSqr1 = 0.0;\n";
+ ss << " double fSum2 = 0.0;\n";
+ ss << " double fSumSqr2 = 0.0;\n";
+ ss << " int length0="<<nCurWindowSize;
+ ss << ";\n";
+ ss << " int length1= "<<nCurWindowSize1;
+ ss << ";\n";
+ ss << " double tmp = 0;\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken *pCurSub = vSubArguments[i]->GetFormulaToken();
+ assert(pCurSub);
+ if (pCurSub->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(pCurSub);
+ ss << " for (int i = ";
+ ss << "0; i < "<< pDVR->GetRefRowSize() << "; i++){\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"<<i<<"--;\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " fSum"<<i+1<<" += arg"<<i<<";\n";
+ ss << " fSumSqr"<<i+1<<" += arg"<<i;
+ ss << " * arg"<<i<<";\n";
+ ss << " }\n";
+ }
+ else if (pCurSub->GetType() == formula::svSingleVectorRef)
+ {
+ ss << "return HUGE_VAL";
+ }
+ else if (pCurSub->GetType() == formula::svDouble)
+ {
+ ss << "return HUGE_VAL";
+ }
+ }
+ ss << " double fS1 = (fSumSqr1-fSum1*fSum1/length0)/(length0-1.0);\n"
+ " double fS2 = (fSumSqr2-fSum2*fSum2/length1)/(length1-1.0);\n"
+ " double fF, fF1, fF2;\n"
+ " if (fS1 > fS2)\n"
+ " {\n"
+ " fF = fS1/fS2;\n"
+ " fF1 = length0-1.0;\n"
+ " fF2 = length1-1.0;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " fF = fS2/fS1;\n"
+ " fF1 = length1-1.0;\n"
+ " fF2 = length0-1.0;\n"
+ " }\n"
+ " tmp = 2.0*GetFDist(fF, fF1, fF2);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+void OpB::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ //decls.insert(fBigInvDecl);decls.insert(fLogDblMaxDecl);
+ decls.insert(GetBinomDistPMFDecl);decls.insert(MinDecl);
+ decls.insert(fMachEpsDecl);decls.insert(fMaxGammaArgumentDecl);
+ decls.insert(GetBetaDistDecl);decls.insert(GetBetaDistPDFDecl);
+ decls.insert(lcl_GetBetaHelperContFracDecl);decls.insert(GetLogBetaDecl);
+ decls.insert(lcl_getLanczosSumDecl); decls.insert(GetBetaDecl);
+ funs.insert(GetBinomDistPMF);funs.insert(lcl_GetBinomDistRange);
+ funs.insert(GetBetaDist);funs.insert(GetBetaDistPDF);
+ funs.insert(lcl_GetBetaHelperContFrac);funs.insert(GetLogBeta);
+ funs.insert(lcl_getLanczosSum);funs.insert(GetBeta);
+}
+
+void OpB::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double min = 2.22507e-308;\n";
+ ss << " double tmp;\n";
+ ss << " double arg0,arg1,arg2,arg3;\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";
+ ss << " {\n";
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"= 0;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " double rxs = floor(arg2);\n"
+ " double rxe = floor(arg3);\n"
+ " double rn = floor(arg0);\n"
+ " double rq = (0.5 - arg1) + 0.5;\n"
+ " bool bIsValidX = (0.0 <= rxs && rxs <= rxe && rxe <= rn);\n"
+ " if (bIsValidX && 0.0 < arg1 && arg1 < 1.0)\n"
+ " {\n"
+ " if (rxs == rxe)\n"
+ " tmp = GetBinomDistPMF(rxs, rn, arg1);\n"
+ " else\n"
+ " {\n"
+ " double fFactor = pow(rq, rn);\n"
+ " if (fFactor > min)\n"
+ " tmp ="
+ " lcl_GetBinomDistRange(rn, rxs, rxe, fFactor, arg1, rq);\n"
+ " else\n"
+ " {\n"
+ " fFactor = pow(arg1, rn);\n"
+ " if (fFactor > min)\n"
+ " {\n"
+ " tmp ="
+ "lcl_GetBinomDistRange(rn, rn - rxe, rn - rxs, fFactor, rq, arg1);\n"
+ " }\n"
+ " else\n"
+ " tmp ="
+ "GetBetaDist(rq, rn - rxe, rxe + 1.0)"
+ "- GetBetaDist(rq, rn - rxs + 1, rxs);\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " if (bIsValidX)\n"
+ " {\n"
+ " if (arg1 == 0.0)\n"
+ " tmp = (rxs == 0.0 ? 1.0 : 0.0);\n"
+ " else if (arg1 == 1.0)\n"
+ " tmp = (rxe == rn ? 1.0 : 0.0);\n"
+ " else\n"
+ " {\n"
+ " tmp = DBL_MIN;\n"
+ " }\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " tmp = DBL_MIN;\n"
+ " }\n"
+ " }\n"
+ " return tmp;"
+ "}\n";
+}
+void OpBetaDist::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fMachEpsDecl);decls.insert(fMaxGammaArgumentDecl);
+ decls.insert(GetBetaDistDecl);decls.insert(GetBetaDistPDFDecl);
+ decls.insert(lcl_GetBetaHelperContFracDecl);decls.insert(GetLogBetaDecl);
+ decls.insert(GetBetaDecl);decls.insert(lcl_getLanczosSumDecl);
+ funs.insert(GetBetaDist);funs.insert(GetBetaDistPDF);
+ funs.insert(lcl_GetBetaHelperContFrac);funs.insert(GetLogBeta);
+ funs.insert(GetBeta);funs.insert(lcl_getLanczosSum);
+}
+void OpPoisson::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fHalfMachEpsDecl);
+ funs.insert("");
+ decls.insert(fMaxGammaArgumentDecl);
+ funs.insert("");
+ decls.insert(fBigInvDecl);
+ funs.insert("");
+ decls.insert(GetLogGammaDecl);
+ funs.insert(GetLogGamma);
+ decls.insert(lcl_GetLogGammaHelperDecl);
+ funs.insert(lcl_GetLogGammaHelper);
+ decls.insert(lcl_GetGammaHelperDecl);
+ funs.insert(lcl_GetGammaHelper);
+ decls.insert(lcl_getLanczosSumDecl);
+ funs.insert(lcl_getLanczosSum);
+ decls.insert(GetUpRegIGammaDecl);
+ funs.insert(GetUpRegIGamma);
+ decls.insert(GetGammaContFractionDecl);
+ funs.insert(GetGammaContFraction);
+ decls.insert(GetGammaSeriesDecl);
+ funs.insert(GetGammaSeries);
+}
+void OpPoisson::GenSlidingWindowFunction(
+ std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " double x,lambda,tmp,tmp0,tmp1,tmp2;\n";
+ ss << " int bCumulative;\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::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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " x = floor(tmp0);\n";
+ ss << " lambda = tmp1;\n";
+ ss << " bCumulative = tmp2;\n ";
+ ss << " if (!bCumulative)\n";
+ ss << " {\n";
+ ss << " if(lambda == 0.0)\n";
+ ss << " {\n";
+ ss << " return 0;\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " if (lambda >712)\n";
+ ss << " {\n";
+ ss << " tmp = (exp(x*log(lambda)-lambda-GetLogGamma(x+1.0)));\n";
+ ss << " return tmp;\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " double fPoissonVar = 1.0;\n";
+ ss << " for ( int f = 0; f < x; ++f )\n";
+ ss << " fPoissonVar *= lambda * pow(( (double)f + 1.0 ),-1);\n";
+ ss << " tmp = ( fPoissonVar * exp( -lambda ) );\n";
+ ss << " return tmp;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " } \n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " if (lambda == 0.0)\n";
+ ss << " {\n";
+ ss << " return 1;\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " if (lambda > 712 )\n";
+ ss << " {\n";
+ ss << " tmp = (GetUpRegIGamma(x+1.0,lambda));\n";
+ ss << " return tmp;\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " if (x >= 936.0)\n";
+ ss << " {\n";
+ ss << " return 1;\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " {\n";
+ ss << " double fSummand = exp(-lambda);\n";
+ ss << " double fSum = fSummand;\n";
+ ss << " int nEnd = (int) (x + 0.5);\n";
+ ss << " for (int i = 1; i <= nEnd; i++)\n";
+ ss << " {\n";
+ ss << " fSummand = (fSummand*lambda)*pow((double)i,-1);\n";
+ ss << " fSum += fSummand;\n";
+ ss << " }\n";
+ ss << " tmp = fSum;\n";
+ ss << " return tmp;\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << " }\n";
+ ss << "}\n";
+}
+void OpCovar::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ CHECK_PARAMETER_COUNT(2,2);
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double vSum = 0.0;\n";
+ ss << " double vSum0 = 0.0;\n";
+ ss << " double vSum1 = 0.0;\n";
+ ss << " double vMean0 = 0.0;\n";
+ ss << " double vMean1 = 0.0;\n";
+ ss << " double arg0 = 0.0;\n";
+ ss << " double arg1 = 0.0;\n";
+ FormulaToken* pCurX = vSubArguments[0]->GetFormulaToken();
+ FormulaToken* pCurY = vSubArguments[1]->GetFormulaToken();
+ if ((pCurX->GetType() == formula::svDoubleVectorRef)&&
+ (pCurY->GetType() == formula::svDoubleVectorRef)){
+ ss << " int cnt = 0;\n";
+ const formula::DoubleVectorRefToken* pCurDVRX =
+ static_cast<const formula::DoubleVectorRefToken* >(pCurX);
+ const formula::DoubleVectorRefToken* pCurDVRY =
+ static_cast<const formula::DoubleVectorRefToken* >(pCurY);
+ size_t nCurWindowSizeX = pCurDVRX->GetRefRowSize();
+ size_t nCurWindowSizeY = pCurDVRY->GetRefRowSize();
+ if(nCurWindowSizeX == nCurWindowSizeY)
+ {
+ ss << " for( ";
+ if (!pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+ ss << "int i = gid0; i < " << nCurWindowSizeX;
+ ss << " && i < " << pCurDVRX->GetArrayLength() << " && i < ";
+ ss << pCurDVRY->GetArrayLength() << "; i++){\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ") ||";
+ ss << " isnan("<< vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ")) {\n";
+ ss << " arg0 = 0.0;\n";
+ ss << " arg1 = 0.0;\n";
+ ss << " --cnt;\n";
+ ss << " }\n";
+ ss << "else{\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << "}\n";
+ ss << " ++cnt;\n";
+ ss << " vSum0 += arg0;\n";
+ ss << " vSum1 += arg1;\n";
+ ss << " }\n";
+ }
+ else if (pCurDVRX->IsStartFixed() && !pCurDVRX->IsEndFixed()) {
+ ss << "int i = 0; i < gid0 + " << nCurWindowSizeX << " && ";
+ ss << " i < " << pCurDVRX->GetArrayLength() << " && ";
+ ss << " i < " << pCurDVRY->GetArrayLength() << "; i++) {\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ") ||";
+ ss << " isnan(" << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ")) {\n";
+ ss << " arg0 = 0.0;\n";
+ ss << " arg1 = 0.0;\n";
+ ss << " --cnt;\n";
+ ss << " }\n";
+ ss << "else{\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";}\n";
+ ss << " ++cnt;\n";
+ ss << " vSum0 += arg0;\n";
+ ss << " vSum1 += arg1;\n";
+ ss << " }\n";
+ }
+ else if (pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+ ss << "int i = 0; i < " << nCurWindowSizeX << " && i < ";
+ ss << pCurDVRX->GetArrayLength() << " && i < ";
+ ss << pCurDVRY->GetArrayLength() << "; i++) {\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ") ||";
+ ss << " isnan(" << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ")) {\n";
+ ss << " arg0 = 0.0;\n";
+ ss << " arg1 = 0.0;\n";
+ ss << " --cnt;\n";
+ ss << " }\n";
+ ss << "else{\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";}\n";
+ ss << " ++cnt;\n";
+ ss << " vSum0 += arg0;\n";
+ ss << " vSum1 += arg1;\n";
+ ss << " }\n";
+ }
+ else {
+ ss << "int i = 0; i < " << nCurWindowSizeX << " && ";
+ ss << " i + gid0 < " << pCurDVRX->GetArrayLength();
+ ss << " && i + gid0 < " << pCurDVRY->GetArrayLength();
+ ss << "; i++) {\n";
+ ss << "if ((isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ")) || ";
+ ss << "(isnan("<< vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << "))) {\n";
+ ss << " arg0 = 0.0;\n";
+ ss << " arg1 = 0.0;\n";
+ ss << " --cnt;\n";
+ ss << " }\n";
+ ss << " else {\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " }\n";
+ ss << " ++cnt;\n";
+ ss << " vSum0 += arg0;\n";
+ ss << " vSum1 += arg1;\n";
+ ss << " }\n";
+ }
+ ss << " if(cnt < 1) {\n";
+ ss << " return CreateDoubleError(NoValue);\n";
+ ss << " }\n";
+ ss << " else {\n";
+ ss << " vMean0 = vSum0 / cnt;\n";
+ ss << " vMean1 = vSum1 / cnt;\n";
+ ss << " for(";
+ if (!pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+ ss << "int i = gid0; i < " << nCurWindowSizeX;
+ ss << " && i < " << pCurDVRX->GetArrayLength() << " && i < ";
+ ss << pCurDVRY->GetArrayLength() << "; i++){\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ") ||";
+ ss << " isnan(" << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ")){\n";
+ ss << " arg0 = vMean0;\n";
+ ss << " arg1 = vMean1;\n";
+ ss << " }\n";
+ ss << " else{\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";}\n";
+ ss << " vSum += (arg0 - vMean0) * (arg1 - vMean1);\n";
+ ss << " }\n";
+ }
+ else if (pCurDVRX->IsStartFixed() && !pCurDVRX->IsEndFixed()) {
+ ss << "int i = 0; i < gid0 + " << nCurWindowSizeX << " && ";
+ ss << " i < " << pCurDVRX->GetArrayLength() << " && ";
+ ss << " i < " << pCurDVRY->GetArrayLength() << "; i++) {\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ") || ";
+ ss << "isnan(" << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ")) {\n";
+ ss << " arg0 = vMean0;\n";
+ ss << " arg1 = vMean1;\n";
+ ss << " }\n";
+ ss << "else{\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";}\n";
+ ss << " vSum += (arg0 - vMean0) * (arg1 - vMean1);\n";
+ ss << " }\n";
+ }
+ else if (pCurDVRX->IsStartFixed() && pCurDVRX->IsEndFixed()) {
+ ss << "int i = 0; i < " << nCurWindowSizeX << " && i < ";
+ ss << pCurDVRX->GetArrayLength() << " && i < ";
+ ss << pCurDVRY->GetArrayLength() << "; i++) {\n";
+ ss << " if(isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ") || ";
+ ss << "isnan(" << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << ")) {\n";
+ ss << " arg0 = vMean0;\n";
+ ss << " arg1 = vMean1;\n";
+ ss << " }\n";
+ ss << "else{\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";}\n";
+ ss << " vSum += (arg0 - vMean0) * (arg1 - vMean1);\n";
+ ss << " }\n";
+ }
+ else {
+ ss << "int i = 0; i < " << nCurWindowSizeX << " && ";
+ ss << " i + gid0 < " << pCurDVRX->GetArrayLength();
+ ss << " && i + gid0 < " << pCurDVRX->GetArrayLength();
+ ss << "; i++) {\n";
+ ss << "if((isnan(";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ")) || ";
+ ss << "(isnan(" << vSubArguments[1]->GenSlidingWindowDeclRef();
+ ss << "))) {\n";
+ ss << " arg0 = vMean0;\n";
+ ss << " arg1 = vMean1;\n";
+ ss << " }\n";
+ ss << " else{\n";
+ ss << " arg0 = ";
+ ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " arg1 = ";
+ ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " }\n";
+ ss << " vSum += (arg0 - vMean0) * (arg1 - vMean1);\n";
+ ss << " }\n";
+ }
+ ss << " return vSum / cnt;\n";
+ ss << " }\n";
+ ss << "}";
+ }
+ else
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+ }
+ else {
+ ss << " int cnt0 = 0,cnt1 = 0;\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ if (pCur->GetType() == formula::svSingleVectorRef){
+ const formula::SingleVectorRefToken* pTVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ ss << " if(isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ") || gid0 >= " << pTVR->GetArrayLength() << ")\n";
+ ss << " arg" << i << " = 0;\n else\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " cnt" << i << "++;\n";
+ ss << " vSum" << i << " += arg" << i << ";\n";
+ }
+ else if (pCur->GetType() == formula::svDouble){
+ ss << " if(isnan ( ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " arg" << i << " = 0;\n else\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " cnt" << i << "++;\n";
+ ss << " vSum" << i << " += arg" << i << ";\n";
+ }
+ else {
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " cnt" << i << "++;\n";
+ ss << " vSum" << i << " += arg" << i << ";\n";
+ }
+ }
+ ss << " vMean0 = vSum0 / cnt0;\n";
+ ss << " vMean1 = vSum0 / cnt1;\n";
+ for(size_t i = 0; i < vSubArguments.size(); i++ ) {
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ if (pCur->GetType() == formula::svSingleVectorRef) {
+ const formula::SingleVectorRefToken* pTVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ ss << " if(isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ") || gid0 >= " << pTVR->GetArrayLength() << ")\n";
+ ss << " arg" << i << " = vMean" << i << ";\n";
+ ss << " else\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ else if (pCur->GetType() == formula::svDouble) {
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(arg" << i << "))\n";
+ ss << " arg" << i << " = vMean" << i << ";\n";
+ }
+ else {
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ }
+ }
+ ss << " vSum += (arg0 - vMean0) * ( arg1 - vMean1 );\n";
+ ss << " return vSum / cnt0;\n";
+ ss << "}";
+ }
+}
+void OpBetaDist::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp;\n";
+ ss << " double arg0,arg1,arg2,arg3,arg4,arg5;\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";
+ ss << " {\n";
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"= 0;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " double fScale = arg4 - arg3;\n"
+ " if (fScale <= 0.0 || arg1 <= 0.0 || arg2 <= 0.0)\n"
+ " {\n"
+ " tmp = DBL_MIN;\n"
+ " return tmp;\n"
+ " }\n"
+ " if (arg5)\n"
+ " {\n"
+ " if (arg0< arg3)\n"
+ " {\n"
+ " tmp = 0.0;\n"
+ " return tmp;\n"
+ " }\n"
+ " if (arg0 > arg4)\n"
+ " {\n"
+ " tmp = 1.0;\n"
+ " return tmp;\n"
+ " }\n"
+ " arg0 = (arg0-arg3)*pow(fScale,-1);\n"
+ " tmp = GetBetaDist(arg0, arg1, arg2);\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " if (arg0 < arg3 || arg0 > arg4 )\n"
+ " {\n"
+ " tmp = 0.0;\n"
+ " return tmp;\n"
+ " }\n"
+ " arg0 = (arg0 - arg3)*pow(fScale,-1);\n"
+ " tmp = GetBetaDistPDF(arg0, arg1, arg2)*pow(fScale,-1);\n"
+ " }\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+void OpBetainv::BinInlineFun(std::set<std::string>& decls,
+ std::set<std::string>& funs)
+{
+ decls.insert(fMachEpsDecl);
+ funs.insert("");
+ decls.insert(fMaxGammaArgumentDecl);
+ funs.insert("");
+ decls.insert(lcl_IterateInverseBetaInvDecl);
+ funs.insert(lcl_IterateInverseBetaInv);
+ decls.insert(GetBetaDistDecl);
+ funs.insert(GetBetaDist);
+ decls.insert(lcl_HasChangeOfSignDecl);
+ funs.insert(lcl_HasChangeOfSign);
+ decls.insert(lcl_HasChangeOfSignDecl);
+ funs.insert(lcl_HasChangeOfSign);
+ decls.insert(lcl_HasChangeOfSignDecl);
+ funs.insert(lcl_HasChangeOfSign);
+ decls.insert(lcl_GetBetaHelperContFracDecl);
+ funs.insert(lcl_GetBetaHelperContFrac);
+ decls.insert(GetBetaDistPDFDecl);
+ funs.insert(GetBetaDistPDF);
+ decls.insert(GetLogBetaDecl);
+ funs.insert(GetLogBeta);
+ decls.insert(GetBetaDecl);
+ funs.insert(GetBeta);
+ decls.insert(lcl_getLanczosSumDecl);
+ funs.insert(lcl_getLanczosSum);
+}
+void OpBetainv::GenSlidingWindowFunction(
+ std::stringstream &ss,const std::string &sSymName,
+ SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " double tmp0,tmp1,tmp2,tmp3,tmp4;\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<<"=\n";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n}\n";
+ }
+ else
+ {
+ ss << "tmp"<<i<<"="<<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss <<";\n";
+ }
+ }
+ ss << " if (tmp0 < 0.0 || tmp0 >= 1.0 ||";
+ ss << "tmp3 == tmp4 || tmp1 <= 0.0 || tmp2 <= 0.0)\n";
+ ss << " {\n";
+ ss << " return DBL_MIN;\n";
+ ss << " }\n";
+ ss << " if (tmp0 == 0.0)\n";
+ ss << " return 0.0;\n";
+ ss << " else\n";
+ ss << " {";
+ ss << " bool bConvError;";
+ ss << " double fVal = lcl_IterateInverseBetaInv";
+ ss << "(tmp0, tmp1, tmp2, 0.0, 1.0, &bConvError);\n";
+ ss << " if(bConvError)\n";
+ ss << " return DBL_MIN;\n";
+ ss << " else\n";
+ ss << " return (tmp3 + fVal*(tmp4 - tmp3));\n";
+ ss << " }";
+ ss << "}\n";
+}
+void OpDevSq::GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double vSum = 0.0;\n";
+ ss << " double vMean = 0.0;\n";
+ ss << " int cnt = 0;\n";
+ for(size_t i = 0; i < vSubArguments.size(); i++ )
+ {
+ ss << " double arg" << i << " = 0.0;\n";
+ FormulaToken* pCur = vSubArguments[i]->GetFormulaToken();
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pCurDVR =
+ static_cast<const formula::DoubleVectorRefToken* >(pCur);
+ size_t nCurWindowSize = pCurDVR->GetRefRowSize();
+ ss << " for(int i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "gid0; i < " << nCurWindowSize << "; i++) {\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(arg" << i << ") || (i >= ";
+ ss << pCurDVR->GetArrayLength() << ")) {\n";
+ ss << " arg" << i << " = 0.0;\n";
+ ss << " --cnt;\n";
+ ss << " }\n";
+ ss << " ++cnt;\n";
+ ss << " vSum += arg" << i << ";\n";
+ ss << " }\n";
+ } else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) {
+ ss << "0; i < gid0 + " << nCurWindowSize << "; i++) {\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(arg" << i << ") || (i >= ";
+ ss << pCurDVR->GetArrayLength() << ")) {\n";
+ ss << " arg" << i << " = 0.0;\n";
+ ss << " --cnt;\n";
+ ss << " }\n";
+ ss << " ++cnt;\n";
+ ss << " vSum += arg" << i << ";\n";
+ ss << " }\n";
+ } else if (pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "0; i < " << nCurWindowSize << "; i++) {\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(arg" << i << ") || (i >= ";
+ ss << pCurDVR->GetArrayLength() << ")) {\n";
+ ss << " arg" << i << " = 0.0;\n";
+ ss << " --cnt;\n";
+ ss << " }\n";
+ ss << " ++cnt;\n";
+ ss << " vSum += arg" << i << ";\n";
+ ss << " }\n";
+ } else {
+ ss << "0; i < " << nCurWindowSize << "; i++) {\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(arg" << i << ") || (i + gid0 >= ";
+ ss << pCurDVR->GetArrayLength() << ")) {\n";
+ ss << " arg" << i << " = 0.0;\n";
+ ss << " --cnt;\n";
+ ss << " }\n";
+ ss << " ++cnt;\n";
+ ss << " vSum += arg" << i << ";\n";
+ ss << " }\n";
+ }
+}
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pTVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ ss << " if(isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ") || gid0 >= " << pTVR->GetArrayLength() << ")\n";
+ ss << " arg" << i << " = 0;\n else\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " cnt++;\n";
+ ss << " vSum += arg" << i << ";\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " if(isnan ( ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << "))\n";
+ ss << " arg" << i << " = 0;\n else\n";
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " cnt++;\n";
+ ss << " vSum += arg" << i << ";\n";
+ }
+ else
+ {
+ ss << " arg" << i << " = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " cnt++;\n";
+ ss << " vSum += arg" << i << ";\n";
+ }
+ }
+ ss << " vMean = vSum / cnt;\n";
+ ss << " vSum = 0.0;\n";
+ for(size_t k = 0; k < vSubArguments.size(); k++ )
+ {
+ FormulaToken* pCur = vSubArguments[k]->GetFormulaToken();
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pCurDVR =
+ static_cast<const formula::DoubleVectorRefToken* >(pCur);
+ size_t nCurWindowSize = pCurDVR->GetRefRowSize();
+ ss << " for(int i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "gid0; i < " << nCurWindowSize << "; i++) {\n";
+ ss << " arg" << k << " = ";
+ ss << vSubArguments[k]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan( arg" << k << " ) || (i >= ";
+ ss << pCurDVR->GetArrayLength() << ")) {\n";
+ ss << " arg" << k << " = vXMean;\n";
+ ss << " }\n";
+ ss << " vSum += pow( arg" << k << " - vMean, 2 );\n";
+ ss << " }\n";
+ } else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) {
+ ss << "0; i < gid0 + " << nCurWindowSize << "; i++) {\n";
+ ss << " arg" << k << " = ";
+ ss << vSubArguments[k]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan( arg" << k << ") || (i >= ";
+ ss << pCurDVR->GetArrayLength() << ")) {\n";
+ ss << " arg" << k << " = vMean;\n";
+ ss << " }\n";
+ ss << " vSum += pow( arg" << k << " - vMean, 2 );\n";
+ ss << " }\n";
+ } else if (pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
+ ss << "0; i < " << nCurWindowSize << "; i++) {\n";
+ ss << " arg" << k << " = ";
+ ss << vSubArguments[k]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(arg" << k << ") || (i >= ";
+ ss << pCurDVR->GetArrayLength() << ")) {\n";
+ ss << " arg" << k << " = vMean;\n";
+ ss << " }\n";
+ ss << " vSum += pow( arg" << k << " - vMean, 2 );\n";
+ ss << " }\n";
+ } else {
+ ss << "0; i < " << nCurWindowSize << "; i++) {\n";
+ ss << " arg" << k << " = ";
+ ss << vSubArguments[k]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(arg" << k << ") || (i + gid0 >= ";
+ ss << pCurDVR->GetArrayLength() << ")) {\n";
+ ss << " arg" << k << " = vMean;\n";
+ ss << " }\n";
+ ss << " vSum += pow( arg" << k << " - vMean, 2 );\n";
+ ss << " }\n";
+ }
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pTVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ ss << " if(isnan(";
+ ss << vSubArguments[k]->GenSlidingWindowDeclRef();
+ ss << ") || gid0 >= " << pTVR->GetArrayLength() << ")\n";
+ ss << " arg" << k << " = vMean;\n else\n";
+ ss << " arg" << k << " = ";
+ ss << vSubArguments[k]->GenSlidingWindowDeclRef()<<";\n";
+ ss << " vSum += pow( arg" << k << " - vMean, 2 );\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " arg" << k << " = ";
+ ss << vSubArguments[k]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " if(isnan(arg" << k << "))\n";
+ ss << " arg" << k << " = vMean;\n";
+ ss << " vSum += pow( arg" << k << " - vMean, 2 );\n";
+ }
+ else
+ {
+ ss << " arg" << k << " = ";
+ ss << vSubArguments[k]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " vSum += pow( arg" << k << " - vMean, 2 );\n";
+ }
+ }
+ ss << " return vSum;\n";
+ ss << "}";
+}
+void OpHypGeomDist::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ") {\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double arg0,arg1,arg2,arg3;\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";
+ ss << " {\n";
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"=";
+ ss <<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " }\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"= 0;\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " if (isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " arg"<<i<<"= 0;\n";
+ ss << " else\n";
+ ss << " arg"<<i<<"=";
+ ss <<vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ }
+ ss << " double N1=floor(arg3);\n"
+ " double M1=floor(arg2);\n"
+ " double n1=floor(arg1);\n"
+ " double x1=floor(arg0);\n"
+ " double num[9];\n"
+ " double PI = 3.1415926535897932384626433832795;\n"
+ " double tmp;\n"
+ " if( (x1 < 0.0) || (n1 < x1) || (M1 < x1) || (N1 < n1) ||"
+ "(N1 < M1) || (x1 < n1 - N1 + M1) )\n"
+ " {\n"
+ " tmp = DBL_MIN;\n"
+ " return tmp;\n"
+ " }\n"
+ " num[0]=M1;\n"
+ " num[1]=x1;\n"
+ " num[2]=M1-x1;\n"
+ " num[3]=N1-M1;\n"
+ " num[4]=n1-x1;\n"
+ " num[5]=N1-M1-n1+x1;\n"
+ " num[6]=N1;\n"
+ " num[7]=n1;\n"
+ " num[8]=N1-n1;\n"
+ " for(int i=0;i<9;i++)\n"
+ " {\n"
+ " if(num[i]<171)\n"
+ " {\n"
+ " if(num[i]==0)\n"
+ " num[i]=0;\n"
+ " else\n"
+ " num[i]=log(tgamma(num[i])*num[i]);\n"
+ " }\n"
+ " else\n"
+ " num[i]=0.5*log(2.0*PI)+(num[i]+0.5)*log(num[i])-num[i]+"
+ "(1.0*pow(12.0*num[i],-1)-1.0*pow(360*pow(num[i],3),-1));\n"
+ " }\n";
+ ss << " tmp=pow(M_E,(num[0]+num[3]+num[7]+num[8]";
+ ss << "-num[1]-num[2]-num[4]-num[5]-num[6]));\n";
+ ss << " return tmp;\n";
+ ss << "}\n";
+}
+
+namespace {
+
+enum MixDoubleString
+{
+ svDoubleVectorRefDoubleString,
+ svDoubleVectorRefDouble,
+ svDoubleVectorRefString,
+ svDoubleVectorRefNULL,
+ svSingleVectorRefDoubleString,
+ svSingleVectorRefDouble,
+ svSingleVectorRefString,
+ svSingleVectorRefNULL,
+ svDoubleDouble
+};
+
+}
+
+void OpMinA::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
+{
+ int isMixed = 0;
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp0 = 1.79769e+308;\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);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixed = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixed = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixed = svDoubleVectorRefString;
+ else
+ isMixed = svDoubleVectorRefNULL;
+ 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);
+
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixed = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixed = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixed = svSingleVectorRefString;
+ else
+ isMixed = svSingleVectorRefNULL;
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << "){\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " {\n";
+ isMixed = svDoubleDouble;
+ }
+
+ if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if(isMixed == svDoubleVectorRefDoubleString
+ || isMixed == svSingleVectorRefDoubleString)
+ {
+ ss << " if (!isnan(";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " tmp0 = tmp0 > ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << " ? ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << " : tmp0;\n";
+ ss << " else if(isnan(";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ") && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " tmp0 = tmp0 > 0.0 ? 0.0 : tmp0;\n";
+ ss << " }\n";
+ }
+ else if(isMixed == svDoubleVectorRefDouble
+ || isMixed == svSingleVectorRefDouble)
+ {
+ ss << " if (!isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " tmp0 = tmp0 > ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " : tmp0;";
+ ss <<"\n }\n";
+ }
+ else if(isMixed == svDoubleVectorRefString)
+ {
+ ss << " if(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n continue;\n";
+ ss << " tmp0 = tmp0 > 0.0 ? 0.0 : tmp0;\n";
+ ss << " }\n";
+ }
+ else if(isMixed == svSingleVectorRefString)
+ {
+ ss << " if(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " tmp0 = tmp0 > 0.0 ? 0.0 : tmp0;\n";
+ ss << " }\n";
+ }
+ else if(isMixed == svDoubleDouble)
+ {
+ ss << " tmp0 = tmp0 > ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " : tmp0;\n }\n";
+ }
+ else
+ {
+ ss << " }\n";
+ }
+ }
+ else
+ {
+ ss << " tmp0 = tmp0 > ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " : tmp0;";
+ ss <<"\n }\n";
+ }
+ }
+ ss << " return tmp0 == 1.79769e+308 ? 0.0 : tmp0;\n";
+ ss << "}\n";
+}
+void OpCountA::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ int isMixed = 0;
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double nCount = 0.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);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixed = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixed = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixed = svDoubleVectorRefString;
+ else
+ isMixed = svDoubleVectorRefNULL;
+ 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);
+
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixed = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixed = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixed = svSingleVectorRefString;
+ else
+ isMixed = svSingleVectorRefNULL;
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << "){\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " {\n";
+ isMixed = svDoubleDouble;
+ }
+
+ if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if(isMixed == svDoubleVectorRefDoubleString
+ || isMixed == svSingleVectorRefDoubleString)
+ {
+ ss << " if (!isnan(";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ")){\n";
+ ss << " nCount+=1.0;\n";
+ ss << " }\n";
+ ss << " else if(isnan(";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ") && ";
+ ss<< vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " nCount+=1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixed == svDoubleVectorRefDouble
+ || isMixed == svSingleVectorRefDouble)
+ {
+ ss << " if (!isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ")){\n";
+ ss << " nCount+=1.0;\n";
+ ss <<"}\n }\n";
+ }
+ else if(isMixed == svDoubleVectorRefString)
+ {
+ ss << " if (!isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " nCount+=1.0;\n";
+ ss <<"\n }\n";
+ }
+ else if(isMixed == svSingleVectorRefString)
+ {
+ ss << " if(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " nCount+=1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixed == svDoubleDouble)
+ {
+ ss << " nCount+=1.0;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " }\n";
+ }
+ }
+ else
+ {
+ ss << " nCount+=1.0;\n";
+ ss << " }\n";
+ }
+ }
+ ss << " return nCount;\n";
+ ss << "}\n";
+}
+void OpMaxA::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ int isMixed = 0;
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp0 = 2.22507e-308;\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);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixed = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixed = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixed = svDoubleVectorRefString;
+ else
+ isMixed = svDoubleVectorRefNULL;
+ 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);
+
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixed = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixed = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixed = svSingleVectorRefString;
+ else
+ isMixed = svSingleVectorRefNULL;
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << "){\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " {\n";
+ isMixed = svDoubleDouble;
+ }
+
+ if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if(isMixed == svDoubleVectorRefDoubleString
+ || isMixed == svSingleVectorRefDoubleString)
+ {
+ ss << " if (!isnan(";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " tmp0 = tmp0 < ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << " ? ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << " : tmp0;\n";
+ ss << " else if(isnan(";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ") && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " tmp0 = tmp0 < 0.0 ? 0.0 : tmp0;\n";
+ ss << " }\n";
+ }
+ else if(isMixed == svDoubleVectorRefDouble
+ || isMixed == svSingleVectorRefDouble)
+ {
+ ss << " if (!isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " tmp0 = tmp0 < ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " : tmp0;";
+ ss <<"\n }\n";
+ }
+ else if(isMixed == svDoubleVectorRefString)
+ {
+ ss << " if(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n continue;\n";
+ ss << " tmp0 = tmp0 < 0.0 ? 0.0 : tmp0;\n";
+ ss << " }\n";
+ }
+ else if(isMixed == svSingleVectorRefString)
+ {
+ ss << " if(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " tmp0 = tmp0 < 0.0 ? 0.0 : tmp0;\n";
+ ss << " }\n";
+ }
+ else if(isMixed == svDoubleDouble)
+ {
+ ss << " tmp0 = tmp0 < ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " : tmp0;\n }\n";
+ }
+ else
+ {
+ ss << " }\n";
+ }
+ }
+ else
+ {
+ ss << " tmp0 = tmp0 < ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " : tmp0;";
+ ss <<"\n }\n";
+ }
+ }
+ ss << " return tmp0 == 2.22507e-308 ? 0.0 : tmp0;\n";
+ ss << "}\n";
+}
+void OpAverageA::GenSlidingWindowFunction(
+ std::stringstream &ss, const std::string &sSymName, SubArguments &
+vSubArguments)
+{
+ int isMixed = 0;
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss << "{\n";
+ ss << " int gid0=get_global_id(0);\n";
+ ss << " double tmp0 = 0.0;\n";
+ ss << " double nCount = 0.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);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixed = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixed = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixed = svDoubleVectorRefString;
+ else
+ isMixed = svDoubleVectorRefNULL;
+ 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);
+
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixed = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixed = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixed = svSingleVectorRefString;
+ else
+ isMixed = svSingleVectorRefNULL;
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << "){\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " {\n";
+ isMixed = svDoubleDouble;
+ }
+
+ if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if(isMixed == svDoubleVectorRefDoubleString
+ || isMixed == svSingleVectorRefDoubleString)
+ {
+ ss << " if (!isnan(";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ")){\n";
+ ss << " tmp0 +=";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " nCount+=1.0;\n";
+ ss << " }\n";
+ ss << " else if(isnan(";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ") && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " nCount+=1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixed == svDoubleVectorRefDouble
+ || isMixed == svSingleVectorRefDouble)
+ {
+ ss << " if (!isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ")){\n";
+ ss << " tmp0 +=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " nCount+=1.0;\n";
+ ss <<"}\n }\n";
+ }
+ else if(isMixed == svDoubleVectorRefString)
+ {
+ ss << " if (!isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " nCount+=1.0;\n";
+ ss <<"\n }\n";
+ }
+ else if(isMixed == svSingleVectorRefString)
+ {
+ ss << " if(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " nCount+=1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixed == svDoubleDouble)
+ {
+ ss << " tmp0 +=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " nCount+=1.0;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " }\n";
+ }
+ }
+ else
+ {
+ ss << " tmp0 +=";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " nCount+=1.0;\n";
+ ss << " }\n";
+ }
+ }
+ ss << " return tmp0*pow(nCount,-1);\n";
+ ss << "}\n";
+}
+void OpVarA::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ int isMixedDV = 0;
+ int isMixedSV = 0;
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum = 0.0;\n";
+ ss << " double fMean = 0.0;\n";
+ ss << " double vSum = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double arg = 0.0;\n";
+ unsigned i = vSubArguments.size();
+ while (i--)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+
+ if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur);
+ assert(pDVR);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixedDV = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefString;
+ else
+ isMixedDV = svDoubleVectorRefNULL;
+
+ 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";
+ }
+
+ if(isMixedDV == svDoubleVectorRefDoubleString)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " if(isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedDV == svDoubleVectorRefDouble)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg))\n";
+ ss << " continue;\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedDV == svDoubleVectorRefString)
+ {
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " continue;\n";
+ ss << " }\n";
+ }
+
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ assert(pSVR);
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixedSV = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefString;
+ else
+ isMixedSV = svSingleVectorRefNULL;
+
+ if(isMixedSV == svSingleVectorRefDoubleString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (!isnan(arg))\n";
+ ss << " {\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedSV == svSingleVectorRefDouble)
+ {
+ 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 if(isMixedSV == svSingleVectorRefString)
+ {
+
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg =0.0;\n";
+ }
+ }
+ else
+ {
+ ss << " arg = " << pCur->GetDouble() << ";\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ }
+ }
+ else
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ }
+ if (i == 0)
+ {
+ ss << " fMean = fSum * pow(fCount,-1.0);\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);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixedDV = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefString;
+ else
+ isMixedDV = svDoubleVectorRefNULL;
+
+ 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";
+ }
+ if(isMixedDV == svDoubleVectorRefDoubleString)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " if(isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean) * (arg - fMean);\n";
+ ss << " }\n";
+
+ }
+ else if(isMixedDV == svDoubleVectorRefDouble)
+ {
+ 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(isMixedDV == svDoubleVectorRefString)
+ {
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean) * (arg - fMean);\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " continue;\n";
+ ss << " }\n";
+ }
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixedSV = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefString;
+ else
+ isMixedSV = svSingleVectorRefNULL;
+
+ if(isMixedSV == svSingleVectorRefDoubleString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (!isnan(arg))\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else if(isMixedSV == svSingleVectorRefDouble)
+ {
+ 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 if(isMixedSV == svSingleVectorRefString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg = 0.0;\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 vSum * pow(fCount - 1.0,-1.0);\n";
+ ss << "}\n";
+}
+
+void OpVarPA::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ int isMixedDV = 0;
+ int isMixedSV = 0;
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum = 0.0;\n";
+ ss << " double fMean = 0.0;\n";
+ ss << " double vSum = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double arg = 0.0;\n";
+ unsigned i = vSubArguments.size();
+ while (i--)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+
+ if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixedDV = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefString;
+ else
+ isMixedDV = svDoubleVectorRefNULL;
+
+ 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";
+ }
+
+ if(isMixedDV == svDoubleVectorRefDoubleString)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " if(isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedDV == svDoubleVectorRefDouble)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg))\n";
+ ss << " continue;\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedDV == svDoubleVectorRefString)
+ {
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " continue;\n";
+ ss << " }\n";
+ }
+
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixedSV = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefString;
+ else
+ isMixedSV = svSingleVectorRefNULL;
+
+ if(isMixedSV == svSingleVectorRefDoubleString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (!isnan(arg))\n";
+ ss << " {\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedSV == svSingleVectorRefDouble)
+ {
+ 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 if(isMixedSV == svSingleVectorRefString)
+ {
+
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg =0.0;\n";
+ }
+ }
+ else
+ {
+ ss << " arg = " << pCur->GetDouble() << ";\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ }
+ }
+ else
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ }
+ if (i == 0)
+ {
+ ss << " fMean = fSum * pow(fCount,-1.0);\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);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixedDV = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefString;
+ else
+ isMixedDV = svDoubleVectorRefNULL;
+
+ 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";
+ }
+ if(isMixedDV == svDoubleVectorRefDoubleString)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " if(isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean) * (arg - fMean);\n";
+ ss << " }\n";
+
+ }
+ else if(isMixedDV == svDoubleVectorRefDouble)
+ {
+ 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(isMixedDV == svDoubleVectorRefString)
+ {
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean) * (arg - fMean);\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " continue;\n";
+ ss << " }\n";
+ }
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixedSV = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefString;
+ else
+ isMixedSV = svSingleVectorRefNULL;
+
+ if(isMixedSV == svSingleVectorRefDoubleString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (!isnan(arg))\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else if(isMixedSV == svSingleVectorRefDouble)
+ {
+ 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 if(isMixedSV == svSingleVectorRefString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg = 0.0;\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 * pow(fCount,-1.0);\n";
+ ss << "}\n";
+}
+void OpStDevA::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ int isMixedDV = 0;
+ int isMixedSV = 0;
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum = 0.0;\n";
+ ss << " double fMean = 0.0;\n";
+ ss << " double vSum = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double arg = 0.0;\n";
+ unsigned i = vSubArguments.size();
+ while (i--)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+
+ if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixedDV = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefString;
+ else
+ isMixedDV = svDoubleVectorRefNULL;
+
+ 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";
+ }
+
+ if(isMixedDV == svDoubleVectorRefDoubleString)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " if(isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedDV == svDoubleVectorRefDouble)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg))\n";
+ ss << " continue;\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedDV == svDoubleVectorRefString)
+ {
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " continue;\n";
+ ss << " }\n";
+ }
+
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixedSV = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefString;
+ else
+ isMixedSV = svSingleVectorRefNULL;
+
+ if(isMixedSV == svSingleVectorRefDoubleString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (!isnan(arg))\n";
+ ss << " {\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedSV == svSingleVectorRefDouble)
+ {
+ 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 if(isMixedSV == svSingleVectorRefString)
+ {
+
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg =0.0;\n";
+ }
+ }
+ else
+ {
+ ss << " arg = " << pCur->GetDouble() << ";\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ }
+ }
+ else
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ }
+ if (i == 0)
+ {
+ ss << " fMean = fSum * pow(fCount,-1.0);\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);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixedDV = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefString;
+ else
+ isMixedDV = svDoubleVectorRefNULL;
+
+ 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";
+ }
+ if(isMixedDV == svDoubleVectorRefDoubleString)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " if(isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean) * (arg - fMean);\n";
+ ss << " }\n";
+
+ }
+ else if(isMixedDV == svDoubleVectorRefDouble)
+ {
+ 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(isMixedDV == svDoubleVectorRefString)
+ {
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean) * (arg - fMean);\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " continue;\n";
+ ss << " }\n";
+ }
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixedSV = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefString;
+ else
+ isMixedSV = svSingleVectorRefNULL;
+
+ if(isMixedSV == svSingleVectorRefDoubleString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (!isnan(arg))\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else if(isMixedSV == svSingleVectorRefDouble)
+ {
+ 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 if(isMixedSV == svSingleVectorRefString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg = 0.0;\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 * pow(fCount - 1.0,-1.0));\n";
+ ss << "}\n";
+}
+
+void OpStDevPA::GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ int isMixedDV = 0;
+ int isMixedSV = 0;
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << "){\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double fSum = 0.0;\n";
+ ss << " double fMean = 0.0;\n";
+ ss << " double vSum = 0.0;\n";
+ ss << " double fCount = 0.0;\n";
+ ss << " double arg = 0.0;\n";
+ unsigned i = vSubArguments.size();
+ while (i--)
+ {
+ FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
+ assert(pCur);
+
+ if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
+ {
+ if (pCur->GetType() == formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pDVR =
+ static_cast<const formula::DoubleVectorRefToken *>(pCur);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixedDV = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefString;
+ else
+ isMixedDV = svDoubleVectorRefNULL;
+
+ 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";
+ }
+
+ if(isMixedDV == svDoubleVectorRefDoubleString)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " if(isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " continue;\n";
+ ss << " }\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedDV == svDoubleVectorRefDouble)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg))\n";
+ ss << " continue;\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedDV == svDoubleVectorRefString)
+ {
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " continue;\n";
+ ss << " }\n";
+ }
+
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixedSV = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefString;
+ else
+ isMixedSV = svSingleVectorRefNULL;
+
+ if(isMixedSV == svSingleVectorRefDoubleString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (!isnan(arg))\n";
+ ss << " {\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else if(isMixedSV == svSingleVectorRefDouble)
+ {
+ 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 if(isMixedSV == svSingleVectorRefString)
+ {
+
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " fCount = fCount + 1.0;\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg =0.0;\n";
+ }
+ }
+ else
+ {
+ ss << " arg = " << pCur->GetDouble() << ";\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ }
+ }
+ else
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
+ ss << " fSum += arg;\n";
+ ss << " fCount = fCount + 1.0;\n";
+ }
+ if (i == 0)
+ {
+ ss << " fMean = fSum * pow(fCount,-1.0);\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);
+ if(pDVR->GetArrays()[0].mpNumericArray
+ && pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefDoubleString;
+ else if(pDVR->GetArrays()[0].mpNumericArray)
+ isMixedDV = svDoubleVectorRefDouble;
+ else if(pDVR->GetArrays()[0].mpStringArray)
+ isMixedDV = svDoubleVectorRefString;
+ else
+ isMixedDV = svDoubleVectorRefNULL;
+
+ 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";
+ }
+ if(isMixedDV == svDoubleVectorRefDoubleString)
+ {
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " if(isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean) * (arg - fMean);\n";
+ ss << " }\n";
+
+ }
+ else if(isMixedDV == svDoubleVectorRefDouble)
+ {
+ 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(isMixedDV == svDoubleVectorRefString)
+ {
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " == 0)\n";
+ ss << " continue;\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean) * (arg - fMean);\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " continue;\n";
+ ss << " }\n";
+ }
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pSVR =
+ static_cast< const formula::SingleVectorRefToken* >(pCur);
+ if(pSVR->GetArray().mpNumericArray
+ && pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefDoubleString;
+ else if(pSVR->GetArray().mpNumericArray)
+ isMixedSV = svSingleVectorRefDouble;
+ else if(pSVR->GetArray().mpStringArray)
+ isMixedSV = svSingleVectorRefString;
+ else
+ isMixedSV = svSingleVectorRefNULL;
+
+ if(isMixedSV == svSingleVectorRefDoubleString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " arg = ";
+ ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if (!isnan(arg))\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " if (isnan(arg) && ";
+ ss << vSubArguments[i]->GenStringSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else if(isMixedSV == svSingleVectorRefDouble)
+ {
+ 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 if(isMixedSV == svSingleVectorRefString)
+ {
+ ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
+ ss << " {\n";
+ ss << " if (";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << " != 0)\n";
+ ss << " {\n";
+ ss << " arg = 0.0;\n";
+ ss << " vSum += (arg - fMean)*(arg - fMean);\n";
+ ss << " }\n";
+ ss << " }\n";
+ }
+ else
+ {
+ ss << " arg = 0.0;\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 * pow(fCount,-1.0));\n";
+ ss << "}\n";
+}
+
+void OpAveDev:: GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments)
+{
+ ss << "\ndouble " << sSymName;
+ ss << "_"<< BinFuncName() <<"( ";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ }
+ ss << ")\n";
+ ss <<"{\n";
+ ss << " int gid0 = get_global_id(0);\n";
+ ss << " double sum=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();
+ 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 << " sum += 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 << " sum += tmp;\n";
+ ss << " totallength +=1;\n";
+ ss << " }\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " tmp = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " sum += tmp;\n";
+ ss << " totallength +=1;\n";
+ }
+ }
+ ss << " double mean = sum * pow(totallength,-1);\n";
+ ss << " sum = 0.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 << " 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 << " continue;\n";
+ ss << " }\n";
+ ss << " sum += fabs(arg"<<i<<"-mean);\n";
+ ss << " }\n";
+ }
+ else if (pCur->GetType() == formula::svSingleVectorRef)
+ {
+ ss << " tmp = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " if(!isnan(tmp))\n";
+ ss << " {\n";
+ ss << " sum += fabs(tmp-mean);\n";
+ ss << " }\n";
+ }
+ else if (pCur->GetType() == formula::svDouble)
+ {
+ ss << " tmp = ";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ ss << " sum += fabs(tmp-mean);\n";
+ }
+ }
+ ss << " tmp=sum*pow(totallength,-1);\n";
+ ss << " return tmp;\n";
+ ss << "}";
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/op_statistical.hxx b/sc/source/core/opencl/op_statistical.hxx
new file mode 100644
index 000000000..557db2b41
--- /dev/null
+++ b/sc/source/core/opencl/op_statistical.hxx
@@ -0,0 +1,553 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_CORE_OPENCL_OP_STATISTICAL_HXX
+#define INCLUDED_SC_SOURCE_CORE_OPENCL_OP_STATISTICAL_HXX
+
+#include "opbase.hxx"
+
+namespace sc::opencl {
+
+class OpStandard: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Standard"; }
+};
+class OpExponDist: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "ExponDist"; }
+};
+class OpVar: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Var"; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+class OpSTEYX: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "STEYX"; }
+};
+class OpVarP: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "VarP"; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+class OpZTest: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual std::string BinFuncName() const override { return "ZTest"; }
+};
+class OpStDevP: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "StDevP"; }
+};
+
+class OpStDev: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "StDev"; }
+};
+class OpSkewp: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Skewp"; }
+};
+class OpSlope: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Slope"; }
+};
+class OpWeibull: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Weibull"; }
+};
+class OpFdist: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual std::string BinFuncName() const override { return "Fdist"; }
+};
+class OpTDist: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "TDist"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+};
+class OpTInv: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "TInv"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+};
+class OpTTest: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "TTest"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+};
+class OpSkew: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Skew"; }
+};
+class OpFisher: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Fisher"; }
+};
+
+class OpFisherInv: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "FisherInv"; }
+};
+
+class OpGamma: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Gamma"; }
+};
+
+class OpCorrel: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Correl"; }
+};
+
+class OpNegbinomdist: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpNegbinomdist"; }
+};
+
+class OpPearson: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpPearson"; }
+};
+
+class OpGammaLn: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "GammaLn"; }
+};
+
+class OpGauss: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,
+ std::set<std::string>& ) override;
+ virtual std::string BinFuncName() const override { return "Gauss"; }
+};
+
+class OpGeoMean: public CheckVariables
+{
+public:
+ OpGeoMean(): CheckVariables() {}
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "GeoMean"; }
+};
+
+class OpHarMean: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "HarMean"; }
+};
+
+class OpRsq: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpRsq"; }
+};
+class OpNormdist:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpNormdist"; }
+};
+class OpMedian:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpMedian"; }
+};
+class OpNormsdist:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpNormsdist"; }
+};
+class OpNorminv:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpNorminv"; }
+};
+class OpNormsinv:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpNormsinv"; }
+};
+class OpPhi:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpPhi"; }
+};
+class OpKurt: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Kurt"; }
+};
+class OpCovar: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Covar"; }
+};
+
+class OpPermut:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpPermut"; }
+};
+class OpPermutationA:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpPermutationA";}
+};
+
+class OpConfidence: public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,
+ std::set<std::string>& ) override;
+
+ virtual std::string BinFuncName() const override { return "Confidence"; }
+};
+class OpIntercept: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Intercept"; }
+};
+class OpLogInv: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "LogInv"; }
+};
+class OpCritBinom: public Normal
+{
+public:
+ virtual std::string GetBottom() override { return "0"; }
+
+ virtual void GenSlidingWindowFunction(std::stringstream& ss,
+ const std::string &sSymName, SubArguments& vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,
+ std::set<std::string>& ) override;
+
+ virtual std::string BinFuncName() const override { return "CritBinom"; }
+};
+class OpForecast: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "Forecast"; }
+};
+class OpLogNormDist: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "LogNormdist"; }
+};
+class OpGammaDist: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ void BinInlineFun(std::set<std::string>& decls,std::set<std::string>& funs) override;
+ virtual std::string BinFuncName() const override { return "GammaDist"; }
+};
+class OpHypGeomDist:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpHypGeomDist"; }
+};
+class OpChiDist:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual std::string BinFuncName() const override { return "OpChiDist"; }
+};
+class OpBinomdist:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual std::string BinFuncName() const override { return "OpBinomdist"; }
+};
+class OpChiSqDist: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "ChiSqDist"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+
+class OpChiSqInv: public CheckVariables
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "ChiSqInv"; }
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) override;
+};
+class OpChiInv:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual std::string BinFuncName() const override { return "OpChiInv"; }
+};
+class OpPoisson:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual std::string BinFuncName() const override { return "OpPoisson"; }
+};
+
+class OpGammaInv: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ void BinInlineFun(std::set<std::string>& decls,std::set<std::string>& funs
+) override;
+ virtual std::string BinFuncName() const override { return "GammaInv"; }
+};
+class OpFInv: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ void BinInlineFun(std::set<std::string>& decls,std::set<std::string>& funs
+) override;
+ virtual std::string BinFuncName() const override { return "FInv"; }
+};
+class OpFTest: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ void BinInlineFun(std::set<std::string>& decls,std::set<std::string>& funs
+) override;
+ virtual std::string BinFuncName() const override { return "FTest"; }
+};
+class OpDevSq: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "DevSq"; }
+};
+class OpB: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ void BinInlineFun(std::set<std::string>& decls,std::set<std::string>& funs
+) override;
+ virtual std::string BinFuncName() const override { return "B"; }
+};
+class OpBetaDist: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ void BinInlineFun(std::set<std::string>& decls,std::set<std::string>& funs
+) override;
+ virtual std::string BinFuncName() const override { return "BetaDist"; }
+};
+class OpBetainv:public Normal{
+ public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>&) override;
+ virtual std::string BinFuncName() const override { return "OpBetainv"; }
+};
+class OpMinA: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpMinA"; }
+ virtual bool takeString() const override { return true; }
+ virtual bool takeNumeric() const override { return true; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+class OpCountA: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpCountA"; }
+ virtual bool takeString() const override { return true; }
+ virtual bool takeNumeric() const override { return true; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+class OpMaxA: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpMaxA"; }
+ virtual bool takeString() const override { return true; }
+ virtual bool takeNumeric() const override { return true; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+class OpVarA: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpVarA"; }
+ virtual bool takeString() const override { return true; }
+ virtual bool takeNumeric() const override { return true; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+class OpVarPA: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpVarPA"; }
+ virtual bool takeString() const override { return true; }
+ virtual bool takeNumeric() const override { return true; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+class OpStDevPA: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpStDevPA"; }
+ virtual bool takeString() const override { return true; }
+ virtual bool takeNumeric() const override { return true; }
+};
+class OpAverageA: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpAverageA"; }
+ virtual bool takeString() const override { return true; }
+ virtual bool takeNumeric() const override { return true; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+class OpStDevA: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "OpStDevA"; }
+ virtual bool takeString() const override { return true; }
+ virtual bool takeNumeric() const override { return true; }
+};
+class OpAveDev: public Normal
+{
+public:
+ virtual void GenSlidingWindowFunction(std::stringstream &ss,
+ const std::string &sSymName, SubArguments &vSubArguments) override;
+ virtual std::string BinFuncName() const override { return "AveDev"; }
+ virtual bool canHandleMultiVector() const override { return true; }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/opbase.cxx b/sc/source/core/opencl/opbase.cxx
new file mode 100644
index 000000000..7755610a1
--- /dev/null
+++ b/sc/source/core/opencl/opbase.cxx
@@ -0,0 +1,391 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <opencl/openclwrapper.hxx>
+#include <formula/vectortoken.hxx>
+#include <sal/log.hxx>
+
+#include "opbase.hxx"
+
+using namespace formula;
+
+namespace sc::opencl {
+
+UnhandledToken::UnhandledToken(
+ const char* m, const std::string& fn, int ln ) :
+ mMessage(m), mFile(fn), mLineNumber(ln) {}
+
+OpenCLError::OpenCLError( const std::string& function, cl_int error, const std::string& file, int line ) :
+ mFunction(function), mError(error), mFile(file), mLineNumber(line)
+{
+ // Not sure if this SAL_INFO() is useful; the place in
+ // CLInterpreterContext::launchKernel() where OpenCLError is
+ // caught already uses SAL_WARN() to display it.
+
+ // SAL_INFO("sc.opencl", "OpenCL error: " << openclwrapper::errorString(mError));
+}
+
+Unhandled::Unhandled( const std::string& fn, int ln ) :
+ mFile(fn), mLineNumber(ln) {}
+
+InvalidParameterCount::InvalidParameterCount( int parameterCount, const std::string& file, int ln ) :
+ mParameterCount(parameterCount), mFile(file), mLineNumber(ln) {}
+
+DynamicKernelArgument::DynamicKernelArgument( const ScCalcConfig& config, const std::string& s,
+ const FormulaTreeNodeRef& ft ) :
+ mCalcConfig(config), mSymName(s), mFormulaTree(ft) { }
+
+std::string DynamicKernelArgument::GenDoubleSlidingWindowDeclRef( bool ) const
+{
+ return std::string("");
+}
+
+/// When Mix, it will be called
+std::string DynamicKernelArgument::GenStringSlidingWindowDeclRef( bool ) const
+{
+ return std::string("");
+}
+
+/// Generate use/references to the argument
+void DynamicKernelArgument::GenDeclRef( std::stringstream& ss ) const
+{
+ ss << mSymName;
+}
+
+void DynamicKernelArgument::GenSlidingWindowFunction( std::stringstream& ) {}
+
+FormulaToken* DynamicKernelArgument::GetFormulaToken() const
+{
+ return mFormulaTree->GetFormulaToken();
+}
+
+std::string DynamicKernelArgument::DumpOpName() const
+{
+ return std::string("");
+}
+
+void DynamicKernelArgument::DumpInlineFun( std::set<std::string>&, std::set<std::string>& ) const {}
+
+const std::string& DynamicKernelArgument::GetName() const
+{
+ return mSymName;
+}
+
+bool DynamicKernelArgument::NeedParallelReduction() const
+{
+ return false;
+}
+
+VectorRef::VectorRef( const ScCalcConfig& config, const std::string& s, const FormulaTreeNodeRef& ft, int idx ) :
+ DynamicKernelArgument(config, s, ft), mpClmem(nullptr), mnIndex(idx)
+{
+ if (mnIndex)
+ {
+ std::stringstream ss;
+ ss << mSymName << "s" << mnIndex;
+ mSymName = ss.str();
+ }
+}
+
+VectorRef::~VectorRef()
+{
+ if (mpClmem)
+ {
+ cl_int err;
+ err = clReleaseMemObject(mpClmem);
+ SAL_WARN_IF(err != CL_SUCCESS, "sc.opencl", "clReleaseMemObject failed: " << openclwrapper::errorString(err));
+ }
+}
+
+/// Generate declaration
+void VectorRef::GenDecl( std::stringstream& ss ) const
+{
+ ss << "__global double *" << mSymName;
+}
+
+/// When declared as input to a sliding window function
+void VectorRef::GenSlidingWindowDecl( std::stringstream& ss ) const
+{
+ VectorRef::GenDecl(ss);
+}
+
+/// When referenced in a sliding window function
+std::string VectorRef::GenSlidingWindowDeclRef( bool nested ) const
+{
+ std::stringstream ss;
+ formula::SingleVectorRefToken* pSVR =
+ dynamic_cast<formula::SingleVectorRefToken*>(DynamicKernelArgument::GetFormulaToken());
+ if (pSVR && !nested)
+ ss << "(gid0 < " << pSVR->GetArrayLength() << "?";
+ ss << mSymName << "[gid0]";
+ if (pSVR && !nested)
+ ss << ":NAN)";
+ return ss.str();
+}
+
+void VectorRef::GenSlidingWindowFunction( std::stringstream& ) {}
+
+size_t VectorRef::GetWindowSize() const
+{
+ FormulaToken* pCur = mFormulaTree->GetFormulaToken();
+ assert(pCur);
+ if (const formula::DoubleVectorRefToken* pCurDVR =
+ dynamic_cast<const formula::DoubleVectorRefToken*>(pCur))
+ {
+ return pCurDVR->GetRefRowSize();
+ }
+ else if (dynamic_cast<const formula::SingleVectorRefToken*>(pCur))
+ {
+ // Prepare intermediate results (on CPU for now)
+ return 1;
+ }
+ else
+ {
+ throw Unhandled(__FILE__, __LINE__);
+ }
+}
+
+std::string VectorRef::DumpOpName() const
+{
+ return std::string("");
+}
+
+void VectorRef::DumpInlineFun( std::set<std::string>&, std::set<std::string>& ) const {}
+
+const std::string& VectorRef::GetName() const
+{
+ return mSymName;
+}
+
+cl_mem VectorRef::GetCLBuffer() const
+{
+ return mpClmem;
+}
+
+bool VectorRef::NeedParallelReduction() const
+{
+ return false;
+}
+
+void Normal::GenSlidingWindowFunction(
+ std::stringstream& ss, const std::string& sSymName, SubArguments& vSubArguments )
+{
+ std::vector<std::string> argVector;
+ ss << "\ndouble " << sSymName;
+ ss << "_" << BinFuncName() << "(";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ if (i)
+ ss << ",";
+ vSubArguments[i]->GenSlidingWindowDecl(ss);
+ argVector.push_back(vSubArguments[i]->GenSlidingWindowDeclRef());
+ }
+ ss << ") {\n\t";
+ ss << "double tmp = " << GetBottom() << ";\n\t";
+ ss << "int gid0 = get_global_id(0);\n\t";
+ ss << "tmp = ";
+ ss << Gen(argVector);
+ ss << ";\n\t";
+ ss << "return tmp;\n";
+ ss << "}";
+}
+
+void CheckVariables::GenTmpVariables(
+ std::stringstream& ss, const SubArguments& vSubArguments )
+{
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ ss << " double tmp";
+ ss << i;
+ ss << ";\n";
+ }
+}
+
+void CheckVariables::CheckSubArgumentIsNan( std::stringstream& ss,
+ SubArguments& vSubArguments, int argumentNum )
+{
+ int i = argumentNum;
+ if (vSubArguments[i]->GetFormulaToken()->GetType() ==
+ formula::svSingleVectorRef)
+ {
+ const formula::SingleVectorRefToken* pTmpDVR1 =
+ static_cast<const formula::SingleVectorRefToken*>(vSubArguments[i]->GetFormulaToken());
+ ss << " if(singleIndex>=";
+ ss << pTmpDVR1->GetArrayLength();
+ ss << " ||";
+ ss << "isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef(true);
+ ss << "))\n";
+ ss << " tmp";
+ ss << i;
+ ss << "=0;\n else \n";
+ ss << " tmp";
+ ss << i;
+ ss << "=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef(true);
+ ss << ";\n";
+ }
+ if (vSubArguments[i]->GetFormulaToken()->GetType() ==
+ formula::svDoubleVectorRef)
+ {
+ const formula::DoubleVectorRefToken* pTmpDVR2 =
+ static_cast<const formula::DoubleVectorRefToken*>(vSubArguments[i]->GetFormulaToken());
+ ss << " if(doubleIndex>=";
+ ss << pTmpDVR2->GetArrayLength();
+ ss << " ||";
+ ss << "isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " tmp";
+ ss << i;
+ ss << "=0;\n else \n";
+ ss << " tmp";
+ ss << i;
+ ss << "=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+ }
+ if (vSubArguments[i]->GetFormulaToken()->GetType() == formula::svDouble ||
+ vSubArguments[i]->GetFormulaToken()->GetOpCode() != ocPush)
+ {
+ ss << " if(";
+ ss << "isnan(";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << "))\n";
+ ss << " tmp";
+ ss << i;
+ ss << "=0;\n else \n";
+ ss << " tmp";
+ ss << i;
+ ss << "=";
+ ss << vSubArguments[i]->GenSlidingWindowDeclRef();
+ ss << ";\n";
+
+ }
+
+}
+
+void CheckVariables::CheckSubArgumentIsNan2( std::stringstream& ss,
+ SubArguments& vSubArguments, int argumentNum, const std::string& p )
+{
+ int i = argumentNum;
+ if (vSubArguments[i]->GetFormulaToken()->GetType() == formula::svDouble)
+ {
+ ss << " tmp";
+ ss << i;
+ ss << "=";
+ vSubArguments[i]->GenDeclRef(ss);
+ ss << ";\n";
+ return;
+ }
+
+ ss << " tmp";
+ ss << i;
+ ss << "= fsum(";
+ vSubArguments[i]->GenDeclRef(ss);
+ if (vSubArguments[i]->GetFormulaToken()->GetType() ==
+ formula::svDoubleVectorRef)
+ ss << "[" << p.c_str() << "]";
+ else if (vSubArguments[i]->GetFormulaToken()->GetType() ==
+ formula::svSingleVectorRef)
+ ss << "[get_group_id(1)]";
+ ss << ", 0);\n";
+}
+
+void CheckVariables::CheckAllSubArgumentIsNan(
+ std::stringstream& ss, SubArguments& vSubArguments )
+{
+ ss << " int k = gid0;\n";
+ for (size_t i = 0; i < vSubArguments.size(); i++)
+ {
+ CheckSubArgumentIsNan(ss, vSubArguments, i);
+ }
+}
+
+void CheckVariables::UnrollDoubleVector( std::stringstream& ss,
+ const std::stringstream& unrollstr, const formula::DoubleVectorRefToken* pCurDVR,
+ int nCurWindowSize )
+{
+ int unrollSize = 16;
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
+ {
+ ss << " loop = (" << nCurWindowSize << " - gid0)/";
+ ss << unrollSize << ";\n";
+ }
+ else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << " loop = (" << nCurWindowSize << " + gid0)/";
+ ss << unrollSize << ";\n";
+
+ }
+ else
+ {
+ ss << " loop = " << nCurWindowSize << "/" << unrollSize << ";\n";
+ }
+
+ ss << " for ( int j = 0;j< loop; j++)\n";
+ ss << " {\n";
+ ss << " int i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
+ {
+ ss << "gid0 + j * " << unrollSize << ";\n";
+ }
+ else
+ {
+ ss << "j * " << unrollSize << ";\n";
+ }
+
+ if (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << " int doubleIndex = i+gid0;\n";
+ }
+ else
+ {
+ ss << " int doubleIndex = i;\n";
+ }
+
+ for (int j = 0; j < unrollSize; j++)
+ {
+ ss << unrollstr.str();
+ ss << "i++;\n";
+ ss << "doubleIndex++;\n";
+ }
+ ss << " }\n";
+ ss << " for (int i = ";
+ if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
+ {
+ ss << "gid0 + loop *" << unrollSize << "; i < ";
+ ss << nCurWindowSize << "; i++)\n";
+ }
+ else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << "0 + loop *" << unrollSize << "; i < gid0+";
+ ss << nCurWindowSize << "; i++)\n";
+ }
+ else
+ {
+ ss << "0 + loop *" << unrollSize << "; i < ";
+ ss << nCurWindowSize << "; i++)\n";
+ }
+ ss << " {\n";
+ if (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
+ {
+ ss << " int doubleIndex = i+gid0;\n";
+ }
+ else
+ {
+ ss << " int doubleIndex = i;\n";
+ }
+ ss << unrollstr.str();
+ ss << " }\n";
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/opbase.hxx b/sc/source/core/opencl/opbase.hxx
new file mode 100644
index 000000000..73a207d74
--- /dev/null
+++ b/sc/source/core/opencl/opbase.hxx
@@ -0,0 +1,249 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_CORE_OPENCL_OPBASE_HXX
+#define INCLUDED_SC_SOURCE_CORE_OPENCL_OPBASE_HXX
+
+#include <clew/clew.h>
+#include <formula/token.hxx>
+#include <formula/types.hxx>
+#include <memory>
+#include <set>
+#include <vector>
+
+namespace formula { class DoubleVectorRefToken; }
+namespace formula { class FormulaToken; }
+struct ScCalcConfig;
+
+namespace sc::opencl {
+
+class FormulaTreeNode;
+
+/// Exceptions
+
+/// Failed in parsing
+class UnhandledToken
+{
+public:
+ UnhandledToken( const char* m, const std::string& fn, int ln );
+
+ std::string mMessage;
+ std::string mFile;
+ int mLineNumber;
+};
+
+/// Failed in marshaling
+class OpenCLError
+{
+public:
+ OpenCLError( const std::string& function, cl_int error, const std::string& file, int line );
+
+ std::string mFunction;
+ cl_int mError;
+ std::string mFile;
+ int mLineNumber;
+};
+
+/// Inconsistent state
+class Unhandled
+{
+public:
+ Unhandled( const std::string& fn, int ln );
+
+ std::string mFile;
+ int mLineNumber;
+};
+
+class InvalidParameterCount
+{
+public:
+ InvalidParameterCount( int parameterCount, const std::string& file, int ln );
+
+ int mParameterCount;
+ std::string mFile;
+ int const mLineNumber;
+};
+
+// Helper macro to be used in code emitting OpenCL code for Calc functions.
+// Requires the vSubArguments parameter.
+#define CHECK_PARAMETER_COUNT(min, max) \
+ do { \
+ const int count = vSubArguments.size(); \
+ if( count < ( min ) || count > ( max )) \
+ throw InvalidParameterCount( count, __FILE__, __LINE__ ); \
+ } while( false )
+
+typedef std::shared_ptr<FormulaTreeNode> FormulaTreeNodeRef;
+
+class FormulaTreeNode
+{
+public:
+ explicit FormulaTreeNode( const formula::FormulaToken* ft ) : mpCurrentFormula(ft)
+ {
+ Children.reserve(8);
+ }
+ std::vector<FormulaTreeNodeRef> Children;
+ formula::FormulaToken* GetFormulaToken() const
+ {
+ return const_cast<formula::FormulaToken*>(mpCurrentFormula.get());
+ }
+
+private:
+ formula::FormulaConstTokenRef mpCurrentFormula;
+};
+
+/// (Partially) abstract base class for an operand
+class DynamicKernelArgument
+{
+public:
+ /// delete copy constructor
+ DynamicKernelArgument( const DynamicKernelArgument& ) = delete;
+
+ /// delete copy-assignment operator
+ const DynamicKernelArgument& operator=( const DynamicKernelArgument& ) = delete;
+
+ DynamicKernelArgument( const ScCalcConfig& config, const std::string& s, const FormulaTreeNodeRef& ft );
+ virtual ~DynamicKernelArgument() {}
+
+ /// Generate declaration
+ virtual void GenDecl( std::stringstream& ss ) const = 0;
+
+ /// When declared as input to a sliding window function
+ virtual void GenSlidingWindowDecl( std::stringstream& ss ) const = 0;
+
+ /// When referenced in a sliding window function
+ virtual std::string GenSlidingWindowDeclRef( bool = false ) const = 0;
+
+ /// Create buffer and pass the buffer to a given kernel
+ virtual size_t Marshal( cl_kernel, int, int, cl_program ) = 0;
+
+ virtual size_t GetWindowSize() const = 0;
+
+ /// When Mix, it will be called
+ virtual std::string GenDoubleSlidingWindowDeclRef( bool = false ) const;
+
+ /// When Mix, it will be called
+ virtual std::string GenStringSlidingWindowDeclRef( bool = false ) const;
+
+ /// Generate use/references to the argument
+ virtual void GenDeclRef( std::stringstream& ss ) const;
+
+ virtual void GenSlidingWindowFunction( std::stringstream& );
+ formula::FormulaToken* GetFormulaToken() const;
+ virtual std::string DumpOpName() const;
+ virtual void DumpInlineFun( std::set<std::string>&, std::set<std::string>& ) const;
+ const std::string& GetName() const;
+ virtual bool NeedParallelReduction() const;
+ /// If there's actually no argument, i.e. it expands to no code.
+ virtual bool IsEmpty() const { return false; }
+
+protected:
+ const ScCalcConfig& mCalcConfig;
+ std::string mSymName;
+ FormulaTreeNodeRef mFormulaTree;
+};
+
+typedef std::shared_ptr<DynamicKernelArgument> DynamicKernelArgumentRef;
+
+/// Holds an input (read-only) argument reference to a SingleVectorRef.
+/// or a DoubleVectorRef for non-sliding-window argument of complex functions
+/// like SumOfProduct
+/// In most of the cases the argument is introduced
+/// by a Push operation in the given RPN.
+class VectorRef : public DynamicKernelArgument
+{
+public:
+ VectorRef( const ScCalcConfig& config, const std::string& s, const FormulaTreeNodeRef& ft, int index = 0 );
+ virtual ~VectorRef() override;
+
+ /// Generate declaration
+ virtual void GenDecl( std::stringstream& ss ) const override;
+ /// When declared as input to a sliding window function
+ virtual void GenSlidingWindowDecl( std::stringstream& ss ) const override;
+
+ /// When referenced in a sliding window function
+ virtual std::string GenSlidingWindowDeclRef( bool = false ) const override;
+
+ /// Create buffer and pass the buffer to a given kernel
+ virtual size_t Marshal( cl_kernel, int, int, cl_program ) override;
+
+ virtual void GenSlidingWindowFunction( std::stringstream& ) override;
+ virtual size_t GetWindowSize() const override;
+ virtual std::string DumpOpName() const override;
+ virtual void DumpInlineFun( std::set<std::string>&, std::set<std::string>& ) const override;
+ const std::string& GetName() const;
+ cl_mem GetCLBuffer() const;
+ virtual bool NeedParallelReduction() const override;
+
+protected:
+ // Used by marshaling
+ cl_mem mpClmem;
+ // index in multiple double vector refs that have multiple ranges
+ const int mnIndex;
+};
+
+/// Abstract class for code generation
+class OpBase
+{
+public:
+ virtual std::string GetBottom() { return "";};
+ virtual std::string Gen2( const std::string&/*lhs*/,
+ const std::string&/*rhs*/ ) const { return "";}
+ static std::string Gen( std::vector<std::string>& /*argVector*/ ) { return "";};
+ virtual std::string BinFuncName() const { return "";};
+ virtual void BinInlineFun( std::set<std::string>&,
+ std::set<std::string>& ) { }
+ virtual bool takeString() const = 0;
+ virtual bool takeNumeric() const = 0;
+ // Whether DoubleRef containing more than one column is handled properly.
+ virtual bool canHandleMultiVector() const { return false; }
+ //Continue process 'Zero' or Not(like OpMul, not continue process when meet
+ // 'Zero'
+ virtual bool ZeroReturnZero() { return false;}
+ virtual ~OpBase() { }
+};
+
+class SlidingFunctionBase : public OpBase
+{
+public:
+ typedef std::vector<DynamicKernelArgumentRef> SubArguments;
+ virtual void GenSlidingWindowFunction( std::stringstream&,
+ const std::string&, SubArguments& ) = 0;
+};
+
+class Normal : public SlidingFunctionBase
+{
+public:
+ virtual void GenSlidingWindowFunction( std::stringstream& ss,
+ const std::string& sSymName, SubArguments& vSubArguments ) override;
+ virtual bool takeString() const override { return false; }
+ virtual bool takeNumeric() const override { return true; }
+};
+
+class CheckVariables : public Normal
+{
+public:
+ static void GenTmpVariables( std::stringstream& ss, const SubArguments& vSubArguments );
+ static void CheckSubArgumentIsNan( std::stringstream& ss,
+ SubArguments& vSubArguments, int argumentNum );
+ static void CheckAllSubArgumentIsNan( std::stringstream& ss,
+ SubArguments& vSubArguments );
+ // only check isnan
+ static void CheckSubArgumentIsNan2( std::stringstream& ss,
+ SubArguments& vSubArguments, int argumentNum, const std::string& p );
+ static void UnrollDoubleVector( std::stringstream& ss,
+ const std::stringstream& unrollstr, const formula::DoubleVectorRefToken* pCurDVR,
+ int nCurWindowSize );
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/opinlinefun_finacial.cxx b/sc/source/core/opencl/opinlinefun_finacial.cxx
new file mode 100644
index 000000000..782e86b89
--- /dev/null
+++ b/sc/source/core/opencl/opinlinefun_finacial.cxx
@@ -0,0 +1,1920 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef SC_OPENCL_OPINLINFUN_finacial
+#define SC_OPENCL_OPINLINFUN_finacial
+
+std::string nCorrValDecl ="double constant nCorrVal[]"
+"= {0, 9e-1, 9e-2, 9e-3, 9e-4, 9e-5, 9e-6, 9e-7, "
+"9e-8,9e-9, 9e-10, 9e-11, 9e-12, 9e-13, 9e-14, 9e-15};\n";
+
+std::string SCdEpsilonDecl =
+"constant double SCdEpsilon = 1.0E-7;\n";
+
+std::string RoundDecl = "double Round(double fValue);\n";
+
+std::string Round =
+"double Round(double fValue)\n"
+"{\n"
+" if ( fValue == 0.0 )\n"
+" return fValue;\n"
+"\n"
+" double fFac = 0;\n"
+" int nExp;\n"
+" if ( fValue > 0.0 )\n"
+" nExp = ( floor( log10( fValue ) ) );\n"
+" else\n"
+" nExp = 0;\n"
+" int nIndex = 15 - nExp;\n"
+" if ( nIndex > 15 )\n"
+" nIndex = 15;\n"
+" else if ( nIndex <= 1 )\n"
+" nIndex = 0;\n"
+" fValue = floor( fValue + 0.5 + nCorrVal[nIndex] );\n"
+" return fValue;\n"
+"}\n";
+
+std::string GetPMTDecl =
+"double GetPMT( double fRate, double fNper, double fPv, double fFv, int nPayType );\n";
+
+std::string GetPMT=
+"double GetPMT( double fRate, double fNper, double fPv, double fFv, int nPayType )\n"
+"{\n"
+" double fPmt;\n"
+" if( fRate == 0.0 )\n"
+" fPmt = ( fPv + fFv ) / fNper;\n"
+" else\n"
+" {\n"
+" double fTerm = pow( 1.0 + fRate, fNper );\n"
+" if( nPayType > 0 )\n"
+" fPmt = ( fFv * fRate / ( fTerm - 1.0 ) + fPv * fRate / ( 1.0 - 1."
+"0 / fTerm ) ) / ( 1.0 + fRate );\n"
+" else\n"
+" fPmt = fFv * fRate / ( fTerm - 1.0 ) + fPv * fRate /( 1.0 - 1.0 "
+"/ fTerm );\n"
+" }\n"
+" return -fPmt;\n"
+"}\n";
+
+std::string GetPMT_newDecl =
+"double GetPMT_new( double fRate, double fNper, double fPv, double fFv,"
+"int nPayType );\n";
+std::string GetPMT_new=
+"double GetPMT_new( double fRate, double fNper, double fPv, double fFv,"
+"int nPayType)\n"
+"{\n"
+" double fPmt;\n"
+" double fTerm = pow( 1.0 + fRate, fNper );\n"
+" if( nPayType > 0 )\n"
+" fPmt = ( fFv * fRate *pow ( fTerm - 1.0,-1 ) + fPv * fRate *pow( "
+"( 1.0 - pow( fTerm,-1) ),-1) )* pow ( 1.0 + fRate,-1 );\n"
+" else\n"
+" fPmt = fFv * fRate *pow ( fTerm - 1.0 ,-1) + fPv * fRate *pow( "
+"1.0 - pow( fTerm,-1),-1 );\n"
+" return -fPmt;\n"
+"}\n";
+std::string GetFVDecl =
+"double GetFV( double fRate, double fNper, double fPmt,"
+"double fPv, int nPayType );\n";
+
+std::string GetFV =
+"double GetFV( double fRate, double fNper, double fPmt,"
+"double fPv, int nPayType )\n"
+"{\n"
+" double fFv;\n"
+" if( fRate == 0.0 )\n"
+" fFv = fPv + fPmt * fNper;\n"
+" else\n"
+" {\n"
+" double fTerm = pow( 1.0 + fRate, fNper );\n"
+" if( nPayType > 0 )\n"
+" fFv = fPv * fTerm + fPmt * ( 1.0 + fRate ) *( fTerm - 1.0 ) "
+"/ fRate;\n"
+" else\n"
+" fFv = fPv * fTerm + fPmt * ( fTerm - 1.0 ) / fRate;\n"
+" }\n"
+" return -fFv;\n"
+"}\n";
+
+std::string GetFV_newDecl =
+"double GetFV_new( double fRate, double fNper, double fPmt,"
+"double fPv, int nPayType );\n";
+
+std::string GetFV_new =
+"double GetFV_new( double fRate, double fNper, double fPmt,"
+"double fPv, int nPayType )\n"
+"{\n"
+" double fFv;\n"
+" double fTerm = pow( 1.0 + fRate, fNper );\n"
+" if( nPayType > 0 )\n"
+" fFv = fPv * fTerm + fPmt * ( 1.0 + fRate ) *( fTerm - 1.0 ) "
+"*pow( fRate,-1);\n"
+" else\n"
+" fFv = fPv * fTerm + fPmt * ( fTerm - 1.0 ) *pow( fRate,-1);\n"
+" return -fFv;\n"
+"}\n";
+
+std::string IsLeapYearDecl =
+"bool IsLeapYear( int n );\n";
+
+std::string IsLeapYear =
+"bool IsLeapYear( int n )\n"
+"{\n"
+" return ( (( ( n % 4 ) == 0 ) && ( ( n % 100 ) != 0)) || ( ( n % 400 ) == "
+"0 ) );\n"
+"}\n";
+
+std::string DaysInMonthDecl=
+"int DaysInMonth( int nMonth, int nYear );\n";
+
+std::string DaysInMonth =
+"int DaysInMonth( int nMonth, int nYear )\n"
+"{\n"
+" int aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,\n"
+" 31, 31, 30, 31, 30, 31 };\n"
+"\n"
+" if ( nMonth != 2 )\n"
+" return aDaysInMonth[nMonth-1];\n"
+" else\n"
+" {\n"
+" if ( IsLeapYear(nYear) )\n"
+" return aDaysInMonth[nMonth-1] + 1;\n"
+" else\n"
+" return aDaysInMonth[nMonth-1];\n"
+" }\n"
+"}\n";
+std::string DaysInMonth_newDecl=
+"int DaysInMonth( int nMonth, int nYear );\n";
+
+std::string DaysInMonth_new =
+"int DaysInMonth( int nMonth, int nYear )\n"
+"{\n"
+" int tmp = 0;\n"
+" switch(nMonth)\n"
+" {\n"
+" case 1:\n"
+" case 3:\n"
+" case 5:\n"
+" case 7:\n"
+" case 8:\n"
+" case 10:\n"
+" case 12:\n"
+" tmp = 31;\n"
+" break;\n"
+" case 4:\n"
+" case 6:\n"
+" case 9:\n"
+" case 11:\n"
+" tmp =30;\n"
+" break;\n"
+" case 2:\n"
+" if ( IsLeapYear(nYear)==1)\n"
+" tmp = 29;\n"
+" else\n"
+" tmp = 28;\n"
+" break;\n"
+" }\n"
+" return tmp;\n"
+"}\n";
+
+std::string DaysToDateDecl =
+"void DaysToDate( int nDays, int *rDay, int* rMonth, int* rYear );\n";
+
+std::string DaysToDate =
+"void DaysToDate( int nDays, int *rDay, int* rMonth, int* rYear )\n"
+"{\n"
+"\n"
+" int nTempDays;\n"
+" int i = 0;\n"
+" bool bCalc;\n"
+
+" do\n"
+" {\n"
+" nTempDays = nDays;\n"
+" *rYear = (int)((nTempDays / 365) - i);\n"
+" nTempDays -= ((int) *rYear -1) * 365;\n"
+" nTempDays -= (( *rYear -1) / 4) - (( *rYear -1) / 100) +"
+"((*rYear -1) / 400);\n"
+" bCalc = false;\n"
+" if ( nTempDays < 1 )\n"
+" {\n"
+" i++;\n"
+" bCalc = true;\n"
+" }\n"
+" else\n"
+" {\n"
+" if ( nTempDays > 365 )\n"
+" {\n"
+" if ( (nTempDays != 366) || !IsLeapYear( *rYear ) )\n"
+" {\n"
+" i--;\n"
+" bCalc = true;\n"
+" }\n"
+" }\n"
+" }\n"
+" }\n"
+" while ( bCalc );\n"
+" if(nTempDays!=0){\n"
+" for (*rMonth = 1; (int)nTempDays > DaysInMonth( *rMonth, *rYear );"
+"*rMonth+=1)\n"
+" {\n"
+" nTempDays -= DaysInMonth( *rMonth, *rYear );\n"
+" }\n"
+" *rDay = (int)nTempDays;\n"
+" }\n"
+"}\n";
+
+std::string DateToDaysDecl=
+"int DateToDays( int nDay, int nMonth, int nYear );\n";
+
+std::string DateToDays=
+"int DateToDays( int nDay, int nMonth, int nYear )\n"
+"{\n"
+" int nDays = ((int)nYear-1) * 365;\n"
+" nDays += ((nYear-1) / 4) - ((nYear-1) / 100) + ((nYear-1) / 400);\n"
+" for( int i = 1; i < nMonth; i++ )\n"
+" nDays += DaysInMonth(i,nYear);\n"
+" nDays += nDay;\n"
+"\n"
+" return nDays;\n"
+"}\n";
+
+std::string DateToDays_newDecl=
+"int DateToDays_new( int nDay, int nMonth, int nYear );\n";
+
+std::string DateToDays_new=
+"int DateToDays_new( int nDay, int nMonth, int nYear )\n"
+"{\n"
+" int nDays = (nYear-1) * 365;\n"
+" nDays += (int)((nYear-1) *pow(4.0,-1.0)- (nYear-1) *pow( 100.0,-1.0)"
+"+ (nYear-1) *pow(400.0,-1.0));\n"
+" for( int i = 1; i < nMonth; i++ )\n"
+" nDays += DaysInMonth(i,nYear);\n"
+" nDays += nDay;\n"
+"\n"
+" return nDays;\n"
+"}\n";
+
+std::string GetNullDateDecl=
+"int GetNullDate();\n";
+
+std::string GetNullDate=
+"int GetNullDate()\n"
+"{\n"
+" return DateToDays(30,12,1899 );\n"
+"}\n";
+std::string GetNullDate_newDecl=
+"int GetNullDate_new();\n";
+
+std::string GetNullDate_new=
+"int GetNullDate_new()\n"
+"{\n"
+" return DateToDays_new(30,12,1899 );\n"
+"}\n";
+
+std::string ScaDateDecl=
+"void ScaDate( int nNullDate, int nDate, int nBase,int *nOrigDay, "
+"int *nMonth,int *nYear,int *bLastDayMode,int *bLastDay,"
+"int *b30Days,int *bUSMode,int *nDay);\n";
+
+std::string ScaDate=
+"void ScaDate( int nNullDate, int nDate, int nBase,int *nOrigDay, "
+"int *nMonth,int *nYear,int *bLastDayMode,int *bLastDay,"
+"int *b30Days,int *bUSMode,int *nDay)\n"
+"{\n"
+" DaysToDate( nNullDate + nDate, nOrigDay, nMonth, nYear );\n"
+" *bLastDayMode = (nBase != 5);\n"
+" *bLastDay = (*nOrigDay >= DaysInMonth( *nMonth, *nYear ));\n"
+" *b30Days = (nBase == 0) || (nBase == 4);\n"
+" *bUSMode = (nBase == 0);\n"
+" if( *b30Days)\n"
+" {\n"
+" *nDay = min( *nOrigDay, 30);\n"
+" if( *bLastDay || (*nDay >=DaysInMonth( *nMonth, *nYear )) )\n"
+" *nDay = 30;\n"
+" }\n"
+" else\n"
+" {\n"
+" int nLastDay = DaysInMonth( *nMonth, *nYear );\n"
+" *nDay = *bLastDay ? nLastDay : min( *nOrigDay, nLastDay );\n"
+" }\n"
+"}\n";
+
+std::string ScaDate2Decl=
+"void ScaDate2( int nNullDate, int nDate, int nBase,int *bLastDayMode,int *"
+"bLastDay,int *b30Days,int *bUSMode);\n";
+
+std::string ScaDate2=
+"void ScaDate2( int nNullDate, int nDate, int nBase,int *bLastDayMode,int *"
+"bLastDay,int *b30Days,int *bUSMode)\n"
+"{\n"
+" int nOrigDay=0, nMonth=0, nYear=0;\n"
+" DaysToDate( nNullDate + nDate, &nOrigDay, &nMonth, &nYear );\n"
+" *bLastDayMode = (nBase != 5);\n"
+" *bLastDay = (nOrigDay >= DaysInMonth( nMonth, nYear ));\n"
+" *b30Days = (nBase == 0) || (nBase == 4);\n"
+" *bUSMode = (nBase == 0);\n"
+"}\n";
+
+std::string lcl_GetCouppcdDecl=
+"int lcl_GetCouppcd(int nNullDate,int nSettle,int nMat,int nFreq,int nBase);\n";
+
+std::string lcl_GetCouppcd=
+"int lcl_GetCouppcd(int nNullDate,int nSettle, int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int aDate = nMat;\n"
+" int rDay=0,rMonth=0, rYear=0,rbLastDayMode=0, rbLastDay=0,rb30Days=0,"
+"rbUSMode=0,rnDay=0;\n"
+" int sDay=0,sMonth=0, sYear=0,sbLastDayMode=0, sbLastDay=0,sb30Days=0,"
+"sbUSMode=0,snDay=0;\n"
+" ScaDate( nNullDate,nSettle,nBase,&sDay,&sMonth,&sYear,&sbLastDayMode,"
+"&sbLastDay,&sb30Days,&sbUSMode,&snDay);\n"
+" ScaDate( nNullDate,aDate,nBase,&rDay,&rMonth,&rYear,&rbLastDayMode,"
+"&rbLastDay,&rb30Days,&rbUSMode,&rnDay);\n"
+" rYear=sYear;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" if(checklessthan(rYear,sYear,rMonth,sMonth,rnDay,snDay,rbLastDay,"
+"sbLastDay,rDay,sDay))\n"
+" {\n"
+" rYear+=1;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" }\n"
+" while(checklessthan(sYear,rYear,sMonth,rMonth,snDay,rnDay,sbLastDay,"
+"rbLastDay,sDay,rDay))\n"
+" {\n"
+" double d = -1*(12/nFreq);\n"
+" addMonths(rb30Days,rbLastDay,&rnDay,rDay,&rMonth,d,&rYear);\n"
+" }\n"
+" int nLastDay = DaysInMonth( rMonth, rYear );\n"
+" int nRealDay = (rbLastDayMode && rbLastDay) ? nLastDay :"
+"min( nLastDay, rDay );\n"
+" return DateToDays( nRealDay, rMonth, rYear ) - nNullDate;\n"
+"}\n";
+
+std::string lcl_GetCoupncdDecl=
+"int lcl_GetCoupncd(int nNullDate,int nSettle,int nMat,int nFreq,int nBase);\n";
+
+std::string lcl_GetCoupncd=
+"int lcl_GetCoupncd(int nNullDate,int nSettle, int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int aDate = nMat;\n"
+" int rDay=0,rMonth=0, rYear=0,rbLastDayMode=0, rbLastDay=0,rb30Days=0,"
+"rbUSMode=0,rnDay=0;\n"
+" int sDay=0,sMonth=0, sYear=0,sbLastDayMode=0, sbLastDay=0,sb30Days=0,"
+"sbUSMode=0,snDay=0;\n"
+" ScaDate( nNullDate,nSettle,nBase,&sDay,&sMonth,&sYear,&sbLastDayMode,"
+"&sbLastDay,&sb30Days,&sbUSMode,&snDay);\n"
+" ScaDate( nNullDate,aDate,nBase,&rDay,&rMonth,&rYear,&rbLastDayMode,"
+"&rbLastDay,&rb30Days,&rbUSMode,&rnDay);\n"
+" rYear=sYear;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" if(checklessthan(sYear,rYear,sMonth,rMonth,snDay,rnDay,sbLastDay,rbLastDay"
+",sDay,rDay))\n"
+" {\n"
+" rYear-=1;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" }\n"
+" while(!checklessthan(sYear,rYear,sMonth,rMonth,snDay,rnDay,sbLastDay,"
+"rbLastDay,sDay,rDay))\n"
+" {\n"
+" addMonths(rb30Days,rbLastDay,&rnDay,rDay,&rMonth,12/nFreq,&rYear);\n"
+" }\n"
+" int nLastDay = DaysInMonth( rMonth, rYear );\n"
+" int nRealDay = (rbLastDayMode && rbLastDay) ? nLastDay :"
+"min( nLastDay, rDay );\n"
+" return DateToDays( nRealDay, rMonth, rYear ) - nNullDate;\n"
+"}\n";
+
+std::string addMonthsDecl=
+"void addMonths(int b30Days,int bLastDay,int *nDay,int nOrigDay,"
+"int *nMonth,int nMonthCount,int *year);\n";
+
+std::string addMonths=
+"void addMonths(int b30Days,int bLastDay,int *nDay,int nOrigDay,"
+"int *nMonth,int nMonthCount,int *year)\n"
+"{\n"
+" int nNewMonth = nMonthCount + *nMonth;\n"
+" if( nNewMonth > 12 )\n"
+" {\n"
+" --nNewMonth;\n"
+" *year+=nNewMonth / 12 ;\n"
+" *nMonth = ( nNewMonth % 12 ) + 1;\n"
+" }\n"
+" else if( nNewMonth < 1 )\n"
+" {\n"
+" *year+= nNewMonth / 12 - 1 ;\n"
+" *nMonth = nNewMonth % 12 + 12 ;\n"
+" }\n"
+" else\n"
+" *nMonth = nNewMonth ;\n"
+" if( b30Days )\n"
+" {\n"
+" *nDay = min( nOrigDay, 30);\n"
+" if( bLastDay || (*nDay >= DaysInMonth( *nMonth, *year )) )\n"
+" *nDay = 30;\n"
+" }\n"
+" else\n"
+" {\n"
+" int nLastDay = DaysInMonth( *nMonth, *year );\n"
+" *nDay = bLastDay ? nLastDay : min( nOrigDay, nLastDay );\n"
+" }\n"
+"}\n";
+
+std::string getDaysInMonthRangeDecl=
+"int getDaysInMonthRange( int nFrom, int nTo,int b30Days,int year);\n";
+
+std::string getDaysInMonthRange=
+"int getDaysInMonthRange( int nFrom, int nTo,int b30Days,int year)\n"
+"{\n"
+" if( nFrom > nTo )\n"
+" return 0;\n"
+" int nRet = 0;\n"
+" if( b30Days )\n"
+" nRet = (nTo - nFrom + 1) * 30;\n"
+" else\n"
+" {\n"
+" for( int nMonthIx = nFrom; nMonthIx <= nTo; ++nMonthIx )\n"
+" nRet += b30Days ? 30 : DaysInMonth( nMonthIx, year );\n"
+" }\n"
+" return nRet;\n"
+"}\n";
+
+std::string GetDaysInYearsDecl=
+"int GetDaysInYears( int nYear1, int nYear2 );\n";
+
+std::string GetDaysInYears=
+"int GetDaysInYears( int nYear1, int nYear2 )\n"
+"{\n"
+" int nLeaps = 0;\n"
+" for( int n = nYear1 ; n <= nYear2 ; n++ )\n"
+" {\n"
+" if( IsLeapYear( n ) )\n"
+" nLeaps++;\n"
+" }\n"
+" int nSum = 1;\n"
+" nSum += nYear2;\n"
+" nSum -= nYear1;\n"
+" nSum *= 365;\n"
+" nSum += nLeaps;\n"
+" return nSum;\n"
+"}\n";
+
+std::string GetDaysInYearDecl=
+"int GetDaysInYear( int nNullDate, int nDate, int nMode );\n";
+
+std::string GetDaysInYear=
+"int GetDaysInYear( int nNullDate, int nDate, int nMode )\n"
+"{\n"
+" switch( nMode )\n"
+" {\n"
+" case 0:\n"
+" case 2:\n"
+" case 4:\n"
+" return 360;\n"
+" case 1:\n"
+" {\n"
+" int nD=0, nM=0, nY=0;\n"
+" nDate += nNullDate;\n"
+" DaysToDate( nDate, &nD, &nM, &nY );\n"
+" return IsLeapYear( nY )? 366 : 365;\n"
+" }\n"
+" case 3:\n"
+" return 365;\n"
+" }\n"
+"}\n";
+
+std::string getDaysInYearRangeDecl =
+"int getDaysInYearRange( int nFrom, int nTo,int b30Days );\n";
+
+std::string getDaysInYearRange=
+"int getDaysInYearRange( int nFrom, int nTo,int b30Days )\n"
+"{\n"
+" if( nFrom > nTo )\n"
+" return 0;\n"
+" return b30Days ? ((nTo - nFrom + 1) * 360) : GetDaysInYears( nFrom, nTo)"
+";\n"
+"}\n";
+
+std::string getDiffDecl=
+"int getDiff(int rFrom,int rTo,int fDay,int fMonth,int fYear,int fbLastDayMode,"
+"int fbLastDay,int fb30Days,int fbUSMode,int fnDay,int tDay,int tMonth,"
+"int tYear,int tbLastDayMode,int tbLastDay,int tb30Days,"
+"int tbUSMode,int tnDay);\n";
+
+std::string getDiff=
+"int getDiff(int rFrom,int rTo,int fDay,int fMonth,int fYear,int fbLastDayMode,"
+"int fbLastDay,int fb30Days,int fbUSMode,int fnDay,int tDay,int tMonth,"
+"int tYear,int tbLastDayMode,int tbLastDay,int tb30Days,"
+"int tbUSMode,int tnDay)\n"
+"{\n"
+" if(rFrom>rTo)\n"
+" {\n"
+" int d=fDay;fDay=tDay;tDay=d;\n"
+" int m=fMonth;fMonth=tMonth;tMonth=m;\n"
+" int y=fYear;fYear=tYear;tYear=y;\n"
+" int a=fbLastDayMode;fbLastDayMode=tbLastDayMode;tbLastDayMode=a;\n"
+" int b=fbLastDay;fbLastDay=tbLastDay;tbLastDay=b;\n"
+" int c=fb30Days;fb30Days=tb30Days;tb30Days=c;\n"
+" int e=fbUSMode;fbUSMode=tbUSMode;tbUSMode=e;\n"
+" int f=fnDay;fnDay=tnDay;tnDay=f;\n"
+" }\n"
+" int nDiff=0;\n"
+" if( tb30Days )\n"
+" {\n"
+" if( tbUSMode )\n"
+" {\n"
+" if( ((fMonth == 2) || (fnDay < 30)) && (tDay == 31) )\n"
+" tnDay = 31;\n"
+" else if( (tMonth == 2) && tbLastDay )\n"
+" tnDay = DaysInMonth( 2, tYear );\n"
+" }\n"
+" else\n"
+" {\n"
+" if( (fMonth == 2) && (fnDay == 30) )\n"
+" fnDay = DaysInMonth( 2, fYear );\n"
+" if( (tMonth == 2) && (tnDay == 30) )\n"
+" tnDay = DaysInMonth( 2, tYear );\n"
+" }\n"
+" }\n"
+" if( (fYear < tYear) || ((fYear == tYear) && (fMonth < tMonth)) )\n"
+" {\n"
+" int d = fb30Days ? 30:DaysInMonth(fMonth,fYear);\n"
+" nDiff = d- fnDay + 1;\n"
+" fDay = fnDay = 1;\n"
+" fbLastDay = 0;\n"
+" addMonths(fb30Days,fbLastDay,&fnDay,fDay,&fMonth,1,&fYear);\n"
+" if( fYear < tYear )\n"
+" {\n"
+" nDiff += getDaysInMonthRange( fMonth, 12,fb30Days,fYear);\n"
+" addMonths(fb30Days,fbLastDay,&fnDay,fDay,&fMonth,13-fMonth,&fYear"
+");\n"
+" nDiff += getDaysInYearRange( fYear, tYear - 1,fb30Days);\n"
+" fYear+=tYear - fYear;\n"
+" }\n"
+" nDiff += getDaysInMonthRange(fMonth, tMonth - 1,fb30Days ,fYear );\n"
+" addMonths(fb30Days,fbLastDay,&fnDay,fDay,&fMonth,tMonth-fMonth,&fYear"
+");\n"
+" }\n"
+" nDiff += tnDay - fnDay;\n"
+" return nDiff > 0 ? nDiff : 0;\n"
+"}\n";
+
+std::string lcl_GetcoupdaybsDecl=
+"int lcl_Getcoupdaybs(int nNullDate,int nSettle, int nMat,int nFreq,int nBase);\n";
+
+std::string lcl_Getcoupdaybs=
+"int lcl_Getcoupdaybs(int nNullDate,int nSettle, int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int aDate = nMat;\n"
+" int rDay=0,rMonth=0, rYear=0;int mDay=0,mMonth=0, mYear=0;int sDay=0,"
+"sMonth=0, sYear=0;\n"
+" int rbLastDayMode=0, rbLastDay=0,rb30Days=0,rbUSMode=0,rnDay=0;\n"
+" int sbLastDayMode=0, sbLastDay=0,sb30Days=0,sbUSMode=0,snDay=0;\n"
+" ScaDate( nNullDate,aDate,nBase,&rDay,&rMonth,&rYear,&rbLastDayMode,&"
+"rbLastDay,&rb30Days,&rbUSMode,&rnDay);\n"
+" ScaDate( nNullDate,nSettle,nBase,&sDay,&sMonth,&sYear,&sbLastDayMode,&"
+"sbLastDay,&sb30Days,&sbUSMode,&snDay);\n"
+" rYear= sYear;\n"
+" nSettle=nSettle+nNullDate;\n"
+" aDate=DateToDays( rDay,rMonth,rYear );\n"
+" if( aDate < nSettle )\n"
+" {\n"
+" rYear+= 1;\n"
+" aDate=DateToDays( rDay,rMonth,rYear );\n"
+" }\n"
+" while(aDate > nSettle )\n"
+" {\n"
+" addMonths(rb30Days,rbLastDay,&rnDay,rDay,&rMonth,-1*(12/nFreq),&rYear"
+");\n"
+" aDate=DateToDays( rDay,rMonth,rYear );\n"
+" }\n"
+" return getDiff( aDate, nSettle, rDay, rMonth, rYear, rbLastDayMode, "
+"rbLastDay, rb30Days, rbUSMode, rnDay, sDay, sMonth, sYear, sbLastDayMode,"
+"sbLastDay, sb30Days, sbUSMode, snDay);\n"
+"}\n";
+
+std::string lcl_Getcoupdaybs_newDecl=
+"int lcl_Getcoupdaybs_new(int nNullDate,int nSettle,int nMat,int nFreq,"
+"int nBase);\n";
+
+std::string lcl_Getcoupdaybs_new=
+"int lcl_Getcoupdaybs_new(int nNullDate,int nSettle,int nMat,int nFreq,"
+"int nBase)\n"
+"{\n"
+" int aDate = nMat;\n"
+" int rDay=0,rMonth=0, rYear=0,rbLastDayMode=0, rbLastDay=0,rb30Days=0,"
+"rbUSMode=0,rnDay=0;\n"
+" int sDay=0,sMonth=0, sYear=0,sbLastDayMode=0, sbLastDay=0,sb30Days=0,"
+"sbUSMode=0,snDay=0;\n"
+" ScaDate( nNullDate,nSettle,nBase,&sDay,&sMonth,&sYear,&sbLastDayMode,"
+"&sbLastDay,&sb30Days,&sbUSMode,&snDay);\n"
+" ScaDate( nNullDate,aDate,nBase,&rDay,&rMonth,&rYear,&rbLastDayMode,"
+"&rbLastDay,&rb30Days,&rbUSMode,&rnDay);\n"
+" rYear=sYear;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" aDate=DateToDays_new( rnDay,rMonth,rYear);\n"
+" if(checklessthan(rYear,sYear,rMonth,sMonth,rnDay,snDay,rbLastDay,"
+"sbLastDay,rDay,sDay))\n"
+" {\n"
+" rYear+=1;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" aDate=DateToDays_new( rnDay,rMonth,rYear );\n"
+" }\n"
+" while(checklessthan(sYear,rYear,sMonth,rMonth,snDay,rnDay,sbLastDay,"
+"rbLastDay,sDay,rDay))\n"
+" {\n"
+" double d = -1*(12/nFreq);\n"
+" addMonths(rb30Days,rbLastDay,&rnDay,rDay,&rMonth,d,&rYear);\n"
+" aDate=DateToDays_new( rnDay,rMonth,rYear );\n"
+" }\n"
+" return getDiff( aDate,nSettle+nNullDate,rDay,rMonth,rYear,rbLastDayMode,"
+"rbLastDay,rb30Days,rbUSMode,rnDay,sDay,sMonth,sYear,sbLastDayMode,sbLastDay,"
+"sb30Days,sbUSMode, snDay);\n"
+"}\n";
+
+std::string lcl_GetcoupdaysDecl=
+"int lcl_Getcoupdays(int nNullDate,int nSettle, "
+"int nMat,int nFreq,int nBase);\n";
+
+std::string lcl_Getcoupdays=
+"int lcl_Getcoupdays(int nNullDate,int nSettle, "
+"int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int aDate = nMat;\n"
+" int rDay=0,rMonth=0, rYear=0;int mDay=0,mMonth=0, mYear=0;int sDay=0,"
+"sMonth=0, sYear=0;\n"
+" int rbLastDayMode=0, rbLastDay=0,rb30Days=0,rbUSMode=0,rnDay=0;\n"
+" int sbLastDayMode=0, sbLastDay=0,sb30Days=0,sbUSMode=0,snDay=0;\n"
+" ScaDate( nNullDate,aDate,nBase,&rDay,&rMonth,&rYear,&rbLastDayMode,&"
+"rbLastDay,&rb30Days,&rbUSMode,&rnDay);\n"
+" ScaDate( nNullDate,nSettle,nBase,&sDay,&sMonth,&sYear,&sbLastDayMode,&"
+"sbLastDay,&sb30Days,&sbUSMode,&snDay);\n"
+" rYear= sYear;\n"
+" nSettle=nSettle+nNullDate;\n"
+" aDate=DateToDays( rDay,rMonth,rYear );\n"
+" if( aDate < nSettle )\n"
+" { \n"
+" rYear+= 1;\n"
+" aDate=DateToDays( rDay,rMonth,rYear );\n"
+" }\n"
+" while(aDate > nSettle )\n"
+" {\n"
+" addMonths(rb30Days,rbLastDay,&rnDay,rDay,&rMonth,-1*(12/nFreq),&rYear"
+");\n"
+" aDate=DateToDays( rDay,rMonth,rYear );\n"
+" }\n"
+" int aNextDate=aDate;int aDay=rDay,aMonth=rMonth, aYear=rYear;\n"
+" int abLastDayMode=rbLastDayMode, abLastDay=rbLastDay,ab30Days=rb30Days,"
+"abUSMode=rbUSMode,anDay=rnDay;\n"
+" addMonths(ab30Days,abLastDay,&anDay,aDay,&aMonth,12/nFreq,&aYear);\n"
+" return getDiff( aDate, aNextDate, rDay, rMonth, rYear, rbLastDayMode, "
+"rbLastDay, rb30Days, rbUSMode, rnDay, aDay, aMonth, aYear, abLastDayMode,"
+"abLastDay, ab30Days, abUSMode, anDay);\n"
+"}\n";
+
+std::string lcl_Getcoupdays_newDecl=
+"int lcl_Getcoupdays_new(int nNullDate,int nSettle, "
+"int nMat,int nFreq,int nBase);\n";
+
+std::string lcl_Getcoupdays_new=
+"int lcl_Getcoupdays_new(int nNullDate,int nSettle, "
+"int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int aDate = nMat;\n"
+" int rDay=0,rMonth=0, rYear=0,rbLastDayMode=0, rbLastDay=0,rb30Days=0,"
+"rbUSMode=0,rnDay=0;\n"
+" int sDay=0,sMonth=0, sYear=0,sbLastDayMode=0, sbLastDay=0,sb30Days=0,"
+"sbUSMode=0,snDay=0;\n"
+" ScaDate( nNullDate,nSettle,nBase,&sDay,&sMonth,&sYear,&sbLastDayMode,"
+"&sbLastDay,&sb30Days,&sbUSMode,&snDay);\n"
+" ScaDate( nNullDate,aDate,nBase,&rDay,&rMonth,&rYear,&rbLastDayMode,"
+"&rbLastDay,&rb30Days,&rbUSMode,&rnDay);\n"
+" rYear=sYear;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" aDate=DateToDays_new( rnDay,rMonth,rYear);\n"
+" if(checklessthan(rYear,sYear,rMonth,sMonth,rnDay,snDay,rbLastDay,"
+"sbLastDay,rDay,sDay))\n"
+" {\n"
+" rYear+=1;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" aDate=DateToDays_new( rnDay,rMonth,rYear );\n"
+" }\n"
+" while(checklessthan(sYear,rYear,sMonth,rMonth,snDay,rnDay,sbLastDay,"
+"rbLastDay,sDay,rDay))\n"
+" {\n"
+" double d = -1*12*pow((double)nFreq,-1.0);\n"
+" addMonths(rb30Days,rbLastDay,&rnDay,rDay,&rMonth,d,&rYear);\n"
+" aDate=DateToDays_new( rnDay,rMonth,rYear );\n"
+" }\n"
+" int aNextDate=aDate;int aDay=rDay,aMonth=rMonth, aYear=rYear;\n"
+" int abLastDayMode=rbLastDayMode, abLastDay=rbLastDay,ab30Days=rb30Days,"
+"abUSMode=rbUSMode,anDay=rnDay;\n"
+" int tmp = (int)(12*pow((double)nFreq,-1.0));\n"
+" addMonths(ab30Days,abLastDay,&anDay,aDay,&aMonth,tmp,&aYear);\n"
+" return getDiff( aDate, aNextDate, rDay, rMonth, rYear, rbLastDayMode, "
+"rbLastDay, rb30Days, rbUSMode, rnDay, aDay, aMonth, aYear, abLastDayMode,"
+"abLastDay, ab30Days, abUSMode, anDay);\n"
+"}\n";
+
+std::string lcl_GetcoupnumDecl=
+"int lcl_Getcoupnum(int nNullDate,int nSettle, int nMat,int nFreq);\n";
+
+std::string lcl_Getcoupnum=
+"int lcl_Getcoupnum(int nNullDate,int nSettle, int nMat,int nFreq)\n"
+"{\n"
+" int aDate = nMat;int rDay=0,rMonth=0, rYear=0;int mDay=0,mMonth=0, mYear="
+"0;\n"
+" int sDay=0,sMonth=0, sYear=0;\n"
+" DaysToDate(aDate+nNullDate,&rDay, &rMonth, &rYear );\n"
+" DaysToDate(nMat+nNullDate,&mDay, &mMonth, &mYear );\n"
+" DaysToDate(nSettle+nNullDate,&sDay, &sMonth, &sYear );\n"
+" rYear= sYear;\n"
+" nSettle=nSettle+nNullDate;\n"
+" aDate=DateToDays( rDay,rMonth,rYear );\n"
+" if( aDate < nSettle )\n"
+" rYear+= 1;\n"
+" int d=DateToDays( rDay,rMonth,rYear );\n"
+" int nMonthCount=-1*(12 / nFreq);\n"
+" while(d > nSettle )\n"
+" {\n"
+" int nNewMonth = nMonthCount + rMonth;\n"
+" if( nNewMonth > 12 )\n"
+" {\n"
+" --nNewMonth;\n"
+" rYear+=nNewMonth / 12;\n"
+" rMonth = nNewMonth % 12 + 1;\n"
+" }\n"
+" else if( nNewMonth < 1 )\n"
+" {\n"
+" rYear+= nNewMonth / 12 - 1;\n"
+" rMonth = nNewMonth % 12 + 12;\n"
+" }\n"
+" else\n"
+" rMonth = nNewMonth;\n"
+" d=DateToDays( rDay,rMonth,rYear );\n"
+" }\n"
+" int n=(mYear-rYear)*12+mMonth-rMonth;\n"
+" n=n*nFreq/12;\n"
+" return n;\n"
+"}\n";
+std::string lcl_Getcoupnum_newDecl=
+"double lcl_Getcoupnum_new(int nNullDate,int nSettle,int nMat,int nFreq,int"
+" nBase);\n";
+std::string lcl_Getcoupnum_new=
+"double lcl_Getcoupnum_new(int nNullDate,int nSettle, int nMat,int nFreq,int"
+" nBase)\n"
+"{\n"
+" int aDate = nMat;\n"
+" int mDay=0,mMonth=0, mYear=0;\n"
+" int rDay=0,rMonth=0, rYear=0,rbLastDayMode=0, rbLastDay=0,rb30Days=0,"
+"rbUSMode=0,rnDay=0;\n"
+" int sDay=0,sMonth=0, sYear=0,sbLastDayMode=0, sbLastDay=0,sb30Days=0,"
+"sbUSMode=0,snDay=0;\n"
+" ScaDate( nNullDate,nSettle,nBase,&sDay,&sMonth,&sYear,&sbLastDayMode,"
+"&sbLastDay,&sb30Days,&sbUSMode,&snDay);\n"
+" ScaDate( nNullDate,aDate,nBase,&rDay,&rMonth,&rYear,&rbLastDayMode,"
+"&rbLastDay,&rb30Days,&rbUSMode,&rnDay);\n"
+" mMonth = rMonth, mYear = rYear;\n"
+" rYear=sYear;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" if(checklessthan(rYear,sYear,rMonth,sMonth,rnDay,snDay,rbLastDay,"
+"sbLastDay,rDay,sDay))\n"
+" {\n"
+" rYear+=1;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" }\n"
+" int m= checklessthan(sYear,rYear,sMonth,rMonth,snDay,rnDay,sbLastDay,"
+"rbLastDay,sDay,rDay);\n"
+" while(m)\n"
+" {\n"
+" double d = -1*(12/nFreq);\n"
+" addMonths(rb30Days,rbLastDay,&rnDay,rDay,&rMonth,d,&rYear);\n"
+" m = checklessthan(sYear,rYear,sMonth,rMonth,snDay,rnDay,sbLastDay,"
+"rbLastDay,sDay,rDay);\n"
+" }\n"
+" int n=(mYear-rYear)*12+mMonth-rMonth;\n"
+" double tmp = (double)(n*nFreq)/12.0;\n"
+" return tmp;\n"
+"}\n";
+
+std::string setDayDecl=
+"void setDay(int nOrigDay, int nMonth,int nYear,int bLastDay,int b30Days,"
+"int *nDay);\n";
+std::string setDay=
+"void setDay(int nOrigDay, int nMonth,int nYear,int bLastDay,int b30Days,"
+"int *nDay)\n"
+"{\n"
+" if( b30Days )\n"
+" {\n"
+" *nDay = min( nOrigDay, 30);\n"
+" if( bLastDay || (*nDay >= DaysInMonth( nMonth, nYear )) )\n"
+" *nDay = 30;\n"
+" }\n"
+" else\n"
+" {\n"
+" int nLastDay = DaysInMonth( nMonth, nYear );\n"
+" *nDay = bLastDay ? nLastDay : min( nOrigDay, nLastDay );\n"
+" }\n"
+"}\n";
+
+std::string coupdaysDecl=
+"double coupdays(int nSettle,int nMat,int nFreq,int nBase);\n";
+
+std::string coupdays=
+"double coupdays(int nSettle,int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int nNullDate=GetNullDate();\n"
+" if( nBase == 1 )\n"
+" return lcl_Getcoupdays(nNullDate, nSettle, nMat,nFreq, nBase);\n"
+" else\n"
+" return (double)GetDaysInYear(0,0,nBase)/nFreq;\n"
+"}\n";
+std::string coupdays_newDecl=
+"double coupdays_new(int nSettle,int nMat,int nFreq,int nBase);\n";
+
+std::string coupdays_new=
+"double coupdays_new(int nSettle,int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int nNullDate=693594;\n"
+" if( nBase == 1 )\n"
+" return lcl_Getcoupdays_new(nNullDate, nSettle, nMat,nFreq, nBase);\n"
+" else\n"
+" return (double)GetDaysInYear(0,0,nBase)*pow((double)nFreq,-1.0);\n"
+"}\n";
+
+std::string coupdaybsDecl=
+"double coupdaybs( int nSettle,int nMat,int nFreq,int nBase);\n";
+
+std::string coupdaybs=
+"double coupdaybs( int nSettle,int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int nNullDate=GetNullDate();\n"
+" return lcl_Getcoupdaybs(nNullDate, nSettle, nMat,nFreq, nBase);\n"
+"}\n";
+
+std::string coupdaybs_newDecl=
+"double coupdaybs_new( int nSettle,int nMat,int nFreq,int nBase);\n";
+
+std::string coupdaybs_new=
+"double coupdaybs_new( int nSettle,int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int nNullDate=693594;\n"
+" return lcl_Getcoupdaybs_new(nNullDate, nSettle, nMat,nFreq, nBase);\n"
+"}\n";
+
+std::string coupdaysncDecl=
+"double coupdaysnc( int nSettle,int nMat,int nFreq,int nBase);\n";
+
+std::string coupdaysnc=
+ "double coupdaysnc( int nSettle,int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int nNullDate=GetNullDate();\n"
+" if((nBase != 0) && (nBase != 4))\n"
+" {\n"
+" int aDate = nMat;\n"
+" int rDay=0,rMonth=0, rYear=0;int mDay=0,mMonth=0, mYear=0;int sDay=0,"
+"sMonth=0, sYear=0;\n"
+" int rbLastDayMode=0, rbLastDay=0,rb30Days=0,rbUSMode=0,rnDay=0;\n"
+" int sbLastDayMode=0, sbLastDay=0,sb30Days=0,sbUSMode=0,snDay=0;\n"
+" ScaDate( nNullDate,aDate,nBase,&rDay,&rMonth,&rYear,&rbLastDayMode,&"
+"rbLastDay,&rb30Days,&rbUSMode,&rnDay);\n"
+" ScaDate( nNullDate,nSettle,nBase,&sDay,&sMonth,&sYear,&sbLastDayMode,"
+"&sbLastDay,&sb30Days,&sbUSMode,&snDay);\n"
+" rYear= sYear;\n"
+" nSettle=nSettle+nNullDate;\n"
+" aDate=DateToDays( rDay,rMonth,rYear );\n"
+" if( aDate > nSettle )\n"
+" {\n"
+" rYear-= 1;\n"
+" aDate=DateToDays( rDay,rMonth,rYear );\n"
+" }\n"
+" while(aDate <= nSettle )\n"
+" {\n"
+" addMonths(rb30Days,rbLastDay,&rnDay,rDay,&rMonth,12/nFreq,&rYear)"
+";\n"
+" aDate=DateToDays( rDay,rMonth,rYear );\n"
+" }\n"
+" return getDiff( nSettle, aDate, sDay, sMonth, sYear, sbLastDayMode, "
+"sbLastDay, sb30Days, sbUSMode, snDay, rDay, rMonth, rYear, rbLastDayMode, "
+"rbLastDay, rb30Days, rbUSMode, rnDay);\n"
+" }\n"
+" else\n"
+" return coupdays(nSettle,nMat,nFreq,nBase)- coupdaybs( nSettle,nMat,"
+"nFreq,nBase);\n"
+"}\n";
+std::string coupdaysnc_newDecl=
+"double coupdaysnc_new( int nSettle,int nMat,int nFreq,int nBase);\n";
+
+std::string coupdaysnc_new=
+"double coupdaysnc_new( int nSettle,int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int nNullDate=693594;\n"
+" if((nBase != 0) && (nBase != 4))\n"
+" {\n"
+" int aDate = nMat;\n"
+" int rDay=0,rMonth=0, rYear=0,rbLastDayMode=0, rbLastDay=0,rb30Days=0,"
+"rbUSMode=0,rnDay=0;\n"
+" int sDay=0,sMonth=0, sYear=0,sbLastDayMode=0, sbLastDay=0,sb30Days=0,"
+"sbUSMode=0,snDay=0;\n"
+" ScaDate( nNullDate,aDate,nBase,&rDay,&rMonth,&rYear,&rbLastDayMode,"
+"&rbLastDay,&rb30Days,&rbUSMode,&rnDay);\n"
+" ScaDate( nNullDate,nSettle,nBase,&sDay,&sMonth,&sYear,&sbLastDayMode,"
+"&sbLastDay,&sb30Days,&sbUSMode,&snDay);\n"
+" rYear=sYear;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" aDate=DateToDays( rnDay,rMonth,rYear);\n"
+" if(checklessthan(sYear,rYear,sMonth,rMonth,snDay,rnDay,sbLastDay,rbLastDay"
+",sDay,rDay))\n"
+" {\n"
+" rYear-=1;\n"
+" setDay(rDay,rMonth,rYear,rbLastDay,rb30Days,&rnDay);\n"
+" aDate=DateToDays( rnDay,rMonth,rYear );\n"
+" }\n"
+" while(!checklessthan(sYear,rYear,sMonth,rMonth,snDay,rnDay,sbLastDay,"
+"rbLastDay,sDay,rDay))\n"
+" {\n"
+" addMonths(rb30Days,rbLastDay,&rnDay,rDay,&rMonth,12/nFreq,&rYear);\n"
+" aDate=DateToDays( rnDay,rMonth,rYear );\n"
+" }\n"
+" return getDiff( nSettle+nNullDate,aDate,sDay,sMonth,sYear,sbLastDayMode, "
+"sbLastDay, sb30Days, sbUSMode, snDay, rDay, rMonth, rYear, rbLastDayMode, "
+"rbLastDay, rb30Days, rbUSMode, rnDay);\n"
+" }\n"
+" else\n"
+" return coupdays_new(nSettle,nMat,nFreq,nBase)- coupdaybs_new( nSettle,"
+"nMat,nFreq,nBase);\n"
+"}\n";
+
+std::string checklessthanDecl=
+"int checklessthan(int aYear,int bYear,int aMonth,int bMonth,int anDay,int "
+"bnDay,int abLastDay,int bbLastDay,int anOrigDay,int bnOrigDay);\n";
+std::string checklessthan=
+"int checklessthan(int aYear,int bYear,int aMonth,int bMonth,int anDay,int "
+"bnDay,int abLastDay,int bbLastDay,int anOrigDay,int bnOrigDay)\n"
+"{\n"
+" if( aYear != bYear )\n"
+" return aYear < bYear;\n"
+" if( aMonth != bMonth )\n"
+" return aMonth < bMonth;\n"
+" if( anDay != bnDay )\n"
+" return anDay < bnDay;\n"
+" if( abLastDay || bbLastDay )\n"
+" return !abLastDay && bbLastDay;\n"
+" return anOrigDay < bnOrigDay;\n"
+"}\n";
+
+std::string coupnumDecl=
+"double coupnum( int nSettle,int nMat,int nFreq,int nBase);\n";
+
+std::string coupnum=
+"double coupnum( int nSettle,int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int nNullDate=GetNullDate();\n"
+" return lcl_Getcoupnum(nNullDate,nSettle,nMat,nFreq);\n"
+"}\n";
+std::string coupnum_newDecl=
+"double coupnum_new( int nSettle,int nMat,int nFreq,int nBase);\n";
+
+std::string coupnum_new=
+"double coupnum_new( int nSettle,int nMat,int nFreq,int nBase)\n"
+"{\n"
+" int nNullDate=693594;\n"
+" return lcl_Getcoupnum_new(nNullDate,nSettle,nMat,nFreq,nBase);\n"
+"}\n";
+
+std::string getPrice_Decl=
+"double getPrice_(int nSettle, int nMat, double fRate, double fYield,\n"
+ "double fRedemp, int nFreq, int nBase );\n";
+
+std::string getPrice_=
+"double getPrice_(int nSettle, int nMat, double fRate, double fYield,\n"
+ "double fRedemp, int nFreq, int nBase )\n"
+"{\n"
+" double fFreq = nFreq;\n"
+" double fE = coupdays( nSettle, nMat, nFreq, nBase );\n"
+" double fDSC_E = coupdaysnc( nSettle, nMat, nFreq, nBase ) / fE;\n"
+" double fN = coupnum( nSettle, nMat, nFreq, nBase );\n"
+" double fA = coupdaybs( nSettle, nMat, nFreq, nBase );\n"
+" double fRet = fRedemp / ( pow( 1.0 + fYield / fFreq, fN - 1.0 + "
+"fDSC_E ) );\n"
+" fRet -= 100.0 * fRate / fFreq * fA / fE;\n"
+" double fT1 = 100.0 * fRate / fFreq;\n"
+" double fT2 = 1.0 + fYield / fFreq;\n"
+" for( double fK = 0.0 ; fK < fN ; fK+=1.0 )\n"
+" fRet += fT1 / pow( fT2, fK + fDSC_E );\n"
+" return fRet;\n"
+"}\n";
+std::string getPrice_new_Decl=
+"double getPrice_(int nSettle, int nMat, double fRate, double fYield,\n"
+ "double fRedemp, int nFreq, int nBase );\n";
+
+std::string getPrice_new=
+"double getPrice_(int nSettle, int nMat, double fRate, double fYield,\n"
+ "double fRedemp, int nFreq, int nBase )\n"
+"{\n"
+" double fFreq = nFreq;\n"
+" double fE = coupdays_new( nSettle, nMat, nFreq, nBase );\n"
+" double fDSC_E = coupdaysnc_new( nSettle, nMat, nFreq, nBase ) / fE;\n"
+" double fN = coupnum_new( nSettle, nMat, nFreq, nBase );\n"
+" double fA = coupdaybs_new( nSettle, nMat, nFreq, nBase );\n"
+" double fRet = fRedemp / ( pow( 1.0 + fYield / fFreq, fN - 1.0 + "
+"fDSC_E ) );\n"
+" fRet -= 100.0 * fRate / fFreq * fA / fE;\n"
+" double fT1 = 100.0 * fRate / fFreq;\n"
+" double fT2 = 1.0 + fYield / fFreq;\n"
+" for( double fK = 0.0 ; fK < fN ; fK+=1.0 )\n"
+" fRet += fT1 / pow( fT2, fK + fDSC_E );\n"
+" return fRet;\n"
+"}\n";
+
+std::string getYield_Decl=
+"double getYield_( int nNullDate, int nSettle, int nMat, double fCoup,"
+"double fPrice,double fRedemp, int nFreq, int nBase);\n";
+
+std::string getYield_=
+"double getYield_( int nNullDate, int nSettle, int nMat, double fCoup,"
+"double fPrice,double fRedemp, int nFreq, int nBase )\n"
+"{\n"
+" double fRate = fCoup;\n"
+" double fPriceN = 0.0;\n"
+" double fYield1 = 0.0;\n"
+" double fYield2 = 1.0;\n"
+" double fPrice1 = getPrice_(nSettle, nMat, fRate, fYield1, fRedemp, "
+"nFreq, nBase );\n"
+" double fPrice2 = getPrice_(nSettle, nMat, fRate, fYield2, fRedemp, "
+"nFreq, nBase );\n"
+" double fYieldN = ( fYield2 - fYield1 ) * 0.5;\n"
+" for( unsigned int nIter = 0 ; nIter < 100 && fPriceN != fPrice ; nIter++ "
+")\n"
+" {\n"
+" fPriceN = getPrice_(nSettle, nMat, fRate, fYieldN, fRedemp, nFreq, "
+"nBase );\n"
+" if( fPrice == fPrice1 )\n"
+" return fYield1;\n"
+" else if( fPrice == fPrice2 )\n"
+" return fYield2;\n"
+" else if( fPrice == fPriceN )\n"
+" return fYieldN;\n"
+" else if( fPrice < fPrice2 )\n"
+" {\n"
+" fYield2 *= 2.0;\n"
+" fPrice2 = getPrice_(nSettle, nMat, fRate, fYield2, fRedemp, nFreq"
+", nBase );\n"
+" fYieldN = ( fYield2 - fYield1 ) * 0.5;\n"
+" }\n"
+" else\n"
+" {\n"
+" if( fPrice < fPriceN )\n"
+" {\n"
+" fYield1 = fYieldN;\n"
+" fPrice1 = fPriceN;\n"
+" }\n"
+" else\n"
+" {\n"
+" fYield2 = fYieldN;\n"
+" fPrice2 = fPriceN;\n"
+" }\n"
+" fYieldN = fYield2 - ( fYield2 - fYield1 ) * ( ( fPrice - fPrice2 "
+") / ( fPrice1 - fPrice2 ) );\n"
+" }\n"
+" }\n"
+" return fYieldN;\n"
+"}\n";
+
+std::string GetYearFracDecl=
+"double GetYearFrac( int nNullDate, int nStartDate, int nEndDate,"
+"int nMode );\n";
+
+std::string GetYearFrac=
+"double GetYearFrac( int nNullDate, int nStartDate, int nEndDate,"
+"int nMode ) \n"
+"{\n"
+" if( nStartDate == nEndDate )\n"
+" return 0.0; \n"
+
+ " if( nStartDate > nEndDate )\n"
+ " {\n"
+ " int n = nEndDate;\n"
+ " nEndDate = nStartDate;\n"
+ " nStartDate = n;\n"
+ " }\n"
+
+ " int nDate1 = nStartDate + nNullDate;\n"
+ " int nDate2 = nEndDate + nNullDate;\n"
+
+ " int nDay1, nDay2;\n"
+ " int nMonth1, nMonth2;\n"
+ " int nYear1, nYear2;\n"
+
+ " DaysToDate( nDate1, &nDay1, &nMonth1, &nYear1 );\n"
+ " DaysToDate( nDate2, &nDay2, &nMonth2, &nYear2 );\n"
+
+ " int nDayDiff;\n"
+ " switch( nMode )\n"
+ " {\n"
+ " case 0: \n"
+ " if ( nDay1 == 31 )\n"
+ " {\n"
+ " nDay1--;\n"
+ " }\n"
+ " if ( nDay1 == 30 && nDay2 == 31 )\n"
+ " {\n"
+ " nDay2--;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " if ( nMonth1 == 2 && nDay1 == "
+ "( IsLeapYear( nYear1 ) ? 29 : 28 ) )\n"
+ " {\n"
+ " nDay1 = 30;\n"
+ " if ( nMonth2 == 2 && nDay2 == "
+ "( IsLeapYear( nYear2 ) ? 29 : 28 ) )\n"
+ " {\n"
+ " nDay2 = 30;\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " nDayDiff = ( nYear2 - nYear1 ) * 360 + "
+ "( nMonth2 - nMonth1 ) * 30 + ( nDay2 - nDay1 );\n"
+ " break;\n"
+ " case 1: \n"
+ " case 2: \n"
+ " case 3: \n"
+ " nDayDiff = nDate2 - nDate1;\n"
+ " break;\n"
+ " case 4: \n"
+ " if ( nDay1 == 31 )\n"
+ " {\n"
+ " nDay1--;\n"
+ " }\n"
+ " if ( nDay2 == 31 )\n"
+ " {\n"
+ " nDay2--;\n"
+ " }\n"
+ " nDayDiff = ( nYear2 - nYear1 ) * 360 + "
+ "( nMonth2 - nMonth1 ) * 30 + ( nDay2 - nDay1 );\n"
+ " break;\n"
+ " }\n"
+
+ " double nDaysInYear;\n"
+ " switch( nMode )\n"
+ " {\n"
+ " case 0: \n"
+ " case 2: \n"
+ " case 4: \n"
+ " nDaysInYear = 360;\n"
+ " break;\n"
+ " case 1: \n"
+ " {\n"
+ " bool isYearDifferent = ( nYear1 != nYear2 );\n"
+ " if ( isYearDifferent &&\n"
+ " ( ( nYear2 != nYear1 + 1 ) ||\n"
+ " ( nMonth1 < nMonth2 ) ||\n"
+ " ( nMonth1 == nMonth2 && nDay1 < nDay2 ) ) )\n"
+ " {\n"
+
+ " int nDayCount = 0;\n"
+ " for ( int i = nYear1; i <= nYear2; i++ )\n"
+ " nDayCount += ( IsLeapYear( i ) ? 366 : 365 );\n"
+
+ " nDaysInYear = ( double ) nDayCount / "
+ "( double ) ( nYear2 - nYear1 + 1 );\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " if ( isYearDifferent && IsLeapYear( nYear1 ) )\n"
+ " {\n"
+ " nDaysInYear = 366;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+
+ " if ( ( IsLeapYear( nYear1 ) && nMonth1 <= 2 "
+ "&& nDay1 <= 29 ) ||\n"
+ " ( IsLeapYear( nYear2 ) && ( nMonth2 > 3 || "
+ "( nMonth2 == 2 && nDay1 == 29 ) ) ) )\n"
+ " {\n"
+ " nDaysInYear = 366;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " nDaysInYear = 365;\n"
+ " for ( int i = nYear1; i <= nYear2; i++ )\n"
+ " {\n"
+ " if ( IsLeapYear( i ) )\n"
+ " {\n"
+ " nDaysInYear = 366;\n"
+ " break;\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " break;\n"
+ " case 3: \n"
+ " nDaysInYear = 365;\n"
+ " break;\n"
+ " }\n"
+ " return (double)( nDayDiff ) / (nDaysInYear);\n"
+"}\n";
+
+std::string GetYieldmatDecl=
+ "double GetYieldmat( int nNullDate, int nSettle, int nMat, int nIssue,\n"
+ "double fRate, double fPrice, int nBase );\n";
+
+std::string GetYieldmat=
+ "double GetYieldmat( int nNullDate, int nSettle, int nMat, int nIssue,\n"
+ "double fRate, double fPrice, int nBase )\n"
+"{\n"
+" double fIssMat = GetYearFrac_new( nNullDate, nIssue, nMat, nBase );\n"
+" double fIssSet = GetYearFrac_new( nNullDate, nIssue, nSettle, nBase );\n"
+" double fSetMat = GetYearFrac_new( nNullDate, nSettle, nMat, nBase );\n"
+" double y = 1.0 + fIssMat * fRate;\n"
+" y =y * pow( (fPrice / 100.0 + fIssSet * fRate),-1);\n"
+" y-=1.0;\n"
+" y = y * pow(fSetMat,-1);\n"
+" return y;\n"
+"}\n";
+
+std::string GetDiffDateDecl=
+"int GetDiffDate( int nNullDate, int nStartDate, int nEndDate, int nMode,"
+" int* pOptDaysIn1stYear );\n";
+
+std::string GetDiffDate=
+"int GetDiffDate( int nNullDate, int nStartDate, int nEndDate, int nMode,"
+" int* pOptDaysIn1stYear )\n"
+"{\n"
+" bool bNeg = nStartDate > nEndDate;\n"
+" if( bNeg )\n"
+" {\n"
+" int n = nEndDate;\n"
+" nEndDate = nStartDate;\n"
+" nStartDate = n;\n"
+" }\n"
+" int nRet;\n"
+" switch( nMode )\n"
+" {\n"
+" case 0: \n"
+" case 4: \n"
+" {\n"
+" int nD1, nM1, nY1, nD2, nM2, nY2;\n"
+" nStartDate += nNullDate;\n"
+" nEndDate += nNullDate;\n"
+" DaysToDate( nStartDate, &nD1, &nM1, &nY1 );\n"
+" DaysToDate( nEndDate, &nD2, &nM2, &nY2 );\n"
+" bool bLeap = IsLeapYear( nY1 );\n"
+" int nDays, nMonths;\n"
+" nMonths = nM2 - nM1;\n"
+" nDays = nD2 - nD1;\n"
+" nMonths += ( nY2 - nY1 ) * 12;\n"
+" nRet = nMonths * 30 + nDays;\n"
+" if( nMode == 0 && nM1 == 2 && nM2 != 2 && nY1 == nY2 )\n"
+" nRet -= bLeap? 1 : 2;\n"
+" if( pOptDaysIn1stYear )\n"
+" *pOptDaysIn1stYear = 360;\n"
+" }\n"
+" break;\n"
+" case 1: \n"
+" if( pOptDaysIn1stYear )\n"
+" {\n"
+" int nD, nM, nY;\n"
+" DaysToDate( nStartDate + nNullDate, &nD, &nM, &nY );\n"
+" *pOptDaysIn1stYear = IsLeapYear( nY )? 366 : 365;\n"
+" }\n"
+" nRet = nEndDate - nStartDate;\n"
+" break;\n"
+" case 2: \n"
+" nRet = nEndDate - nStartDate;\n"
+" if( pOptDaysIn1stYear )\n"
+" *pOptDaysIn1stYear = 360;\n"
+" break;\n"
+" case 3: \n"
+" nRet = nEndDate - nStartDate;\n"
+" if( pOptDaysIn1stYear )\n"
+" *pOptDaysIn1stYear = 365;\n"
+" break;\n"
+" }\n"
+" return bNeg? -nRet : nRet;\n"
+"}\n";
+
+std::string GetYearDiffDecl=
+"double GetYearDiff( int nNullDate, int nStartDate, int nEndDate,"
+"int nMode);\n";
+
+std::string GetYearDiff=
+"double GetYearDiff( int nNullDate, int nStartDate, int nEndDate,"
+"int nMode )\n"
+"{\n"
+" int nDays1stYear;\n"
+" int nTotalDays = GetDiffDate( nNullDate, nStartDate, nEndDate,"
+"nMode, &"
+"nDays1stYear );\n"
+" return (double)(nTotalDays)*pow((double)nDays1stYear,-1);\n"
+"}\n";
+
+std::string GetDiffDate360_Decl=
+"int GetDiffDate360_(\n"
+" int nDay1, int nMonth1, int nYear1, bool bLeapYear1,\n"
+" int nDay2, int nMonth2, int nYear2,\n"
+" bool bUSAMethod );\n";
+
+std::string GetDiffDate360_=
+"int GetDiffDate360_(\n"
+" int nDay1, int nMonth1, int nYear1, bool bLeapYear1,\n"
+" int nDay2, int nMonth2, int nYear2,\n"
+" bool bUSAMethod )\n"
+"{\n"
+" if( nDay1 == 31 )\n"
+" nDay1--;\n"
+" else if( bUSAMethod && ( nMonth1 == 2 && ( nDay1 == 29 || ( nDay1 == 28 "
+"&& !bLeapYear1 ) ) ) )\n"
+" nDay1 = 30;\n"
+" if( nDay2 == 31 )\n"
+" {\n"
+" if( bUSAMethod && nDay1 != 30 )\n"
+" {\n"
+" nDay2 = 1;\n"
+" if( nMonth2 == 12 )\n"
+" {\n"
+" nYear2++;\n"
+" nMonth2 = 1;\n"
+" }\n"
+" else\n"
+" nMonth2++;\n"
+" }\n"
+" else\n"
+" nDay2 = 30;\n"
+" }\n"
+" return nDay2 + nMonth2 * 30 + nYear2 * 360 - nDay1 - nMonth1 * 30 - "
+"nYear1 * 360;\n"
+"}\n";
+
+std::string GetDiffDate360Decl=
+"int GetDiffDate360( int nNullDate, int nDate1, int nDate2,"
+"bool bUSAMethod);\n";
+
+std::string GetDiffDate360=
+"int GetDiffDate360( int nNullDate, int nDate1, int nDate2,"
+"bool bUSAMethod )\n"
+"{\n"
+" nDate1 += nNullDate;\n"
+" nDate2 += nNullDate;\n"
+" int nDay1, nMonth1, nYear1, nDay2, nMonth2, nYear2;\n"
+" DaysToDate( nDate1, &nDay1, &nMonth1, &nYear1 );\n"
+" DaysToDate( nDate2, &nDay2, &nMonth2, &nYear2 );\n"
+" return GetDiffDate360_( nDay1, nMonth1, nYear1, IsLeapYear( nYear1 ), "
+"nDay2, nMonth2, nYear2, bUSAMethod );\n"
+"}\n";
+
+std::string GetDurationDecl=
+"double GetDuration( \n"
+" int nNullDate, int nSettle, int nMat, double fCoup,\n"
+" double fYield, int nFreq, int nBase );\n";
+
+std::string GetDuration=
+"double GetDuration( \n"
+" int nNullDate, int nSettle, int nMat, double fCoup,\n"
+" double fYield, int nFreq, int nBase )\n"
+"{\n"
+" double fYearfrac = GetYearFrac( nNullDate, nSettle, nMat, nBase );\n"
+" double fNumOfCoups = lcl_Getcoupnum(nNullDate,nSettle,nMat,nFreq);\n"
+" double fDur = 0.0;\n"
+" double f100 = 100.0;\n"
+" fCoup *= f100 / nFreq;\n"
+" fYield /= nFreq;\n"
+" fYield += 1.0;\n"
+" double nDiff = fYearfrac * nFreq - fNumOfCoups;\n"
+" int t;\n"
+" for( t = 1 ; t < fNumOfCoups ; t++ )\n"
+" fDur += ( t + nDiff ) * ( fCoup ) / pow( fYield, t + nDiff );\n"
+" fDur += ( fNumOfCoups + nDiff ) * ( fCoup + f100 ) /"
+" pow( fYield, fNumOfCoups + nDiff );\n"
+" double p = 0.0;\n"
+" for( t = 1 ; t < fNumOfCoups ; t++ )\n"
+" p += fCoup / pow( fYield, t + nDiff );\n"
+" p += ( fCoup + f100 ) / pow( fYield, fNumOfCoups + nDiff );\n"
+" fDur /= p;\n"
+" fDur /= nFreq;\n"
+" return fDur;\n""}\n";
+
+std::string GetDuration_newDecl=
+"double GetDuration_new( \n"
+" int nNullDate, int nSettle, int nMat, double fCoup,\n"
+" double fYield, int nFreq, int nBase );\n";
+
+std::string GetDuration_new=
+"double GetDuration_new( \n"
+" int nNullDate, int nSettle, int nMat, double fCoup,\n"
+" double fYield, int nFreq, int nBase )\n"
+" {\n"
+" double fYearfrac = GetYearFrac(nNullDate,nSettle,nMat,nBase);\n"
+" double fNumOfCoups = lcl_Getcoupnum_new(nNullDate,nSettle,nMat,"
+"nFreq,nBase);\n"
+" double fDur = 0.0;\n"
+" fCoup = fCoup * 100.0 * pow(nFreq, -1.0);\n"
+" fYield = fYield * pow(nFreq, -1.0);\n"
+" fYield += 1.0;\n"
+" double nDiff = fYearfrac * nFreq - fNumOfCoups;\n"
+" int t;\n"
+" double tmp0 = 0, tmp1 = 0, tmp2 = 0;\n"
+" for( t = 1 ; t < fNumOfCoups ; t++ ){\n"
+" tmp0 = (t + nDiff) * ( fCoup ) ;\n"
+" tmp1 = pow( fYield, t + nDiff ) ;\n"
+" tmp2 = tmp0 * pow(tmp1, -1);\n"
+" fDur += tmp2;\n"
+" }\n"
+" fDur += (fNumOfCoups + nDiff) * (fCoup + 100.0) * pow(pow(fYield,"
+" fNumOfCoups + nDiff ),-1);\n"
+" double p = 0.0;\n"
+" for( t = 1 ; t < fNumOfCoups ; t++ ){\n"
+" tmp0 = pow( fYield, t + nDiff );\n"
+" p += fCoup * pow(tmp0, -1);}\n"
+" p += (fCoup + 100.0) * pow(pow(fYield, fNumOfCoups + nDiff), -1);\n"
+" fDur = fDur * pow(p, -1.0);\n"
+" fDur = fDur * pow(nFreq, -1.0);\n"
+" return fDur;\n"
+" }\n";
+
+std::string ScGetDDBDecl=
+"double ScGetDDB(double fCost, double fSalvage, double fLife, double fPeriod,"
+"double fFactor);\n";
+
+std::string ScGetDDB=
+"double ScGetDDB(double fCost, double fSalvage, double fLife, double fPeriod,"
+"double fFactor)\n"
+"{\n"
+" double fDdb, fRate, fOldValue, fNewValue;\n"
+" fRate = fFactor / fLife;\n"
+" if (fRate >= 1.0)\n"
+" {\n"
+" fRate = 1.0;\n"
+" if (fPeriod == 1.0)\n"
+" fOldValue = fCost;\n"
+" else\n"
+" fOldValue = 0.0;\n"
+" }\n"
+" else\n"
+" fOldValue = fCost * pow(1.0 - fRate, fPeriod - 1.0);\n"
+" fNewValue = fCost * pow(1.0 - fRate, fPeriod);\n"
+
+" if (fNewValue < fSalvage)\n"
+" fDdb = fOldValue - fSalvage;\n"
+" else\n"
+" fDdb = fOldValue - fNewValue;\n"
+" if (fDdb < 0.0)\n"
+" fDdb = 0.0;\n"
+" return fDdb;\n"
+"}\n";
+
+std::string DblMinDecl=
+"inline double DblMin( double a, double b );\n";
+
+std::string DblMin=
+"inline double DblMin( double a, double b )\n"
+"{\n"
+" return (a < b) ? a : b;\n"
+"}\n";
+
+std::string ScInterVDBDecl=
+"double ScInterVDB(double fCost, double fSalvage, double fLife, double fLife1,"
+"double fPeriod, double fFactor);\n";
+
+std::string ScInterVDB=
+"double ScInterVDB(double fCost, double fSalvage, double fLife, double fLife1,"
+"double fPeriod, double fFactor)\n"
+"{\n"
+" double fVdb=0;\n"
+" double fIntEnd = ceil(fPeriod);\n"
+" int nLoopEnd = fIntEnd;\n"
+
+" double fTerm, fSln;\n"
+" double fSalvageValue = fCost - fSalvage;\n"
+" int nNowSln = 0;\n"
+" double fDdb;\n"
+" int i;\n"
+" fSln=0;\n"
+" for ( i = 1; i <= nLoopEnd; i++)\n"
+" {\n"
+" if(!nNowSln)\n"
+" {\n"
+" fDdb = ScGetDDB(fCost, fSalvage, fLife, (double) i, fFactor);\n"
+" fSln = fSalvageValue/ (fLife1 - (double) (i-1));\n"
+" if (fSln > fDdb)\n"
+" {\n"
+" fTerm = fSln;\n"
+" nNowSln = 1;\n"
+" }\n"
+" else\n"
+" {\n"
+" fTerm = fDdb;\n"
+" fSalvageValue =fSalvageValue- fDdb;\n"
+" }\n"
+" }\n"
+" else\n"
+" {\n"
+" fTerm = fSln;\n"
+" }\n"
+
+" if ( i == nLoopEnd)\n"
+" fTerm *= ( fPeriod + 1.0 - fIntEnd );\n"
+
+" fVdb += fTerm;\n"
+" }\n"
+" return fVdb;\n"
+"}\n";
+
+std::string VDBImplementDecl=
+"double VDBImplement(double fCost, double fSalvage, double fLife, double fStart"
+", double fEnd, double fFactor, bool bNoSwitch);\n";
+
+std::string VDBImplement=
+"double VDBImplement(double fCost, double fSalvage, double fLife, double fStart"
+", double fEnd, double fFactor, bool bNoSwitch)\n"
+"{\n"
+" double result=0;\n"
+" double fIntStart = floor(fStart);\n"
+" double fIntEnd = ceil(fEnd);\n"
+" int nLoopStart = (int) fIntStart;\n"
+" int nLoopEnd = (int) fIntEnd;\n"
+" if (bNoSwitch)\n"
+" {\n"
+" for (int i = nLoopStart + 1; i <= nLoopEnd; i++)\n"
+" {\n"
+" double fTerm = ScGetDDB(fCost, fSalvage, fLife, (double) i, fFactor"
+");\n"
+" if ( i == nLoopStart+1 )\n"
+" fTerm *= ( DblMin( fEnd, fIntStart + 1.0 ) - fStart );\n"
+" else if ( i == nLoopEnd )\n"
+" fTerm *= ( fEnd + 1.0 - fIntEnd );\n"
+" result += fTerm;\n"
+" }\n"
+" }\n"
+" else\n"
+" {\n"
+" double fLife1=fLife;\n"
+" if(!isequal(fStart,floor(fStart)))\n"
+" {\n"
+" if(fFactor>1)\n"
+" {\n"
+" if(fStart>fLife/2 || isequal(fStart,fLife/2))\n"
+" {\n"
+" double fPart=fStart-fLife/2;\n"
+" fStart=fLife/2;\n"
+" fEnd-=fPart;\n"
+" fLife1+=1;\n"
+" }\n"
+" }\n"
+" }\n"
+" fCost-=ScInterVDB(fCost, fSalvage, fLife, fLife1, fStart, fFactor);\n"
+" result=ScInterVDB(fCost, fSalvage, fLife, fLife-fStart, fEnd-fStart,"
+"fFactor);\n"
+" }\n"
+" return result;\n"
+"}\n";
+
+std::string GetOddlpriceDecl=
+"double GetOddlprice( int nNullDate, int nSettle, int nMat, int nLastCoup,\n"
+" double fRate, double fYield, double fRedemp, int nFreq, int nBase );\n";
+
+std::string GetOddlprice=
+"double GetOddlprice( int nNullDate, int nSettle, int nMat, int nLastCoup,\n"
+" double fRate, double fYield, double fRedemp, int nFreq, int nBase )\n"
+"{\n"
+" double fFreq = nFreq ;\n"
+" double fDCi = GetYearFrac( nNullDate, nLastCoup,"
+"nMat, nBase ) * fFreq;\n"
+" double fDSCi = GetYearFrac( nNullDate, nSettle,"
+"nMat, nBase ) * fFreq;\n"
+" double fAi = GetYearFrac( nNullDate, nLastCoup,"
+"nSettle, nBase ) * fFreq;\n"
+" double p = fRedemp + fDCi * 100.0 * fRate / fFreq;\n"
+" p /= fDSCi * fYield / fFreq + 1.0;\n"
+" p -= fAi * 100.0 * fRate / fFreq;\n"
+" return p;\n"
+"}\n";
+
+std::string GetOddlyieldDecl=
+"double GetOddlyield( int nNullDate, int nSettle, int nMat, int nLastCoup,\n"
+" double fRate, double fPrice, double fRedemp, int nFreq, int nBase );\n";
+
+std::string GetOddlyield=
+"double GetOddlyield( int nNullDate, int nSettle, int nMat, int nLastCoup,\n"
+" double fRate, double fPrice, double fRedemp, int nFreq, int nBase ) \n"
+"{\n"
+" double fFreq = nFreq ;\n"
+" double fDCi= GetYearFrac( nNullDate, nLastCoup, nMat, nBase ) * fFreq;\n"
+" double fDSCi= GetYearFrac( nNullDate, nSettle, nMat, nBase ) * fFreq;\n"
+" double fAi= GetYearFrac( nNullDate, nLastCoup, nSettle, nBase )*fFreq;\n"
+" double y = fRedemp + fDCi * 100.0 * fRate / fFreq;\n"
+" y /= fPrice + fAi * 100.0 * fRate / fFreq;\n"
+" y -= 1.0;\n"
+" y *= fFreq / fDSCi;\n"
+" return y;\n"
+"}\n";
+
+std::string GetYearFrac_newDecl=
+"double GetYearFrac_new( int nNullDate, int nStartDate, int nEndDate,"
+"int nMode );\n";
+
+std::string GetYearFrac_new=
+"double GetYearFrac_new( int nNullDate, int nStartDate, int nEndDate,"
+"int nMode ) \n"
+"{\n"
+" if( nStartDate == nEndDate )\n"
+" return 0.0; \n"
+" if( nStartDate > nEndDate )\n"
+" {\n"
+" int n = nEndDate;\n"
+" nEndDate = nStartDate;\n"
+" nStartDate = n;\n"
+" }\n"
+" int nDate1 = nStartDate + nNullDate;\n"
+" int nDate2 = nEndDate + nNullDate;\n"
+" int nDay1, nDay2;\n"
+" int nMonth1, nMonth2;\n"
+" int nYear1, nYear2;\n"
+" DaysToDate_new( nDate1, &nDay1, &nMonth1, &nYear1 );\n"
+" DaysToDate_new( nDate2, &nDay2, &nMonth2, &nYear2 );\n"
+" int nDayDiff;\n"
+" switch( nMode )\n"
+" {\n"
+" case 0: \n"
+" if ( nDay1 == 31 )\n"
+" {\n"
+" nDay1--;\n"
+" }\n"
+" if ( nDay1 == 30 && nDay2 == 31 )\n"
+" {\n"
+" nDay2--;\n"
+" }\n"
+" else\n"
+" {\n"
+" if ( nMonth1 == 2 && nDay1 == "
+"( IsLeapYear( nYear1 ) ? 29 : 28 ) )\n"
+" {\n"
+" nDay1 = 30;\n"
+" if ( nMonth2 == 2 && nDay2 == "
+"( IsLeapYear( nYear2 ) ? 29 : 28 ) )\n"
+" {\n"
+" nDay2 = 30;\n"
+" }\n"
+" }\n"
+" }\n"
+" nDayDiff = ( nYear2 - nYear1 ) * 360 + "
+"( nMonth2 - nMonth1 ) * 30 + ( nDay2 - nDay1 );\n"
+" break;\n"
+" case 1: \n"
+" case 2: \n"
+" case 3: \n"
+" nDayDiff = nDate2 - nDate1;\n"
+" break;\n"
+" case 4: \n"
+" if ( nDay1 == 31 )\n"
+" {\n"
+" nDay1--;\n"
+" }\n"
+" if ( nDay2 == 31 )\n"
+" {\n"
+" nDay2--;\n"
+" }\n"
+" nDayDiff = ( nYear2 - nYear1 ) * 360 + "
+"( nMonth2 - nMonth1 ) * 30 + ( nDay2 - nDay1 );\n"
+" break;\n"
+" }\n"
+" double nDaysInYear;\n"
+" switch( nMode )\n"
+" {\n"
+" case 0: \n"
+" case 2: \n"
+" case 4: \n"
+" nDaysInYear = 360;\n"
+" break;\n"
+" case 1: \n"
+" {\n"
+" bool isYearDifferent = ( nYear1 != nYear2 );\n"
+" if ( isYearDifferent &&\n"
+" ( ( nYear2 != nYear1 + 1 ) ||\n"
+" ( nMonth1 < nMonth2 ) ||\n"
+" ( nMonth1 == nMonth2 && nDay1 < nDay2 ) ) )\n"
+" {\n"
+" int nDayCount = 0;\n"
+" for ( int i = nYear1; i <= nYear2; i++ )\n"
+" nDayCount += ( IsLeapYear( i ) ? 366 : 365 );\n"
+" nDaysInYear = ( double ) nDayCount / "
+"( double ) ( nYear2 - nYear1 + 1 );\n"
+" }\n"
+" else\n"
+" {\n"
+" if ( isYearDifferent && IsLeapYear( nYear1 ) )\n"
+" {\n"
+" nDaysInYear = 366;\n"
+" }\n"
+" else\n"
+" {\n"
+" if ( ( IsLeapYear( nYear1 ) && nMonth1 <= 2 "
+"&& nDay1 <= 29 ) ||\n"
+" ( IsLeapYear( nYear2 ) && ( nMonth2 > 3 || "
+"( nMonth2 == 2 && nDay1 == 29 ) ) ) )\n"
+" {\n"
+" nDaysInYear = 366;\n"
+" }\n"
+" else\n"
+" {\n"
+" nDaysInYear = 365;\n"
+" for ( int i = nYear1; i <= nYear2; i++ )\n"
+" {\n"
+" if ( IsLeapYear( i ) )\n"
+" {\n"
+" nDaysInYear = 366;\n"
+" break;\n"
+" }\n"
+" }\n"
+" }\n"
+" }\n"
+" }\n"
+" }\n"
+" break;\n"
+" case 3: \n"
+" nDaysInYear = 365;\n"
+" break;\n"
+" }\n"
+" return (double)( nDayDiff ) / (nDaysInYear);\n"
+"}\n";
+
+std::string DaysToDate_newDecl =
+"void DaysToDate_new( int nDays, int *rDay, int* rMonth, int* rYear );\n";
+
+std::string DaysToDate_new =
+"void DaysToDate_new( int nDays, int *rDay, int* rMonth, int* rYear )\n"
+"{\n"
+" int nTempDays;\n"
+" int i = 0;\n"
+" bool bCalc;\n"
+" do\n"
+" {\n"
+" nTempDays = nDays;\n"
+" *rYear = (int)((nTempDays / 365) - i);\n"
+" nTempDays -= ((int) *rYear -1) * 365;\n"
+" nTempDays -= ((*rYear -1) / 4) - ((*rYear -1) / 100) + ((*rYear -1)"
+" / 400);\n"
+" bCalc = false;\n"
+" if ( nTempDays < 1 )\n"
+" {\n"
+" i++;\n"
+" bCalc = true;\n"
+" }\n"
+" else\n"
+" {\n"
+" if ( nTempDays > 365 )\n"
+" {\n"
+" if ( (nTempDays != 366) || !IsLeapYear( *rYear ) )\n"
+" {\n"
+" i--;\n"
+" bCalc = true;\n"
+" }\n"
+" }\n"
+" }\n"
+" }\n"
+" while ( bCalc );\n"
+" if(nTempDays != 0){\n"
+" for (*rMonth = 1; (int)nTempDays > DaysInMonth( *rMonth, *rYear );"
+" *rMonth += 1)\n"
+" {\n"
+" nTempDays -= DaysInMonth( *rMonth, *rYear ); \n"
+" }\n"
+" *rDay = (int)nTempDays;\n"
+" }\n"
+"}\n";
+
+std::string DaysToDate_LocalBarrierDecl =
+"void DaysToDate( int nDays, int *rDay, int* rMonth, int* rYear );\n";
+
+std::string DaysToDate_LocalBarrier =
+"void DaysToDate( int nDays, int *rDay, int* rMonth, int* rYear )\n"
+"{\n"
+" int nTempDays;\n"
+" int i = 0;\n"
+" bool bCalc;\n"
+" do\n"
+" {\n"
+" nTempDays = nDays;\n"
+" *rYear = (int)((nTempDays / 365) - i);\n"
+" nTempDays -= ((int) *rYear -1) * 365;\n"
+" nTempDays -= ((*rYear -1) / 4) - ((*rYear -1) / 100) + ((*rYear -1)"
+" / 400);\n"
+" bCalc = false;\n"
+" if ( nTempDays < 1 )\n"
+" {\n"
+" i++;\n"
+" bCalc = true;\n"
+" }\n"
+" else\n"
+" {\n"
+" if ( nTempDays > 365 )\n"
+" {\n"
+" if ( (nTempDays != 366) || !IsLeapYear( *rYear ) )\n"
+" {\n"
+" i--;\n"
+" bCalc = true;\n"
+" }\n"
+" }\n"
+" }\n"
+" }\n"
+" while ( bCalc );\n"
+" barrier(CLK_LOCAL_MEM_FENCE);\n"
+" if(nTempDays != 0){\n"
+" for (*rMonth = 1; (int)nTempDays > DaysInMonth( *rMonth, *rYear );"
+" *rMonth += 1)\n"
+" {\n"
+" nTempDays -= DaysInMonth( *rMonth, *rYear ); \n"
+" }\n"
+" *rDay = (int)nTempDays;\n"
+" }\n"
+"}\n";
+
+std::string GetYearDiff_newDecl=
+"double GetYearDiff_new( int nNullDate, int nStartDate, int nEndDate,"
+"int nMode);\n";
+
+std::string GetYearDiff_new=
+"double GetYearDiff_new( int nNullDate, int nStartDate, int nEndDate,"
+"int nMode )\n"
+"{\n"
+" int nDays1stYear;\n"
+" int nTotalDays = GetDiffDate_new( nNullDate, nStartDate, nEndDate,"
+"nMode, &"
+"nDays1stYear );\n"
+" return (double)(nTotalDays)* pow((double)nDays1stYear,-1);\n"
+"}\n";
+
+std::string GetDiffDate_newDecl=
+"int GetDiffDate_new( int nNullDate, int nStartDate, int nEndDate, int nMode,"
+" int* pOptDaysIn1stYear );\n";
+
+std::string GetDiffDate_new=
+"int GetDiffDate_new( int nNullDate, int nStartDate, int nEndDate, int nMode,"
+" int* pOptDaysIn1stYear )\n"
+"{\n"
+" bool bNeg = nStartDate > nEndDate;\n"
+" if( bNeg )\n"
+" {\n"
+" int n = nEndDate;\n"
+" nEndDate = nStartDate;\n"
+" nStartDate = n;\n"
+" }\n"
+" int nRet;\n"
+" switch( nMode )\n"
+" {\n"
+" case 0: \n"
+" case 4: \n"
+" {\n"
+" int nD1, nM1, nY1, nD2, nM2, nY2;\n"
+" nStartDate += nNullDate;\n"
+" nEndDate += nNullDate;\n"
+" DaysToDate_new( nStartDate, &nD1, &nM1, &nY1 );\n"
+" DaysToDate_new( nEndDate, &nD2, &nM2, &nY2 );\n"
+" bool bLeap = IsLeapYear( nY1 );\n"
+" int nDays, nMonths;\n"
+" nMonths = nM2 - nM1;\n"
+" nDays = nD2 - nD1;\n"
+" nMonths += ( nY2 - nY1 ) * 12;\n"
+" nRet = nMonths * 30 + nDays;\n"
+" if( nMode == 0 && nM1 == 2 && nM2 != 2 && nY1 == nY2 )\n"
+" nRet -= bLeap? 1 : 2;\n"
+" if( pOptDaysIn1stYear )\n"
+" *pOptDaysIn1stYear = 360;\n"
+" }\n"
+" break;\n"
+" case 1: \n"
+" if( pOptDaysIn1stYear )\n"
+" {\n"
+" int nD, nM, nY;\n"
+" DaysToDate_new( nStartDate + nNullDate, &nD, &nM, &nY );\n"
+" *pOptDaysIn1stYear = IsLeapYear( nY )? 366 : 365;\n"
+" }\n"
+" nRet = nEndDate - nStartDate;\n"
+" break;\n"
+" case 2: \n"
+" nRet = nEndDate - nStartDate;\n"
+" if( pOptDaysIn1stYear )\n"
+" *pOptDaysIn1stYear = 360;\n"
+" break;\n"
+" case 3: \n"
+" nRet = nEndDate - nStartDate;\n"
+" if( pOptDaysIn1stYear )\n"
+" *pOptDaysIn1stYear = 365;\n"
+" break;\n"
+" }\n"
+" return bNeg? -nRet : nRet;\n"
+"}\n";
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/opinlinefun_math.hxx b/sc/source/core/opencl/opinlinefun_math.hxx
new file mode 100644
index 000000000..ab9dc02ef
--- /dev/null
+++ b/sc/source/core/opencl/opinlinefun_math.hxx
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SC_SOURCE_CORE_OPENCL_OPINLINEFUN_MATH_HXX
+#define INCLUDED_SC_SOURCE_CORE_OPENCL_OPINLINEFUN_MATH_HXX
+
+std::string Math_Intg_Str=
+"\ndouble Intg(double n)\n\
+{\n\
+ if(trunc(n)==n )\n\
+ return n;\n\
+ else if(n<0)\n\
+ return trunc(n)-1;\n\
+ else\n\
+ return trunc(n)+1;\n\
+}\n";
+
+std::string bikDecl = "double bik(double n,double k);\n";
+std::string bik =
+"double bik(double n,double k)\n"
+"{\n"
+" double nVal1 = n;\n"
+" double nVal2 = k;\n"
+" n = n - 1;\n"
+" k = k - 1;\n"
+" while (k > 0)\n"
+" {\n"
+" nVal1 = nVal1 * n;\n"
+" nVal2 = nVal2 * k;\n"
+" k = k - 1;\n"
+" n = n - 1;\n"
+" }\n"
+" return (nVal1 / nVal2);\n"
+"}\n";
+
+std::string local_cothDecl = "double local_coth(double n);\n";
+std::string local_coth =
+"double local_coth(double n)\n"
+"{\n"
+" double a = exp(n);\n"
+" double b = exp(-n);\n"
+" double nVal = (a + b) / (a - b);\n"
+" return nVal;\n"
+"}\n";
+
+std::string local_coshDecl = "double local_cosh(double n);\n";
+std::string local_cosh =
+"double local_cosh(double n)\n"
+"{\n"
+" double nVal = (exp(n) + exp(-n)) / 2;\n"
+" return nVal;\n"
+"}\n";
+std::string atan2Decl = "double arctan2(double y, double x);\n";
+std::string atan2Content =
+"double arctan2(double y, double x)\n"
+"{\n"
+" if(y==0.0)\n"
+" return 0.0;\n"
+" double a,num,den,tmpPi;\n"
+" int flag;\n"
+" tmpPi = 0;\n"
+" if (fabs(x) >= fabs(y))\n"
+" {\n"
+" num = y;\n"
+" den = x;\n"
+" flag = 1;\n"
+" if (x < 0.0)\n"
+" tmpPi = M_PI;\n"
+" }\n"
+" if(fabs(x) < fabs(y))\n"
+" {\n"
+" num = x;\n"
+" den = y;\n"
+" flag = -1;\n"
+" tmpPi = M_PI_2;\n"
+" }\n"
+" a = atan(num/den);\n"
+" a = flag==1?a:-a;\n"
+" a = a + (y >= 0.0 ? tmpPi : -tmpPi);\n"
+" return a;\n"
+"}\n";
+
+#endif // INCLUDED_SC_SOURCE_CORE_OPENCL_OPINLINEFUN_MATH_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/opencl/opinlinefun_statistical.cxx b/sc/source/core/opencl/opinlinefun_statistical.cxx
new file mode 100644
index 000000000..dfed055a9
--- /dev/null
+++ b/sc/source/core/opencl/opinlinefun_statistical.cxx
@@ -0,0 +1,1366 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef SC_OPENCL_OPINLINFUN_statistical
+#define SC_OPENCL_OPINLINFUN_statistical
+std::string MinDecl = "#define Min 2.22507e-308\n";
+std::string F_PIDecl="#define F_PI 3.1415926\n";
+std::string fBigInvDecl ="#define fBigInv 2.22045e-016\n";
+std::string fMachEpsDecl ="#define fMachEps 2.22045e-016\n";
+std::string fLogDblMaxDecl ="#define fLogDblMax log(1.79769e+308)\n";
+std::string fHalfMachEpsDecl ="#define fHalfMachEps 0.5*2.22045e-016\n";
+std::string fMaxGammaArgumentDecl=
+"#define fMaxGammaArgument 171.624376956302\n";
+std::string GetValueDecl=
+"double GetValue( double x,double fp,double fDF );\n";
+std::string GetValue=
+"double GetValue( double x,double fp,double fDF )\n"
+"{\n"
+" return fp - 2 * GetTDist(x, fDF);\n"
+"}\n";
+std::string GetGammaSeriesDecl=
+"double GetGammaSeries( double fA, double fX );\n";
+std::string GetGammaSeries =
+"double GetGammaSeries( double fA, double fX )\n"
+"{\n"
+" double fDenomfactor = fA;\n"
+" double fSummand = 1.0/fA;\n"
+" double fSum = fSummand;\n"
+" int nCount=1;\n"
+" do\n"
+" {\n"
+" fDenomfactor = fDenomfactor + 1.0;\n"
+" fSummand = fSummand * fX/fDenomfactor;\n"
+" fSum = fSum + fSummand;\n"
+" nCount = nCount+1;\n"
+" } while ( fSummand/fSum > fHalfMachEps && nCount<=10000);\n"
+" if (nCount>10000)\n"
+" {\n"
+" }\n"
+" return fSum;\n"
+"}\n";
+std::string GetGammaContFractionDecl = "double GetGammaContFraction( double "
+"fA, double fX );\n";
+std::string GetGammaContFraction =
+"double GetGammaContFraction( double fA, double fX )\n"
+"{\n"
+" double fBig = 1.0/fBigInv;\n"
+" double fCount = 0.0;\n"
+" double fNum = 0.0;\n"
+" double fY = 1.0 - fA;\n"
+" double fDenom = fX + 2.0-fA;\n"
+" double fPk = 0.0;\n"
+" double fPkm1 = fX + 1.0;\n"
+" double fPkm2 = 1.0;\n"
+" double fQk = 1.0;\n"
+" double fQkm1 = fDenom * fX;\n"
+" double fQkm2 = fX;\n"
+" double fApprox = fPkm1/fQkm1;\n"
+" bool bFinished = false;\n"
+" double fR = 0.0;\n"
+" do\n"
+" {\n"
+" fCount = fCount +1.0;\n"
+" fY = fY+ 1.0;\n"
+" fNum = fY * fCount;\n"
+" fDenom = fDenom +2.0;\n"
+" fPk = fPkm1 * fDenom - fPkm2 * fNum;\n"
+" fQk = fQkm1 * fDenom - fQkm2 * fNum;\n"
+" if (fQk != 0.0)\n"
+" {\n"
+" fR = fPk/fQk;\n"
+" bFinished = (fabs( (fApprox - fR)/fR ) <= fHalfMachEps);\n"
+" fApprox = fR;\n"
+" }\n"
+" fPkm2 = fPkm1;\n"
+" fPkm1 = fPk;\n"
+" fQkm2 = fQkm1;\n"
+" fQkm1 = fQk;\n"
+" if (fabs(fPk) > fBig)\n"
+" {\n"
+" fPkm2 = fPkm2 * fBigInv;\n"
+" fPkm1 = fPkm1 * fBigInv;\n"
+" fQkm2 = fQkm2 * fBigInv;\n"
+" fQkm1 = fQkm1 * fBigInv;\n"
+" }\n"
+" } while (!bFinished && fCount<10000);\n"
+" if (!bFinished)\n"
+" {\n"
+" }\n"
+" return fApprox;\n"
+"}\n";
+std::string GetLowRegIGammaDecl = "double GetLowRegIGamma( double "
+"fA, double fX );\n";
+std::string GetLowRegIGamma =
+"double GetLowRegIGamma( double fA, double fX )\n"
+"{\n"
+" double fLnFactor = fA * log(fX) - fX - lgamma(fA);\n"
+" double fFactor = exp(fLnFactor);\n"
+" if (fX>fA+1.0) \n"
+" return 1.0 - fFactor * GetGammaContFraction(fA,fX);\n"
+" else\n"
+" return fFactor * GetGammaSeries(fA,fX);\n"
+"}\n";
+std::string GetGammaDistDecl = "double GetGammaDist( double fX, double "
+"fAlpha, double fLambda );\n";
+std::string GetGammaDist =
+"double GetGammaDist( double fX, double fAlpha, double fLambda )\n"
+"{\n"
+" if (fX <= 0.0)\n"
+" return 0.0;\n"
+" else\n"
+" return GetLowRegIGamma( fAlpha, fX / fLambda);\n"
+"}\n";
+std::string GetGammaDistPDFDecl = "double GetGammaDistPDF( double fX"
+", double fAlpha, double fLambda );\n";
+std::string GetGammaDistPDF =
+"double GetGammaDistPDF( double fX, double fAlpha, double fLambda )\n"
+"{\n"
+" if (fX < 0.0)\n"
+" return 0.0;\n"
+" else if (fX == 0)\n"
+" {\n"
+" if (fAlpha < 1.0)\n"
+" {\n"
+" return HUGE_VAL;\n"
+" }\n"
+" else if (fAlpha == 1)\n"
+" {\n"
+" return (1.0 / fLambda);\n"
+" }\n"
+" else\n"
+" {\n"
+" return 0.0;\n"
+" }\n"
+" }\n"
+" else\n"
+" {\n"
+" double fXr = fX / fLambda;\n"
+" if (fXr > 1.0)\n"
+" {\n"
+" if (log(fXr) * (fAlpha-1.0) < fLogDblMax &&"
+"fAlpha < fMaxGammaArgument)\n"
+" {\n"
+" return pow( fXr, fAlpha-1.0) * exp(-fXr) / "
+"fLambda / tgamma(fAlpha);\n"
+" }\n"
+" else\n"
+" {\n"
+" return exp( (fAlpha-1.0) * log(fXr) - fXr - "
+"log(fLambda) - lgamma(fAlpha));\n"
+" }\n"
+" }\n"
+" else\n"
+" {\n"
+" if (fAlpha<fMaxGammaArgument)\n"
+" {\n"
+" return pow( fXr, fAlpha-1.0) * exp(-fXr) / "
+"fLambda / tgamma(fAlpha);\n"
+" }\n"
+" else\n"
+" {\n"
+" return pow( fXr, fAlpha-1.0) * exp(-fXr) / "
+"fLambda / exp( lgamma(fAlpha));\n"
+" }\n"
+" }\n"
+" }\n"
+"}\n";
+std::string GetBetaDistDecl =
+"double GetBetaDist(double fXin, double fAlpha, double fBeta);\n";
+std::string GetBetaDist =
+"double GetBetaDist(double fXin, double fAlpha, double fBeta)\n"
+"{\n"
+" if (fXin <= 0.0)\n"
+" return 0.0;\n"
+" if (fXin >= 1.0)\n"
+" return 1.0;\n"
+" if (fBeta == 1.0)\n"
+" return pow(fXin, fAlpha);\n"
+" if (fAlpha == 1.0)\n"
+" return -expm1(fBeta * log1p(-fXin));\n"
+" double fResult;\n"
+" double fY = (0.5-fXin)+0.5;\n"
+" double flnY = log1p(-fXin);\n"
+" double fX = fXin;\n"
+" double flnX = log(fXin);\n"
+" double fA = fAlpha;\n"
+" double fB = fBeta;\n"
+" bool bReflect = fXin > fAlpha*pow((fAlpha+fBeta),-1.0);\n"
+" if (bReflect)\n"
+" {\n"
+" fA = fBeta;\n"
+" fB = fAlpha;\n"
+" fX = fY;\n"
+" fY = fXin;\n"
+" flnX = flnY;\n"
+" flnY = log(fXin);\n"
+" }\n"
+" fResult = lcl_GetBetaHelperContFrac(fX,fA,fB)*pow(fA,-1.0);\n"
+" double fP = fA*pow((fA+fB),-1.0);\n"
+" double fQ = fB*pow((fA+fB),-1.0);\n"
+" if (fA > 1.0 && fB > 1.0 && fP < 0.97 && fQ < 0.97)\n"
+" fResult *= GetBetaDistPDF(fX,fA,fB)*fX*fY;\n"
+" else\n"
+" fResult *= pow(exp(1.0),(fA*flnX + fB*flnY - GetLogBeta(fA,fB)));\n"
+" if (bReflect)\n"
+" fResult = 0.5 - fResult + 0.5;\n"
+" if (fResult > 1.0)\n"
+" fResult = 1.0;\n"
+" if (fResult < 0.0)\n"
+" fResult = 0.0;\n"
+" return fResult;\n"
+"}\n";
+
+std::string GetFDistDecl =
+ "double GetFDist(double x, double fF1, double fF2);\n";
+std::string GetFDist =
+"double GetFDist(double x, double fF1, double fF2)\n"
+"{\n"
+" double arg = fF2*pow((fF2+fF1*x),-1.0);\n"
+" double alpha = fF2*pow(2.0,-1.0);\n"
+" double beta = fF1*pow(2.0,-1.0);\n"
+" return (GetBetaDist(arg, alpha, beta));\n"
+"}\n";
+std::string GetGammaInvValueDecl = "double"
+" GetGammaInvValue(double fAlpha,double fBeta,double fX1 );\n";
+std::string GetGammaInvValue =
+"double GetGammaInvValue(double fAlpha,double fBeta,double fX1 )\n"
+"{\n"
+" if (fX1 <= 0.0)\n"
+" return 0.0;\n"
+" else\n"
+" {\n"
+" double fX=fX1*pow(fBeta,-1.0);\n"
+" double fLnFactor = fAlpha * log(fX) - fX - lgamma(fAlpha);\n"
+" double fFactor = exp(fLnFactor);\n"
+" if (fX>fAlpha+1.0)\n"
+" return 1.0 - fFactor * GetGammaContFraction(fAlpha,fX);\n"
+" else\n"
+" return fFactor * GetGammaSeries(fAlpha,fX);\n"
+" }\n"
+"}\n";
+std::string GetFInvValueDecl = "double GetFInvValue(double fF1,double fF2"
+",double fX1 );";
+std::string GetFInvValue =
+"double GetFInvValue(double fF1,double fF2,double fX1 )\n"
+"{\n"
+" double arg = fF2*pow((fF2+fF1*fX1),-1.0);\n"
+" double alpha = fF2*pow(2.0,-1.0);\n"
+" double beta = fF1*pow(2.0,-1.0);\n"
+" double fXin,fAlpha,fBeta;\n"
+" fXin=arg;fAlpha=alpha;fBeta=beta;\n"
+" if (fXin <= 0.0)\n"
+" return 0.0;\n"
+" if (fXin >= 1.0)\n"
+" return 1.0;\n"
+" if (fBeta == 1.0)\n"
+" return pow(fXin, fAlpha);\n"
+" if (fAlpha == 1.0)\n"
+" return -expm1(fBeta * log1p(-fXin));\n"
+" double fResult;\n"
+" double fY = (0.5-fXin)+0.5;\n"
+" double flnY = log1p(-fXin);\n"
+" double fX = fXin;\n"
+" double flnX = log(fXin);\n"
+" double fA = fAlpha;\n"
+" double fB = fBeta;\n"
+" bool bReflect = fXin > fAlpha*pow((fAlpha+fBeta),-1.0);\n"
+" if (bReflect)\n"
+" {\n"
+" fA = fBeta;\n"
+" fB = fAlpha;\n"
+" fX = fY;\n"
+" fY = fXin;\n"
+" flnX = flnY;\n"
+" flnY = log(fXin);\n"
+" }\n"
+" fResult = lcl_GetBetaHelperContFrac(fX,fA,fB);\n"
+" fResult = fResult*pow(fA,-1.0);\n"
+" double fP = fA*pow((fA+fB),-1.0);\n"
+" double fQ = fB*pow((fA+fB),-1.0);\n"
+" double fTemp;\n"
+" if (fA > 1.0 && fB > 1.0 && fP < 0.97 && fQ < 0.97)\n"
+" fTemp = GetBetaDistPDF(fX,fA,fB)*fX*fY;\n"
+" else\n"
+" fTemp = exp(fA*flnX + fB*flnY - GetLogBeta(fA,fB));\n"
+" fResult *= fTemp;\n"
+" if (bReflect)\n"
+" fResult = 0.5 - fResult + 0.5;\n"
+" if (fResult > 1.0)\n"
+" fResult = 1.0;\n"
+" if (fResult < 0.0)\n"
+" fResult = 0.0;\n"
+" return fResult;\n"
+"}\n";
+std::string GetBinomDistPMFDecl =
+ "double GetBinomDistPMF(double x, double n, double p);";
+std::string GetBinomDistPMF =
+"double GetBinomDistPMF(double x, double n, double p)\n"
+"{\n"
+" double q = (0.5 - p) + 0.5;\n"
+" double fFactor = pow(q, n);\n"
+" if (fFactor <= Min)\n"
+" {\n"
+" fFactor = pow(p, n);\n"
+" if (fFactor <= Min)\n"
+" return GetBetaDistPDF(p, x + 1.0, n - x + 1.0)*pow((n + 1.0),-1.0);\n"
+" else\n"
+" {\n"
+" uint max = (uint)(n - x);\n"
+" for (uint i = 0; i < max && fFactor > 0.0; ++i)\n"
+" fFactor *= (n - i)*pow((i + 1),-1.0)*q*pow(p,-1.0);\n"
+" return fFactor;\n"
+" }\n"
+" }\n"
+" else\n"
+" {\n"
+" uint max = (uint)x;\n"
+" for (uint i = 0; i < max && fFactor > 0.0; ++i)\n"
+" fFactor *= (n - i)*pow((i + 1),-1.0)*p*pow(q,-1.0);\n"
+" return fFactor;\n"
+" }\n"
+"}\n";
+
+std::string lcl_GetBinomDistRangeDecl =
+ "double lcl_GetBinomDistRange(double n, \n"
+"double xs, double xe, double fFactor, double p, double q);";
+std::string lcl_GetBinomDistRange=
+"double lcl_GetBinomDistRange(double n, double xs, double xe,\n"
+" double fFactor, double p, double q)\n"
+"{\n"
+" uint i;\n"
+" double fSum;\n"
+" uint nXs = (uint)xs;\n"
+" for (i = 1; i <= nXs && fFactor > 0.0; ++i)\n"
+" fFactor *= (n - i + 1)*pow(i,-1.0)*p*pow(q,-1.0);\n"
+" fSum = fFactor;\n"
+" uint nXe =(uint)xe;\n"
+" for (i = nXs + 1; i <= nXe && fFactor > 0.0; ++i)\n"
+" {\n"
+" fFactor *= (n - i + 1)*pow(i,-1.0)*p*pow(q,-1.0);\n"
+" fSum += fFactor;\n"
+" }\n"
+" return (fSum > 1.0) ? 1.0 : fSum;\n"
+"}\n";
+
+std::string GetLogGammaDecl = "double GetLogGamma(double fZ);\n";
+std::string GetLogGamma =
+"double GetLogGamma(double fZ)\n"
+"{\n"
+" if (fZ >= fMaxGammaArgument)\n"
+" return lcl_GetLogGammaHelper(fZ);\n"
+" if (fZ >= 1.0)\n"
+" return log(lcl_GetGammaHelper(fZ));\n"
+" if (fZ >= 0.5)\n"
+" return log( lcl_GetGammaHelper(fZ+1) *pow(fZ,-1.0));\n"
+" return lcl_GetLogGammaHelper(fZ+2) - log(fZ+1) - log(fZ);\n"
+"}\n";
+
+std::string GetChiDistDecl = "double GetChiDist(double fX, double fDF);\n";
+std::string GetChiDist =
+"double GetChiDist(double fX, double fDF)\n"
+"{\n"
+" if (fX <= 0.0)\n"
+" return 1.0;\n"
+" else\n"
+" return GetUpRegIGamma( fDF*pow(2.0,-1.0), fX*pow(2.0,-1.0));\n"
+"}\n";
+
+std::string GetChiSqDistCDFDecl =
+"double GetChiSqDistCDF(double fX, double fDF);\n";
+std::string GetChiSqDistCDF =
+"double GetChiSqDistCDF(double fX, double fDF)\n"
+"{\n"
+" if (fX <= 0.0)\n"
+" return 0.0;"
+" else\n"
+" return GetLowRegIGamma( fDF*pow(2.0,-1.0), fX*pow(2.0,-1.0));\n"
+"}\n";
+
+std::string GetChiSqDistPDFDecl=
+"double GetChiSqDistPDF(double fX, double fDF);\n";
+std::string GetChiSqDistPDF =
+"double GetChiSqDistPDF(double fX, double fDF)\n"
+"{\n"
+" double fValue;\n"
+" if (fX <= 0.0)\n"
+" return 0.0;\n"
+" if (fDF*fX > 1391000.0)\n"
+" {\n"
+" fValue = exp((0.5*fDF - 1) * log(fX*0.5) - 0.5 * fX - log(2.0)"
+" - lgamma(0.5*fDF));\n"
+" }\n"
+" else\n"
+" {\n"
+" double fCount;\n"
+" if (fmod(fDF,2.0)<0.5)\n"
+" {\n"
+" fValue = 0.5;\n"
+" fCount = 2.0;\n"
+" }\n"
+" else\n"
+" {\n"
+" fValue = pow(sqrt(fX*2*F_PI),-1.0);\n"
+" fCount = 1.0;\n"
+" }\n"
+" while ( fCount < fDF)\n"
+" {\n"
+" fValue *= (fX *pow(fCount,-1.0));\n"
+" fCount += 2.0;\n"
+" }\n"
+" if (fX>=1425.0)\n"
+" fValue = exp(log(fValue)-fX*pow(2,-1.0));\n"
+" else\n"
+" fValue *= exp(-fX*pow(2,-1.0));\n"
+" }\n"
+" return fValue;\n"
+"}\n";
+
+std::string lcl_IterateInverseBetaInvDecl =
+"static double lcl_IterateInverseBetaInv(double fp, double fAlpha, \n"
+" double fBeta, double fAx, double fBx, bool *rConvError );\n";
+std::string lcl_IterateInverseBetaInv =
+"static double lcl_IterateInverseBetaInv(double fp, double fAlpha, \n"
+" double fBeta, double fAx, double fBx, bool *rConvError )\n"
+"{\n"
+" *rConvError = false;\n"
+" double fYEps = 1.0E-307;\n"
+" double fXEps = fMachEps;\n"
+" if(!(fAx < fBx))\n"
+" {\n"
+" //print error\n"
+" }\n"
+" double fAy = fp - GetBetaDist(fAx, fAlpha, fBeta);\n"
+" double fBy = fp - GetBetaDist(fBx, fAlpha, fBeta);\n"
+" double fTemp;\n"
+" unsigned short nCount;\n"
+" for (nCount = 0; nCount < 1000 && !lcl_HasChangeOfSign(fAy,fBy);"
+" nCount++)\n"
+" {\n"
+" if (fabs(fAy) <= fabs(fBy))\n"
+" {\n"
+" fTemp = fAx;\n"
+" fAx += 2.0 * (fAx - fBx);\n"
+" if (fAx < 0.0)\n"
+" fAx = 0.0;\n"
+" fBx = fTemp;\n"
+" fBy = fAy;\n"
+" fAy = fp - GetBetaDist(fAx, fAlpha, fBeta);\n"
+" }\n"
+" else\n"
+" {\n"
+" fTemp = fBx;\n"
+" fBx += 2.0 * (fBx - fAx);\n"
+" fAx = fTemp;\n"
+" fAy = fBy;\n"
+" fBy = fp - GetBetaDist(fBx, fAlpha, fBeta);\n"
+" }\n"
+" }\n"
+" if (fAy == 0.0)\n"
+" return fAx;\n"
+" if (fBy == 0.0)\n"
+" return fBx;\n"
+" if (!lcl_HasChangeOfSign( fAy, fBy))\n"
+" {\n"
+" *rConvError = true;\n"
+" return 0.0;\n"
+" }\n"
+" double fPx = fAx;\n"
+" double fPy = fAy;\n"
+" double fQx = fBx;\n"
+" double fQy = fBy;\n"
+" double fRx = fAx;\n"
+" double fRy = fAy;\n"
+" double fSx = 0.5 * (fAx + fBx);\n"
+" bool bHasToInterpolate = true;\n"
+" nCount = 0;\n"
+" while ( nCount < 500 && fabs(fRy) > fYEps &&\n"
+" (fBx-fAx) > fmax( fabs(fAx), fabs(fBx)) * fXEps )\n"
+" {\n"
+" if (bHasToInterpolate)\n"
+" {\n"
+" if (fPy!=fQy && fQy!=fRy && fRy!=fPy)\n"
+" {\n"
+" fSx = fPx*fRy*fQy*pow(fRy-fPy,-1.0)*pow(fQy-fPy,-1.0)\n"
+" + fRx*fQy*fPy*pow(fQy-fRy,-1.0)*pow(fPy-fRy,-1.0)\n"
+" + fQx*fPy*fRy*pow(fPy-fQy,-1.0)*pow(fRy-fQy,-1.0);\n"
+" bHasToInterpolate = (fAx < fSx) && (fSx < fBx);\n"
+" }\n"
+" else\n"
+" bHasToInterpolate = false;\n"
+" }\n"
+" if(!bHasToInterpolate)\n"
+" {\n"
+" fSx = 0.5 * (fAx + fBx);\n"
+" fPx = fAx; fPy = fAy;\n"
+" fQx = fBx; fQy = fBy;\n"
+" bHasToInterpolate = true;\n"
+" }\n"
+" fPx = fQx; fQx = fRx; fRx = fSx;\n"
+" fPy = fQy; fQy = fRy; fRy = fp - GetBetaDist(fSx, fAlpha, fBeta);\n"
+" if (lcl_HasChangeOfSign( fAy, fRy))\n"
+" {\n"
+" fBx = fRx; fBy = fRy;\n"
+" }\n"
+" else\n"
+" {\n"
+" fAx = fRx; fAy = fRy;\n"
+" }\n"
+" bHasToInterpolate = bHasToInterpolate && (fabs(fRy) *"
+" 2.0 <= fabs(fQy));\n"
+" ++nCount;\n"
+" }\n"
+" return fRx;\n"
+"}\n";
+
+std::string lcl_IterateInverseChiInvDecl =
+"static double lcl_IterateInverseChiInv"
+"(double fp, double fdf, double fAx, double fBx, bool *rConvError);\n";
+std::string lcl_IterateInverseChiInv =
+"static double lcl_IterateInverseChiInv"
+"(double fp, double fdf, double fAx, double fBx, bool *rConvError)\n"
+"{\n"
+" *rConvError = false;\n"
+" double fYEps = 1.0E-307;\n"
+" double fXEps = fMachEps;\n"
+" if(!(fAx < fBx))\n"
+" {\n"
+" //print error\n"
+" }"
+" double fAy = fp - GetChiDist(fAx, fdf);\n"
+" double fBy = fp - GetChiDist(fBx, fdf);\n"
+" double fTemp;\n"
+" unsigned short nCount;\n"
+" for (nCount = 0; nCount < 1000 && "
+"!lcl_HasChangeOfSign(fAy,fBy); nCount++)\n"
+" {\n"
+" if (fabs(fAy) <= fabs(fBy))\n"
+" {\n"
+" fTemp = fAx;\n"
+" fAx += 2.0 * (fAx - fBx);\n"
+" if (fAx < 0.0)\n"
+" fAx = 0.0;\n"
+" fBx = fTemp;\n"
+" fBy = fAy;\n"
+" fAy = fp - GetChiDist(fAx, fdf);\n"
+" }\n"
+" else\n"
+" {\n"
+" fTemp = fBx;\n"
+" fBx += 2.0 * (fBx - fAx);\n"
+" fAx = fTemp;\n"
+" fAy = fBy;\n"
+" fBy = fp - GetChiDist(fBx, fdf);\n"
+" }\n"
+" }\n"
+" if (fAy == 0.0)\n"
+" return fAx;\n"
+" if (fBy == 0.0)\n"
+" return fBx;\n"
+" if (!lcl_HasChangeOfSign( fAy, fBy))\n"
+" {\n"
+" *rConvError = true;\n"
+" return 0.0;\n"
+" }\n"
+" double fPx = fAx;\n"
+" double fPy = fAy;\n"
+" double fQx = fBx;\n"
+" double fQy = fBy;\n"
+" double fRx = fAx;\n"
+" double fRy = fAy;\n"
+" double fSx = 0.5 * (fAx + fBx);\n"
+" bool bHasToInterpolate = true;\n"
+" nCount = 0;\n"
+" while ( nCount < 500 && fabs(fRy) > fYEps &&\n"
+" (fBx-fAx) > fmax( fabs(fAx), fabs(fBx)) * fXEps )\n"
+" {\n"
+" if (bHasToInterpolate)\n"
+" {\n"
+" if (fPy!=fQy && fQy!=fRy && fRy!=fPy)\n"
+" {\n"
+" fSx = fPx * fRy * fQy*pow(fRy-fPy,-1.0)*pow(fQy-fPy,-1.0)\n"
+" + fRx * fQy * fPy*pow(fQy-fRy,-1.0)*pow(fPy-fRy,-1.0)\n"
+" + fQx * fPy * fRy*pow(fPy-fQy,-1.0)*pow(fRy-fQy,-1.0);\n"
+" bHasToInterpolate = (fAx < fSx) && (fSx < fBx);\n"
+" }\n"
+" else\n"
+" bHasToInterpolate = false;\n"
+" }\n"
+" if(!bHasToInterpolate)\n"
+" {\n"
+" fSx = 0.5 * (fAx + fBx);\n"
+" fPx = fAx; fPy = fAy;\n"
+" fQx = fBx; fQy = fBy;\n"
+" bHasToInterpolate = true;\n"
+" }\n"
+" fPx = fQx; fQx = fRx; fRx = fSx;\n"
+" fPy = fQy; fQy = fRy; fRy = fp - GetChiDist(fSx, fdf);\n"
+" if (lcl_HasChangeOfSign( fAy, fRy))\n"
+" {\n"
+" fBx = fRx; fBy = fRy;\n"
+" }\n"
+" else\n"
+" {\n"
+" fAx = fRx; fAy = fRy;\n"
+" }\n"
+" bHasToInterpolate = bHasToInterpolate && (fabs(fRy)"
+" * 2.0 <= fabs(fQy));\n"
+" ++nCount;\n"
+" }\n"
+" return fRx;\n"
+"}\n";
+
+std::string lcl_IterateInverseChiSQInvDecl =
+"static double lcl_IterateInverseChiSQInv( double fp, double fdf, \n"
+" double fAx, double fBx, bool *rConvError );\n";
+std::string lcl_IterateInverseChiSQInv =
+"static double lcl_IterateInverseChiSQInv( double fp, double fdf, \n"
+" double fAx, double fBx, bool *rConvError )\n"
+"{\n"
+" *rConvError = false;\n"
+" double fYEps = 1.0E-307;\n"
+" double fXEps = fMachEps;\n"
+
+" if(!(fAx < fBx))\n"
+" {\n"
+" //print error\n"
+" }\n"
+" double fAy = fp - GetChiSqDistCDF(fAx, fdf);\n"
+" double fBy = fp - GetChiSqDistCDF(fBx, fdf);\n"
+" double fTemp;\n"
+" unsigned short nCount;\n"
+" for (nCount = 0; nCount < 1000 && !lcl_HasChangeOfSign(fAy,fBy);"
+" nCount++)\n"
+" {\n"
+" if (fabs(fAy) <= fabs(fBy))\n"
+" {\n"
+" fTemp = fAx;\n"
+" fAx += 2.0 * (fAx - fBx);\n"
+" if (fAx < 0.0)\n"
+" fAx = 0.0;\n"
+" fBx = fTemp;\n"
+" fBy = fAy;\n"
+" fAy = fp - GetChiSqDistCDF(fAx, fdf);\n"
+" }\n"
+" else\n"
+" {\n"
+" fTemp = fBx;\n"
+" fBx += 2.0 * (fBx - fAx);\n"
+" fAx = fTemp;\n"
+" fAy = fBy;\n"
+" fBy = fp - GetChiSqDistCDF(fBx, fdf);\n"
+" }\n"
+" }\n"
+" if (fAy == 0.0)\n"
+" return fAx;\n"
+" if (fBy == 0.0)\n"
+" return fBx;\n"
+" if (!lcl_HasChangeOfSign( fAy, fBy))\n"
+" {\n"
+" *rConvError = true;\n"
+" return 0.0;\n"
+" }\n"
+" double fPx = fAx;\n"
+" double fPy = fAy;\n"
+" double fQx = fBx;\n"
+" double fQy = fBy;\n"
+" double fRx = fAx;\n"
+" double fRy = fAy;\n"
+" double fSx = 0.5 * (fAx + fBx);\n"
+" bool bHasToInterpolate = true;\n"
+" nCount = 0;\n"
+" while ( nCount < 500 && fabs(fRy) > fYEps &&\n"
+" (fBx-fAx) > fmax( fabs(fAx), fabs(fBx)) * fXEps )\n"
+" {\n"
+" if (bHasToInterpolate)\n"
+" {\n"
+" if (fPy!=fQy && fQy!=fRy && fRy!=fPy)\n"
+" {\n"
+" fSx = fPx * fRy * fQy / (fRy-fPy) / (fQy-fPy)\n"
+" + fRx * fQy * fPy / (fQy-fRy) / (fPy-fRy)\n"
+" + fQx * fPy * fRy / (fPy-fQy) / (fRy-fQy);\n"
+" bHasToInterpolate = (fAx < fSx) && (fSx < fBx);\n"
+" }\n"
+" else\n"
+" bHasToInterpolate = false;\n"
+" }\n"
+" if(!bHasToInterpolate)\n"
+" {\n"
+" fSx = 0.5 * (fAx + fBx);\n"
+" fPx = fAx; fPy = fAy;\n"
+" fQx = fBx; fQy = fBy;\n"
+" bHasToInterpolate = true;\n"
+" }\n"
+" fPx = fQx; fQx = fRx; fRx = fSx;\n"
+" fPy = fQy; fQy = fRy; fRy = fp - GetChiSqDistCDF(fSx, fdf);\n"
+" if (lcl_HasChangeOfSign( fAy, fRy))\n"
+" {\n"
+" fBx = fRx; fBy = fRy;\n"
+" }\n"
+" else\n"
+" {\n"
+" fAx = fRx; fAy = fRy;\n"
+" }\n"
+" bHasToInterpolate = bHasToInterpolate && (fabs(fRy) * 2.0"
+" <= fabs(fQy));\n"
+" ++nCount;\n"
+" }\n"
+" return fRx;\n"
+"}\n";
+
+std::string gaussinvDecl = "double gaussinv(double x);\n";
+std::string gaussinv =
+"double gaussinv(double x)\n"
+"{\n"
+" double q,t,z;\n"
+" q=x-0.5;\n"
+" if(fabs(q)<=.425)\n"
+" {\n"
+" t=0.180625-q*q;\n"
+" z=\n"
+" q*\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" t*2509.0809287301226727+33430.575583588128105\n"
+" )\n"
+" *t+67265.770927008700853\n"
+" )\n"
+" *t+45921.953931549871457\n"
+" )\n"
+" *t+13731.693765509461125\n"
+" )\n"
+" *t+1971.5909503065514427\n"
+" )\n"
+" *t+133.14166789178437745\n"
+" )\n"
+" *t+3.387132872796366608\n"
+" )\n"
+" *pow\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" t*5226.495278852854561+28729.085735721942674\n"
+" )\n"
+" *t+39307.89580009271061\n"
+" )\n"
+" *t+21213.794301586595867\n"
+" )\n"
+" *t+5394.1960214247511077\n"
+" )\n"
+" *t+687.1870074920579083\n"
+" )\n"
+" *t+42.313330701600911252\n"
+" )\n"
+" *t+1.0\n"
+" , -1.0);\n"
+" }\n"
+" else\n"
+" {\n"
+" if(q>0) t=1-x;\n"
+" else t=x;\n"
+" t=sqrt(-log(t));\n"
+" if(t<=5.0)\n"
+" {\n"
+" t+=-1.6;\n"
+" z=\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" t*7.7454501427834140764e-4+0.0227238449892691845833\n"
+" )\n"
+" *t+0.24178072517745061177\n"
+" )\n"
+" *t+1.27045825245236838258\n"
+" )\n"
+" *t+3.64784832476320460504\n"
+" )\n"
+" *t+5.7694972214606914055\n"
+" )\n"
+" *t+4.6303378461565452959\n"
+" )\n"
+" *t+1.42343711074968357734\n"
+" )\n"
+" *pow\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" t*1.05075007164441684324e-9+5.475938084995344946e-4\n"
+" )\n"
+" *t+0.0151986665636164571966\n"
+" )\n"
+" *t+0.14810397642748007459\n"
+" )\n"
+" *t+0.68976733498510000455\n"
+" )\n"
+" *t+1.6763848301838038494\n"
+" )\n"
+" *t+2.05319162663775882187\n"
+" )\n"
+" *t+1.0\n"
+" , -1.0);\n"
+" }\n"
+" else\n"
+" {\n"
+" t+=-5.0;\n"
+" z=\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" t*2.01033439929228813265e-7+2.71155556874348757815e-5\n"
+" )\n"
+" *t+0.0012426609473880784386\n"
+" )\n"
+" *t+0.026532189526576123093\n"
+" )\n"
+" *t+0.29656057182850489123\n"
+" )\n"
+" *t+1.7848265399172913358\n"
+" )\n"
+" *t+5.4637849111641143699\n"
+" )\n"
+" *t+6.6579046435011037772\n"
+" )\n"
+" *pow\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" (\n"
+" t*2.04426310338993978564e-15+1.4215117583164458887e-7\n"
+" )\n"
+" *t+1.8463183175100546818e-5\n"
+" )\n"
+" *t+7.868691311456132591e-4\n"
+" )\n"
+" *t+0.0148753612908506148525\n"
+" )\n"
+" *t+0.13692988092273580531\n"
+" )\n"
+" *t+0.59983220655588793769\n"
+" )\n"
+" *t+1.0\n"
+" , -1.0);\n"
+" }\n"
+" if(q<0.0) z=-z;\n"
+" }\n"
+" return z;\n"
+"}\n";
+
+std::string lcl_GetLogGammaHelperDecl=
+"static double lcl_GetLogGammaHelper(double fZ);\n";
+std::string lcl_GetLogGammaHelper =
+"static double lcl_GetLogGammaHelper(double fZ)\n"
+"{\n"
+" double fg = 6.024680040776729583740234375;\n"
+" double fZgHelp = fZ + fg - 0.5;\n"
+" return log( lcl_getLanczosSum(fZ)) + (fZ-0.5) * log(fZgHelp) - fZgHelp;\n"
+"}\n";
+std::string lcl_GetGammaHelperDecl=
+"static double lcl_GetGammaHelper(double fZ);\n";
+std::string lcl_GetGammaHelper =
+"static double lcl_GetGammaHelper(double fZ)\n"
+"{\n"
+" double fGamma = lcl_getLanczosSum(fZ);\n"
+" double fg = 6.024680040776729583740234375;\n"
+" double fZgHelp = fZ + fg - 0.5;\n"
+" double fHalfpower = pow( fZgHelp, fZ*pow(2,-1.0) - 0.25);\n"
+" fGamma *= fHalfpower;\n"
+" fGamma = fGamma*pow(exp(fZgHelp),-1.0);\n"
+" fGamma *= fHalfpower;\n"
+" fGamma = 120.4;\n"
+" if (fZ <= 20.0 && fZ == (int)fZ)\n"
+" {\n"
+" fGamma = (int)(fGamma+0.5);\n"
+" }\n"
+" return fGamma;\n"
+"}\n";
+std::string lcl_getLanczosSumDecl=
+"static double lcl_getLanczosSum(double fZ);\n";
+std::string lcl_getLanczosSum =
+"static double lcl_getLanczosSum(double fZ) \n"
+"{ \n"
+" double fNum[13] ={ \n"
+" 23531376880.41075968857200767445163675473, \n"
+" 42919803642.64909876895789904700198885093, \n"
+" 35711959237.35566804944018545154716670596, \n"
+" 17921034426.03720969991975575445893111267, \n"
+" 6039542586.35202800506429164430729792107, \n"
+" 1439720407.311721673663223072794912393972, \n"
+" 248874557.8620541565114603864132294232163, \n"
+" 31426415.58540019438061423162831820536287, \n"
+" 2876370.628935372441225409051620849613599, \n"
+" 186056.2653952234950402949897160456992822, \n"
+" 8071.672002365816210638002902272250613822, \n"
+" 210.8242777515793458725097339207133627117, \n"
+" 2.506628274631000270164908177133837338626 \n"
+" }; \n"
+" double fDenom[13] = { \n"
+" 0,\n"
+" 39916800,\n"
+" 120543840,\n"
+" 150917976,\n"
+" 105258076,\n"
+" 45995730,\n"
+" 13339535,\n"
+" 2637558,\n"
+" 357423,\n"
+" 32670,\n"
+" 1925,\n"
+" 66,\n"
+" 1\n"
+" };\n"
+" double fSumNum;\n"
+" double fSumDenom;\n"
+" int nI;\n"
+" if (fZ<=1.0)\n"
+" {\n"
+" fSumNum = fNum[12];\n"
+" fSumDenom = fDenom[12];\n"
+" nI = 11;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" nI = 10;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" nI = 9;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" nI = 8;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" nI = 7;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" nI = 6;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" nI = 5;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" nI = 4;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" nI = 3;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" nI = 2;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" nI = 1;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" nI = 0;\n"
+" fSumNum = fSumNum*fZ+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZ+fDenom[nI];\n"
+" }\n"
+" if (fZ>1.0)\n"
+" {\n"
+" double fZInv = pow(fZ,-1.0);\n"
+" fSumNum = fNum[0];\n"
+" fSumDenom = fDenom[0];\n"
+" nI = 1;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" nI = 2;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" nI = 3;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" nI = 4;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" nI = 5;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" nI = 6;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" nI = 7;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" nI = 8;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" nI = 9;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" nI = 10;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" nI = 11;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" nI = 12;\n"
+" fSumNum = fSumNum*fZInv+fNum[nI];\n"
+" fSumDenom = fSumDenom*fZInv+fDenom[nI];\n"
+" }\n"
+" return fSumNum*pow(fSumDenom,-1.0);\n"
+"}\n";
+
+std::string GetUpRegIGammaDecl=
+" double GetUpRegIGamma( double fA, double fX ) ;\n";
+std::string GetUpRegIGamma =
+"double GetUpRegIGamma( double fA, double fX )\n"
+"{\n"
+" double fLnFactor= fA*log(fX)-fX-lgamma(fA);\n"
+" double fFactor = exp(fLnFactor); \n"
+" if (fX>fA+1.0) \n"
+" return fFactor * GetGammaContFraction(fA,fX);\n"
+" else \n"
+" return 1.0 -fFactor * GetGammaSeries(fA,fX);\n"
+"}\n";
+
+std::string lcl_HasChangeOfSignDecl=
+"static inline bool lcl_HasChangeOfSign( double u, double w );\n";
+std::string lcl_HasChangeOfSign =
+"static inline bool lcl_HasChangeOfSign( double u, double w )\n"
+"{\n"
+" return (u < 0.0 && w > 0.0) || (u > 0.0 && w < 0.0);\n"
+"}\n";
+
+std::string GetTDistDecl=" double GetTDist(double T, double fDF);\n";
+std::string GetTDist =
+"double GetTDist(double T, double fDF)\n"
+"{\n"
+" return 0.5 * GetBetaDist(fDF*pow(fDF+T*T,-1.0),fDF*pow(2.0,-1.0), 0.5);\n"
+"}\n";
+
+std::string GetBetaDecl=" double GetBeta(double fAlpha, double fBeta);\n";
+std::string GetBeta =
+"double GetBeta(double fAlpha, double fBeta)\n"
+"{\n"
+" double fA;\n"
+" double fB;\n"
+" fAlpha>fBeta?(fA = fAlpha,fB = fBeta):(fA = fBeta,fB = fAlpha);\n"
+" double fAB = fA + fB;\n"
+
+" if (fAB < fMaxGammaArgument)\n"
+" return tgamma(fA)*pow(tgamma(fAB),-1.0)*tgamma(fB);\n"
+" double fgm = 5.524680040776729583740234375;\n"
+" double fLanczos = lcl_getLanczosSum(fA)*lcl_getLanczosSum(fB)\n"
+" *pow(lcl_getLanczosSum(fAB),-1.0);\n"
+" fLanczos *= sqrt(((fAB + fgm)*pow(fA + fgm,-1.0))*pow(fB + fgm,-1.0));\n"
+" return fLanczos * pow(exp(1.0),(-fA*log1p(fB*pow(fA + fgm,-1.0)))"
+" - fB*log1p(fA*pow(fB + fgm,-1.0)) - fgm);\n"
+"}\n";
+
+std::string GetLogBetaDecl=
+" double GetLogBeta(double fAlpha, double fBeta);\n";
+std::string GetLogBeta =
+"double GetLogBeta(double fAlpha, double fBeta)\n"
+"{\n"
+" double fA;\n"
+" double fB;\n"
+" fAlpha>fBeta?(fA = fAlpha,fB = fBeta):(fA = fBeta,fB = fAlpha);\n"
+" double fgm = 5.524680040776729583740234375;\n"
+
+" double fLanczos = lcl_getLanczosSum(fA)*lcl_getLanczosSum(fB)*\n"
+" pow(lcl_getLanczosSum(fA + fB),-1.0);\n"
+" double fResult= -fA *log1p(fB*pow(fA + fgm,-1.0))"
+"-fB *log1p(fA*pow(fB + fgm,-1.0))-fgm;\n"
+" fResult += log(fLanczos)+0.5*(log(fA + fB + fgm) - log(fA + fgm)\n"
+" - log(fB + fgm));\n"
+" return fResult;\n"
+"}\n";
+
+std::string GetBetaDistPDFDecl=
+"double GetBetaDistPDF(double fX, double fA, double fB);\n";
+std::string GetBetaDistPDF =
+"double GetBetaDistPDF(double fX, double fA, double fB)\n"
+"{\n"
+" if (fA == 1.0) \n"
+" {\n"
+" if (fB == 1.0)\n"
+" return 1.0;\n"
+" if (fB == 2.0)\n"
+" return -2.0*fX + 2.0;\n"
+" if (fX == 1.0 && fB < 1.0)\n"
+" {\n"
+" return HUGE_VAL;\n"
+" }\n"
+" if (fX <= 0.01)\n"
+" return fB + fB * expm1((fB-1.0) * log1p(-fX));\n"
+" else \n"
+" return fB * pow(0.5-fX+0.5,fB-1.0);\n"
+" }\n"
+" if (fB == 1.0) \n"
+" {\n"
+" if (fA == 2.0)\n"
+" return fA * fX;\n"
+" if (fX == 0.0 && fA < 1.0)\n"
+" {\n"
+" return HUGE_VAL;\n"
+" }\n"
+" return fA * pow(fX,fA-1);\n"
+" }\n"
+" if (fX <= 0.0)\n"
+" {\n"
+" if (fA < 1.0 && fX == 0.0)\n"
+" {\n"
+" return HUGE_VAL;\n"
+" }\n"
+" else\n"
+" return 0.0;\n"
+" }\n"
+" if (fX >= 1.0)\n"
+" {\n"
+" if (fB < 1.0 && fX == 1.0)\n"
+" {\n"
+" return HUGE_VAL;\n"
+" }\n"
+" else \n"
+" return 0.0;\n"
+" }\n"
+" double fLogDblMax = log( 1.79769e+308 );\n"
+" double fLogDblMin = log( 2.22507e-308 );\n"
+" double fLogY = (fX < 0.1) ? log1p(-fX) : log(0.5-fX+0.5);\n"
+" double fLogX = log(fX);\n"
+" double fAm1LogX = (fA-1.0) * fLogX;\n"
+" double fBm1LogY = (fB-1.0) * fLogY;\n"
+" double fLogBeta = GetLogBeta(fA,fB);\n"
+" if ( fAm1LogX < fLogDblMax && fAm1LogX > fLogDblMin\n"
+" && fBm1LogY < fLogDblMax && fBm1LogY > fLogDblMin\n"
+" && fLogBeta < fLogDblMax && fLogBeta > fLogDblMin\n"
+" && fAm1LogX + fBm1LogY < fLogDblMax && fAm1LogX + fBm1LogY > \n"
+" fLogDblMin)\n"
+" return pow(fX,fA-1.0)*pow(0.5-fX+0.5,fB-1.0)"
+"*pow(GetBeta(fA,fB),-1.0);\n"
+" else \n"
+" return exp( fAm1LogX + fBm1LogY - fLogBeta);\n"
+"}\n";
+
+std::string lcl_GetBetaHelperContFracDecl=
+"double lcl_GetBetaHelperContFrac(double fX, double fA, double fB);\n";
+std::string lcl_GetBetaHelperContFrac =
+"double lcl_GetBetaHelperContFrac(double fX, double fA, double fB)\n"
+"{ \n"
+
+" double a1, b1, a2, b2, fnorm, apl2m, d2m, d2m1, cfnew, cf;\n"
+" a1 = 1.0; b1 = 1.0;\n"
+" b2 = 1.0 - (fA+fB)*pow(fA+1.0,-1.0)*fX;\n"
+" b2==0.0?(a2 = 0.0,fnorm = 1.0,cf = 1.0):\n"
+" (a2 = 1.0,fnorm = pow(b2,-1.0),cf = a2*fnorm);\n"
+" cfnew = 1.0;\n"
+" double rm = 1.0;\n"
+" double fMaxIter = 50000.0;\n"
+" bool bfinished = false;\n"
+" do\n"
+" {\n"
+" apl2m = fA + 2.0*rm;\n"
+" d2m = (rm*(fB-rm))*fX*pow(apl2m*(apl2m-1.0),-1.0);\n"
+" d2m1 = -((fA+rm)*(fA+rm+fB))*fX*pow(apl2m*(apl2m+1.0),-1.0);\n"
+" a1 = (a2+d2m*a1)*fnorm;\n"
+" b1 = (b2+d2m*b1)*fnorm;\n"
+" a2 = a1 + d2m1*a2*fnorm;\n"
+" b2 = b1 + d2m1*b2*fnorm;\n"
+" if (b2 != 0.0) \n"
+" {\n"
+" fnorm = pow(b2,-1.0);\n"
+" cfnew = a2*fnorm;\n"
+" bfinished = (fabs(cf-cfnew) < fabs(cf)*fMachEps);\n"
+" }\n"
+" cf = cfnew;\n"
+" rm += 1.0;\n"
+" }\n"
+" while (rm < fMaxIter && !bfinished);\n"
+" return cf;\n"
+"}\n";
+
+std::string lcl_IterateInverseDecl=
+"double lcl_IterateInverse("
+"double fAx, double fBx, bool* rConvError,double fp,double fDF );\n";
+std::string lcl_IterateInverse =
+"double lcl_IterateInverse( "
+"double fAx, double fBx, bool* rConvError,double fp,double fDF )\n"
+"{\n"
+" *rConvError = false;\n"
+" double fYEps = 1.0E-307;\n"
+" double fXEps =DBL_EPSILON;\n"
+" if(fAx>fBx)\n"
+" return DBL_MAX;\n"
+" double fAy = GetValue(fAx,fp,fDF);\n"
+" double fBy = GetValue(fBx,fp,fDF);\n"
+" double fTemp;\n"
+" unsigned short nCount;\n"
+" double inter;\n"
+" bool sign;\n"
+" for (nCount =0;nCount<1000&&!lcl_HasChangeOfSign(fAy,fBy);nCount++)\n"
+" {\n"
+" inter = 2.0 * (fAx - fBx);\n"
+" if (fabs(fAy) <= fabs(fBy)) \n"
+" {\n"
+" sign = true;\n"
+" fTemp = fAx;\n"
+" fAx += inter;\n"
+" if (fAx < 0.0)\n"
+" fAx = 0.0;\n"
+" fBx = fTemp;\n"
+" fBy = fAy;\n"
+" fTemp = fAx;\n"
+" }\n"
+" else\n"
+" {\n"
+" sign = false;\n"
+" fTemp = fBx;\n"
+" fBx -= inter;\n"
+" fAx = fTemp;\n"
+" fAy = fBy;\n"
+" fTemp = fBx;\n"
+" }\n"
+" fTemp = GetValue(fTemp,fp,fDF);\n"
+" sign?(fAy = fTemp):(fBy = fTemp);\n"
+" }\n"
+" if (fAy == 0.0)\n"
+" return fAx;\n"
+" if (fBy == 0.0)\n"
+" return fBx;\n"
+" if (!lcl_HasChangeOfSign( fAy, fBy))\n"
+" {\n"
+" *rConvError = true;\n"
+" return 0.0;\n"
+" }\n"
+" double fPx = fAx;\n"
+" double fPy = fAy;\n"
+" double fQx = fBx;\n"
+" double fQy = fBy;\n"
+" double fRx = fAx;\n"
+" double fRy = fAy;\n"
+" double fSx = 0.5 * (fAx + fBx); \n"
+" bool bHasToInterpolate = true;\n"
+" nCount = 0;\n"
+" while ( nCount < 500 && fabs(fRy) > fYEps &&\n"
+" (fBx-fAx) > max( fabs(fAx), fabs(fBx)) * fXEps )\n"
+" {\n"
+" if (bHasToInterpolate)\n"
+" {\n"
+" if (fPy!=fQy && fQy!=fRy && fRy!=fPy)\n"
+" {\n"
+" fSx = fPx * fRy * fQy * pow(fRy-fPy,-1.0)*pow(fQy-fPy,-1.0)\n"
+" + fRx * fQy * fPy * pow(fQy-fRy,-1.0)*pow(fPy-fRy,-1.0)\n"
+" + fQx * fPy * fRy * pow(fPy-fQy,-1.0)*pow(fRy-fQy,-1.0);\n"
+" bHasToInterpolate = (fAx < fSx) && (fSx < fBx);\n"
+" }\n"
+" else\n"
+" bHasToInterpolate = false;\n"
+" }\n"
+" if(!bHasToInterpolate)\n"
+" {\n"
+" fSx = 0.5 * (fAx + fBx);\n"
+" \n"
+" fPx = fAx; fPy = fAy;\n"
+" fQx = fBx; fQy = fBy;\n"
+" bHasToInterpolate = true;\n"
+" }\n"
+" fPx = fQx; fQx = fRx; fRx = fSx;\n"
+" fPy = fQy; fQy = fRy; fRy = GetValue(fSx,fp,fDF);\n"
+" lcl_HasChangeOfSign( fAy, fRy)?(fBx = fRx,fBy = fRy):\n"
+" (fAx = fRx,fAy = fRy);\n"
+" bHasToInterpolate =\n"
+" bHasToInterpolate && (fabs(fRy) * 2.0 <= fabs(fQy));\n"
+" ++nCount;\n"
+" }\n"
+" return fRx;\n"
+"}\n";
+std::string phiDecl=
+"double phi(double x);\n";
+std::string phi =
+"double phi(double x)\n"
+"{\n"
+" return 0.39894228040143268 * exp(-(x * x) / 2.0);\n"
+"}\n";
+std::string taylorDecl =
+"double taylor(double* pPolynom, uint nMax, double x);\n";
+std::string taylor =
+"double taylor(double* pPolynom, uint nMax, double x)\n"
+"{\n"
+" double nVal = pPolynom[nMax];\n"
+" for (short i = nMax-1; i >= 0; i--)\n"
+" {\n"
+" nVal = pPolynom[i] + (nVal * x);\n"
+" }\n"
+" return nVal;\n"
+"}";
+std::string gaussDecl = "double gauss(double x);\n";
+std::string gauss =
+"double gauss(double x)\n"
+"{\n"
+" double xAbs = fabs(x);\n"
+" uint xShort = (uint)(floor(xAbs));\n"
+" double nVal = 0.0;\n"
+" if (xShort == 0)\n"
+" {\n"
+" double t0[] =\n"
+" { 0.39894228040143268, -0.06649038006690545, 0.00997355701003582,\n"
+" -0.00118732821548045, 0.00011543468761616, -0.00000944465625950,\n"
+" 0.00000066596935163, -0.00000004122667415, 0.00000000227352982,\n"
+" 0.00000000011301172, 0.00000000000511243, -0.00000000000021218 };\n"
+" nVal = taylor(t0, 11, (xAbs * xAbs)) * xAbs;\n"
+" }\n"
+" else if ((xShort >= 1) && (xShort <= 2))\n"
+" {\n"
+" double t2[] =\n"
+" { 0.47724986805182079, 0.05399096651318805, -0.05399096651318805,\n"
+" 0.02699548325659403, -0.00449924720943234, -0.00224962360471617,\n"
+" 0.00134977416282970, -0.00011783742691370, -0.00011515930357476,\n"
+" 0.00003704737285544, 0.00000282690796889, -0.00000354513195524,\n"
+" 0.00000037669563126, 0.00000019202407921, -0.00000005226908590,\n"
+" -0.00000000491799345, 0.00000000366377919, -0.00000000015981997,\n"
+" -0.00000000017381238, 0.00000000002624031, 0.00000000000560919,\n"
+" -0.00000000000172127, -0.00000000000008634, 0.00000000000007894 };\n"
+" nVal = taylor(t2, 23, (xAbs - 2.0));\n"
+" }\n"
+" else if ((xShort >= 3) && (xShort <= 4))\n"
+" {\n"
+" double t4[] =\n"
+" { 0.49996832875816688, 0.00013383022576489, -0.00026766045152977,\n"
+" 0.00033457556441221, -0.00028996548915725, 0.00018178605666397,\n"
+" -0.00008252863922168, 0.00002551802519049, -0.00000391665839292,\n"
+" -0.00000074018205222, 0.00000064422023359, -0.00000017370155340,\n"
+" 0.00000000909595465, 0.00000000944943118, -0.00000000329957075,\n"
+" 0.00000000029492075, 0.00000000011874477, -0.00000000004420396,\n"
+" 0.00000000000361422, 0.00000000000143638, -0.00000000000045848 };\n"
+" nVal = taylor(t4, 20, (xAbs - 4.0));\n"
+" }\n"
+" else\n"
+" {\n"
+" double asympt[] = { -1.0, 1.0, -3.0, 15.0, -105.0 };\n"
+" nVal = 0.5 + phi(xAbs) * taylor(asympt, 4, 1.0/(xAbs * xAbs))/xAbs;\n"
+" }\n"
+" if (x < 0.0)\n"
+" return -nVal;\n"
+" else\n"
+" return nVal;\n"
+"}\n";
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */