{"id":1448,"date":"2018-09-05T17:05:00","date_gmt":"2018-09-05T17:05:00","guid":{"rendered":"https:\/\/nag.com\/?post_type=insights&#038;p=1257"},"modified":"2023-07-05T12:14:04","modified_gmt":"2023-07-05T12:14:04","slug":"the-making-of-the-new-nag-library-for-python-with-usage-tutorials","status":"publish","type":"insights","link":"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/","title":{"rendered":"The Making of the New <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Library for <em>Python<\/em>, With Usage Tutorials"},"content":{"rendered":"<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>We have a new Python package for accessing the <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Library. It has been a few person-years in the making and is a substantial improvement over its predecessors in terms of usability.<\/p>\n<p>This post splits into two sections: <a href=\"#Background\">the first<\/a>\u00a0covers some technical details, history and context about what&#8217;s happened behind the scenes with the package;\u00a0<a href=\"#Code-Examples\">the second<\/a>\u00a0jumps into some examples of how to use it.<\/p>\n<h3 id=\"Background\">Background<\/h3>\n<h4>Previous Offerings<\/h4>\n<p>Earlier packages for accessing the <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Library from Python based themselves on the off-the-peg <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG C Library.<\/p>\n<p>The downside was that the result was still very much like using a C Library, but from Python (i.e., fairly unforgiving!). Particularly close to the metal were callback functions (where you had to supply Python callbacks having C signatures &#8230;) and the I\/O system (where you could interact solely with the spartan C-like default system used by the underlying compiled library). C header files were used as the source templates for the Python wrappers. The inherent tersity of these meant that incorrectly-shaped arrays supplied by the caller could not be detected at the Python level, instead they bubbled up from the bowels of the OS as scary illegal memory access crashes.<\/p>\n<p>In response to customer interest and feedback we decided to commit to an overhaul, to deliver a more Pythonic product.<\/p>\n<h4><span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Engine Technology<\/h4>\n<p>The <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Library is a single, growing, collection of mathematical and statistical algorithms. Initially provided for use from Fortran and subsequently also as native C interfaces, for many years these two products used two separate implementations of the same methods. Naturally that made it suboptimal to develop new features and to support existing ones.<\/p>\n<p>The <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Library Engine was introduced to unify the implementation of the algorithms into a single core, interoperable with ANSI C. For any language that can talk to ANSI C we can &#8216;wrap&#8217; the <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Engine with a minimal communication layer for marshalling between the user&#8217;s environment and the Engine API:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre><code>define optimization_foolang_wrapper(Array x, ...):\n   [...]\n   engine_x = EnsureContiguous(x);\n   New c_exit_struct();\n   Call nag_engine_optimizer(engine_x, ..., c_exit_struct);\n   c_exit_struct.handle_errors();<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>We document the Engine API using XML:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>&lt;param&gt;\n&lt;paramhead xid= \"X\" type= \"iarray\" class= \"I\" purpose= \"data\" \/&gt; \n   [...]<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>For reasons of interface mutability we do not make this API public; as new language environments come along we often need to expand the API in some way to assist communication with the Engine.<\/p>\n<p>The public interfaces you see in the <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG C Library or <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Toolbox\u00a0<i>for MATLAB<\/i>\u00ae, say, are just facets of the full superset Engine API. For each routine in the Library we encode a plethora of metadata which may or may not be discarded or made irrelevant depending on the language framework being targeted. For example: detailed loci for errors diagnosed in the Engine; or full metadata for an array shape that is expected by the Engine, extending in some cases to the shape that is actually used on entry or that is of interest to the user on exit:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>&lt;paramhead xid=\"V\" type=\"iarray\" class=\"IO\" purpose=\"data\"&gt;\n   &lt;dim1&gt;100&lt;\/dim1&gt;\n   &lt;dim1-input&gt;3&lt;\/dim1-input&gt;\n   &lt;input&gt;three algorithmic flags. The remainder of this array is used as workspace.&lt;\/input&gt;\n   &lt;dim1-output&gt;10&lt;\/dim1-output&gt;\n   &lt;output&gt;ten interesting iteration statistics.&lt;\/output&gt;\n&lt;\/paramhead&gt;<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>The implication there is that the interface for this algorithm could be created to require an array of length 3 on entry, expand it to 100 for the Engine to use, and return just the first 10 elements back to the caller, in a high-level language where this was appropriate.<\/p>\n<p>When we approach a language framework for the first time (or in the Python case, when we revisit it for a usability revamp) there is naturally a large amount of initial design work required to fill out how the user API is going to look. But once that has been agreed, when a new wrapper is needed for a particular Engine algorithm in that framework we can interrogate its XML and create some appropriate set of marshalling commands to get the user&#8217;s data between the two systems.<\/p>\n<p>It is very important to remember that some algorithms must return back to the user&#8217;s space\u00a0<em>during<\/em>\u00a0the course of their computations and not just on completion. This is usually when a supplied callback procedure is present (as with an objective function in optimization, for example). In recent years, as we began to supply access to the algorithmic Engine from languages that have rich I\/O systems, we also expanded the Engine API to allow Engine I\/O calls (e.g. for iteration monitoring) to call back to the user.<\/p>\n<p>Just as small wrapper layers manage the initial and final movement of data between the user and the Engine, we use &#8216;helper&#8217; procedures in an similar context for managing movement between a callback argument written in the user&#8217;s language and its invocation from within the Engine core:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>def cb_objfun(x, y, z):\n   \"\"\"\n   Wrapping the user's Python objfun.\n   Engine argument z is not required in the Python interface.\n   \"\"\"\n   y[:] = objfun(x.asndarray)\n[...]\nnag_engine_call(..., objfun_helper=cb_objfun, ...)<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>The moral is that to get the most usable interfaces in any given language context one must interface directly to the underlying Engine.<\/p>\n<h3 id=\"Intermediate-XML\">Intermediate XML<\/h3>\n<p>The original model we used to underpin the code generation for language wrappers was that the &#8216;root&#8217; XML contained annotations about\u00a0<em>where<\/em>\u00a0a piece of information was relevant.<\/p>\n<p>Consider language environment\u00a0<code>somelib<\/code>\u00a0(the only language we support that handles array sections\/slices) and an array that we can receive as a slice. In all other environments where there is no provision for slicing we need to make the array addressable using an increment; that is, whatever the operation in question is, it is performed on elements $1, 1+\\mathrm{incx}, 1+2*\\mathrm{incx},\\ldots$, say, of the array:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre><code>&lt;param&gt;\n  &lt;paramhead xid=\"INCX\" type=\"integer\" class=\"I\" purpose=\"index-increment\"\/&gt;\n  [...]\n&lt;\/param&gt;\n[...]\n&lt;param&gt;\n  &lt;paramhead xid=\"X\" type=\"iarray\" class=\"IO\" purpose=\"data\" omitlib=\"somelib\"&gt;\n    &lt;dim1&gt;max(1, 1+(&lt;arg&gt;N&lt;\/arg&gt;-1)*&lt;arg&gt;INCX&lt;\/arg&gt;)&lt;\/dim1&gt;\n  &lt;\/paramhead&gt;\n  &lt;paramhead xid=\"X\" type=\"iarray\" class=\"IO\" purpose=\"data\" lib=\"somelib\"&gt;\n    &lt;dim1&gt;&lt;arg&gt;N&lt;\/arg&gt;&lt;\/dim1&gt;\n  &lt;\/paramhead&gt;\n  [...]<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>By interfacing to more and higher-level languages in which design paradigms are repeated it is apparent that using\u00a0<em>where<\/em>\u00a0is not scalable. With the example above, once we start supporting calling the <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Library from Python (which allows slicing), then the\u00a0<code>somelib<\/code>\u00a0tags above need to be extended to also cover this case.<\/p>\n<p>We need instead to tag what happens\u00a0<em>when<\/em>\u00a0an entity or annotation is active:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\">&lt;param&gt;\n  &lt;paramhead xid=\"X\" type=\"iarray\" class=\"IO\" purpose=\"data\" when-arg=\"INCX\"&gt;\n    &lt;dim1&gt;max(1, 1+(&lt;arg&gt;N&lt;\/arg&gt;-1)*&lt;arg&gt;INCX&lt;\/arg&gt;)&lt;\/dim1&gt;\n  &lt;\/paramhead&gt;\n  &lt;paramhead xid=\"X\" type=\"iarray\" class=\"IO\" purpose=\"data\" not-when-arg=\"INCX\"&gt;\n    &lt;dim1&gt;&lt;arg&gt;N&lt;\/arg&gt;&lt;\/dim1&gt;\n  &lt;\/paramhead&gt;\n  [...]<\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>To collapse down the entirety of the multifaceted description in the root XML for code generation we run a series of filtering stylesheets which define the relevant characteristics of the outer and inner interfaces for the two &#8216;layers&#8217; we are interfacing between.<\/p>\n<p>In the example above, the Python filtering stylesheet may mark that it will be dropping arguments that have\u00a0<code>purpose=\"index-increment\"<\/code>\u00a0(because the language supports array sections), and hence it will make the\u00a0<code>not-when-arg=\"INCX\"<\/code>\u00a0element become active.<\/p>\n<p>After filtering, the resulting &#8216;intermediate&#8217; XML file is purely the information required for the layer pairing, and no more:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-12 col-lg-12 col-xl-12\">\n            <pre><code>&lt;params type=\"input\"&gt;\n   &lt;param interface=\"wrapper-input\" xid=\"x\" stype=\"int\" pclass=\"array\" class=\"I\" purpose=\"data\"&gt;\n      &lt;dim1&gt;:&lt;\/dim1&gt;\n   &lt;\/param&gt;\n&lt;\/params&gt;\n[...]<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>By annotating our XML so that it does not focus on specific language environments but more generally on language features we get a more future-proofed description of each API.<\/p>\n<h3 id=\"New-Package\">New Package<\/h3>\n<p>Our new <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Library for<i>\u00a0Python<\/i>\u00a0is intended to be intuitive, flexible and natural. We believe that there should be no need to spell out what it does from the Python viewpoint, because it should do everything you would expect it to. We are confident that it addresses the usability issues of the previous offerings.<\/p>\n<p>The Library interface collection is suppled by a\u00a0<code>library<\/code>\u00a0subpackage, which is a one-to-one provision of all algorithmics in a standard procedural form to match the set supplied by the traditional <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Libraries. We have been careful to build in space so that other encapsulations could be included in the future depending on demand &#8211; a subpackage for a specific vertical domain perhaps, or a certain object-oriented bundling suitable for use by a particular application.<\/p>\n<p>There are two points of technical interest that came up during the design of the new package.<\/p>\n<p>The <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Engine uses\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/Row-_and_column-major_order\" target=\"_blank\" rel=\"noopener\">column-major storage<\/a>\u00a0for multidimensional arrays. This is therefore the scheme you should use for your own data, for best efficiency. The NumPy default storage scheme is row-major, but the\u00a0<code>ndarray<\/code>\u00a0container supports either scheme. So for flexibility the new <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG interfaces support both schemes as well.<\/p>\n<p>We have added a unified transposition kernel to the <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Engine which can be activated for row-ordered input, so that the Engine-proper on input, and the caller on output, receives the correct view it is expecting of the data. The language wrapper (and consequently the code-generation framework that creates it) does not need to include any of the tranposition code, it merely decides when to ask the Engine to activate it:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>nag_engine_marshalling(do_transpose=True, a)\n[...]\ndefine nag_engine_marshalling(do_transpose, a):\n   [...]\n   if do_transpose\n      transposer(a, a_t);\n      nag_engine_proper(a_t);\n      transposer(a_t, a);\n   else\n      nag_engine_proper(a);<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Along similar lines we have &#8216;workspace allocation&#8217; handlers in the Engine too. In a user environment where workspace arrays in the Engine are suppressed from the caller\u2014which will usually be the case except for lower-level environments\u2014a single allocation handler can be triggered to set up workspace of the correct size without the language wrapper having to worry about the details:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>nag_engine_marshalling(alloc_work=True, wk=0)\n[...]\ndefine nag_engine_marshalling(alloc_work, wk_array):\n   [...]\n   if alloc_work\n      allocate(local_work(100));\n      nag_engine_proper(local_work);\n   else\n      nag_engine_proper(wk_array);<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>We&#8217;re hoping that all the innovations above can help us respond quicker to supplying <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG algorithmics in emerging environments and that they can ensure that what we do provide is as natural as possible.<\/p>\n<h3 id=\"Access\">Access<\/h3>\n<p>All the information on applicability, installation, and getting started can be found in the HTML documentation for the new package,\u00a0<a href=\"https:\/\/support.nag.com\/numeric\/py\/nagdoc_latest\/index.html\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n<p>Installation directly from the <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG website can be as simple as<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>pip install --extra-index-url https:\/\/www.<span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>ag.com\/downloads\/py\/naginterfaces_mkl naginterfaces<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <h3 id=\"Code-Examples\">Code Examples<\/h3>\n<p>Now we&#8217;ll take a look at some examples of using the new package. The emphasis is on how to access functionality from the Library, so the problems we are solving are fairly simplistic but good for illustrative purposes.<\/p>\n<p>We cover\u00a0<a href=\"#Surface-Fitting\" target=\"_blank\" rel=\"noopener\">surface fitting<\/a>,\u00a0<a href=\"#Global-Optimization\" target=\"_blank\" rel=\"noopener\">global optimization<\/a>,\u00a0<a href=\"#Quantile-Regression\" target=\"_blank\" rel=\"noopener\">quantile regression<\/a>,\u00a0<a href=\"#Kernel-Density-Estimation\" target=\"_blank\" rel=\"noopener\">kernel density estimation<\/a>\u00a0and\u00a0<a href=\"#Change-Point-Analysis\" target=\"_blank\" rel=\"noopener\">change point analysis<\/a>.<\/p>\n<h3 id=\"Surface-Fitting\">Surface Fitting<\/h3>\n<p>This first example fits a surface to some scattered data and plots the result.<\/p>\n<p>To begin, generate some scattered $(x, y)$ data, of a modest size for this example: 100 pseudorandom uniformly-distributed values on (0,1] using the Wichmann\u2013Hill I generator.<\/p>\n<p><span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG random number generators pass around their state using a communication structure which is constructed by an initialization function. To create a repeatable sequence we use\u00a0<code>rand.init_repeat<\/code>, for which the required generator is selected using\u00a0<code>genid = 2<\/code>:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>from naginterfaces.library import rand\nstatecomm = rand.init_repeat(genid=2, seed=[32958])<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Generate the scattered data using this initialized RNG state<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[2]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>n = 100\nx = rand.dist_uniform01(n, statecomm)\ny = rand.dist_uniform01(n, statecomm)<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Ensure that the bounding box for the data includes the corners $(0, 0)$ and $(1, 1)$<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[3]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>x[0], y[0] = 0., 0.\nx[-1], y[-1] = 1., 1.<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Here are the function values to fit, which are from the Franke function\u2014a popular function for testing surface-fitting methods<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[4]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>import numpy as np\nf = (\n    0.75*np.exp(\n        -(\n            (9.*x-2.)**2 +\n            (9.*y-2.)**2\n        )\/4.\n    ) +\n    0.75*np.exp(\n        -(9.*x+1.)**2\/49. -\n        (9.*y+1.)\/10.\n    ) +\n    0.5*np.exp(\n        -(\n            (9.*x-7.)**2 +\n            (9.*y-3.)**2\n        )\/4.\n    ) -\n    0.2*np.exp(\n        -(9.*x-4.)**2 -\n        (9.*y-7.)**2\n    )\n)<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>The <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Library supplies a very configurable function (based on the TSFIT package of Davydov and Zeilfelder) for fitting a smooth ($C^1$ or $C^2$) surface to scattered data:\u00a0<a href=\"https:\/\/support.nag.com\/numeric\/py\/nagdoc_latest\/naginterfaces.library.fit.html#naginterfaces.library.fit.dim2_spline_ts_sctr\"><code>fit.dim2_spline_ts_sctr<\/code><\/a>.<\/p>\n<p>We need to choose a granularity for the triangulation that the function will use<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[5]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>nxcels = 6\nnycels = 6<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>and also filtering thresholds for that triangulation<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[6]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>lsminp = 3\nlsmaxp = 100<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>The fitting function needs its communication state to be initialized using the\u00a0<code>fit<\/code>\u00a0Chapter&#8217;s initialization and option-setting function<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[7]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre><code>from naginterfaces.library import fit\ncomm = {}\nfit.opt_set('Initialize = dim2_spline_ts_sctr', comm)<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Further algorithmic options can also be configured using the option-setting function, if the documented defaults are not desired; we would like to use $C^2$ global smoothing and for the local approximations on the triangulation to use averaged radial basis functions<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[8]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>for fit_opt <span class=\"ow\">in [\n    'Global Smoothing Level = 2',\n    'Averaged Spline = Yes',\n    'Local Method = RBF',\n]:\n    fit.opt_set(fit_opt, comm)<\/span><\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Now compute the spline coefficients, which are entered into the communication structure for subsequent use by the evaluation functions for the fitter<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[9]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>fit.dim2_spline_ts_sctr(\n    x, y, f, lsminp, lsmaxp, nxcels, nycels, comm,\n)<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>For plotting the spline we use the associated mesh evaluator, which is\u00a0<code>fit.dim2_spline_ts_evalm<\/code>. For the evaluation this requires a vector of $x$ coordinates and a vector of $y$ coordinates<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[10]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>x_m = np.linspace(0, 1, 101)\ny_m = np.linspace(0, 1, 101)<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>The values of the spline on the grid defined by these vectors is then<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[11]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>z_m = fit.dim2_spline_ts_evalm(x_m, y_m, comm)<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>For compatibility with surface plotting in\u00a0<code>matplotlib<\/code>\u00a0we need to convert the mesh vectors into a mesh grid<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[12]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>X, Y = np.meshgrid(x_m, y_m, indexing='ij')<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Now plot the spline surface (in wireframe here) with a projection of the contours<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[13]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code><span class=\"c1\"># Jupyter magic for displaying figures inline:\n%matplotlib inline<\/span><\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>In\u00a0[14]:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>import matplotlib.pyplot as plt\nfrom mpl_toolkits.mplot3d import Axes3D\nfrom matplotlib import cm\nfig = plt.figure()\nax = Axes3D(fig)\nax.grid(<span class=\"kc\">False)\nax.plot_wireframe(X, Y, z_m, color='red', linewidths=0.4)\nax.contour(X, Y, z_m, 15, offset=-1.2, cmap=cm.jet)\nax.set_title('Spline Fit of the Franke Function')\nax.set_xlabel(r'$\\mathit<span class=\"si\">{x}$')\nax.set_ylabel(r'$\\mathit{y}$')\nax.set_zlim3d(-1.2, 1.2)\nax.azim = -20\nax.elev = 20\nplt.show()<\/span><\/span><\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1261 size-full\" src=\"https:\/\/nag.com\/wp-content\/uploads\/2018\/09\/spline-fit-franke-function.png\" alt=\"Spline fit\" width=\"453\" height=\"309\" \/><\/p>\n<h3 id=\"Global-Optimization\">Global Optimization<\/h3>\n<p>Finding the absolute maximum or minimum value of a function can be hard. For problems with a few tens of variables and only bound constraints the <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG solver\u00a0<a href=\"https:\/\/support.nag.com\/numeric\/py\/nagdoc_latest\/naginterfaces.library.glopt.html#naginterfaces.library.glopt.bnd_mcs_solve\"><code>glopt.bnd_mcs_solve<\/code><\/a>\u00a0for multi-level coordinate search (from Huyer and Neumaier) is an effective routine.<\/p>\n<p>For a quick demonstration of\u00a0<code>glopt.bnd_mcs_solve<\/code>\u00a0we find the global minimum of the two-dimensional &#8216;peaks&#8217; function, which (in a suitable form for the solver&#8217;s\u00a0<code>objfun<\/code>\u00a0argument) is<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[15]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>from math import exp\nobjfun = lambda x, _nstate: (\n    3.*(1. - x[0])**2*exp(-x[0]**2 - (x[1] + 1.)**2)\n    - (10.*(x[0]\/5. - x[0]**3 - x[1]**5)*exp(-x[0]**2 - x[1]**2))\n    - 1.\/3.0*exp(-(x[0] + 1.)**2 - x[1]**2)\n)<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>The optimization is over the box $[-3, -3]\\times[3, 3]$<\/p>\n<p>In\u00a0[16]:<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>n = 2\nbl = [-3.]*n\nbu = [3.]*n<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>The\u00a0<code>ibound<\/code>\u00a0argument tells the solver that we are supplying the bounds explicitly ourselves<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[17]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\">ibound = 0<\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>The plot for this example is going to show the search boxes that the optimizer considers as it iterates. We can use the function&#8217;s monitoring callback to store the boxes that it visits<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[18]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>from matplotlib.patches import Rectangle\n\nboxes = []\n\ndef <span class=\"nf\">monit(\n    _ncall, _xbest, _icount, _inlist, _numpts,\n    _initpt, _xbaskt, boxl, boxu, _nstate,\n):\n    boxes.append(Rectangle(boxl, *(boxu - boxl)))<\/span><\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Before calling the optimizer we need to initialize its communication state<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[19]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <div class=\"prompt input_prompt\">\n<pre class=\"prettyprint\"><code>from naginterfaces.library import glopt\ncomm = glopt.bnd_mcs_init()\n<\/code><\/pre>\n<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Now do the optimization. The monitoring function is an optional keyword argument. In this example we don&#8217;t need to access any of the return data<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[20]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>glopt.bnd_mcs_solve(objfun, ibound, bl, bu, comm, monit=monit);<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Grid the objective function for plotting<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[21]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>import numpy as np\ndelta = 0.025\nx = np.arange(bl[0], bu[0], delta)\ny = np.arange(bl[1], bu[1], delta)\nX, Y = np.meshgrid(x, y)\nZ = np.empty((len(X), len(Y)))\nfor i, x_i <span class=\"ow\">in enumerate(x):\n    for j, y_j in enumerate(y):\n        Z[j, i] = objfun([x_i, y_j], <span class=\"kc\">None)<\/span><\/span><\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Store the optimization start and end points for inclusion in the plot. For the routine&#8217;s default &#8216;simple&#8217; initialization method (<code>iinit = 0<\/code>) the start point (<code>initpt<\/code>) was at the origin<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[22]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>start_x = [0.]*n<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Here is the known global minimum for the problem<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[23]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>min_x = [0.23, -1.63]<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Aggregate the search boxes to include in the subsequent plot<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[24]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>from matplotlib.collections import PatchCollection\nboxes_col = PatchCollection(\n    boxes,\n    edgecolor='b', facecolor='none', linewidth=0.2,\n)<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Now assemble the plot<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[25]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>from matplotlib import cm\nimport matplotlib.pyplot as plt\nax = plt.axes()\nax.contour(\n    X, Y, Z,\n    levels=[-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 6, 8],\n    cmap=cm.jet,\n)\nax.plot(start_x[0], start_x[1], 'rx')\nax.plot(min_x[0], min_x[1], 'go')\nax.legend(('Start', 'Glob. min.'), loc='upper right')\nax.add_collection(boxes_col)\nax.axis(xmin=bl[0], ymin=bl[1], xmax=bu[0], ymax=bu[1])\nax.set_title(r'The Peaks Function and MCS Search Boxes')\nplt.show()<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1264 size-full\" src=\"https:\/\/nag.com\/wp-content\/uploads\/2018\/09\/peaks-function-and-mcs-search-boxes.png\" alt=\"Peaks Function\" width=\"374\" height=\"264\" \/><\/p>\n<h3 id=\"Quantile-Regression\">Quantile Regression<\/h3>\n<p>The <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG function <a href=\"https:\/\/support.nag.com\/numeric\/py\/nagdoc_latest\/naginterfaces.library.correg.html#naginterfaces.library.correg.quantile_linreg_easy\"><code>correg.quantile_linreg_easy<\/code><\/a>\u00a0can be used to model the conditional $\\tau$-th quantile of a dependent variable against one or more independent or explanatory variables.<\/p>\n<p>In our example below the dependent variable is household food expenditure, which is regressed against household income. The data is from a study of 1857 by Engels.<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[26]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>income = [\n    420.1577, 541.4117, 901.1575, 639.0802, 750.8756, 945.7989, 829.3979, 979.1648,\n    1309.8789, 1492.3987, 502.8390, 616.7168, 790.9225, 555.8786, 713.4412, 838.7561,\n    535.0766, 596.4408, 924.5619, 487.7583, 692.6397, 997.8770, 506.9995, 654.1587,\n    933.9193, 433.6813, 587.5962, 896.4746, 454.4782, 584.9989, 800.7990, 502.4369,\n    713.5197, 906.0006, 880.5969, 796.8289, 854.8791, 1167.3716, 523.8000, 670.7792,\n    377.0584, 851.5430, 1121.0937, 625.5179, 805.5377, 558.5812, 884.4005, 1257.4989,\n    2051.1789, 1466.3330, 730.0989, 2432.3910, 940.9218, 1177.8547, 1222.5939, 1519.5811,\n    687.6638, 953.1192, 953.1192, 953.1192, 939.0418, 1283.4025, 1511.5789, 1342.5821,\n    511.7980, 689.7988, 1532.3074, 1056.0808, 387.3195, 387.3195, 410.9987, 499.7510,\n    832.7554, 614.9986, 887.4658, 1595.1611, 1807.9520, 541.2006, 1057.6767, 800.7990,\n    1245.6964, 1201.0002, 634.4002, 956.2315, 1148.6010, 1768.8236, 2822.5330, 922.3548,\n    2293.1920, 627.4726, 889.9809, 1162.2000, 1197.0794, 530.7972, 1142.1526, 1088.0039,\n    484.6612, 1536.0201, 678.8974, 671.8802, 690.4683, 860.6948, 873.3095, 894.4598,\n    1148.6470, 926.8762, 839.0414, 829.4974, 1264.0043, 1937.9771, 698.8317, 920.4199,\n    1897.5711, 891.6824, 889.6784, 1221.4818, 544.5991, 1031.4491, 1462.9497, 830.4353,\n    975.0415, 1337.9983, 867.6427, 725.7459, 989.0056, 1525.0005, 672.1960, 923.3977,\n    472.3215, 590.7601, 831.7983, 1139.4945, 507.5169, 576.1972, 696.5991, 650.8180,\n    949.5802, 497.1193, 570.1674, 724.7306, 408.3399, 638.6713, 1225.7890, 715.3701,\n    800.4708, 975.5974, 1613.7565, 608.5019, 958.6634, 835.9426, 1024.8177, 1006.4353,\n    726.0000, 494.4174, 776.5958, 415.4407, 581.3599, 643.3571, 2551.6615, 1795.3226,\n    1165.7734, 815.6212, 1264.2066, 1095.4056, 447.4479, 1178.9742, 975.8023, 1017.8522,\n    423.8798, 558.7767, 943.2487, 1348.3002, 2340.6174, 587.1792, 1540.9741, 1115.8481,\n    1044.6843, 1389.7929, 2497.7860, 1585.3809, 1862.0438, 2008.8546, 697.3099, 571.2517,\n    598.3465, 461.0977, 977.1107, 883.9849, 718.3594, 543.8971, 1587.3480, 4957.8130,\n    969.6838, 419.9980, 561.9990, 689.5988, 1398.5203, 820.8168, 875.1716, 1392.4499,\n    1256.3174, 1362.8590, 1999.2552, 1209.4730, 1125.0356, 1827.4010, 1014.1540, 880.3944,\n    873.7375, 951.4432, 473.0022, 601.0030, 713.9979, 829.2984, 959.7953, 1212.9613,\n    958.8743, 1129.4431, 1943.0419, 539.6388, 463.5990, 562.6400, 736.7584, 1415.4461,\n    2208.7897, 636.0009, 759.4010, 1078.8382, 748.6413, 987.6417, 788.0961, 1020.0225,\n    1230.9235, 440.5174, 743.0772,\n]\nexpenditure = [\n    255.8394, 310.9587, 485.6800, 402.9974, 495.5608, 633.7978, 630.7566,\n    700.4409, 830.9586, 815.3602, 338.0014, 412.3613, 520.0006, 452.4015,\n    512.7201, 658.8395, 392.5995, 443.5586, 640.1164, 333.8394, 466.9583,\n    543.3969, 317.7198, 424.3209, 518.9617, 338.0014, 419.6412, 476.3200,\n    386.3602, 423.2783, 503.3572, 354.6389, 497.3182, 588.5195, 654.5971,\n    550.7274, 528.3770, 640.4813, 401.3204, 435.9990, 276.5606, 588.3488,\n    664.1978, 444.8602, 462.8995, 377.7792, 553.1504, 810.8962, 1067.9541,\n    1049.8788, 522.7012, 1424.8047, 517.9196, 830.9586, 925.5795, 1162.0024,\n    383.4580, 621.1173, 621.1173, 621.1173, 548.6002, 745.2353, 837.8005,\n    795.3402, 418.5976, 508.7974, 883.2780, 742.5276, 242.3202, 242.3202,\n    266.0010, 408.4992, 614.7588, 385.3184, 515.6200, 1138.1620, 993.9630,\n    299.1993, 750.3202, 572.0807, 907.3969, 811.5776, 427.7975, 649.9985,\n    860.6002, 1143.4211, 2032.6792, 590.6183, 1570.3911, 483.4800, 600.4804,\n    696.2021, 774.7962, 390.5984, 612.5619, 708.7622, 296.9192, 1071.4627,\n    496.5976, 503.3974, 357.6411, 430.3376, 624.6990, 582.5413, 580.2215,\n    543.8807, 588.6372, 627.9999, 712.1012, 968.3949, 482.5816, 593.1694,\n    1033.5658, 693.6795, 693.6795, 761.2791, 361.3981, 628.4522, 771.4486,\n    757.1187, 821.5970, 1022.3202, 679.4407, 538.7491, 679.9981, 977.0033,\n    561.2015, 728.3997, 372.3186, 361.5210, 620.8006, 819.9964, 360.8780,\n    395.7608, 442.0001, 404.0384, 670.7993, 297.5702, 353.4882, 383.9376,\n    284.8008, 431.1000, 801.3518, 448.4513, 577.9111, 570.5210, 865.3205,\n    444.5578, 680.4198, 576.2779, 708.4787, 734.2356, 433.0010, 327.4188,\n    485.5198, 305.4390, 468.0008, 459.8177, 863.9199, 831.4407, 534.7610,\n    392.0502, 934.9752, 813.3081, 263.7100, 769.0838, 630.5863, 645.9874,\n    319.5584, 348.4518, 614.5068, 662.0096, 1504.3708, 406.2180, 692.1689,\n    588.1371, 511.2609, 700.5600, 1301.1451, 879.0660, 912.8851, 1509.7812,\n    484.0605, 399.6703, 444.1001, 248.8101, 527.8014, 500.6313, 436.8107,\n    374.7990, 726.3921, 1827.2000, 523.4911, 334.9998, 473.2009, 581.2029,\n    929.7540, 591.1974, 637.5483, 674.9509, 776.7589, 959.5170, 1250.9643,\n    737.8201, 810.6772, 983.0009, 708.8968, 633.1200, 631.7982, 608.6419,\n    300.9999, 377.9984, 397.0015, 588.5195, 681.7616, 807.3603, 696.8011,\n    811.1962, 1305.7201, 442.0001, 353.6013, 468.0008, 526.7573, 890.2390,\n    1318.8033, 331.0005, 416.4015, 596.8406, 429.0399, 619.6408, 400.7990,\n    775.0209, 772.7611, 306.5191, 522.6019,\n]<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>In the design matrix for the regression we include an intercept term by augmenting the income data set with a column of ones<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[27]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>income_X = [[1., incomei] for incomei in income]<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Our quantiles of interest<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[28]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>tau = [0.10, 0.25, 0.5, 0.75, 0.9]<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Compute the regression<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[29]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>from naginterfaces.library import correg\nregn = correg.quantile_linreg_easy(income_X, expenditure, tau)<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>The regression coefficients are returned in attribute\u00a0b\u00a0of the function&#8217;s return tuple.<\/p>\n<p>For the plot, compute the regression lines<\/p>\n<div>In\u00a0[30]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <p>\u00a0<\/p>\n<pre><code>import numpy as np\nplot_x = np.linspace(0, max(income))\nplot_ys = [regn.b[0, i] + regn.b[1, i]*plot_x for i in range(len(tau))]<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Make a scatter plot of the original income data (without the intercept) and add in the regression lines<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[31]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>import matplotlib.pyplot as plt\nplt.scatter(income, expenditure, c='red', marker='+', linewidth=0.5)\nfor tau_i, tau_val in enumerate(tau):\n    plt.plot(\n        plot_x, plot_ys[tau_i],\n        label=r'$\\tau$ = {:.2f}'.format(tau_val),\n    )\nplt.ylim((0., max(expenditure)))\nplt.xlabel('Household Income')\nplt.ylabel('Household Food Expenditure')\nplt.legend(loc='lower right')\nplt.title(\n    'Quantile Regression\\n'\n    'Engels\\' 1857 Study of Household Expenditure on Food'\n)\nplt.show()<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1265 size-full\" src=\"https:\/\/nag.com\/wp-content\/uploads\/2018\/09\/quantile-regression-engels-857-study.png\" alt=\"Quantile Regression\" width=\"399\" height=\"293\" \/><\/p>\n<h3 id=\"Kernel-Density-Estimation\">Kernel Density Estimation<\/h3>\n<p>Density estimation starts from a set of observations and produces a smooth nonparametric estimate of the unknown density function from which the observations were drawn. The <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG function for this computation is\u00a0<a href=\"https:\/\/support.nag.com\/numeric\/py\/nagdoc_latest\/naginterfaces.library.smooth.html#naginterfaces.library.smooth.kerndens_gauss\"><code>smooth.kerndens_gauss<\/code><\/a>.<\/p>\n<p>Here is some trial data<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[32]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <p><code><\/code><\/p>\n<pre class=\"prettyprint\"><code>x = [\n    0.114, -0.232, -0.570, 1.853, -0.994, -0.374, -1.028, 0.509, 0.881, -0.453,\n    0.588, -0.625, -1.622, -0.567, 0.421, -0.475, 0.054, 0.817, 1.015, 0.608,\n    -1.353, -0.912, -1.136, 1.067, 0.121, -0.075, -0.745, 1.217, -1.058, -0.894,\n    1.026, -0.967, -1.065, 0.513, 0.969, 0.582, -0.985, 0.097, 0.416, -0.514,\n    0.898, -0.154, 0.617, -0.436, -1.212, -1.571, 0.210, -1.101, 1.018, -1.702,\n    -2.230, -0.648, -0.350, 0.446, -2.667, 0.094, -0.380, -2.852, -0.888, -1.481,\n    -0.359, -0.554, 1.531, 0.052, -1.715, 1.255, -0.540, 0.362, -0.654, -0.272,\n    -1.810, 0.269, -1.918, 0.001, 1.240, -0.368, -0.647, -2.282, 0.498, 0.001,\n    -3.059, -1.171, 0.566, 0.948, 0.925, 0.825, 0.130, 0.930, 0.523, 0.443,\n    -0.649, 0.554, -2.823, 0.158, -1.180, 0.610, 0.877, 0.791, -0.078, 1.412,\n]<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>We are going to repeat the density estimation using four different multipliers for the window width<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[33]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>window_ms = [2.\/2.**i for i <span class=\"ow\">in range(4)]<\/span><\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>The <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG routine has an initialization mode for computing FFT data from the input data once only. The mode is triggered by passing an empty communication dict. On subsequent calls the FFT is then re-used<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[34]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>from naginterfaces.library import smooth\ncomm = {}\nk_gs = [smooth.kerndens_gauss(x, comm, window=window_m) for window_m <span class=\"ow\">in window_ms]<\/span><\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>From each return tuple the\u00a0<code>window<\/code>\u00a0attribute gives the window width that was actually used,\u00a0<code>t<\/code>\u00a0the points at which the density estimate was calculated, and\u00a0<code>smooth<\/code>\u00a0the values of the estimate<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[35]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>import matplotlib.pyplot as plt\nfor k_g <span class=\"ow\">in k_gs:\n    plt.plot(\n        k_g.t, k_g.smooth,\n        linewidth=0.75, label='window = {:.4f}'.format(k_g.window),\n    )\nplt.xlabel(r'$\\mathit{t}$')\nplt.ylabel('Density Estimate')\nplt.legend()\nplt.title('Gaussian Kernel Density Estimation')\nplt.show()<\/span><\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1266 size-full\" src=\"https:\/\/nag.com\/wp-content\/uploads\/2018\/09\/gaussian-kernel-density-est.png\" alt=\"Kernal Density\" width=\"389\" height=\"280\" \/><\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <h3 id=\"Change-Point-Analysis\">Change Point Analysis<\/h3>\n<p>Change points are time points at which some feature of a data set changes. For detecting change points in a univariate time series we can use\u00a0<a href=\"https:\/\/support.nag.com\/numeric\/py\/nagdoc_latest\/naginterfaces.library.tsa.html#naginterfaces.library.tsa.cp_pelt\"><code>tsa.cp_pelt<\/code><\/a>.<\/p>\n<p>Consider the following time series, assumed to be from a Normal distribution<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[36]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <div class=\"prompt input_prompt\">\n<pre class=\"prettyprint\"><code>y = [\n    0., 0.78, -0.02, 0.17, 0.04, -1.23, 0.24, 1.7, 0.77, 0.06,\n    0.67, 0.94, 1.99, 2.64, 2.26, 3.72, 3.14, 2.28, 3.78, 0.83,\n    2.8, 1.66, 1.93, 2.71, 2.97, 3.04, 2.29, 3.71, 1.69, 2.76,\n    1.96, 3.17, 1.04, 1.5, 1.12, 1.11, 1., 1.84, 1.78, 2.39,\n    1.85, 0.62, 2.16, 0.78, 1.7, 0.63, 1.79, 1.21, 2.2, -1.34,\n    0.04, -0.14, 2.78, 1.83, 0.98, 0.19, 0.57, -1.41, 2.05, 1.17,\n    0.44, 2.32, 0.67, 0.73, 1.17, -0.34, 2.95, 1.08, 2.16, 2.27,\n    -0.14, -0.24, 0.27, 1.71, -0.04, -1.03, -0.12, -0.67, 1.15,\n    -1.1, -1.37, 0.59, 0.44, 0.63, -0.06, -0.62, 0.39, -2.63, -1.63,\n    -0.42, -0.73, 0.85, 0.26, 0.48, -0.26, -1.77, -1.53, -1.39, 1.68, 0.43,\n]\n<\/code><\/pre>\n<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>We wish to look for changes in the mean, which is selected using the following\u00a0<code>ctype<\/code>\u00a0value in the <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG routine<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[37]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>ctype = 1<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>We are also assuming unit variance for this problem, which must be communicated to the <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG function using the\u00a0<code>param<\/code>\u00a0keyword argument<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[38]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>param = [1.]<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>Find the change points<\/p>\n<div class=\"prompt input_prompt\">In\u00a0[39]:<\/div>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\">from naginterfaces.library import tsa\nsoln = tsa.cp_pelt(ctype, y, param=param)<\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p>The locations of the change points are in attribute\u00a0<code>tau<\/code>\u00a0of the return tuple, while the estimated distribution parameters are in attribute\u00a0<code>sparam<\/code>.<\/p>\n<p>Plot the time series, and also the change points as vertical lines with the corresponding means as horizontal lines<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-10 col-xl-10\">\n            <pre class=\"prettyprint\"><code>import matplotlib.pyplot as plt\nplt.plot(range(1, len(y)+1), y, color='r', linewidth=0.75)\nlast_cp = 1.\nfor tau_i, tau_val in enumerate(soln.tau):\n    vl = plt.axvline(tau_val, label='Change pt.')\n    hl = plt.hlines(\n        soln.sparam[2*tau_i],\n        xmin=last_cp, xmax=tau_val, color='g', label='Mean',\n    )\n    last_cp = tau_val\nplt.xlim((1, len(y)))\nplt.xticks(range(10, len(y)+1, 10))\nplt.xlabel('Time')\nplt.ylabel('Value')\nplt.title(\n    'Simulated Time Series and\\n'\n    'Corresponding Changes in Mean')\nplt.legend(handles=[vl, hl], loc='upper right')\nplt.show()<\/code><\/pre>\n        <\/div>\n    <\/div>\n<\/div>\n\n<div class=\"container content-area-default \">\n    <div class=\"row justify-content--center\">\n        <div class=\"col-12 col-md-10 col-lg-8 col-xl-6\">\n            <p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-1267\" src=\"https:\/\/nag.com\/wp-content\/uploads\/2018\/09\/simulated-time-series-corres-changes-in-mean-300x223.png\" alt=\"simulated time series\" width=\"300\" height=\"223\" \/><\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n\n<div class=\"gbc-title-banner tac tac-lg tac-xl\" style='border-radius: 0px; '>\n    <div class=\"container\" style='border-radius: 0px; '>\n        <div class=\"row justify-content--center\" >\n            <div class=\"col-12\"  >\n                <div class=\"wrap pv-4 \" style=\"0pxbackground-color: \">\n                                <div class=\"col-12 col-md-12 col-lg-12 col-xl-12  banner-content\"  >\n    \n                    \n                    <div class=\"mt-1 mb-1 content\"><\/div>\n\n                    \n                    <a href='https:\/\/nag.com\/nag-library\/' style='background-color: #ff7d21ff; color: #ffffffff; border-radius: 30px; font-weight: 600; ' class='btn mr-1  ' >Learn more about the <span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG Library <i class='fas fa-angle-right'><\/i><\/a>                <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"nag-n-override\" style=\"margin-left: 0 !important;\"><i>n<\/i><\/span>AG has a new Python package for accessing the Library. It has been a few person years in the making and is a substantial improvement over its predecessors in terms of usability.<br \/>\nThis post splits into two sections: the first covers some technical details, history and context about what&#8217;s happened behind the scenes with the package; the second jumps into some examples of how to use it.<\/p>\n","protected":false},"author":13,"featured_media":1258,"parent":0,"menu_order":0,"template":"","meta":{"content-type":"","footnotes":""},"post-tag":[27,18,41],"class_list":["post-1448","insights","type-insights","status-publish","has-post-thumbnail","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>The Making of the New NAG Library for Python, With Usage Tutorials - nAG<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The Making of the New NAG Library for Python, With Usage Tutorials - nAG\" \/>\n<meta property=\"og:description\" content=\"NAG has a new Python package for accessing the Library. It has been a few person years in the making and is a substantial improvement over its predecessors in terms of usability. This post splits into two sections: the first covers some technical details, history and context about what&#039;s happened behind the scenes with the package; the second jumps into some examples of how to use it.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/\" \/>\n<meta property=\"og:site_name\" content=\"nAG\" \/>\n<meta property=\"article:modified_time\" content=\"2023-07-05T12:14:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/nag.com\/wp-content\/uploads\/2023\/05\/python_Library.jpeg\" \/>\n\t<meta property=\"og:image:width\" content=\"2000\" \/>\n\t<meta property=\"og:image:height\" content=\"1000\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@NAGTalk\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/\",\"url\":\"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/\",\"name\":\"The Making of the New NAG Library for Python, With Usage Tutorials - nAG\",\"isPartOf\":{\"@id\":\"https:\/\/nag.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/nag.com\/wp-content\/uploads\/2023\/05\/python_Library.jpeg\",\"datePublished\":\"2018-09-05T17:05:00+00:00\",\"dateModified\":\"2023-07-05T12:14:04+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/#primaryimage\",\"url\":\"https:\/\/nag.com\/wp-content\/uploads\/2023\/05\/python_Library.jpeg\",\"contentUrl\":\"https:\/\/nag.com\/wp-content\/uploads\/2023\/05\/python_Library.jpeg\",\"width\":2000,\"height\":1000,\"caption\":\"Python Library\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/nag.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Insights\",\"item\":\"https:\/\/nag.com\/insights\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"The Making of the New NAG Library for Python, With Usage Tutorials\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/nag.com\/#website\",\"url\":\"https:\/\/nag.com\/\",\"name\":\"NAG\",\"description\":\"Robust, trusted numerical software and computational expertise.\",\"publisher\":{\"@id\":\"https:\/\/nag.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/nag.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/nag.com\/#organization\",\"name\":\"Numerical Algorithms Group\",\"alternateName\":\"NAG\",\"url\":\"https:\/\/nag.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/nag.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/nag.com\/wp-content\/uploads\/2023\/11\/NAG-Logo.png\",\"contentUrl\":\"https:\/\/nag.com\/wp-content\/uploads\/2023\/11\/NAG-Logo.png\",\"width\":1244,\"height\":397,\"caption\":\"Numerical Algorithms Group\"},\"image\":{\"@id\":\"https:\/\/nag.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/NAGTalk\",\"https:\/\/www.linkedin.com\/company\/nag\/\",\"https:\/\/www.youtube.com\/user\/NumericalAlgorithms\",\"https:\/\/github.com\/numericalalgorithmsgroup\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The Making of the New NAG Library for Python, With Usage Tutorials - nAG","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/","og_locale":"en_US","og_type":"article","og_title":"The Making of the New NAG Library for Python, With Usage Tutorials - nAG","og_description":"NAG has a new Python package for accessing the Library. It has been a few person years in the making and is a substantial improvement over its predecessors in terms of usability. This post splits into two sections: the first covers some technical details, history and context about what's happened behind the scenes with the package; the second jumps into some examples of how to use it.","og_url":"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/","og_site_name":"nAG","article_modified_time":"2023-07-05T12:14:04+00:00","og_image":[{"width":2000,"height":1000,"url":"https:\/\/nag.com\/wp-content\/uploads\/2023\/05\/python_Library.jpeg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_site":"@NAGTalk","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/","url":"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/","name":"The Making of the New NAG Library for Python, With Usage Tutorials - nAG","isPartOf":{"@id":"https:\/\/nag.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/#primaryimage"},"image":{"@id":"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/#primaryimage"},"thumbnailUrl":"https:\/\/nag.com\/wp-content\/uploads\/2023\/05\/python_Library.jpeg","datePublished":"2018-09-05T17:05:00+00:00","dateModified":"2023-07-05T12:14:04+00:00","breadcrumb":{"@id":"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/#primaryimage","url":"https:\/\/nag.com\/wp-content\/uploads\/2023\/05\/python_Library.jpeg","contentUrl":"https:\/\/nag.com\/wp-content\/uploads\/2023\/05\/python_Library.jpeg","width":2000,"height":1000,"caption":"Python Library"},{"@type":"BreadcrumbList","@id":"https:\/\/nag.com\/insights\/the-making-of-the-new-nag-library-for-python-with-usage-tutorials\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/nag.com\/"},{"@type":"ListItem","position":2,"name":"Insights","item":"https:\/\/nag.com\/insights\/"},{"@type":"ListItem","position":3,"name":"The Making of the New NAG Library for Python, With Usage Tutorials"}]},{"@type":"WebSite","@id":"https:\/\/nag.com\/#website","url":"https:\/\/nag.com\/","name":"NAG","description":"Robust, trusted numerical software and computational expertise.","publisher":{"@id":"https:\/\/nag.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/nag.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/nag.com\/#organization","name":"Numerical Algorithms Group","alternateName":"NAG","url":"https:\/\/nag.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/nag.com\/#\/schema\/logo\/image\/","url":"https:\/\/nag.com\/wp-content\/uploads\/2023\/11\/NAG-Logo.png","contentUrl":"https:\/\/nag.com\/wp-content\/uploads\/2023\/11\/NAG-Logo.png","width":1244,"height":397,"caption":"Numerical Algorithms Group"},"image":{"@id":"https:\/\/nag.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/NAGTalk","https:\/\/www.linkedin.com\/company\/nag\/","https:\/\/www.youtube.com\/user\/NumericalAlgorithms","https:\/\/github.com\/numericalalgorithmsgroup"]}]}},"_links":{"self":[{"href":"https:\/\/nag.com\/wp-json\/wp\/v2\/insights\/1448","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nag.com\/wp-json\/wp\/v2\/insights"}],"about":[{"href":"https:\/\/nag.com\/wp-json\/wp\/v2\/types\/insights"}],"author":[{"embeddable":true,"href":"https:\/\/nag.com\/wp-json\/wp\/v2\/users\/13"}],"version-history":[{"count":12,"href":"https:\/\/nag.com\/wp-json\/wp\/v2\/insights\/1448\/revisions"}],"predecessor-version":[{"id":3053,"href":"https:\/\/nag.com\/wp-json\/wp\/v2\/insights\/1448\/revisions\/3053"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nag.com\/wp-json\/wp\/v2\/media\/1258"}],"wp:attachment":[{"href":"https:\/\/nag.com\/wp-json\/wp\/v2\/media?parent=1448"}],"wp:term":[{"taxonomy":"post-tag","embeddable":true,"href":"https:\/\/nag.com\/wp-json\/wp\/v2\/post-tag?post=1448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}