docs: def _parse_quadratic_expression(expression, expanded=False):
      """
      Parse a quadratic expression. It is assumed that the expression is known to be quadratic or linear.
  
      The 'expanded' parameter tells whether the expression has already been expanded. If it hasn't the parsing
      might fail and will expand the expression and try again.
      """
      linear_coefficients = {}
      quadratic_coefficients = {}
      offset = 0
  
      if expression.is_Number:  # Constant expression, no coefficients
          return float(expression), linear_coefficients, quadratic_coefficients
  
      if expression.is_Mul:
          terms = (expression,)
      elif expression.is_Add:
          terms = expression.args
      else:
          raise ValueError("Expression of type {} could not be parsed.".format(type(expression)))
  
      try:
          for term in terms:
              if term.is_Number:
                  offset += float(term)
                  continue
              if term.is_Pow:
                  term = 1.0 * term
              assert term.is_Mul, "What is this? {}".format(type(term))
              factors = term.args
              coef = factors[0]
              vars = factors[1:]
              assert len(vars) <= 2, "This should not happen. Is this expression quadratic?"
              if len(vars) == 2:
                  key = frozenset(vars)
                  quadratic_coefficients[key] = quadratic_coefficients.get(key, 0) + coef
              else:
                  var = vars[0]
                  if var.is_Symbol:
                      linear_coefficients[var] = linear_coefficients.get(var, 0) + coef
                  elif var.is_Pow:
                      var, exponent = var.args
                      if exponent != 2:
                          raise ValueError("The expression is not quadratic")
                      key = frozenset((var,))
                      quadratic_coefficients[key] = quadratic_coefficients.get(key, 0) + coef
          if quadratic_coefficients:
              assert all(var.is_Symbol for var in frozenset.union(*quadratic_coefficients))  # Raise an exception to trigger expand
          if linear_coefficients:
              assert all(var.is_Symbol for var in linear_coefficients)
      except Exception as e:
          if expanded:
              raise e
          else:
              # Try to expand the expression and parse it again
              return _parse_quadratic_expression(expression.expand(), expanded=True)
  
      return offset, linear_coefficients, quadratic_coefficients