LibreOffice Module sc (master)  1
op_addin.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include "op_addin.hxx"
11 
12 #include <formula/vectortoken.hxx>
13 #include <sstream>
14 
15 using namespace formula;
16 
17 namespace sc::opencl {
18 
19 void OpBesselj::GenSlidingWindowFunction(std::stringstream &ss,
20  const std::string &sSymName, SubArguments &vSubArguments)
21 {
22  CHECK_PARAMETER_COUNT( 2, 2 );
23  ss << "\ndouble " << sSymName;
24  ss << "_" << BinFuncName() << "(";
25  for (size_t i = 0; i < vSubArguments.size(); i++)
26  {
27  if (i)
28  ss << ",";
29  vSubArguments[i]->GenSlidingWindowDecl(ss);
30  }
31  ss << ") {\n";
32  ss << " int gid0 = get_global_id(0);\n";
33  ss << " double x = 0.0;\n";
34  ss << " double N = 0.0;\n";
35  FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
36  assert(tmpCur0);
37  if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
38  {
39  if(tmpCur0->GetType() == formula::svSingleVectorRef)
40  {
41  const formula::SingleVectorRefToken*tmpCurSVR0 =
42  static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
43  ss << " if (gid0 < " << tmpCurSVR0->GetArrayLength() << ")\n";
44  ss << " {\n";
45  ss << " x = ";
46  ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
47  ss << " if (isnan(x))\n";
48  ss << " x = 0.0;\n";
49  ss << " }\n";
50  }
51  else if(tmpCur0->GetType() == formula::svDouble)
52  {
53  ss << " x = " << tmpCur0->GetDouble() << ";\n";
54  }
55  else
56  {
57  throw Unhandled(__FILE__, __LINE__);
58  }
59  }
60  else
61  {
62  ss << " x = ";
63  ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
64  }
65 
66  FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
67  assert(tmpCur1);
68  if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
69  {
70  if(tmpCur1->GetType() == formula::svSingleVectorRef)
71  {
72  const formula::SingleVectorRefToken*tmpCurSVR1 =
73  static_cast<const formula::SingleVectorRefToken *>(tmpCur1);
74  ss << " if (gid0 < " << tmpCurSVR1->GetArrayLength() << ")\n";
75  ss << " {\n";
76  ss << " N = ";
77  ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
78  ss << " if (isnan(N))\n";
79  ss << " N = 0.0;\n";
80  ss << " }\n";
81  }
82  else if(tmpCur1->GetType() == formula::svDouble)
83  {
84  ss << " N = " << tmpCur1->GetDouble() << ";\n";
85  }
86  else
87  {
88  throw Unhandled(__FILE__, __LINE__);
89  }
90  }
91  else
92  {
93  ss << " N = ";
94  ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
95  }
96  ss << " double f_PI = 3.1415926535897932385;\n";
97  ss << " double f_2_DIV_PI = 2.0 / f_PI;\n";
98  ss << " double f_PI_DIV_2 = f_PI / 2.0;\n";
99  ss << " double f_PI_DIV_4 = f_PI / 4.0;\n";
100  ss << " if( N < 0.0 )\n";
101  ss << " return CreateDoubleError(IllegalArgument);\n";
102  ss << " if (x == 0.0)\n";
103  ss << " return (N == 0.0) ? 1.0 : 0.0;\n";
104  ss << " double fSign = ((int)N % 2 == 1 && x < 0.0) ? -1.0 : 1.0;\n";
105  ss << " double fX = fabs(x);\n";
106  ss << " double fMaxIteration = 9000000.0;\n";
107  ss << " double fEstimateIteration = fX * 1.5 + N;\n";
108  ss << " bool bAsymptoticPossible = pow(fX,0.4) > N;\n";
109  ss << " if (fEstimateIteration > fMaxIteration)\n";
110  ss << " {\n";
111  ss << " if (bAsymptoticPossible)\n";
112  ss << " return fSign * sqrt(f_2_DIV_PI/fX)";
113  ss << "* cos(fX-N*f_PI_DIV_2-f_PI_DIV_4);\n";
114  ss << " else\n";
115  ss << " return CreateDoubleError(NoConvergence);\n";
116  ss << " }\n";
117  ss << " double epsilon = 1.0e-15;\n";
118  ss << " bool bHasfound = false;\n";
119  ss << " double k= 0.0;\n";
120  ss << " double u ;\n";
121  ss << " double m_bar;\n";
122  ss << " double g_bar;\n";
123  ss << " double g_bar_delta_u;\n";
124  ss << " double g = 0.0;\n";
125  ss << " double delta_u = 0.0;\n";
126  ss << " double f_bar = -1.0;\n";
127  ss << " if (N==0)\n";
128  ss << " {\n";
129  ss << " u = 1.0;\n";
130  ss << " g_bar_delta_u = 0.0;\n";
131  ss << " g_bar = - 2.0/fX; \n";
132  ss << " delta_u = g_bar_delta_u / g_bar;\n";
133  ss << " u = u + delta_u ;\n";
134  ss << " g = -1.0 / g_bar; \n";
135  ss << " f_bar = f_bar * g;\n";
136  ss << " k = 2.0;\n";
137  ss << " }\n";
138  ss << " if (N!=0)\n";
139  ss << " {\n";
140  ss << " u=0.0;\n";
141  ss << " for (k =1.0; k<= N-1; k = k + 1.0)\n";
142  ss << " {\n";
143  ss << " m_bar=2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
144  ss << " g_bar_delta_u = - g * delta_u - m_bar * u;\n";
145  ss << " g_bar = m_bar - 2.0*k/fX + g;\n";
146  ss << " delta_u = g_bar_delta_u / g_bar;\n";
147  ss << " u = u + delta_u;\n";
148  ss << " g = -1.0/g_bar;\n";
149  ss << " f_bar=f_bar * g;\n";
150  ss << " }\n";
151  ss << " m_bar=2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
152  ss << " g_bar_delta_u = f_bar - g * delta_u - m_bar * u;\n";
153  ss << " g_bar = m_bar - 2.0*k/fX + g;\n";
154  ss << " delta_u = g_bar_delta_u / g_bar;\n";
155  ss << " u = u + delta_u;\n";
156  ss << " g = -1.0/g_bar;\n";
157  ss << " f_bar = f_bar * g;\n";
158  ss << " k = k + 1.0;\n";
159  ss << " }\n";
160  ss << " do\n";
161  ss << " {\n";
162  ss << " m_bar = 2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
163  ss << " g_bar_delta_u = - g * delta_u - m_bar * u;\n";
164  ss << " g_bar = m_bar - 2.0*k/fX + g;\n";
165  ss << " delta_u = g_bar_delta_u / g_bar;\n";
166  ss << " u = u + delta_u;\n";
167  ss << " g = -pow(g_bar,-1.0);\n";
168  ss << " f_bar = f_bar * g;\n";
169  ss << " bHasfound = (fabs(delta_u)<=fabs(u)*epsilon);\n";
170  ss << " k = k + 1.0;\n";
171  ss << " }\n";
172  ss << " while (!bHasfound && k <= fMaxIteration);\n";
173  ss << " if (bHasfound)\n";
174  ss << " return u * fSign;\n";
175  ss << " else\n";
176  ss << " return CreateDoubleError(NoConvergence);\n";
177  ss << "}";
178 }
179 void OpGestep::GenSlidingWindowFunction(
180  std::stringstream &ss,const std::string &sSymName,
181  SubArguments &vSubArguments)
182 {
183  ss << "\ndouble " << sSymName;
184  ss << "_"<< BinFuncName() <<"(";
185  for (size_t i = 0; i < vSubArguments.size(); i++)
186  {
187  if (i)
188  ss << ",";
189  vSubArguments[i]->GenSlidingWindowDecl(ss);
190  }
191  ss << ")\n";
192  ss << "{\n";
193  ss << " double tmp=0,tmp0 =0,tmp1 = 0;\n";
194  ss << " int gid0=get_global_id(0);\n";
195  ss <<"\n";
196  for (size_t i = 0; i < vSubArguments.size(); i++)
197  {
198  FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
199  assert(pCur);
200  if (pCur->GetType() == formula::svSingleVectorRef)
201  {
202  const formula::SingleVectorRefToken& rSVR =
203  dynamic_cast< const formula::SingleVectorRefToken& >(*pCur);
204  ss << " if (gid0 < " << rSVR.GetArrayLength() << ")\n";
205  ss << " {\n";
206  }
207  else if (pCur->GetType() == formula::svDouble)
208  {
209  ss << " {\n";
210  }
211 
212  if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
213  {
214  ss << " if (isnan(";
215  ss << vSubArguments[i]->GenSlidingWindowDeclRef();
216  ss << "))\n";
217  ss << " tmp"<<i<<" = 0;\n";
218  ss << " else\n";
219  ss << " tmp"<<i<<" = ";
220  ss << vSubArguments[i]->GenSlidingWindowDeclRef();
221  ss << ";\n }\n";
222  }
223  else
224  {
225  ss << "tmp"<<i<<" ="<<vSubArguments[i]->GenSlidingWindowDeclRef();
226  ss <<";\n";
227  }
228  }
229  ss << " tmp =tmp0 >= tmp1 ? 1 : 0;\n";
230  ss << " return tmp;\n";
231  ss << "}\n";
232 }
233 
234 }
235 
236 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Inconsistent state.
Definition: opbase.hxx:54
virtual double GetDouble() const
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
int i
ocPush
std::vector< DynamicKernelArgumentRef > SubArguments
Definition: opbase.hxx:215
Arguments that are actually compile-time constant string Currently, only the hash is passed...
#define CHECK_PARAMETER_COUNT(min, max)
Definition: opbase.hxx:75
size_t GetArrayLength() const
StackVar GetType() const