docs: def get_qcqp_form(prob):
      """Returns the problem metadata in QCQP class
      """
      # Check quadraticity
      if not prob.objective.args[0].is_quadratic():
          raise Exception("Objective is not quadratic.")
      if not all([constr._expr.is_quadratic() for constr in prob.constraints]):
          raise Exception("Not all constraints are quadratic.")
      if prob.is_dcp():
          logging.warning("Problem is already convex; specifying solve method is unnecessary.")
  
      extractor = QuadCoeffExtractor(*get_id_map(prob.variables()))
  
      P0, q0, r0 = extractor.get_coeffs(prob.objective.args[0])
      # unpacking values
      P0, q0, r0 = (P0[0]+P0[0].T)/2., q0.T.tocsc(), r0[0]
  
      if prob.objective.NAME == "maximize":
          P0, q0, r0 = -P0, -q0, -r0
  
      f0 = QuadraticFunction(P0, q0, r0)
  
      fs = []
      for constr in prob.constraints:
          sz = constr._expr.size[0]*constr._expr.size[1]
          Pc, qc, rc = extractor.get_coeffs(constr._expr)
          for i in range(sz):
              fs.append(QuadraticFunction((Pc[i]+Pc[i].T)/2., qc[i, :].T.tocsc(), rc[i], constr.OP_NAME))
  
      return QCQPForm(f0, fs)