code: def test_raf_form_constraints():
      """Tests ReconcileAdditiveForecasts _form_constraints"""
      levels = [[2]]
      tree = HierarchicalRelationship(levels)
      m = tree.num_nodes
      transform_variable = cp.Variable((m, m))
      # actuals that satisfy the constraints, each row is a timeseries
      Ya = np.array(
          [
              [2.0, 3.0, 5.0, 8.0],
              [1.0, 2.0, 3.0, 4.0],
              [1.0, 1.0, 2.0, 4.0],
          ]
      )
  
      # `Ya` is None, unbiased=False, no upper/lower bound, constraint_matrix
      raf = ReconcileAdditiveForecasts()
      raf.constraint_matrix = tree.constraint_matrix
      raf.unbiased = False
      raf.lower_bound = None
      raf.upper_bound = None
      constraints = raf._form_constraints(
          transform_variable=transform_variable, Ya=None
      )
      assert len(constraints) == 1
      assert [c.is_dcp() for c in constraints]
      constraint = constraints[0]
      assert (
          constraint.atoms()[0]
          == cp.atoms.affine.binary_operators.MulExpression
      )
      assert_equal(
          constraint.constants()[0].value, raf.constraint_matrix
      )
      assert_equal(constraint.constants()[1].value, np.array([0]))
  
      # `Ya` is not None, unbiased=True, constraint_matrix
      raf = ReconcileAdditiveForecasts()
      raf.constraint_matrix = tree.constraint_matrix
      raf.unbiased = True
      raf.lower_bound = None
      raf.upper_bound = None
      constraints = raf._form_constraints(
          transform_variable=transform_variable, Ya=Ya
      )
      assert len(constraints) == 2
      assert [c.is_dcp() for c in constraints]
      assert_equal(constraints[1].constants()[0].value, Ya)
      assert_equal(constraints[1].constants()[1].value, Ya)
  
      # `Ya` is not None, unbiased=True, upper/lower bound, tree
      raf = ReconcileAdditiveForecasts()
      raf.unbiased = True
      raf.tree = tree
      raf.constraint_matrix = np.zeros_like(tree.constraint_matrix)
      raf.lower_bound = -1.0
      raf.upper_bound = 1.0
      constraints = raf._form_constraints(
          transform_variable=transform_variable, Ya=Ya
      )
      assert len(constraints) == 4
      assert_equal(
          constraints[0].constants()[0].value, np.array(raf.lower_bound)
      )
      assert_equal(
          constraints[1].constants()[0].value, np.array(raf.upper_bound)
      )
      assert_equal(
          constraints[2].constants()[0].value,
          np.array(raf.tree.constraint_matrix),
      )  # prefers raf.tree.constraint_matrix
      assert_equal(
          constraints[3].constants()[0].value,
          np.array(raf.tree.sum_matrix),
      )
      assert_equal(
          constraints[3].constants()[1].value,
          np.array(raf.tree.sum_matrix),
      )
  
      with pytest.warns(
          UserWarning, match="Actuals do not satisfy the constraints!"
      ):
          Ya[0] += 1.0
          raf._form_constraints(
              transform_variable=transform_variable, Ya=Ya
          )
  
      with pytest.raises(
          ValueError,
          match="`Ya` must be provided if `unbiased` and `tree` is None.",
      ):
          raf.tree = None
          raf._form_constraints(
              transform_variable=transform_variable, Ya=None
          )
  
imports: import math
  import os
  import warnings
  import cvxpy
  import numpy
  import pandas
  import pytest
  from scipy.linalg import sqrtm
  from sklearn.exceptions import NotFittedError
  from greykite.algo.reconcile.convex.reconcile_forecasts import ReconcileAdditiveForecasts
  from greykite.algo.reconcile.convex.reconcile_forecasts import TraceInfo
  from greykite.algo.reconcile.convex.reconcile_forecasts import apply_method_defaults
  from greykite.algo.reconcile.convex.reconcile_forecasts import evaluation_plot
  from greykite.algo.reconcile.convex.reconcile_forecasts import get_fit_params
  from greykite.algo.reconcile.convex.reconcile_forecasts import get_weight_matrix
  from greykite.algo.reconcile.hierarchical_relationship import HierarchicalRelationship
  from greykite.common.constants import TIME_COL
  from greykite.common.data_loader import DataLoader
  from greykite.common.evaluation import mean_absolute_percent_error
  from greykite.common.evaluation import median_absolute_percent_error
  from greykite.common.evaluation import root_mean_squared_error
  from greykite.common.python_utils import assert_equal
  from greykite.common.python_utils import reorder_columns
label_desc: Use image node_id 8 for calling a global function with example usage: test_raf_form_constraints() without return types