diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /sc/source/core/opencl | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sc/source/core/opencl')
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 Binary files differnew file mode 100644 index 000000000..7e2bae4cb --- /dev/null +++ b/sc/source/core/opencl/cl-test.ods 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: */ |