{ "info": { "author": "Reuben Rusk", "author_email": "pythoro@mindquip.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "# npsolve\n\nMany numerical solvers (like those in scipy) provide candidate solutions as a numpy array. They often also require a numpy array as a return value (e.g. an array of derivatives) during the solution. These requirements can make it difficult to use an object oriented approach to performing the calculations. \n\nThe *npsolve* package is a small, simple package built on *numpy* and *fastwire* to make it easy to use object-oriented code for the calculation step for numerical solvers.\n\n\n## Basic usage tutorial\n\n\nFirst, setup some classes that you want to do calculations with. We do this by using the *add_var* method to setup variables and their initial values.\n\n```python\n\nimport numpy as np\nimport npsolve\n\nclass Component1(npsolve.Partial):\n def __init__(self):\n super().__init__() # Don't forget to call this!\n self.add_var('position', init=0.1)\n self.add_var('velocity', init=0.3)\n \nclass Component2(npsolve.Partial):\n def __init__(self):\n super().__init__() # Don't forget to call this!\n self.add_var('force', init=-0.1)\n\n```\n\nNext override the *set_vectors* method to store views you might want. In this case, we'll just save the variables as attributes. Note that these are actually views, that are automatically updated by the solver. We'll do it differently with Component2.\n\n```python\n\n\nclass Component1(npsolve.Partial):\n def __init__(self):\n super().__init__() # Don't forget to call this!\n self.add_var('position', init=0.1)\n self.add_var('velocity', init=0.3)\n \n def set_vectors(self, state_dct, ret_dct):\n ''' Set some state views for use during calculations '''\n self.position = state_dct['position']\n self.velocity = state_dct['velocity']\n self.force = state_dct['force']\n \n\nclass Component2(npsolve.Partial):\n def __init__(self):\n super().__init__() # Don't forget to call this!\n self.add_var('force', init=-0.1)\n\n```\n\nNote that variables are made available to all Partial instances automatically.\n\nThen, we'll tell them how to do the calculations. The *step* method is called automatically and expects a dictionary of return values (e.g. derivatives). A dictionary of the current state values is provided (again), but we're going to use the views we set in the *set_vectors* method.\n\n```python\n\nclass Component1(npsolve.Partial):\n def __init__(self):\n super().__init__() # Don't forget to call this!\n self.add_var('position', init=0.1)\n self.add_var('velocity', init=0.3)\n \n def set_vectors(self, state_dct, ret_dct):\n ''' Set some state views for use during calculations '''\n self.position = state_dct['position']\n self.velocity = state_dct['velocity']\n self.force = state_dct['force']\n \n def step(self, state_dct, *args):\n ''' Called by the solver at each time step \n Calculate acceleration based on the \n '''\n acceleration = 1.0 * self.force\n derivatives = {'position': self.velocity,\n 'velocity': acceleration}\n return derivatives\n\t\t\n\nclass Component2(npsolve.Partial):\n def __init__(self):\n super().__init__() # Don't forget to call this!\n self.add_var('force', init=-0.1)\n\n def calculate(self, state_dct, t):\n ''' Some arbitrary calculations based on current time t\n and the position at that time calculated in Component1.\n This returns a derivative for variable 'c'\n '''\n dc = 1.0 * np.cos(2*t) * state_dct['position']\n derivatives = {'force': dc}\n return derivatives\n \n def step(self, state_dct, t, *args):\n ''' Called by the solver at each time step '''\n return self.calculate(state_dct, t)\n \n\t\t\n```\n\nNow, we'll set up the solver. By default, Solvers have a *step* method that's ready to use, and after initialisation, the initial values set by the Partial classes are captured in the *npsolve_initial_values* attribute. By default, the Solver's *step* method returns a vector of all the return values, the same size as the Solver's npsolve_initial_values array.\n\n\n```python\n\nfrom scipy.integrate import odeint\n\nclass Solver(npsolve.Solver):\n def solve(self):\n self.t_vec = np.linspace(0, 5, 1001)\n result = odeint(self.step, self.npsolve_initial_values, self.t_vec)\n return result\n```\n\n\nTo run, we just have to instantiate the Solver before the Partials that use it, then call the *npsolve_init* method. It doesn't matter where in the code we create the Solver and Partial instances - they'll link up automatically through *fastwire*.\n\n\n```python\n\ndef run():\n s = Solver()\n c1 = Component1()\n c2 = Component2()\n\t\n\t# Now we connect the components\n s.setup_signals() # Always call this before calling connect on the Partial classes.\n c1.connect()\n c2.connect()\n\t\n\t# Get the solver ready\n s.npsolve_init()\n\t\n # Now we can run!\n res = s.solve()\n return res, s\n\n```\n\nLet's set up a plot to see the results. Use the *npsolve_slices* attribute of the Solver to get the right columns.\n\n```python\n\ndef plot(res, s):\n slices = s.npsolve_slices\n \n plt.plot(s.t_vec, res[:,slices['position']], label='position')\n plt.plot(s.t_vec, res[:,slices['velocity']], label='velocity')\n plt.plot(s.t_vec, res[:,slices['force']], label='force')\n plt.legend()\n\n```\n\nRun it and see what happens!\n\n```python\n\nres, s = run()\nplot(res, s)\n\n```", "description_content_type": "text/markdown", "docs_url": null, "download_url": "https://github.com/pythoro/npsolve/archive/v0.0.2.zip", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/pythoro/npsolve.git", "keywords": "NUMERICAL SOLVER,NUMPY,SCIPY,ODE,INTEGRATION", "license": "", "maintainer": "", "maintainer_email": "", "name": "npsolve", "package_url": "https://pypi.org/project/npsolve/", "platform": "", "project_url": "https://pypi.org/project/npsolve/", "project_urls": { "Download": "https://github.com/pythoro/npsolve/archive/v0.0.2.zip", "Homepage": "https://github.com/pythoro/npsolve.git" }, "release_url": "https://pypi.org/project/npsolve/0.0.2/", "requires_dist": null, "requires_python": "", "summary": "Easier object-oriented calculations for numerical solvers.", "version": "0.0.2" }, "last_serial": 5769310, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "a14aee1f73819649c70b9263105e6251", "sha256": "7bfea301fb57f62a3f26764acfec5cee7429b0a6d754dfed7b2bc4704131a1e9" }, "downloads": -1, "filename": "npsolve-0.0.1.tar.gz", "has_sig": false, "md5_digest": "a14aee1f73819649c70b9263105e6251", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8118, "upload_time": "2019-09-02T06:43:43", "url": "https://files.pythonhosted.org/packages/2e/30/0dc69d9c7b0cf1ead4e7aec7ef00c7e7d87f26a90e1765a157bc26ddf122/npsolve-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "ba07873f960ae091f405f0220abd0d07", "sha256": "1ff14a1b7a08fadbe27025db71ad5abaa783ccd023cd001828756383771840cc" }, "downloads": -1, "filename": "npsolve-0.0.2.tar.gz", "has_sig": false, "md5_digest": "ba07873f960ae091f405f0220abd0d07", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8326, "upload_time": "2019-09-02T07:14:29", "url": "https://files.pythonhosted.org/packages/73/ec/37563fffe3530a83a84b9ed171e8ac4cd57c188db9f14ab1d60a7d792f71/npsolve-0.0.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ba07873f960ae091f405f0220abd0d07", "sha256": "1ff14a1b7a08fadbe27025db71ad5abaa783ccd023cd001828756383771840cc" }, "downloads": -1, "filename": "npsolve-0.0.2.tar.gz", "has_sig": false, "md5_digest": "ba07873f960ae091f405f0220abd0d07", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8326, "upload_time": "2019-09-02T07:14:29", "url": "https://files.pythonhosted.org/packages/73/ec/37563fffe3530a83a84b9ed171e8ac4cd57c188db9f14ab1d60a7d792f71/npsolve-0.0.2.tar.gz" } ] }