code: def optimize_restarts(self, num_restarts=10, robust=False, verbose=True, parallel=False, num_processes=None, **kwargs):
          initial_length = len(self.optimization_runs)
          initial_parameters = self.optimizer_array.copy()
          if parallel:
              try:
                  pool = mp.Pool(processes=num_processes)
                  obs = [self.copy() for i in range(num_restarts)]
                  [obs[i].randomize() for i in range(num_restarts-1)]
                  jobs = pool.map(opt_wrapper, [(o,kwargs) for o in obs])
                  pool.close()
                  pool.join()
              except KeyboardInterrupt:
                  print("Ctrl+c received, terminating and joining pool.")
                  pool.terminate()
                  pool.join()
          for i in range(num_restarts):
              try:
                  if not parallel:
                      if i > 0:
                          self.randomize()
                      self.optimize(**kwargs)
                  else:
                      self.optimization_runs.append(jobs[i])
                  if verbose:
                      print(("Optimization restart {0}/{1}, f = {2}".format(i + 1, num_restarts, self.optimization_runs[-1].f_opt)))
              except Exception as e:
                  if robust:
                      print(("Warning - optimization restart {0}/{1} failed".format(i + 1, num_restarts)))
                  else:
                      raise e
          if len(self.optimization_runs) > initial_length:
              i = np.argmin([o.f_opt for o in self.optimization_runs[initial_length:]])
              self.optimizer_array = self.optimization_runs[initial_length + i].x_opt
          else:
              self.optimizer_array = initial_parameters
          return self.optimization_runs