code: """
  @author: Maziar Raissi
  """
  
  import sys
  
  sys.path.insert(0, "../../Utilities/")
  
  import tensorflow as tf
  import numpy as np
  import time
  import scipy.io
  
  np.random.seed(1234)
  tf.set_random_seed(1234)
  
  
  class PhysicsInformedNN:
      # Initialize the class
      def __init__(self, x0, u0, x1, layers, dt, lb, ub, q):
  
          self.lb = lb
          self.ub = ub
  
          self.x0 = x0
          self.x1 = x1
  
          self.u0 = u0
  
          self.layers = layers
          self.dt = dt
          self.q = max(q, 1)
  
          # Initialize NN
          self.weights, self.biases = self.initialize_NN(layers)
  
          # Load IRK weights
          tmp = np.float32(
              np.loadtxt("../../Utilities/IRK_weights/Butcher_IRK%d.txt" % (q), ndmin=2)
          )
          self.IRK_weights = np.reshape(tmp[0 : q ** 2 + q], (q + 1, q))
          self.IRK_times = tmp[q ** 2 + q :]
  
          # tf placeholders and graph
          self.sess = tf.Session(
              config=tf.ConfigProto(allow_soft_placement=True, log_device_placement=True)
          )
  
          self.x0_tf = tf.placeholder(tf.float32, shape=(None, self.x0.shape[1]))
          self.x1_tf = tf.placeholder(tf.float32, shape=(None, self.x1.shape[1]))
          self.u0_tf = tf.placeholder(tf.float32, shape=(None, self.u0.shape[1]))
          self.dummy_x0_tf = tf.placeholder(
              tf.float32, shape=(None, self.q)
          )  # dummy variable for fwd_gradients
          self.dummy_x1_tf = tf.placeholder(
              tf.float32, shape=(None, self.q + 1)
          )  # dummy variable for fwd_gradients
  
          self.U0_pred = self.net_U0(self.x0_tf)  # N x (q+1)
          self.U1_pred = self.net_U1(self.x1_tf)  # N1 x (q+1)
  
          self.loss = tf.reduce_sum(tf.square(self.u0_tf - self.U0_pred)) + tf.reduce_sum(
              tf.square(self.U1_pred)
          )
  
          self.optimizer = tf.contrib.opt.ScipyOptimizerInterface(
              self.loss,
              method="L-BFGS-B",
              options={
                  "maxiter": 50000,
                  "maxfun": 50000,
                  "maxcor": 50,
                  "maxls": 50,
                  "ftol": 1.0 * np.finfo(float).eps,
              },
          )
  
          self.optimizer_Adam = tf.train.AdamOptimizer()
          self.train_op_Adam = self.optimizer_Adam.minimize(self.loss)
  
          init = tf.global_variables_initializer()
          self.sess.run(init)
  
      def initialize_NN(self, layers):
          weights = []
          biases = []
          num_layers = len(layers)
          for l in range(0, num_layers - 1):
              W = self.xavier_init(size=[layers[l], layers[l + 1]])
              b = tf.Variable(
                  tf.zeros([1, layers[l + 1]], dtype=tf.float32), dtype=tf.float32
              )
              weights.append(W)
              biases.append(b)
          return weights, biases
  
      def xavier_init(self, size):
          in_dim = size[0]
          out_dim = size[1]
          xavier_stddev = np.sqrt(2 / (in_dim + out_dim))
          return tf.Variable(
              tf.truncated_normal([in_dim, out_dim], stddev=xavier_stddev),
              dtype=tf.float32,
          )
  
      def neural_net(self, X, weights, biases):
          num_layers = len(weights) + 1
  
          H = 2.0 * (X - self.lb) / (self.ub - self.lb) - 1.0
          for l in range(0, num_layers - 2):
              W = weights[l]
              b = biases[l]
              H = tf.tanh(tf.add(tf.matmul(H, W), b))
          W = weights[-1]
          b = biases[-1]
          Y = tf.add(tf.matmul(H, W), b)
          return Y
  
      def fwd_gradients_0(self, U, x):
          g = tf.gradients(U, x, grad_ys=self.dummy_x0_tf)[0]
          return tf.gradients(g, self.dummy_x0_tf)[0]
  
      def fwd_gradients_1(self, U, x):
          g = tf.gradients(U, x, grad_ys=self.dummy_x1_tf)[0]
          return tf.gradients(g, self.dummy_x1_tf)[0]
  
      def net_U0(self, x):
          nu = 0.01 / np.pi
          U1 = self.neural_net(x, self.weights, self.biases)
          U = U1[:, :-1]
          U_x = self.fwd_gradients_0(U, x)
          U_xx = self.fwd_gradients_0(U_x, x)
          F = -U * U_x + nu * U_xx
          U0 = U1 - self.dt * tf.matmul(F, self.IRK_weights.T)
          return U0
  
      def net_U1(self, x):
          U1 = self.neural_net(x, self.weights, self.biases)
          return U1  # N x (q+1)
  
      def callback(self, loss):
          print("Loss:", loss)
  
      def train(self, nIter):
          tf_dict = {
              self.x0_tf: self.x0,
              self.u0_tf: self.u0,
              self.x1_tf: self.x1,
              self.dummy_x0_tf: np.ones((self.x0.shape[0], self.q)),
              self.dummy_x1_tf: np.ones((self.x1.shape[0], self.q + 1)),
          }
  
          start_time = time.time()
          for it in range(nIter):
              self.sess.run(self.train_op_Adam, tf_dict)
  
              # Print
              if it % 10 == 0:
                  elapsed = time.time() - start_time
                  loss_value = self.sess.run(self.loss, tf_dict)
                  print("It: %d, Loss: %.3e, Time: %.2f" % (it, loss_value, elapsed))
                  start_time = time.time()
  
          self.optimizer.minimize(
              self.sess,
              feed_dict=tf_dict,
              fetches=[self.loss],
              loss_callback=self.callback,
          )
  
      def predict(self, x_star):
  
          U1_star = self.sess.run(self.U1_pred, {self.x1_tf: x_star})
  
          return U1_star
  
  
  def main_loop(q, skip, num_layers, num_neurons):
  
      layers = (
          np.concatenate([[1], num_neurons * np.ones(num_layers), [q + 1]])
          .astype(int)
          .tolist()
      )
  
      lb = np.array([-1.0])
      ub = np.array([1.0])
  
      N = 250
  
      data = scipy.io.loadmat("../Data/burgers_shock.mat")
  
      t = data["t"].flatten()[:, None]  # T x 1
      x = data["x"].flatten()[:, None]  # N x 1
      Exact = np.real(data["usol"]).T  # T x N
  
      idx_t0 = 10
      idx_t1 = idx_t0 + skip
      dt = t[idx_t1] - t[idx_t0]
  
      # Initial data
      noise_u0 = 0.0
      idx_x = np.random.choice(Exact.shape[1], N, replace=False)
      x0 = x[idx_x, :]
      u0 = Exact[idx_t0 : idx_t0 + 1, idx_x].T
      u0 = u0 + noise_u0 * np.std(u0) * np.random.randn(u0.shape[0], u0.shape[1])
  
      # Boudanry data
      x1 = np.vstack((lb, ub))
  
      # Test data
      x_star = x
  
      model = PhysicsInformedNN(x0, u0, x1, layers, dt, lb, ub, q)
      model.train(10000)
  
      U1_pred = model.predict(x_star)
  
      error = np.linalg.norm(U1_pred[:, -1] - Exact[idx_t1, :], 2) / np.linalg.norm(
          Exact[idx_t1, :], 2
      )
  
      return error
  
  
  if __name__ == "__main__":
  
      q = [1, 2, 4, 8, 16, 32, 64, 100, 500]
      skip = [20, 40, 60, 80]
  
      num_layers = [1, 2, 3]
      num_neurons = [10, 25, 50]
  
      error_table_1 = np.zeros((len(q), len(skip)))
      error_table_2 = np.zeros((len(num_layers), len(num_neurons)))
  
      for i in range(len(q)):
          for j in range(len(skip)):
              error_table_1[i, j] = main_loop(
                  q[i], skip[j], num_layers[-1], num_neurons[-1]
              )
  
      for i in range(len(num_layers)):
          for j in range(len(num_neurons)):
              error_table_2[i, j] = main_loop(
                  q[-1], skip[-1], num_layers[i], num_neurons[j]
              )
  
      np.savetxt(
          "./tables/error_table_1.csv",
          error_table_1,
          delimiter=" & ",
          fmt="$%.2e$",
          newline=" \\\\\n",
      )
      np.savetxt(
          "./tables/error_table_2.csv",
          error_table_2,
          delimiter=" & ",
          fmt="$%.2e$",
          newline=" \\\\\n",
      )
  
apis: numpy.sqrt tensorflow.zeros numpy.vstack numpy.random.randn tensorflow.train.AdamOptimizer numpy.reshape tensorflow.gradients numpy.finfo tensorflow.ConfigProto numpy.real numpy.std tensorflow.square tensorflow.matmul tensorflow.truncated_normal numpy.random.choice tensorflow.placeholder tensorflow.global_variables_initializer tensorflow.set_random_seed numpy.savetxt numpy.array numpy.random.seed numpy.linalg.norm numpy.ones numpy.loadtxt
api_extract: [(7, 'sys.path.insert', 'sys.path.insert', (['(0)', '"""../../Utilities/"""'], {}), False, 'import sys\n'), (14, 'numpy.random.seed', 'np.random.seed', (['(1234)'], {}), True, 'import numpy as np\n'), (15, 'tensorflow.set_random_seed', 'tf.set_random_seed', (['(1234)'], {}), True, 'import tensorflow as tf\n'), (186, 'numpy.array', 'np.array', (['[-1.0]'], {}), True, 'import numpy as np\n'), (187, 'numpy.array', 'np.array', (['[1.0]'], {}), True, 'import numpy as np\n'), (203, 'numpy.random.choice', 'np.random.choice', (['Exact.shape[1]', 'N'], {'replace': '(False)'}), True, 'import numpy as np\n'), (209, 'numpy.vstack', 'np.vstack', (['(lb, ub)'], {}), True, 'import numpy as np\n'), (249, 'numpy.savetxt', 'np.savetxt', (['"""./tables/error_table_1.csv"""', 'error_table_1'], {'delimiter': '""" & """', 'fmt': '"""$%.2e$"""', 'newline': '""" \\\\\\\\\n"""'}), True, 'import numpy as np\n'), (256, 'numpy.savetxt', 'np.savetxt', (['"""./tables/error_table_2.csv"""', 'error_table_2'], {'delimiter': '""" & """', 'fmt': '"""$%.2e$"""', 'newline': '""" \\\\\\\\\n"""'}), True, 'import numpy as np\n'), (41, 'numpy.reshape', 'np.reshape', (['tmp[0:q ** 2 + q]', '(q + 1, q)'], {}), True, 'import numpy as np\n'), (49, 'tensorflow.placeholder', 'tf.placeholder', (['tf.float32'], {'shape': '(None, self.x0.shape[1])'}), True, 'import tensorflow as tf\n'), (50, 'tensorflow.placeholder', 'tf.placeholder', (['tf.float32'], {'shape': '(None, self.x1.shape[1])'}), True, 'import tensorflow as tf\n'), (51, 'tensorflow.placeholder', 'tf.placeholder', (['tf.float32'], {'shape': '(None, self.u0.shape[1])'}), True, 'import tensorflow as tf\n'), (52, 'tensorflow.placeholder', 'tf.placeholder', (['tf.float32'], {'shape': '(None, self.q)'}), True, 'import tensorflow as tf\n'), (55, 'tensorflow.placeholder', 'tf.placeholder', (['tf.float32'], {'shape': '(None, self.q + 1)'}), True, 'import tensorflow as tf\n'), (78, 'tensorflow.train.AdamOptimizer', 'tf.train.AdamOptimizer', ([], {}), True, 'import tensorflow as tf\n'), (81, 'tensorflow.global_variables_initializer', 'tf.global_variables_initializer', ([], {}), True, 'import tensorflow as tf\n'), (100, 'numpy.sqrt', 'np.sqrt', (['(2 / (in_dim + out_dim))'], {}), True, 'import numpy as np\n'), (153, 'time.time', 'time.time', ([], {}), False, 'import time\n'), (195, 'numpy.real', 'np.real', (["data['usol']"], {}), True, 'import numpy as np\n'), (219, 'numpy.linalg.norm', 'np.linalg.norm', (['(U1_pred[:, (-1)] - Exact[(idx_t1), :])', '(2)'], {}), True, 'import numpy as np\n'), (219, 'numpy.linalg.norm', 'np.linalg.norm', (['Exact[(idx_t1), :]', '(2)'], {}), True, 'import numpy as np\n'), (39, 'numpy.loadtxt', 'np.loadtxt', (["('../../Utilities/IRK_weights/Butcher_IRK%d.txt' % q)"], {'ndmin': '(2)'}), True, 'import numpy as np\n'), (102, 'tensorflow.truncated_normal', 'tf.truncated_normal', (['[in_dim, out_dim]'], {'stddev': 'xavier_stddev'}), True, 'import tensorflow as tf\n'), (116, 'tensorflow.matmul', 'tf.matmul', (['H', 'W'], {}), True, 'import tensorflow as tf\n'), (120, 'tensorflow.gradients', 'tf.gradients', (['U', 'x'], {'grad_ys': 'self.dummy_x0_tf'}), True, 'import tensorflow as tf\n'), (121, 'tensorflow.gradients', 'tf.gradients', (['g', 'self.dummy_x0_tf'], {}), True, 'import tensorflow as tf\n'), (124, 'tensorflow.gradients', 'tf.gradients', (['U', 'x'], {'grad_ys': 'self.dummy_x1_tf'}), True, 'import tensorflow as tf\n'), (125, 'tensorflow.gradients', 'tf.gradients', (['g', 'self.dummy_x1_tf'], {}), True, 'import tensorflow as tf\n'), (149, 'numpy.ones', 'np.ones', (['(self.x0.shape[0], self.q)'], {}), True, 'import numpy as np\n'), (150, 'numpy.ones', 'np.ones', (['(self.x1.shape[0], self.q + 1)'], {}), True, 'import numpy as np\n'), (206, 'numpy.random.randn', 'np.random.randn', (['u0.shape[0]', 'u0.shape[1]'], {}), True, 'import numpy as np\n'), (46, 'tensorflow.ConfigProto', 'tf.ConfigProto', ([], {'allow_soft_placement': '(True)', 'log_device_placement': '(True)'}), True, 'import tensorflow as tf\n'), (62, 'tensorflow.square', 'tf.square', (['(self.u0_tf - self.U0_pred)'], {}), True, 'import tensorflow as tf\n'), (63, 'tensorflow.square', 'tf.square', (['self.U1_pred'], {}), True, 'import tensorflow as tf\n'), (91, 'tensorflow.zeros', 'tf.zeros', (['[1, layers[l + 1]]'], {'dtype': 'tf.float32'}), True, 'import tensorflow as tf\n'), (134, 'tensorflow.matmul', 'tf.matmul', (['F', 'self.IRK_weights.T'], {}), True, 'import tensorflow as tf\n'), (162, 'time.time', 'time.time', ([], {}), False, 'import time\n'), (206, 'numpy.std', 'np.std', (['u0'], {}), True, 'import numpy as np\n'), (113, 'tensorflow.matmul', 'tf.matmul', (['H', 'W'], {}), True, 'import tensorflow as tf\n'), (159, 'time.time', 'time.time', ([], {}), False, 'import time\n'), (74, 'numpy.finfo', 'np.finfo', (['float'], {}), True, 'import numpy as np\n'), (181, 'numpy.ones', 'np.ones', (['num_layers'], {}), True, 'import numpy as np\n')]