Line data Source code
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 "formulagroup.hxx"
13 : #include "document.hxx"
14 : #include "formulacell.hxx"
15 : #include "tokenarray.hxx"
16 : #include "compiler.hxx"
17 : #include "interpre.hxx"
18 : #include <formula/vectortoken.hxx>
19 : #include <sstream>
20 :
21 : using namespace formula;
22 :
23 : namespace sc { namespace opencl {
24 :
25 0 : void OpBesselj::GenSlidingWindowFunction(std::stringstream &ss,
26 : const std::string &sSymName, SubArguments &vSubArguments)
27 : {
28 0 : ss << "\ndouble " << sSymName;
29 0 : ss << "_" << BinFuncName() << "(";
30 0 : for (size_t i = 0; i < vSubArguments.size(); i++)
31 : {
32 0 : if (i)
33 0 : ss << ",";
34 0 : vSubArguments[i]->GenSlidingWindowDecl(ss);
35 : }
36 0 : ss << ") {\n";
37 0 : ss << " int gid0 = get_global_id(0);\n";
38 0 : ss << " double x = 0.0;\n";
39 0 : ss << " double N = 0.0;\n";
40 0 : if(vSubArguments.size() != 2)
41 : {
42 0 : ss << " return DBL_MAX;\n}\n";
43 0 : return ;
44 : }
45 0 : FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken();
46 : assert(tmpCur0);
47 0 : if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
48 : {
49 0 : if(tmpCur0->GetType() == formula::svSingleVectorRef)
50 : {
51 : const formula::SingleVectorRefToken*tmpCurSVR0 =
52 0 : static_cast<const formula::SingleVectorRefToken *>(tmpCur0);
53 0 : ss << " if (gid0 < " << tmpCurSVR0->GetArrayLength() << ")\n";
54 0 : ss << " {\n";
55 0 : ss << " x = ";
56 0 : ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
57 0 : ss << " if (isNan(x))\n";
58 0 : ss << " x = 0.0;\n";
59 0 : ss << " }\n";
60 : }
61 0 : else if(tmpCur0->GetType() == formula::svDouble)
62 : {
63 0 : ss << " x = " << tmpCur0->GetDouble() << ";\n";
64 : }
65 : else
66 : {
67 0 : ss << " return DBL_MAX;\n}\n";
68 0 : return ;
69 : }
70 : }
71 : else
72 : {
73 0 : ss << " x = ";
74 0 : ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n";
75 : }
76 :
77 0 : FormulaToken *tmpCur1 = vSubArguments[1]->GetFormulaToken();
78 : assert(tmpCur1);
79 0 : if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
80 : {
81 0 : if(tmpCur1->GetType() == formula::svSingleVectorRef)
82 : {
83 : const formula::SingleVectorRefToken*tmpCurSVR1 =
84 0 : static_cast<const formula::SingleVectorRefToken *>(tmpCur1);
85 0 : ss << " if (gid0 < " << tmpCurSVR1->GetArrayLength() << ")\n";
86 0 : ss << " {\n";
87 0 : ss << " N = ";
88 0 : ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
89 0 : ss << " if (isNan(N))\n";
90 0 : ss << " N = 0.0;\n";
91 0 : ss << " }\n";
92 : }
93 0 : else if(tmpCur1->GetType() == formula::svDouble)
94 : {
95 0 : ss << " N = " << tmpCur1->GetDouble() << ";\n";
96 : }
97 : else
98 : {
99 0 : ss << " return DBL_MAX;\n}\n";
100 0 : return ;
101 : }
102 : }
103 : else
104 : {
105 0 : ss << " N = ";
106 0 : ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n";
107 : }
108 0 : ss << " double f_PI = 3.1415926535897932385;\n";
109 0 : ss << " double f_2_DIV_PI = 2.0 / f_PI;\n";
110 0 : ss << " double f_PI_DIV_2 = f_PI / 2.0;\n";
111 0 : ss << " double f_PI_DIV_4 = f_PI / 4.0;\n";
112 0 : ss << " if( N < 0.0 )\n";
113 0 : ss << " return DBL_MAX;\n";
114 0 : ss << " if (x == 0.0)\n";
115 0 : ss << " return (N == 0.0) ? 1.0 : 0.0;\n";
116 0 : ss << " double fSign = ((int)N % 2 == 1 && x < 0.0) ? -1.0 : 1.0;\n";
117 0 : ss << " double fX = fabs(x);\n";
118 0 : ss << " double fMaxIteration = 9000000.0;\n";
119 0 : ss << " double fEstimateIteration = fX * 1.5 + N;\n";
120 0 : ss << " bool bAsymptoticPossible = pow(fX,0.4) > N;\n";
121 0 : ss << " if (fEstimateIteration > fMaxIteration)\n";
122 0 : ss << " {\n";
123 0 : ss << " if (bAsymptoticPossible)\n";
124 0 : ss << " return fSign * sqrt(f_2_DIV_PI/fX)";
125 0 : ss << "* cos(fX-N*f_PI_DIV_2-f_PI_DIV_4);\n";
126 0 : ss << " else\n";
127 0 : ss << " return DBL_MAX;\n";
128 0 : ss << " }\n";
129 0 : ss << " double epsilon = 1.0e-15;\n";
130 0 : ss << " bool bHasfound = false;\n";
131 0 : ss << " double k= 0.0;\n";
132 0 : ss << " double u ;\n";
133 0 : ss << " double m_bar;\n";
134 0 : ss << " double g_bar;\n";
135 0 : ss << " double g_bar_delta_u;\n";
136 0 : ss << " double g = 0.0;\n";
137 0 : ss << " double delta_u = 0.0;\n";
138 0 : ss << " double f_bar = -1.0;\n";
139 0 : ss << " if (N==0)\n";
140 0 : ss << " {\n";
141 0 : ss << " u = 1.0;\n";
142 0 : ss << " g_bar_delta_u = 0.0;\n";
143 0 : ss << " g_bar = - 2.0/fX; \n";
144 0 : ss << " delta_u = g_bar_delta_u / g_bar;\n";
145 0 : ss << " u = u + delta_u ;\n";
146 0 : ss << " g = -1.0 / g_bar; \n";
147 0 : ss << " f_bar = f_bar * g;\n";
148 0 : ss << " k = 2.0;\n";
149 0 : ss << " }\n";
150 0 : ss << " if (N!=0)\n";
151 0 : ss << " {\n";
152 0 : ss << " u=0.0;\n";
153 0 : ss << " for (k =1.0; k<= N-1; k = k + 1.0)\n";
154 0 : ss << " {\n";
155 0 : ss << " m_bar=2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
156 0 : ss << " g_bar_delta_u = - g * delta_u - m_bar * u;\n";
157 0 : ss << " g_bar = m_bar - 2.0*k/fX + g;\n";
158 0 : ss << " delta_u = g_bar_delta_u / g_bar;\n";
159 0 : ss << " u = u + delta_u;\n";
160 0 : ss << " g = -1.0/g_bar;\n";
161 0 : ss << " f_bar=f_bar * g;\n";
162 0 : ss << " }\n";
163 0 : ss << " m_bar=2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
164 0 : ss << " g_bar_delta_u = f_bar - g * delta_u - m_bar * u;\n";
165 0 : ss << " g_bar = m_bar - 2.0*k/fX + g;\n";
166 0 : ss << " delta_u = g_bar_delta_u / g_bar;\n";
167 0 : ss << " u = u + delta_u;\n";
168 0 : ss << " g = -1.0/g_bar;\n";
169 0 : ss << " f_bar = f_bar * g;\n";
170 0 : ss << " k = k + 1.0;\n";
171 0 : ss << " }\n";
172 0 : ss << " do\n";
173 0 : ss << " {\n";
174 0 : ss << " m_bar = 2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
175 0 : ss << " g_bar_delta_u = - g * delta_u - m_bar * u;\n";
176 0 : ss << " g_bar = m_bar - 2.0*k/fX + g;\n";
177 0 : ss << " delta_u = g_bar_delta_u / g_bar;\n";
178 0 : ss << " u = u + delta_u;\n";
179 0 : ss << " g = -pow(g_bar,-1.0);\n";
180 0 : ss << " f_bar = f_bar * g;\n";
181 0 : ss << " bHasfound = (fabs(delta_u)<=fabs(u)*epsilon);\n";
182 0 : ss << " k = k + 1.0;\n";
183 0 : ss << " }\n";
184 0 : ss << " while (!bHasfound && k <= fMaxIteration);\n";
185 0 : ss << " if (bHasfound)\n";
186 0 : ss << " return u * fSign;\n";
187 0 : ss << " else\n";
188 0 : ss << " return DBL_MAX;\n";
189 0 : ss << "}";
190 : }
191 0 : void OpGestep::GenSlidingWindowFunction(
192 : std::stringstream &ss,const std::string &sSymName,
193 : SubArguments &vSubArguments)
194 : {
195 0 : ss << "\ndouble " << sSymName;
196 0 : ss << "_"<< BinFuncName() <<"(";
197 0 : for (size_t i = 0; i < vSubArguments.size(); i++)
198 : {
199 0 : if (i)
200 0 : ss << ",";
201 0 : vSubArguments[i]->GenSlidingWindowDecl(ss);
202 : }
203 0 : ss << ")\n";
204 0 : ss << "{\n";
205 0 : ss << " double tmp=0,tmp0 =0,tmp1 = 0;\n";
206 0 : ss << " int gid0=get_global_id(0);\n";
207 0 : size_t i = vSubArguments.size();
208 0 : ss <<"\n";
209 0 : for (i = 0; i < vSubArguments.size(); i++)
210 : {
211 0 : FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
212 : assert(pCur);
213 0 : if (pCur->GetType() == formula::svSingleVectorRef)
214 : {
215 : const formula::SingleVectorRefToken& rSVR =
216 0 : dynamic_cast< const formula::SingleVectorRefToken& >(*pCur);
217 0 : ss << " if (gid0 < " << rSVR.GetArrayLength() << ")\n";
218 0 : ss << " {\n";
219 : }
220 0 : else if (pCur->GetType() == formula::svDouble)
221 : {
222 0 : ss << " {\n";
223 : }
224 : else
225 : {
226 : }
227 0 : if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode())
228 : {
229 0 : ss << " if (isNan(";
230 0 : ss << vSubArguments[i]->GenSlidingWindowDeclRef();
231 0 : ss << "))\n";
232 0 : ss << " tmp"<<i<<" = 0;\n";
233 0 : ss << " else\n";
234 0 : ss << " tmp"<<i<<" = ";
235 0 : ss << vSubArguments[i]->GenSlidingWindowDeclRef();
236 0 : ss << ";\n }\n";
237 : }
238 : else
239 : {
240 0 : ss << "tmp"<<i<<" ="<<vSubArguments[i]->GenSlidingWindowDeclRef();
241 0 : ss <<";\n";
242 : }
243 : }
244 0 : ss << " tmp =tmp0 >= tmp1 ? 1 : 0;\n";
245 0 : ss << " return tmp;\n";
246 0 : ss << "}\n";
247 0 : }
248 :
249 156 : }}
250 :
251 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|