1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include "op_addin.hxx"
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"
21 using namespace formula
;
23 namespace sc
{ namespace opencl
{
25 void OpBesselj::GenSlidingWindowFunction(std::stringstream
&ss
,
26 const std::string sSymName
, SubArguments
&vSubArguments
)
28 ss
<< "\ndouble " << sSymName
;
29 ss
<< "_" << BinFuncName() << "(";
30 for (unsigned i
= 0; i
< vSubArguments
.size(); i
++)
34 vSubArguments
[i
]->GenSlidingWindowDecl(ss
);
37 ss
<< " int gid0 = get_global_id(0);\n";
38 ss
<< " double x = 0.0;\n";
39 ss
<< " double N = 0.0;\n";
40 if(vSubArguments
.size() != 2)
42 ss
<< " return DBL_MAX;\n" << "}\n";
45 FormulaToken
*tmpCur0
= vSubArguments
[0]->GetFormulaToken();
47 if(ocPush
== vSubArguments
[0]->GetFormulaToken()->GetOpCode())
49 if(tmpCur0
->GetType() == formula::svSingleVectorRef
)
51 const formula::SingleVectorRefToken
*tmpCurSVR0
=
52 dynamic_cast<const formula::SingleVectorRefToken
*>(tmpCur0
);
54 ss
<< " if (gid0 < " << tmpCurSVR0
->GetArrayLength() << ")\n";
58 ss
<< vSubArguments
[0]->GenSlidingWindowDeclRef() << ";\n";
60 ss
<< " if (isNan(x))\n";
65 else if(tmpCur0
->GetType() == formula::svDouble
)
67 ss
<< " x = " << tmpCur0
->GetDouble() << ";\n";
71 ss
<< " return DBL_MAX;\n" << "}\n";
78 ss
<< vSubArguments
[0]->GenSlidingWindowDeclRef() << ";\n";
81 FormulaToken
*tmpCur1
= vSubArguments
[1]->GetFormulaToken();
83 if(ocPush
== vSubArguments
[1]->GetFormulaToken()->GetOpCode())
85 if(tmpCur1
->GetType() == formula::svSingleVectorRef
)
87 const formula::SingleVectorRefToken
*tmpCurSVR1
=
88 dynamic_cast<const formula::SingleVectorRefToken
*>(tmpCur1
);
90 ss
<< " if (gid0 < " << tmpCurSVR1
->GetArrayLength() << ")\n";
94 ss
<< vSubArguments
[1]->GenSlidingWindowDeclRef() << ";\n";
96 ss
<< " if (isNan(N))\n";
101 else if(tmpCur1
->GetType() == formula::svDouble
)
103 ss
<< " N = " << tmpCur1
->GetDouble() << ";\n";
107 ss
<< " return DBL_MAX;\n" << "}\n";
114 ss
<< vSubArguments
[1]->GenSlidingWindowDeclRef() << ";\n";
116 ss
<< " double f_PI = 3.1415926535897932385;\n";
117 ss
<< " double f_2_DIV_PI = 2.0 / f_PI;\n";
118 ss
<< " double f_PI_DIV_2 = f_PI / 2.0;\n";
119 ss
<< " double f_PI_DIV_4 = f_PI / 4.0;\n";
120 ss
<< " if( N < 0.0 )\n";
121 ss
<< " return DBL_MAX;\n";
122 ss
<< " if (x == 0.0)\n";
123 ss
<< " return (N == 0.0) ? 1.0 : 0.0;\n";
124 ss
<< " double fSign = ((int)N % 2 == 1 && x < 0.0) ? -1.0 : 1.0;\n";
125 ss
<< " double fX = fabs(x);\n";
126 ss
<< " double fMaxIteration = 9000000.0;\n";
127 ss
<< " double fEstimateIteration = fX * 1.5 + N;\n";
128 ss
<< " bool bAsymptoticPossible = pow(fX,0.4) > N;\n";
129 ss
<< " if (fEstimateIteration > fMaxIteration)\n";
131 ss
<< " if (bAsymptoticPossible)\n";
132 ss
<< " return fSign * sqrt(f_2_DIV_PI/fX)";
133 ss
<< "* cos(fX-N*f_PI_DIV_2-f_PI_DIV_4);\n";
135 ss
<< " return DBL_MAX;\n";
137 ss
<< " double epsilon = 1.0e-15;\n";
138 ss
<< " bool bHasfound = false;\n";
139 ss
<< " double k= 0.0;\n";
140 ss
<< " double u ;\n";
141 ss
<< " double m_bar;\n";
142 ss
<< " double g_bar;\n";
143 ss
<< " double g_bar_delta_u;\n";
144 ss
<< " double g = 0.0;\n";
145 ss
<< " double delta_u = 0.0;\n";
146 ss
<< " double f_bar = -1.0;\n";
147 ss
<< " if (N==0)\n";
150 ss
<< " g_bar_delta_u = 0.0;\n";
151 ss
<< " g_bar = - 2.0/fX; \n";
152 ss
<< " delta_u = g_bar_delta_u / g_bar;\n";
153 ss
<< " u = u + delta_u ;\n";
154 ss
<< " g = -1.0 / g_bar; \n";
155 ss
<< " f_bar = f_bar * g;\n";
158 ss
<< " if (N!=0)\n";
161 ss
<< " for (k =1.0; k<= N-1; k = k + 1.0)\n";
163 ss
<< " m_bar=2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
164 ss
<< " g_bar_delta_u = - g * delta_u - m_bar * u;\n";
165 ss
<< " g_bar = m_bar - 2.0*k/fX + g;\n";
166 ss
<< " delta_u = g_bar_delta_u / g_bar;\n";
167 ss
<< " u = u + delta_u;\n";
168 ss
<< " g = -1.0/g_bar;\n";
169 ss
<< " f_bar=f_bar * g;\n";
171 ss
<< " m_bar=2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
172 ss
<< " g_bar_delta_u = f_bar - g * delta_u - m_bar * u;\n";
173 ss
<< " g_bar = m_bar - 2.0*k/fX + g;\n";
174 ss
<< " delta_u = g_bar_delta_u / g_bar;\n";
175 ss
<< " u = u + delta_u;\n";
176 ss
<< " g = -1.0/g_bar;\n";
177 ss
<< " f_bar = f_bar * g;\n";
178 ss
<< " k = k + 1.0;\n";
182 ss
<< " m_bar = 2.0 * fmod(k-1.0, 2.0) * f_bar;\n";
183 ss
<< " g_bar_delta_u = - g * delta_u - m_bar * u;\n";
184 ss
<< " g_bar = m_bar - 2.0*k/fX + g;\n";
185 ss
<< " delta_u = g_bar_delta_u / g_bar;\n";
186 ss
<< " u = u + delta_u;\n";
187 ss
<< " g = -pow(g_bar,-1.0);\n";
188 ss
<< " f_bar = f_bar * g;\n";
189 ss
<< " bHasfound = (fabs(delta_u)<=fabs(u)*epsilon);\n";
190 ss
<< " k = k + 1.0;\n";
192 ss
<< " while (!bHasfound && k <= fMaxIteration);\n";
193 ss
<< " if (bHasfound)\n";
194 ss
<< " return u * fSign;\n";
196 ss
<< " return DBL_MAX;\n";
202 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */