Skip to content

Commit 1a497ab

Browse files
committed
...
2 parents 0ff2a19 + 24afbfe commit 1a497ab

File tree

9 files changed

+235
-23
lines changed

9 files changed

+235
-23
lines changed

CHANGELOG.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,40 @@ The filling functions can be called also with a specific backend policy and with
165165

166166
#### Data fitting
167167

168-
1. Adding support to simultaneous fit.
168+
1. Added support to multi-layered simultaneous fit of different models, over different datasets, deploying different parallelization strategies for each model. No categorization of the dataset is needed, but just to set up preliminarly the different component FCNs, that can be optimized in isolation or in the context of the simultaneous FCN. Simultaneous FCNs can be created via direct instantiation or using the convenience function `hydra::make_simultaneous_fcn(...)`, as shown in the following snippet.
169+
170+
```cpp
171+
...
172+
#include <hydra/LogLikelihoodFCN.h>
173+
...
174+
175+
int main(int argv, char** argc)
176+
{
177+
...
178+
//=====================================================================================
179+
// +----< fcn(model-x)
180+
// +----< simultaneous fcn 1 ----- |
181+
// | +----< fcn(model-y)
182+
// simultaneous fcn <----+
183+
// | +----< fcn(model-w)
184+
// +----< simultaneous fcn 2 ------|
185+
// | +----< fcn(model-z)
186+
// +----< fcn(model-v)
187+
//=====================================================================================
188+
auto fcnX = hydra::make_loglikehood_fcn(modelX, dataX);
189+
auto fcnY = hydra::make_loglikehood_fcn(modelY, dataY);
190+
auto fcnW = hydra::make_loglikehood_fcn(modelY, dataY);
191+
auto fcnZ = hydra::make_loglikehood_fcn(modelZ, dataZ);
192+
auto fcnV = hydra::make_loglikehood_fcn(modelv, datav);
193+
194+
auto sim_fcn1 = hydra::make_simultaneous_fcn(fcnx, fcny);
195+
auto sim_fcn2 = hydra::make_simultaneous_fcn(fcnw, fcnz);
196+
auto sim_fcn = hydra::make_simultaneous_fcn(sim_fcn1, sim_fcn2, fcnV);
197+
...
198+
}
199+
```
200+
Moreover, the generic interface allows to build up a simultaneous FCN object by composing usual FCNs and simultaneous FCNs. An example of such new method can be found in `examples/fit/simultaneous_fit.inl`.
201+
169202
2. Fitting of convoluted PDFs.
170203

171204
#### General

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ SET(CMAKE_VERBOSE_MAKEFILE ON)
1818
#check if compiler is C++14 compliant
1919
include(CheckCXXCompilerFlag)
2020
CHECK_CXX_COMPILER_FLAG("--std=c++14" COMPILER_SUPPORTS_CXX14)
21-
if(NOT COMPILER_SUPPORTS_CXX11)
21+
if(NOT COMPILER_SUPPORTS_CXX14)
2222
message(FATAL "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
2323
endif()
2424

examples/convolution/convolute_functions.inl

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@
4747
#include <hydra/functions/Ipatia.h>
4848
#include <hydra/device/System.h>
4949
#include <hydra/functions/ConvolutionFunctor.h>
50-
#include <hydra/Random.h>
50+
#include <hydra/GaussKronrodQuadrature.h>
51+
5152
//hydra
5253
#if HYDRA_DEVICE_SYSTEM == CUDA
5354
#include <hydra/CuFFT.h>
@@ -114,7 +115,7 @@ int main(int argv, char** argc)
114115
auto mean = hydra::Parameter::Create( "mean").Value(0.0).Error(0.0001);
115116
auto sigma = hydra::Parameter::Create("sigma").Value(1.0).Error(0.0001);
116117

117-
hydra::Gaussian<double> gaussian_kernel(mean, sigma);
118+
hydra::Gaussian<double> kernel(mean, sigma);
118119

119120
//===========================
120121
// signals
@@ -162,7 +163,7 @@ int main(int argv, char** argc)
162163
auto start_d = std::chrono::high_resolution_clock::now();
163164

164165
hydra::convolute(hydra::device::sys, fft_backend,
165-
signal, gaussian_kernel, min, max, conv_result, true);
166+
signal, kernel, min, max, conv_result, true);
166167

167168
auto end_d = std::chrono::high_resolution_clock::now();
168169

@@ -176,7 +177,22 @@ int main(int argv, char** argc)
176177
/*
177178
* using the hydra::ConvolutionFunctor
178179
*/
179-
auto convoluton = hydra::make_convolution<double>( hydra::device::sys, fft_backend, signal, gaussian_kernel, min, max, conv_result.size() );
180+
auto convoluton = hydra::make_convolution<double>( hydra::device::sys, fft_backend,
181+
signal, kernel, min, max, conv_result.size() );
182+
183+
hydra::GaussKronrodQuadrature<61,100, hydra::device::sys_t> GKQ61_Kernel(-25.0, 25.0);
184+
hydra::GaussKronrodQuadrature<61,100, hydra::device::sys_t> GKQ61_Signal(min, max);
185+
186+
auto kernel_int = GKQ61_Kernel.Integrate(kernel);
187+
auto signal_int = GKQ61_Signal.Integrate(signal);
188+
auto convol_int = GKQ61_Signal.Integrate(convoluton);
189+
190+
std::cout << "===========================================" << std::endl;
191+
std::cout << "Kernel Integral: " <<kernel_int.first <<"+/-"<< kernel_int.second << std::endl;
192+
std::cout << "Signal Integral: " <<signal_int.first <<"+/-"<< signal_int.second << std::endl;
193+
std::cout << "Convol Integral: " <<convol_int.first <<"+/-"<< convol_int.second << std::endl;
194+
std::cout << "===========================================" << std::endl;
195+
180196

181197
//------------------------
182198
//------------------------
@@ -193,7 +209,7 @@ int main(int argv, char** argc)
193209
hist_convol_functor->SetBinContent(i, convoluton(hist_convol_functor->GetBinCenter(i)) );
194210
hist_convol->SetBinContent(i, conv_result[i-1] );
195211
hist_signal->SetBinContent(i, signal(hist_signal->GetBinCenter(i) ) );
196-
hist_kernel->SetBinContent(i, gaussian_kernel( hist_kernel->GetBinCenter(i)));
212+
hist_kernel->SetBinContent(i, kernel( hist_kernel->GetBinCenter(i)));
197213
}
198214
#endif //_ROOT_AVAILABLE_
199215

hydra/Convolution.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,28 +79,34 @@ convolute(detail::BackendPolicy<BACKEND> policy, detail::FFTPolicy<T, FFTBackend
7979

8080
int nsamples = std::forward<Iterable>(output).size();
8181

82-
8382
T delta = (max - min)/(nsamples);
8483

8584
auto complex_buffer = hydra_thrust::get_temporary_buffer<complex_type>(policy, nsamples+1);
8685
auto kernel_samples = hydra_thrust::get_temporary_buffer<T>(policy, 2*nsamples);
8786
auto functor_samples = hydra_thrust::get_temporary_buffer<T>(policy, 2*nsamples);
8887

8988
//
90-
auto counting_samples = range(0, 2*nsamples-1);
89+
90+
auto counting_samples = range(0, 2*nsamples);
91+
9192
// sample kernel
9293
auto kernel_sampler = hydra::detail::convolution::KernelSampler<Kernel>(kernel, nsamples, delta);
9394

9495
hydra_thrust::transform(policy, counting_samples.begin(), counting_samples.end(),
9596
kernel_samples.first , kernel_sampler);
9697

9798

99+
//auto norm_factor = hydra_thrust::reduce(policy, kernel_samples.first, kernel_samples.first + kernel_samples.second );
100+
101+
98102
// sample function
99103
auto functor_sampler = hydra::detail::convolution::FunctorSampler<Functor>(functor, nsamples, min, delta);
100104

101105
hydra_thrust::transform( policy, counting_samples.begin(), counting_samples.end(),
102106
functor_samples.first, functor_sampler);
103107

108+
//norm_factor *= hydra_thrust::reduce(policy, functor_samples.first, functor_samples.first + functor_samples.second );
109+
104110
//transform kernel
105111
auto fft_kernel = _RealToComplexFFT( kernel_samples.second );
106112

@@ -134,14 +140,17 @@ convolute(detail::BackendPolicy<BACKEND> policy, detail::FFTPolicy<T, FFTBackend
134140

135141
//transform product back to real
136142

143+
137144
auto fft_product = _ComplexToRealFFT( complex_buffer.second );
138145

146+
139147
fft_product.LoadInputData(complex_buffer.second, complex_buffer.first);
140148
fft_product.Execute();
141149

142150
auto fft_product_output = fft_product.GetOutputData();
143151

144-
T n = 2*nsamples;//*norm_factor;
152+
153+
T n = 2*nsamples;
145154

146155
auto normalize_fft = detail::convolution::NormalizeFFT<T>(n);
147156

hydra/Random.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,26 @@ struct is_callable: std::conditional<
199199
} // namespace detail
200200

201201

202+
/**
203+
* \ingroup random
204+
*
205+
* This functions reorder a dataset to produce a unweighted sample according to the weights
206+
* [wbegin, wend]. The length of the range [wbegin, wend] should be equal or greater than
207+
* the dataset size.
208+
*
209+
* @param policy parallel backend to perform the unweighting
210+
* @param data_begin iterator pointing to the begin of the range of weights
211+
* @param data_end iterator pointing to the begin of the range of weights
212+
* @param weights_begin iterator pointing to the begin of the range of data
213+
* @return
214+
*/
215+
template<typename RNG=default_random_engine, typename DerivedPolicy, typename IteratorData, typename IteratorWeight>
216+
typename std::enable_if<
217+
detail::random::is_iterator<IteratorData>::value && detail::random::is_iterator<IteratorWeight>::value,
218+
Range<IteratorData> >::type
219+
unweight( hydra_thrust::detail::execution_policy_base<DerivedPolicy> const& policy, IteratorData data_begin, IteratorData data_end, IteratorWeight weights_begin);
220+
221+
202222

203223

204224
/**
@@ -276,6 +296,25 @@ typename std::enable_if<
276296
unweight( IterableData data, IterableWeight weights);
277297

278298

299+
/**
300+
* \ingroup random
301+
*
302+
* This functions reorder a dataset to produce an unweighted sample according to @param functor .
303+
*
304+
* @param policy
305+
* @param begin
306+
* @param end
307+
* @param functor
308+
* @return the index of the last entry of the unweighted event.
309+
*/
310+
template<typename RNG=default_random_engine, typename Functor, typename Iterator, typename DerivedPolicy>
311+
typename std::enable_if<
312+
detail::random::is_callable<Functor>::value && detail::random::is_iterator<Iterator>::value,
313+
Range<Iterator>
314+
>::type
315+
unweight( hydra_thrust::detail::execution_policy_base<DerivedPolicy> const& policy, Iterator begin, Iterator end, Functor const& functor);
316+
317+
279318
/**
280319
* \ingroup random
281320
*

hydra/SeedRNG.h

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*----------------------------------------------------------------------------
2+
*
3+
* Copyright (C) 2016 - 2020 Antonio Augusto Alves Junior
4+
*
5+
* This file is part of Hydra Data Analysis Framework.
6+
*
7+
* Hydra is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* Hydra is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with Hydra. If not, see <http://www.gnu.org/licenses/>.
19+
*
20+
*---------------------------------------------------------------------------*/
21+
22+
/*
23+
* SeedRNG.h
24+
*
25+
* Created on: 30/06/2020
26+
* Author: Antonio Augusto Alves Junior
27+
*/
28+
29+
#ifndef SEEDRNG_H_
30+
#define SEEDRNG_H_
31+
32+
33+
#include <hydra/detail/Config.h>
34+
#include <stdint.h>
35+
36+
37+
namespace hydra {
38+
39+
class SeedRNG
40+
{
41+
public:
42+
43+
__hydra_host__ __hydra_device__
44+
SeedRNG(size_t state=1337 ):
45+
fState(state)
46+
{}
47+
48+
__hydra_host__ __hydra_device__
49+
SeedRNG(SeedRNG const& other):
50+
fState(other.GetState())
51+
{}
52+
53+
__hydra_host__ __hydra_device__
54+
inline SeedRNG& operator=(SeedRNG const& other)
55+
{
56+
if(this==&other) return *this;
57+
58+
fState=other.GetState();
59+
60+
return *this;
61+
}
62+
63+
__hydra_host__ __hydra_device__
64+
size_t GetState() const {
65+
return fState;
66+
}
67+
68+
__hydra_host__ __hydra_device__
69+
void SetState(size_t state) {
70+
fState = state;
71+
}
72+
73+
__hydra_host__ __hydra_device__
74+
size_t operator()()
75+
{
76+
size_t z = (fState += 0x9e3779b97f4a7c15);
77+
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
78+
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
79+
return z ^ (z >> 31);
80+
}
81+
82+
83+
private:
84+
85+
size_t fState;
86+
87+
};
88+
89+
} // namespace hydra
90+
91+
#endif /* SEEDRNG_H_ */

hydra/detail/Convolution.inl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,11 @@ struct KernelSampler
7070

7171
KernelSampler(Kernel const& kernel, int nsamples , double delta):
7272
fDelta(delta),
73-
7473
fKernel(kernel)
7574
{
7675
fNZero = nsamples;
77-
fNMin = nsamples- nsamples/16;
78-
fNMax = nsamples+ nsamples/16;
76+
fNMin = nsamples- nsamples/2;
77+
fNMax = nsamples+ nsamples/2;
7978
}
8079

8180
__hydra_host__ __hydra_device__
@@ -215,7 +214,7 @@ struct FunctorSampler
215214

216215
double t = index*fDelta + fMin;
217216

218-
if( (t >= fMin) && ( t <= (fNSamples)*fDelta + fMin)){
217+
if( (t >= fMin) && ( t < (fNSamples)*fDelta + fMin)){
219218

220219
value = fFunctor(t);
221220
}

hydra/detail/Decays.inl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public:
8585

8686
hydra_thrust::uniform_real_distribution<double> uniDist(0.0,1.0);
8787

88-
return ( weight/fMaxWeight >= uniDist(randEng)) ;
88+
return ( weight/fMaxWeight > uniDist(randEng)) ;
8989
}
9090

9191
__hydra_host__ __hydra_device__
@@ -474,7 +474,7 @@ typedef hydra_thrust::transform_iterator<reweight_functor,iterator> reweight_ite
474474
typedef detail::FlagDaugthers< reweight_functor> tagger_type;
475475

476476
//number of events to trial
477-
size_t ntrials = this->size();
477+
size_t ntrials = fDecays.size();
478478

479479
//create iterators
480480
hydra_thrust::counting_iterator < size_t > first(0);

0 commit comments

Comments
 (0)