class_docstr: DualFormulation is a class that creates the dual objective function
  and access to matrix vector products for the matrix that is constrained
  to be Positive semidefinite
class_docstr_tok: ["DualFormulation","is","a","class","that","creates","the","dual","objective","function","and","access","to","matrix","vector","products","for","the","matrix","that","is","constrained","to","be","Positive","semidefinite"]
docstr: Function to compute the certificate based either current value
  or dual variables loaded from dual folder
docstr_tok: ["Function","to","compute","the","certificate","based","either","current","value","or","dual","variables","loaded","from","dual","folder"]
code: def compute_certificate(self, current_step, feed_dictionary):
      """Function to compute the certificate based either current value
      or dual variables loaded from dual folder"""
      feed_dict = feed_dictionary.copy()
      nu = feed_dict[self.nu]
      second_term = self.make_m_psd(nu, feed_dict)
      tf.logging.info("Nu after modifying: " + str(second_term))
      feed_dict.update({self.nu: second_term})
      computed_certificate = self.sess.run(
          self.unconstrained_objective, feed_dict=feed_dict
      )
  
      tf.logging.info(
          "Inner step: %d, current value of certificate: %f",
          current_step,
          computed_certificate,
      )
  
      # Sometimes due to either overflow or instability in inverses,
      # the returned certificate is large and negative -- keeping a check
      if LOWER_CERT_BOUND < computed_certificate < 0:
          _, min_eig_val_m = self.get_lanczos_eig(feed_dict=feed_dict)
          tf.logging.info(
              "min eig val from lanczos: " + str(min_eig_val_m)
          )
          input_vector_m = tf.placeholder(
              tf.float32, shape=(self.matrix_m_dimension, 1)
          )
          output_vector_m = self.get_psd_product(input_vector_m)
  
          def np_vector_prod_fn_m(np_vector):
              np_vector = np.reshape(np_vector, [-1, 1])
              feed_dict.update({input_vector_m: np_vector})
              output_np_vector = self.sess.run(
                  output_vector_m, feed_dict=feed_dict
              )
              return output_np_vector
  
          linear_operator_m = LinearOperator(
              (self.matrix_m_dimension, self.matrix_m_dimension),
              matvec=np_vector_prod_fn_m,
          )
          # Performing shift invert scipy operation when eig val estimate is available
          min_eig_val_m_scipy, _ = eigs(
              linear_operator_m, k=1, which="SR", tol=TOL
          )
  
          tf.logging.info(
              "min eig val m from scipy: " + str(min_eig_val_m_scipy)
          )
  
          if min_eig_val_m - TOL > 0:
              tf.logging.info("Found certificate of robustness!")
              return True
  
      return False
  
file_path: cleverhans/cleverhans/experimental/certification/dual_formulation.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from scipy.sparse.linalg import eigs, LinearOperator
  import tensorflow
  from tensorflow.contrib import autograph
  import numpy
  from cleverhans.experimental.certification import utils
label_desc: Use image node_id 10 for calling the DualFormulation obj's underlying member method code with example usage: obj.compute_certificate(current_step, feed_dictionary) and returns: False, output_np_vector, True