def implicit_solve(self, next_x, func, method="hybr", **kwargs): """A solver for implicit equations. Finds the implicitly defined :math:`x_{i+1}` for the given right hand side function :math:`f(x_{i+1})`, such that :math:`x_{i+1}=f(x_{i+1})`. Parameters ---------- next_x : :py:class:`numpy.ndarray` A starting guess for the implicitly defined value. rhs_call : :py:class:`callable` The right hand side function depending on the implicitly defined new value. method : :py:class:`str` *(optional, default=``hybr``)* Method fo the root finding algorithm. See `scipy.optimize.root <http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.root.html#scipy.optimize.root>` for details. Returns ------- next_x : :py:class:`numpy.ndarray` The calculated new value. Raises ------ ValueError : * if ``next_x`` is not a :py:class:`numpy.ndarray` of shape :py:attr:`.IProblem.dim` * if ``fun`` is not :py:class:`callable` * if computed solution is not a `:py:class:`numpy.ndarray` UserWarning : If the implicit solver did not converged, i.e. the solution object's ``success`` is not :py:class:`True`. """ assert_is_instance(next_x, np.ndarray, descriptor="Initial Guess", checking_obj=self) assert_is_callable(func, descriptor="Function of RHS for Implicit Solver", checking_obj=self) sol = find_root(fun=func, x0=next_x.reshape(-1), method=method) if not sol.success: warnings.warn("Implicit solver did not converged.") LOG.debug("sol.x: %s" % sol.x) LOG.error("Implicit solver failed: %s" % sol.message) else: assert_is_instance(sol.x, np.ndarray, descriptor="Solution", checking_obj=self) return sol.x.reshape(self.dim_for_time_solver)
def testSimpleRoot(self): _func = lambda x: np.array([-1.0 + 1.0j, -1.0], dtype=np.complex) + x _in_x = np.array([0.0, 0.0], dtype=np.complex) _sol = find_root(_func, _in_x) self.assertTrue(_sol.success) self.assertNumpyArrayAlmostEqual(_sol.x, np.array([1.0 - 1.0j, 1.0], dtype=np.complex))