|
| 1 | +# Using the NAG Library for Python witk Kdb+ and PyQ |
| 2 | + |
| 3 | +Christopher Brandt <br> |
| 4 | +Numerical Algorithms Group (NAG), Inc. <br> |
| 5 | +Lisle, IL, USA <br> |
| 6 | +April 3, 2019 |
| 7 | + |
| 8 | +## 1 Background |
| 9 | + |
| 10 | +This paper provides detailed instructions on how to use the [NAG Library for *Python*](https://www.nag.co.uk/numeric/py/nagdoc_latest/index.html) with [kdb+](https://kx.com/) and [PyQ](https://code.kx.com/q/interfaces/pyq/). The NAG Library contains more than 1,700 mathematical and statistical routines, and is accessible by numerous programming languages (including Python, C++, Java, Fortran, etc.). PyQ is an extension to kdb+ featuring zero-copy sharing of data between Python and the q programming language. The enclosed examples will illustrate how to access routines within the NAG Library for *Python* using data stored in kdb+. |
| 11 | + |
| 12 | +## 2 Setting Up the Workspace |
| 13 | + |
| 14 | +Installation for both the NAG Library for *Python* and the PyQ extension to kdb+ may be performed using pip. |
| 15 | + |
| 16 | +To install the NAG Library for *Python*: |
| 17 | + |
| 18 | +``` |
| 19 | +$ python -m pip install --extra-index-url https:nag/com/downloads/py/naginterfaces_nag naginterfaces |
| 20 | +``` |
| 21 | +To install PyQ from Kx: |
| 22 | +``` |
| 23 | +$ python -m pip install pyq |
| 24 | +``` |
| 25 | +Both the NAG Library for *Python* and kdb+ are commercial software packages that require active licenses for their respective usage. To obtain a temporary license for the NAG Library for Python, please contact NAG support at [support@nag.com](mailto:support@nag.com). |
| 26 | + |
| 27 | +## 3 Examples |
| 28 | + |
| 29 | +The following three examples demonstrate how to call the NAG Library for *Python* routines using kdb+ and PyQ. These examples were carefully selected, as they cover techniques found in the majority of usage cases a customer will encounter across all 1,700+ routines within the library. If your usage case falls outside of these three examples, please contact [NAG support](mailto:support@nag.com) for assistance. |
| 30 | + |
| 31 | +### 3.1 Example One: BLAS Routine DAXPY |
| 32 | + |
| 33 | +Our first example demonstrates how to perform the linear algebra operation |
| 34 | + |
| 35 | +$$ y \coloneqq \alpha x + b. $$ |
| 36 | + |
| 37 | +Below is the NAG Library for *Python* signature for this routine. |
| 38 | + |
| 39 | +``` |
| 40 | + naginterfaces.library.blas.daxpy(alpha,x,y) |
| 41 | + |
| 42 | + Parameters: alpha: float |
| 43 | + x: float, array-like, shape(n) |
| 44 | + y: float, array-like, shape(n) |
| 45 | + |
| 46 | + Returns: y: float, ndarray, shape(n) |
| 47 | +``` |
| 48 | + |
| 49 | +Within our terminal, we begin by starting a PyQ interaction session. |
| 50 | + |
| 51 | +``` |
| 52 | +$ pyq |
| 53 | +``` |
| 54 | + |
| 55 | +Next, we import PyQ and the NAG Library for *Python*. |
| 56 | + |
| 57 | +``` |
| 58 | +>>> from pyq import q |
| 59 | +>>> from naginterfaces.library import blas |
| 60 | +``` |
| 61 | + |
| 62 | +We then enter a q environment and define our parameers as q objects. |
| 63 | + |
| 64 | +``` |
| 65 | +>>> q() |
| 66 | +q) alpha:0.5f |
| 67 | +q) x:(2.0, 2.0, 2.0, 2.0f) |
| 68 | +q) y:(4.0, 4.0, 4.0, 4.0f) |
| 69 | +``` |
| 70 | + |
| 71 | +Finally, we exit the q environment and invoke the NAG routine. |
| 72 | + |
| 73 | +``` |
| 74 | +q) \ |
| 75 | +>>> z = blas.daxpy(float(q.alpha), q.x, q.y) |
| 76 | +>>> z # display solution: array([4., 4., 4., 4.]) |
| 77 | +``` |
| 78 | + |
| 79 | +### 3.2 Example Two: Nearest Correlation Matrix |
| 80 | + |
| 81 | +Our second example employs a nearest correlation matrix routine which, for a given approximate correlation matrix $G$, computes the nearest correlation matrix $X$ by minimizing the weighted Frobenius norm |
| 82 | + |
| 83 | +$$ \Big\lVert W^{1/2}(G - X)W^{1/2} \Big\rVert_{F}^{2} $$ |
| 84 | + |
| 85 | +where $W$ is a diagonal matrix of weights. |
| 86 | + |
| 87 | +The NAG Library for *Python* signature for this routine is below. |
| 88 | + |
| 89 | +``` |
| 90 | +naginterfaces.library.correg.bounded(g,opt,alpha=None,w=None,errtol=0.0,maxits=0,maxit=200) |
| 91 | +
|
| 92 | +Parameters: g: float, array-like, shape(n,n) |
| 93 | + opt:str, length 1 |
| 94 | + alpha: None or float, optional |
| 95 | + w: None or float, array-like, shape(n), optional |
| 96 | + errtol: float, optional |
| 97 | + maxits: int, optional |
| 98 | + maxit: int, optional |
| 99 | +
|
| 100 | +Returns: x: float, ndarray, shape(n,n) |
| 101 | + itera: int |
| 102 | + feval: int |
| 103 | + nrmgrd: float |
| 104 | +``` |
| 105 | + |
| 106 | +Within our interactive PyQ session, we again begin by entering a q environment and defining our parameters as q objects. |
| 107 | + |
| 108 | +``` |
| 109 | +>>> q() |
| 110 | +q) alpha:0.5f |
| 111 | +q) x:(2.0, 2.0, 2.0, 2.0f) |
| 112 | +q) g:(2.0, -1.0, 0.0, 0.0f; -1.0, 2.0, -1.0, 0.0f; |
| 113 | + 0.0, -1.0, 2.0, -1.0f; 0.0, 0.0, -1.0, 2.0f) |
| 114 | +q) opt:”B” |
| 115 | +q) alpha = 0.02f |
| 116 | +q) w:(100.0, 20.0, 20.0, 20.0f) |
| 117 | +``` |
| 118 | + |
| 119 | +We then exit the q environment and invoke the NAG routine. |
| 120 | + |
| 121 | +``` |
| 122 | +q) \ |
| 123 | +>>> x = correg.corrmat_nearest_bounded(q.g, str(q.opt), |
| 124 | + float(q.alpha), q.w) |
| 125 | +>>> x # display solution |
| 126 | +``` |
| 127 | + |
| 128 | +### 3.3 Example Three: Numerical Integration |
| 129 | + |
| 130 | +With our final example, we demonstrate how to incorporate a user-defined callback function with a NAG Library for *Python* routine. This example approximates the definite integal |
| 131 | + |
| 132 | +$$ \int_{a}^{b} f(x) dx. $$ |
| 133 | + |
| 134 | +The NAG Library for *Python* signature for this routine is below. |
| 135 | + |
| 136 | +``` |
| 137 | +naginterfaces.library.quad.dim1_fin_smooth(f,a,b,epsabs,epsrel,data=None) |
| 138 | +
|
| 139 | +Parameters: f: callable, result = f(x,data=None) |
| 140 | + Parameters: |
| 141 | + x: float |
| 142 | + data: arbitrary, optional, modifiable in place |
| 143 | + a: float |
| 144 | + b: float |
| 145 | + epsabs: float |
| 146 | + epsrel: float |
| 147 | + data: arbitrary, optional |
| 148 | +
|
| 149 | +Returns: result: float |
| 150 | + abserr: float |
| 151 | +``` |
| 152 | + |
| 153 | +We start by entering a q environment and defining our parameters as q objects. |
| 154 | + |
| 155 | +``` |
| 156 | +>>> q() |
| 157 | +q) a:0.0f |
| 158 | +q) b:2.0f |
| 159 | +q) epsabs:0.0f |
| 160 | +q) epsrel:0.0001f |
| 161 | +``` |
| 162 | + |
| 163 | +Next, we exit the q environment and define an integrable Python function. To satisfy this parameter we may use either a Python function or a lambda expression. |
| 164 | + |
| 165 | +``` |
| 166 | +q) \ |
| 167 | +>>> f(x): |
| 168 | +... return x*x |
| 169 | +... |
| 170 | +``` |
| 171 | + |
| 172 | +With our problem now fully defined, we invoke the NAG Library routine to compute our solution. |
| 173 | + |
| 174 | +``` |
| 175 | +>>> result, error = quad.dim1_fin_smooth(f,float(q.a),float(q.b), |
| 176 | + float(q.epsabs),float(q.epsrel)) |
| 177 | +>>> result # 2.6666666666666667 |
| 178 | +>>> error # 1.4802973661668755e-14 |
| 179 | +``` |
| 180 | + |
| 181 | +## 4 Additional Usage Cases |
| 182 | + |
| 183 | +NAG recently published the technical report [Using the NAG Library with Kdb+ in a Pure Q Environment](https://www.nag.com/doc/techrep/pdf/tr1_18.pdf) discussing how to call the NAG Library using the new Foreign Function Interface (FFI) from Kx. |
| 184 | + |
| 185 | +Additionally, the NAG Blog titled [Calling the NAG C Library from Kdb+](http://blog.nag.com/2013/05/calling-nag-c-library-from-kdb.html) details how to incorporate the NAG Library with kdb+ within a C++ program. We speculate that among our shared clients, a mixture of these methods will be employed. |
| 186 | + |
| 187 | +If your desired usage case happens to fall outside of those described within our current publications, please contact NAG support at support@nag.com for asisstance with your application. |
| 188 | + |
| 189 | +## 5 Links |
| 190 | + |
| 191 | +* Using Python with kdb+ (PyQ) [https://code.kx.com/q/interfaces/pyq/](https://code.kx.com/q/interfaces/pyq/) |
| 192 | +* Kdb+ and Python: embedPy and PyQ [https://kx.com/blog/kdb-python-embedpy-pyq/]([https://kx.com/blog/kdb-python-embedpy-pyq/) |
| 193 | +* Using the NAG Library with Kdb+ in a Pure Q Environment [https://www.nag.com/doc/techrep/pdf/tr1_18.pdf](https://www.nag.com/doc/techrep/pdf/tr1_18.pdf) |
| 194 | +* Calling the NAG C Library from Kdb+ [http://blog.nag.com/2013/05/calling-nag-c-library-from-kdb.html](http://blog.nag.com/2013/05/calling-nag-c-library-from-kdb.html) |
| 195 | +* NAG Library for Python Manual [https://www.nag.com/numeric/py/nagdoc_latest/index.html](https://www.nag.com/numeric/py/nagdoc_latest/index.html) |
| 196 | +* NAG GitHub Organisation [https://github.com/numericalalgorithmsgroup/](https://github.com/numericalalgorithmsgroup/) |
0 commit comments