-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
348 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
ref-names: $Format:%D$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.git_archival.txt export-subst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
zfit>=0.3.1 | ||
zfit>=0.3.7 | ||
numpy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,105 @@ | ||
from functools import reduce | ||
from typing import Callable, Union | ||
|
||
import tensorflow as tf | ||
import tensorflow_probability as tfp | ||
import zfit | ||
from zfit import ztf | ||
from zfit.util import ztyping | ||
import zfit.models.functor | ||
from zfit import ztf, z | ||
from zfit.util import exception | ||
from zfit.util.container import convert_to_container | ||
from zfit.util.exception import DueToLazynessNotImplementedError | ||
from zfit.util import ztyping | ||
from zfit.util.exception import WorkInProgressError | ||
|
||
|
||
class ConvPDF(zfit.pdf.BasePDF): | ||
def __init__(self, func: Union[Callable, zfit.pdf.BasePDF], kernel: Union[Callable, zfit.pdf.BasePDF], | ||
class NumConvPDFUnbinnedV1(zfit.models.functor.BaseFunctor): | ||
def __init__(self, func: zfit.pdf.BasePDF, kernel: zfit.pdf.BasePDF, | ||
limits: ztyping.ObsTypeInput, obs: ztyping.ObsTypeInput, | ||
ndraws: int = 20000, name: str = "Convolution"): | ||
"""Numerical Convolutional pdf of _func_ convoluted with _kernel_. | ||
ndraws: int = 20000, name: str = "Convolution", experimental_pdf_normalized=False): | ||
"""Numerical Convolution pdf of *func* convoluted with *kernel*. | ||
Args: | ||
func (callable): Function that takes x and return the function value. Here x is a `Data` with the obs and limits | ||
of _limits_. Can also be a PDF. | ||
kernel (callable): Kernel function that takes x and return the function value. Here x is a `Data` with the obs and limits | ||
of _limits_. Can also be a PDF. | ||
limits (:py:class:`zfit.Space`): Limits of the numerical integration | ||
obs (:py:class:`zfit.Space`): | ||
func (:py:class:`zfit.pdf.BasePDF`): PDF with `pdf` method that takes x and returns the function value. | ||
Here x is a `Data` with the obs and limits of *limits*. | ||
kernel (:py:class:`zfit.pdf.BasePDF`): PDF with `pdf` method that takes x acting as the kernel. | ||
Here x is a `Data` with the obs and limits of *limits*. | ||
limits (:py:class:`zfit.Space`): Limits for the numerical integration. | ||
obs (:py:class:`zfit.Space`): Observables of the class | ||
ndraws (int): Number of draws for the mc integration | ||
name (str): | ||
name (str): Human readable name of the pdf | ||
""" | ||
super().__init__(obs=obs, params={}, name=name) | ||
super().__init__(obs=obs, pdfs=[func, kernel], params={}, name=name) | ||
limits = self._check_input_limits(limits=limits) | ||
if limits.n_limits == 0: | ||
raise exception.LimitsNotSpecifiedError("obs have to have limits to define where to integrate over.") | ||
if limits.n_limits > 1: | ||
raise DueToLazynessNotImplementedError("Multiple Limits not implemented") | ||
|
||
if isinstance(func, zfit.pdf.BasePDF): | ||
func = lambda x: func.unnormalized_pdf(x=x) | ||
if isinstance(kernel, zfit.pdf.BasePDF): | ||
kernel = lambda x: kernel.unnormalized_pdf(x=x) | ||
|
||
lower = limits.lower[0] | ||
upper = limits.upper[0] | ||
lower = ztf.convert_to_tensor(lower, dtype=self.dtype) | ||
upper = ztf.convert_to_tensor(upper, dtype=self.dtype) | ||
samples_normed = tfp.mcmc.sample_halton_sequence(dim=limits.n_obs, num_results=ndraws, dtype=self.dtype, | ||
randomized=False) | ||
samples = samples_normed * (upper - lower) + lower # samples is [0, 1], stretch it | ||
samples = zfit.Data.from_tensor(obs=limits, tensor=samples) | ||
|
||
self._grid_points = samples # true vars | ||
self._kernel_func = kernel # callable func of reco - true vars | ||
self._func_values = func(samples) # func of true vars | ||
self._conv_limits = limits | ||
raise WorkInProgressError("Multiple Limits not implemented") | ||
|
||
# if not isinstance(func, zfit.pdf.BasePDF): | ||
# raise TypeError(f"func has to be a PDF, not {type(func)}") | ||
# if isinstance(kernel, zfit.pdf.BasePDF): | ||
# raise TypeError(f"kernel has to be a PDF, not {type(kernel)}") | ||
|
||
# func = lambda x: func.unnormalized_pdf(x=x) | ||
# kernel = lambda x: kernel.unnormalized_pdf(x=x) | ||
|
||
self._grid_points = None # true vars # callable func of reco - true vars | ||
self._func_values = None | ||
self.conv_limits = limits | ||
self._ndraws = ndraws | ||
self._experimental_pdf_normalized = experimental_pdf_normalized | ||
|
||
@z.function | ||
def _unnormalized_pdf(self, x): | ||
area = self._conv_limits.area() | ||
limits = self.conv_limits | ||
area = limits.area() | ||
|
||
samples = self._grid_points | ||
func_values = self._func_values | ||
# if func_values is None: | ||
if True: | ||
# create sample for numerical integral | ||
lower = limits.lower[0] | ||
upper = limits.upper[0] | ||
lower = ztf.convert_to_tensor(lower, dtype=self.dtype) | ||
upper = ztf.convert_to_tensor(upper, dtype=self.dtype) | ||
samples_normed = tfp.mcmc.sample_halton_sequence(dim=limits.n_obs, num_results=self._ndraws, | ||
dtype=self.dtype, | ||
randomized=False) | ||
samples = samples_normed * (upper - lower) + lower # samples is [0, 1], stretch it | ||
samples = zfit.Data.from_tensor(obs=limits, tensor=samples) | ||
self._grid_points = samples | ||
|
||
func_values = self.pdfs[0].unnormalized_pdf(samples) # func of true vars | ||
self._func_values = func_values | ||
|
||
return tf.map_fn( | ||
lambda xi: area * tf.reduce_mean(self._func_values * self._kernel_func(xi - self._grid_points)), | ||
lambda xi: area * tf.reduce_mean(func_values * self.pdfs[1].unnormalized_pdf(xi - samples)), | ||
x.value()) # func of reco vars | ||
|
||
@z.function | ||
def _pdf(self, x, norm_range): | ||
if not self._experimental_pdf_normalized: | ||
raise NotImplementedError | ||
|
||
limits = self.conv_limits | ||
area = limits.area() | ||
|
||
samples = self._grid_points | ||
func_values = self._func_values | ||
# if func_values is None: | ||
if True: | ||
# create sample for numerical integral | ||
lower = limits.lower[0] | ||
upper = limits.upper[0] | ||
lower = ztf.convert_to_tensor(lower, dtype=self.dtype) | ||
upper = ztf.convert_to_tensor(upper, dtype=self.dtype) | ||
samples_normed = tfp.mcmc.sample_halton_sequence(dim=limits.n_obs, num_results=self._ndraws, | ||
dtype=self.dtype, | ||
randomized=False) | ||
samples = samples_normed * (upper - lower) + lower # samples is [0, 1], stretch it | ||
samples = zfit.Data.from_tensor(obs=limits, tensor=samples) | ||
self._grid_points = samples | ||
|
||
func_values = self.pdfs[0].pdf(samples) # func of true vars | ||
self._func_values = func_values | ||
|
||
return tf.map_fn( | ||
lambda xi: area * tf.reduce_mean(func_values * self.pdfs[1].pdf(xi - samples)), | ||
x.value()) |
Oops, something went wrong.