code: def test_convolve_functions():
      # replicate convolution
      # This is a square wave on (0,1)
      f1 = sympy.Piecewise((0, t <= 0), (1, t < 1), (0, True))
      # ff1 is the numerical implementation of same
      ff1 = lambdify(t, f1)
      # Time delta
      dt = 1e-3
      # Numerical convolution to test against
      # The convolution of ``f1`` with itself is a triangular wave on [0, 2],
      # peaking at 1 with height 1
      time, value = numerical_convolve(ff1, ff1, [0, 2], dt)
  
      # shells to wrap convolve kernel version
      def kern_conv1(
          f1, f2, f1_interval, f2_interval, dt, fill=0, name=None
      ):
          kern = TimeConvolver(f1, f1_interval, dt, fill)
          return kern.convolve(f2, f2_interval, name=name)
  
      def kern_conv2(
          f1, f2, f1_interval, f2_interval, dt, fill=0, name=None
      ):
          kern = TimeConvolver(f2, f2_interval, dt, fill)
          return kern.convolve(f1, f1_interval, name=name)
  
      for cfunc in (convolve_functions, kern_conv1, kern_conv2):
          tri = cfunc(f1, f1, [0, 2], [0, 2], dt, name="conv")
          assert str(tri) == "conv(t)"
          ftri = lambdify(t, tri)
          y = ftri(time)
          # numerical convolve about the same as ours
          assert_array_almost_equal(value, y)
          # peak is at 1
          assert_array_almost_equal(time[np.argmax(y)], 1)
          # Flip the interval and get the same result
          for seq1, seq2 in (
              ((0, 2), (2, 0)),
              ((2, 0), (0, 2)),
              ((2, 0), (2, 0)),
          ):
              tri = cfunc(f1, f1, seq1, seq2, dt)
              ftri = lambdify(t, tri)
              y = ftri(time)
              assert_array_almost_equal(value, y)
          # offset square wave by 1 - offset triangle by 1
          f2 = sympy.Piecewise((0, t <= 1), (1, t < 2), (0, True))
          tri = cfunc(f1, f2, [0, 3], [0, 3], dt)
          ftri = lambdify(t, tri)
          o1_time = np.arange(0, 3, dt)
          z1s = np.zeros(int(round(1.0 / dt)))
          assert_array_almost_equal(ftri(o1_time), np.r_[z1s, value])
          # Same for input function
          tri = cfunc(f2, f1, [0, 3], [0, 3], dt)
          ftri = lambdify(t, tri)
          assert_array_almost_equal(ftri(o1_time), np.r_[z1s, value])
          # 2 seconds for both
          tri = cfunc(f2, f2, [0, 4], [0, 4], dt)
          ftri = lambdify(t, tri)
          o2_time = np.arange(0, 4, dt)
          assert_array_almost_equal(
              ftri(o2_time), np.r_[z1s, z1s, value]
          )
          # offset by -0.5 - offset triangle by -0.5
          f3 = sympy.Piecewise((0, t <= -0.5), (1, t < 0.5), (0, True))
          tri = cfunc(f1, f3, [0, 2], [-0.5, 1.5], dt)
          ftri = lambdify(t, tri)
          o1_time = np.arange(-0.5, 1.5, dt)
          assert_array_almost_equal(ftri(o1_time), value)
          # Same for input function
          tri = cfunc(f3, f1, [-0.5, 1.5], [0, 2], dt)
          ftri = lambdify(t, tri)
          assert_array_almost_equal(ftri(o1_time), value)
          # -1 second for both
          tri = cfunc(f3, f3, [-0.5, 1.5], [-0.5, 1.5], dt)
          ftri = lambdify(t, tri)
          o2_time = np.arange(-1, 1, dt)
          assert_array_almost_equal(ftri(o2_time), value)
          # Check it's OK to be off the dt grid
          tri = cfunc(
              f1, f1, [dt / 2, 2 + dt / 2], [0, 2], dt, name="conv"
          )
          ftri = lambdify(t, tri)
          assert_array_almost_equal(ftri(time), value, 3)
          # Check fill value
          nan_tri = cfunc(f1, f1, [0, 2], [0, 2], dt, fill=np.nan)
          nan_ftri = lambdify(t, nan_tri)
          y = nan_ftri(time)
          assert_array_equal(y, value)
          assert np.all(np.isnan(nan_ftri(np.arange(-2, 0))))
          assert np.all(np.isnan(nan_ftri(np.arange(4, 6))))
          # The original fill value was 0
          assert_array_equal(ftri(np.arange(-2, 0)), 0)
          assert_array_equal(ftri(np.arange(4, 6)), 0)
  
imports: import re
  import numpy
  import pytest
  import sympy
  from numpy.testing import assert_almost_equal, assert_array_almost_equal, assert_array_equal
  from sympy import DiracDelta, Dummy, Function, Symbol
  from sympy.utilities.lambdify import implemented_function, lambdify
  from nipy.algorithms.statistics.formula import Term
  from ..None import hrf
  from ..utils import Interp1dNumeric, TimeConvolver, blocks, convolve_functions, define, events, interp, lambdify_t, linear_interp, step_function
label_desc: Use image node_id 8 for calling a global function with example usage: test_convolve_functions() and returns: kern, kern