class_docstr: Hawkes process with sum-exponential kernels simulation
  
  They are defined by the intensity:
  
  .. math::
      \forall i \in [1 \dots D], \quad
      \lambda_i(t) = \mu_i(t)
                      + \sum_{j=1}^D \int \phi_{ij}(t - s) dN_j(s)
  
  where
  
    - :math:`D` is the number of nodes
    - :math:`\mu_i(t)` are the baseline intensities
    - :math:`\phi_{ij}` are the kernels
    - :math:`dN_j` are the processes differentiates
  
  and with an exponential parametrisation of the kernels
  
  .. math::
      \phi_{ij}(t) = \sum_{u=1}^{U} \alpha^u_{ij} \beta^u
                     \exp (- \beta^u t) 1_{t > 0}
  
  where :math:`\alpha^u_{ij}` are the intensities of the kernel and
  :math:`\beta^u` its decays. The matrix of all :math:`\alpha` is called
  adjacency matrix. Note that all nodes kernels share the same decays list.
  
  Parameters
  ----------
  baseline : `np.ndarray` or `list`
      The baseline of all intensities, also noted :math:`\mu(t)`. It might 
      be three different types:
      
      * `np.ndarray`, shape=(n_nodes,) : One baseline per node is given. 
        Hence baseline is assumed to be constant, ie. 
        :math:`\mu_i(t) = \mu_i`
      * `np.ndarray`, shape=(n_nodes, n_intervals) : `n_intervals` baselines 
        are given per node. This assumes parameter `period_length` is also 
        given. In this case baseline is piecewise constant on intervals of 
        size `period_length / n_intervals` and periodic.
      * `list` of `tick.base.TimeFunction`, shape=(n_nodes,) : One function 
        is given per node, ie. :math:`\mu_i(t)` is explicitely given.
  
  adjacency : `np.ndarray`, shape=(n_nodes, n_nodes, n_decays)
      Intensities of exponential kernels, also named :math:`\alpha^u_{ij}`
  
  decays : `np.ndarray`, shape=(n_decays, )
      Decays of exponential kernels, also named :math:`\beta^u`
      If a `float` is given, all decays are equal to this float
  
  end_time : `float`, default=None
      Time until which this point process will be simulated
  
  max_jumps : `int`, default=None
      Simulation will stop if this number of jumps in reached
  
  seed : `int`, default = None
      The seed of the random sampling. If it is None then a random seed
      (different at each run) will be chosen.
  
  force_simulation : `bool`, default = False
      If force is not set to True, simulation won't be run if the matrix of
      the L1 norm of kernels has a spectral radius greater or equal to 1 as
      it would be unstable
  
  Attributes
  ----------
  timestamps : `list` of `np.ndarray`, size=n_nodes
      A list of n_nodes timestamps arrays, each array containing the
      timestamps of all the jumps for this node
  
  n_decays : `int`
      Number of decays of the `HawkesSumExpKernel` , also noted :math:`U`
  
  simulation_time : `float`
      Time until which this point process has been simulated
  
  n_total_jumps : `int`
      Total number of jumps simulated
  
  tracked_intensity : `list[np.ndarray]`, size=n_nodes
      A record of the intensity with which this point process has been
      simulated.
      Note: you must call track_intensity before simulation to record it
  
  intensity_tracked_times : `np.ndarray`
      The times at which intensity has been recorded.
      Note: you must call track_intensity before simulation to record it
  
  intensity_track_step : `float`
      Step with which the intensity has been recorded
docstr: Build sum-exponential kernels from adjacency and decays
          
code: def _build_sumexp_kernels(self):
      """Build sum-exponential kernels from adjacency and decays"""
      n_nodes = self.adjacency.shape[0]
  
      kernel_0 = HawkesKernel0()
      kernels = np.empty((n_nodes, n_nodes), dtype=object)
      for i, j in product(range(n_nodes), range(n_nodes)):
          kernel_intensities = self.adjacency[i, j, :]
          if all(kernel_intensities == 0):
              kernels[i, j] = kernel_0
          else:
              kernels[i, j] = HawkesKernelSumExp(
                  kernel_intensities, self.decays
              )
  
      return kernels
  
file_path: tick/tick/hawkes/simulation/simu_hawkes_sumexp_kernels.py
imports: from itertools import product
  import numpy
  from tick.hawkes.simulation import SimuHawkes
  from .hawkes_kernels import HawkesKernel0, HawkesKernelSumExp
label_desc: Use image node_id 3 for calling the SimuHawkesSumExpKernels obj's underlying member method code with example usage: obj._build_sumexp_kernels() and returns: kernels