9#ifdef PORTABLE_LAR_SHAPE
10#define SINCOSPOLY_USE_EIGEN 1
13#ifndef SINCOSPOLY_USE_EIGEN
17#include "TMatrixDLazy.h"
19#include "TDecompSVD.h"
25typedef Eigen::VectorXd
VECTOR;
26typedef Eigen::MatrixXd
MATRIX;
29#define Double_t double
39#include "GeoModelKernel/Units.h"
40using namespace GeoModelKernelUnits;
42#ifndef SINCOSPOLY_USE_EIGEN
43template<
typename T,
typename Q>
44std::ostream &
operator << (std::ostream & ostr,
const TVectorT<T> & v)
46 std::ios_base::fmtflags save_flags(ostr.flags());
48 ostr << std::scientific;
49 for(Int_t idx=v.GetLwb();idx<v.GetUpb();idx++) {
50 ostr << v[idx] <<
", ";
52 ostr << v[v.GetUpb()];
54 ostr.flags(save_flags);
61 const Int_t dataLen,
const Int_t nBasisFuntions,
64#ifndef SINCOSPOLY_USE_EIGEN
68 SYMMATRIX A=SYMMATRIX::Zero(nBasisFuntions,nBasisFuntions);
69 VECTOR vY=VECTOR::Zero(nBasisFuntions);
71 for(Int_t j = 0; j < nBasisFuntions; ++ j){
72 for(Int_t k = 0; k < nBasisFuntions; ++ k){
74 for(Int_t i = 0; i < dataLen; ++ i){
75 Ajk += bf(j, i) * bf(k, i);
81 for(Int_t k = 0; k < nBasisFuntions; ++ k){
83 for(Int_t i = 0; i < dataLen; ++ i){
88#ifndef SINCOSPOLY_USE_EIGEN
93 return A.inverse()*vY;
104 struct sincos_params {
105 std::array<double, nBasisFunctions> sin{};
106 std::array<double, nBasisFunctions> cos{};
114 const Double_t Rstep = 1.*
mm;
115 const Int_t nrPoints = (Rmax - Rmin) * (1./Rstep);
116 const Int_t dataLen = nrPoints + 1;
117#ifndef SINCOSPOLY_USE_EIGEN
121 MATRIX bf(nBasisFunctions, dataLen);
123 VECTOR x=VECTOR::Zero(dataLen);
124 VECTOR ysin=VECTOR::Zero(dataLen);
125 VECTOR ycos=VECTOR::Zero(dataLen);
126 MATRIX bf=MATRIX::Zero(nBasisFunctions, dataLen);
128 for(Int_t i = 0;
i < dataLen; ++
i){
129 const Double_t
a = Rmin +
i * Rstep;
132 ysin[
i] = scalpha.sn;
133 ycos[
i] = scalpha.cs;
134 for(Int_t n = 0;
n < nBasisFunctions; ++
n) {
135 bf(n, i) =
pow(
a, n);
144 for(Int_t i = 0;
i < nBasisFunctions; ++
i){
145 p.sin[
i] = params_sin[
i];
146 p.cos[
i] = params_cos[
i];
154 std::cout <<
"sin params:" << params_sin << std::endl;
155 std::cout <<
"cos params:" << params_cos << std::endl;
157 double dsinr = 0., dcosr = 0.;
160 double dsin = 0., dcos = 0.;
162 for(
double r = Rmin + 40.;
r < Rmax - 40.;
r += Rstep / 10.){
165 double sin_a_v, cos_a_v;
166 lwc.parameterized_sincos(
r, sin_a, cos_a);
167 lwc.m_vsincos_par.eval(
r, sin_a_v, cos_a_v);
168 std::streamsize
ss = std::cout.precision();
169 std::cout.precision(16);
170 std::cout <<
"def: " <<
r <<
" " << sin_a <<
" " << cos_a << std::endl;
171 std::cout <<
"vec: " <<
r <<
" " << sin_a_v <<
" " << cos_a_v << std::endl;
172 std::cout <<
"dif: " <<
r <<
" " << (sin_a - sin_a_v) / sin_a <<
" " << (cos_a - cos_a_v) / cos_a << std::endl;
173 std::cout.precision(
ss);
174 double ds = fabs(scalpha.sn - sin_a);
179 double dc = fabs(scalpha.cs - cos_a);
184 double dt = fabs(sin_a*sin_a + cos_a*cos_a - 1.);
191 std::cout <<
"Max. difference: " << std::endl
192 <<
"\tsin: " << dsin <<
" at " << dsinr << std::endl
193 <<
"\tcos: " << dcos <<
" at " << dcosr << std::endl
194 <<
"\tsin^2+cos^2: " << dtrig <<
" at " << dtrigr << std::endl;
198 TVectorD y_test(dataLen);
199 const Int_t nIter=10000;
200 std::cout <<
"Perfomance test started, " << nIter <<
" iterations" << std::endl;
202 double y_testsin[dataLen] ={};
203 double y_testcos[dataLen] ={};
204 struct timeval tvsincos_start, tvsincos_stop;
205 gettimeofday(&tvsincos_start, 0);
206 for(Int_t iIter=0;iIter<nIter;iIter++) {
207 for(Int_t i=0;
i<dataLen;
i++) {
208 sincos(parameterized_slant_angle(
x[i]), &y_testsin[i], &y_testcos[i]);
211 gettimeofday(&tvsincos_stop, 0);
212 double timeSinCos=(tvsincos_stop.tv_sec-tvsincos_start.tv_sec + 1
E-6*(tvsincos_stop.tv_usec-tvsincos_start.tv_usec))/nIter;
214 std::cout.unsetf ( std::ios::fixed | std::ios::scientific );
215 std::cout <<
"Time to fill 2x" << dataLen <<
" elements using sincos function: " << timeSinCos << std::endl;
217 struct timeval tvpoly_start, tvpoly_stop;
218 gettimeofday(&tvpoly_start, 0);
219 for(Int_t iIter=0;iIter<nIter;iIter++) {
220 for(Int_t i=0;
i<dataLen;
i++) {
221 lwc.parameterized_sincos(
x[i], y_testsin[i], y_testcos[i]);
224 gettimeofday(&tvpoly_stop, 0);
225 double timePoly=(tvpoly_stop.tv_sec - tvpoly_start.tv_sec + 1
E-6*(tvpoly_stop.tv_usec - tvpoly_start.tv_usec))/nIter;
226 std::cout <<
"Time to fill 2x" << dataLen <<
" elements using approximation sin&cos: " << timePoly << std::endl;
227 std::cout.unsetf ( std::ios::fixed | std::ios::scientific );
228 std::cout <<
"Approximation is " << timeSinCos/timePoly <<
" faster " << std::endl;
236 static const sincos_params
p = calc_params(lwc, 250.*mm, 750.*mm);
242 static const sincos_params
p = calc_params(lwc, 560.*mm, 2090.*mm);
251 const sincos_params& p =
m_isInner ? inner_params(*
this) : outer_params(*
this);
#define LARWC_SINCOS_POLY
constexpr int pow(int base, int exp) noexcept
This class separates some of the geometry details of the LAr endcap.
std::array< double, LARWC_SINCOS_POLY+1 > m_cos_parametrization
std::array< double, LARWC_SINCOS_POLY+1 > m_sin_parametrization
void fill_sincos_parameterization()
lwc(flags, cells_name, *args, **kw)
Helper to simultaneously calculate sin and cos of the same angle.
static VECTOR findLinearApproximation(const Int_t dataLen, const Int_t nBasisFuntions, const VECTOR &y, const MATRIX &bf)
std::ostream & operator<<(std::ostream &ostr, const TVectorT< T > &v)
hold the test vectors and ease the comparison
Helper to simultaneously calculate sin and cos of the same angle.