├── .gitignore
├── jkernel
├── __init__.py
├── jkernel.py
└── jinter.py
├── kernel_definition
├── logo-32x32.png
├── logo-64x64.png
└── kernel.json
├── Jupyter_Notebook_J_Example_Data
├── moon.bmp
├── galaxy.bmp
├── assembly1.bmp
├── assembly2.bmp
└── Weather_Stations.txt
├── README.md
├── setup.py
├── syntax
└── J.js
└── Jupyter_Notebook_J_Labs
├── math
├── Spirals.ipynb
├── Frame's_Method.ipynb
├── Binomial_Coefficients.ipynb
├── Rotations.ipynb
├── Iteration_and_the_Power_Operator.ipynb
├── Best_Fit.ipynb
└── Catalan_Numbers.ipynb
├── core
├── Monad_Dyad.ipynb
└── A_Taste_of_J_(2).ipynb
├── graphics
└── Plot_Package.ipynb
└── general
├── The_Tower_of_Hanoi.ipynb
└── Huffman_Coding.ipynb
/.gitignore:
--------------------------------------------------------------------------------
1 | .ipynb_checkpoints/
2 | build/
3 | dist/
4 | *.swp
5 | *.egg-info
6 |
--------------------------------------------------------------------------------
/jkernel/__init__.py:
--------------------------------------------------------------------------------
1 | # Dummy __init__.py for Python2.7 package initialization
2 |
--------------------------------------------------------------------------------
/kernel_definition/logo-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fastai/jkernel/master/kernel_definition/logo-32x32.png
--------------------------------------------------------------------------------
/kernel_definition/logo-64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fastai/jkernel/master/kernel_definition/logo-64x64.png
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Example_Data/moon.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fastai/jkernel/master/Jupyter_Notebook_J_Example_Data/moon.bmp
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Example_Data/galaxy.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fastai/jkernel/master/Jupyter_Notebook_J_Example_Data/galaxy.bmp
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Example_Data/assembly1.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fastai/jkernel/master/Jupyter_Notebook_J_Example_Data/assembly1.bmp
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Example_Data/assembly2.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fastai/jkernel/master/Jupyter_Notebook_J_Example_Data/assembly2.bmp
--------------------------------------------------------------------------------
/kernel_definition/kernel.json:
--------------------------------------------------------------------------------
1 | {
2 | "argv" : ["python","-m","jkernel.jkernel", "-f", "{connection_file}"],
3 | "display_name" : "J",
4 | "language" : "J"
5 | }
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Jupyter Notebook/Lab jkernel
2 |
3 | The jkernel is a J programming language integration for the [Jupyter Notebook](http://jupyter.org)
4 |
5 | ## What's new (August 2020)
6 |
7 | * Updated for J901
8 | * Windows 10 64bit compatibility
9 |
10 | ## Prerequisites
11 |
12 | * [Jupyter Notebook](http://jupyter.org) Version 4.x (or greater)
13 |
14 | * Recommended: [Anaconda from Anaconda Inc.](https://www.anaconda.com/distribution)
15 |
16 | * Or: [Miniconda](https://conda.io/miniconda.html) (Jupyter must be installed manually)
17 |
18 | * A working [J 901](http://www.jsoftware.com) (or greater)
19 |
20 | ## Installation / Uninstallation / Installation Check
21 |
22 | **Please Note:**
23 | It is mandatory to use the **python** command from Anaconda or Miniconda!
24 |
25 | NOT the python command that probably comes pre-installed on your operating system.
26 |
27 | On *nix OS, the command **which python** shows you the path of the python interpreter.
28 |
29 | * python setup.py **install**
30 |
31 | * python setup.py **uninstall**
32 |
33 | * python setup.py **check**
34 |
35 | ## Examples
36 |
37 | The sub-directories **Jupyter_Notebook_J_Labs** and **Jupyter_Notebook_J_Examples** contain some example notebooks
38 |
39 | The sub-directory **Jupyter_Notebook_J_Example_Data** should be copied to the J user directory to run the example notebooks in **Jupyter_Notebook_J_Examples**
40 |
41 | ## Run
42 |
43 | Run: **jupyter notebook** (from the command line)
44 |
45 | Run: **jupyter lab** (from the command line)
46 |
47 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import glob,setuptools,os
2 | from pathlib import Path
3 | from setuptools import setup
4 |
5 | DISTNAME = 'j_kernel'
6 | DESCRIPTION = 'A Jupyter kernel for J.'
7 | LONG_DESCRIPTION = open('README.md').read()
8 | MAINTAINER = 'Jeremy Howard'
9 | MAINTAINER_EMAIL = 'info@howard.fm'
10 | URL = 'http://github.com/fastai/j_kernel'
11 | LICENSE = 'GPL'
12 | REQUIRES = ["jupyter_client (>=4.3.0)", "ipykernel"]
13 | INSTALL_REQUIRES = REQUIRES
14 |
15 | CLASSIFIERS = """\
16 | Intended Audience :: Science/Research
17 | License :: OSI Approved :: GPL License
18 | Operating System :: OS Independent
19 | Programming Language :: Python
20 | Programming Language :: Python :: 3.6
21 | Programming Language :: Python :: 3.7
22 | Programming Language :: Python :: 3.8
23 | Topic :: Scientific/Engineering
24 | Topic :: Software Development
25 | Topic :: System :: Shells
26 | """
27 |
28 | import notebook
29 | nb_dir = Path(notebook.__file__).parent.relative_to(os.environ['CONDA_PREFIX'])
30 | DATA_FILES = [
31 | (f'{nb_dir}/static/components/codemirror/mode/j', ['syntax/J.js']),
32 | ('share/jupyter/kernels/j', glob.glob('kernel_definition/*.*')),
33 | ]
34 |
35 | setup(
36 | name=DISTNAME,
37 | version='0.0.1',
38 | maintainer=MAINTAINER, maintainer_email=MAINTAINER_EMAIL,
39 | packages = setuptools.find_packages(),
40 | data_files=DATA_FILES,
41 | url=URL, download_url=URL,
42 | license=LICENSE,
43 | platforms=["Any"],
44 | description=DESCRIPTION, long_description=LONG_DESCRIPTION, long_description_content_type='text/x-rst',
45 | classifiers=list(filter(None, CLASSIFIERS.split('\n'))),
46 | install_requires=INSTALL_REQUIRES
47 | )
48 |
49 |
--------------------------------------------------------------------------------
/syntax/J.js:
--------------------------------------------------------------------------------
1 | // J syntax definition for CodeMirror
2 |
3 | (function(mod)
4 | {
5 | if(typeof exports == "object" && typeof module == "object") // CommonJS
6 | {
7 | mod(require("../../lib/codemirror"));
8 | }
9 | else if(typeof define == "function" && define.amd) // AMD
10 | {
11 | define(["../../lib/codemirror"],mod);
12 | }
13 | else // Plain browser env
14 | {
15 | mod(CodeMirror);
16 | }
17 | })
18 |
19 | (function(CodeMirror)
20 | {
21 | "use strict";
22 |
23 | CodeMirror.defineMode('J',function(config)
24 | {
25 |
26 | var c;
27 | var words = {};
28 |
29 | function define(style,string)
30 | {
31 | var split = string.split(' ');
32 | for(var i=0;i'):
48 | try:
49 | prefix = '
', '') \
74 | .replace('canvas1', f'canvas{canvasnum}')
75 | htmnam.unlink(missing_ok=False)
76 |
77 | canvasnum += 1
78 | content['data']['text/html'] = htmdat
79 | self.send_response(self.iopub_socket, 'display_data', content)
80 |
81 | except Exception as e:
82 | content = { 'name': 'stdout', 'text': f'JKernel: Internal Error.\n{e}\n' }
83 | self.send_response(self.iopub_socket,'stream',content)
84 |
85 | # Is it an html output
86 | elif output.startswith(''):
87 | content['data']['text/html'] = output
88 | self.send_response(self.iopub_socket, 'display_data', content)
89 | else:
90 | # Normal text output
91 | content = { 'name': 'stdout', 'text': output }
92 | self.send_response(self.iopub_socket,'stream',content)
93 |
94 | def do_execute(self, code, silent, *args, **kwargs):
95 | global canvasnum
96 |
97 | # Pass input to J (new version)
98 | # Multi-line statements (like verb definitions) are now possible
99 | # Only the output of the last line (statement) is printed
100 | lines = [line for line in code.splitlines() if line.strip()]
101 | lastline = ''
102 | # Check last line (end of multiline statement)
103 | if lines:
104 | lastline = lines.pop().strip()
105 | if not lastline == ')': code = '\n'.join(lines)
106 |
107 | code = code.replace("'","''")
108 | self.J.Exec(f"input_jinter_ =: '{code}'")
109 | self.J.Exec('0!:110 input_jinter_')
110 |
111 | # Process last line (receive output)
112 | if lastline:
113 | self.J.Exec(lastline)
114 | output = self.J.Recv()
115 | if output: self._retr(output, silent)
116 |
117 | return {
118 | 'status': 'ok',
119 | 'execution_count': self.execution_count,
120 | 'payload': [],
121 | 'user_expressions': {},
122 | }
123 |
124 | def do_shutdown(self,restart): pass
125 | def do_inspect(self,code,cursor_pos,detail_level=0): pass
126 |
127 | if __name__ == '__main__':
128 | from ipykernel.kernelapp import IPKernelApp
129 | IPKernelApp.launch_instance(kernel_class=JKernel)
130 |
131 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/math/Spirals.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# J Labs\n",
8 | "\n",
9 | "### Spirals"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {},
15 | "source": [
16 | "### (1 of 5) LINK AND PLOT\n",
17 | "\n",
18 | "The function ; links its vector arguments to form a list of boxed vectors. Thus:"
19 | ]
20 | },
21 | {
22 | "cell_type": "code",
23 | "execution_count": null,
24 | "metadata": {},
25 | "outputs": [],
26 | "source": [
27 | "load 'trig'"
28 | ]
29 | },
30 | {
31 | "cell_type": "code",
32 | "execution_count": null,
33 | "metadata": {},
34 | "outputs": [],
35 | "source": [
36 | "cos 1 NB. Cosine of radian arguments"
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": null,
42 | "metadata": {},
43 | "outputs": [],
44 | "source": [
45 | "cos 1 2 3.14"
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": null,
51 | "metadata": {},
52 | "outputs": [],
53 | "source": [
54 | "cosd 0 30 45 60 NB. Cosine of degree arguments"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": null,
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "(sind 0 30 45 60) ; (cosd 0 30 45 60)"
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": null,
69 | "metadata": {},
70 | "outputs": [],
71 | "source": [
72 | "circle=: cosd ; sind"
73 | ]
74 | },
75 | {
76 | "cell_type": "code",
77 | "execution_count": null,
78 | "metadata": {},
79 | "outputs": [],
80 | "source": [
81 | "circle 0 30 45 60"
82 | ]
83 | },
84 | {
85 | "cell_type": "markdown",
86 | "metadata": {},
87 | "source": [
88 | "### (2 of 5) LINK AND PLOT (ctd)\n",
89 | "\n",
90 | "The function circle yields coordinates of points on a unit circle, as may be seen in the following plot for angles from 0 to 12 degrees:\n",
91 | "\n",
92 | "After viewing the plot, press Alt F4 to return focus from the plot window:"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": null,
98 | "metadata": {},
99 | "outputs": [],
100 | "source": [
101 | "load 'plot'"
102 | ]
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": null,
107 | "metadata": {},
108 | "outputs": [],
109 | "source": [
110 | "plot circle 10 * 0 1 2 3 4 5 6 7 8 9 10 11 12"
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "### (3 of 5) INTEGER LISTS\n",
118 | "\n",
119 | "The function i. produces a vector of the first non-negative integers, as in the next example shown.\n",
120 | "\n",
121 | "Note that the plot of the circle is correct according to the scales of the plot, although it may appear flattened because of the aspect ratio of the screen."
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": null,
127 | "metadata": {},
128 | "outputs": [],
129 | "source": [
130 | "i. 13 NB. First 13 non-negative integers"
131 | ]
132 | },
133 | {
134 | "cell_type": "code",
135 | "execution_count": null,
136 | "metadata": {},
137 | "outputs": [],
138 | "source": [
139 | "plot circle i. 270"
140 | ]
141 | },
142 | {
143 | "cell_type": "markdown",
144 | "metadata": {},
145 | "source": [
146 | "### (4 of 5) THREE DIMENSIONS\n",
147 | "\n",
148 | "The function:\n",
149 | "\n",
150 | " ```spiral=: cosd ; sind ; %:```
\n",
151 | "\n",
152 | "produces tables of vectors in three dimensions, the z coordinate being the square root (%:) of the argument. For example:"
153 | ]
154 | },
155 | {
156 | "cell_type": "code",
157 | "execution_count": null,
158 | "metadata": {},
159 | "outputs": [],
160 | "source": [
161 | "spiral=: cosd ; sind ; %:"
162 | ]
163 | },
164 | {
165 | "cell_type": "code",
166 | "execution_count": null,
167 | "metadata": {},
168 | "outputs": [],
169 | "source": [
170 | "spiral 0 10 20 30"
171 | ]
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": null,
176 | "metadata": {},
177 | "outputs": [],
178 | "source": [
179 | "plot spiral i. 1000"
180 | ]
181 | },
182 | {
183 | "cell_type": "markdown",
184 | "metadata": {},
185 | "source": [
186 | "### (5 of 5) NON-CIRCULAR SPIRALS\n",
187 | "\n",
188 | "Functions other than sine and cosine may be used. In particular, the exponential (^) applied to negative arguments can be used to produce a decaying spiral. For example:"
189 | ]
190 | },
191 | {
192 | "cell_type": "code",
193 | "execution_count": null,
194 | "metadata": {},
195 | "outputs": [],
196 | "source": [
197 | "decay=: ^@(%&_500)"
198 | ]
199 | },
200 | {
201 | "cell_type": "code",
202 | "execution_count": null,
203 | "metadata": {},
204 | "outputs": [],
205 | "source": [
206 | "desin=: decay * sind"
207 | ]
208 | },
209 | {
210 | "cell_type": "code",
211 | "execution_count": null,
212 | "metadata": {},
213 | "outputs": [],
214 | "source": [
215 | "decos=: decay * cosd"
216 | ]
217 | },
218 | {
219 | "cell_type": "code",
220 | "execution_count": null,
221 | "metadata": {},
222 | "outputs": [],
223 | "source": [
224 | "despi=: decos ; desin ; %:"
225 | ]
226 | },
227 | {
228 | "cell_type": "code",
229 | "execution_count": null,
230 | "metadata": {},
231 | "outputs": [],
232 | "source": [
233 | "plot despi i. 1000"
234 | ]
235 | },
236 | {
237 | "cell_type": "markdown",
238 | "metadata": {},
239 | "source": [
240 | "### End of Lab"
241 | ]
242 | },
243 | {
244 | "cell_type": "code",
245 | "execution_count": null,
246 | "metadata": {},
247 | "outputs": [],
248 | "source": []
249 | }
250 | ],
251 | "metadata": {
252 | "kernelspec": {
253 | "display_name": "J",
254 | "language": "J",
255 | "name": "jkernel"
256 | },
257 | "language_info": {
258 | "file_extension": "ijs",
259 | "mimetype": "text/x-J",
260 | "name": "J"
261 | }
262 | },
263 | "nbformat": 4,
264 | "nbformat_minor": 2
265 | }
266 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/core/Monad_Dyad.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "deletable": true,
7 | "editable": true
8 | },
9 | "source": [
10 | "# J Labs\n",
11 | "\n",
12 | "### Monad/Dyad"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {
18 | "deletable": true,
19 | "editable": true
20 | },
21 | "source": [
22 | "### (1 of 4) INTRODUCTION\n",
23 | "\n",
24 | "If u and v are functions, then f=: u : v defines f to be a function whose monadic case is u and whose dyadic case is v\n",
25 | "\n",
26 | "For example, if v=: +, then 3 v 4 is 7 and v 4 is 4, i.e. since the monadic case of + is the conjugate, which produces an effect only on a complex argument such as 6j10.\n",
27 | "\n",
28 | "We may, however, define a function add that performs addition on two arguments, and increments a single argument. Thus:"
29 | ]
30 | },
31 | {
32 | "cell_type": "code",
33 | "execution_count": null,
34 | "metadata": {
35 | "collapsed": false,
36 | "deletable": true,
37 | "editable": true
38 | },
39 | "outputs": [],
40 | "source": [
41 | "add=: >: : +"
42 | ]
43 | },
44 | {
45 | "cell_type": "code",
46 | "execution_count": null,
47 | "metadata": {
48 | "collapsed": false,
49 | "deletable": true,
50 | "editable": true
51 | },
52 | "outputs": [],
53 | "source": [
54 | "3 add 4"
55 | ]
56 | },
57 | {
58 | "cell_type": "code",
59 | "execution_count": null,
60 | "metadata": {
61 | "collapsed": false,
62 | "deletable": true,
63 | "editable": true
64 | },
65 | "outputs": [],
66 | "source": [
67 | "add 4"
68 | ]
69 | },
70 | {
71 | "cell_type": "code",
72 | "execution_count": null,
73 | "metadata": {
74 | "collapsed": false,
75 | "deletable": true,
76 | "editable": true
77 | },
78 | "outputs": [],
79 | "source": [
80 | "add 4 5 6 7 8"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": null,
86 | "metadata": {
87 | "collapsed": false,
88 | "deletable": true,
89 | "editable": true
90 | },
91 | "outputs": [],
92 | "source": [
93 | "v=: +"
94 | ]
95 | },
96 | {
97 | "cell_type": "code",
98 | "execution_count": null,
99 | "metadata": {
100 | "collapsed": false,
101 | "deletable": true,
102 | "editable": true
103 | },
104 | "outputs": [],
105 | "source": [
106 | "3 v 4"
107 | ]
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": null,
112 | "metadata": {
113 | "collapsed": false,
114 | "deletable": true,
115 | "editable": true
116 | },
117 | "outputs": [],
118 | "source": [
119 | "v 4"
120 | ]
121 | },
122 | {
123 | "cell_type": "markdown",
124 | "metadata": {
125 | "deletable": true,
126 | "editable": true
127 | },
128 | "source": [
129 | "### (2 of 4) INTRODUCTION (ctd)\n",
130 | "\n",
131 | "Mnemonic names may be assigned to functions for the absolute value (or magnitude) and remainder (or residue) as shown below. However, the fact that these functions may each be used either monadically or dyadically can lead to some confusion. Thus:"
132 | ]
133 | },
134 | {
135 | "cell_type": "code",
136 | "execution_count": null,
137 | "metadata": {
138 | "collapsed": false,
139 | "deletable": true,
140 | "editable": true
141 | },
142 | "outputs": [],
143 | "source": [
144 | "mag=: |"
145 | ]
146 | },
147 | {
148 | "cell_type": "code",
149 | "execution_count": null,
150 | "metadata": {
151 | "collapsed": false,
152 | "deletable": true,
153 | "editable": true
154 | },
155 | "outputs": [],
156 | "source": [
157 | "res=: |"
158 | ]
159 | },
160 | {
161 | "cell_type": "code",
162 | "execution_count": null,
163 | "metadata": {
164 | "collapsed": false,
165 | "deletable": true,
166 | "editable": true
167 | },
168 | "outputs": [],
169 | "source": [
170 | "y=: 3 _4 5 _6"
171 | ]
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": null,
176 | "metadata": {
177 | "collapsed": false,
178 | "deletable": true,
179 | "editable": true
180 | },
181 | "outputs": [],
182 | "source": [
183 | "mag y"
184 | ]
185 | },
186 | {
187 | "cell_type": "code",
188 | "execution_count": null,
189 | "metadata": {
190 | "collapsed": false,
191 | "deletable": true,
192 | "editable": true
193 | },
194 | "outputs": [],
195 | "source": [
196 | "4 res y"
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": null,
202 | "metadata": {
203 | "collapsed": false,
204 | "deletable": true,
205 | "editable": true
206 | },
207 | "outputs": [],
208 | "source": [
209 | "4 mag y"
210 | ]
211 | },
212 | {
213 | "cell_type": "code",
214 | "execution_count": null,
215 | "metadata": {
216 | "collapsed": false,
217 | "deletable": true,
218 | "editable": true
219 | },
220 | "outputs": [],
221 | "source": [
222 | "res y"
223 | ]
224 | },
225 | {
226 | "cell_type": "markdown",
227 | "metadata": {
228 | "deletable": true,
229 | "editable": true
230 | },
231 | "source": [
232 | "### (3 of 4) THE CAP FUNCTION\n",
233 | "\n",
234 | "The cap function (denoted by [:) has empty domains, and therefore yields errors for any arguments. It may be used to define functions such as mag and res which yield errors unless used with the intended valence.\n",
235 | "\n",
236 | "Illustrate this by experimenting with the following functions:"
237 | ]
238 | },
239 | {
240 | "cell_type": "code",
241 | "execution_count": null,
242 | "metadata": {
243 | "collapsed": false,
244 | "deletable": true,
245 | "editable": true
246 | },
247 | "outputs": [],
248 | "source": [
249 | "mag=: | : [:"
250 | ]
251 | },
252 | {
253 | "cell_type": "code",
254 | "execution_count": null,
255 | "metadata": {
256 | "collapsed": false,
257 | "deletable": true,
258 | "editable": true
259 | },
260 | "outputs": [],
261 | "source": [
262 | "res=: [: : |"
263 | ]
264 | },
265 | {
266 | "cell_type": "markdown",
267 | "metadata": {
268 | "deletable": true,
269 | "editable": true
270 | },
271 | "source": [
272 | "### (4 of 4) THE CAP FUNCTION (ctd)\n",
273 | "\n",
274 | "The cap function may also be used in a train to cause a verb that follows it to be applied monadically.\n",
275 | "\n",
276 | "For example, a vector may be scaled to unit length by dividing it by its length, the length being the square root (%:) of the sum (+/) of the squares (*:) of its elements. Thus:"
277 | ]
278 | },
279 | {
280 | "cell_type": "code",
281 | "execution_count": null,
282 | "metadata": {
283 | "collapsed": false,
284 | "deletable": true,
285 | "editable": true
286 | },
287 | "outputs": [],
288 | "source": [
289 | "scale=: ] % [: %: [: +/ *:"
290 | ]
291 | },
292 | {
293 | "cell_type": "code",
294 | "execution_count": null,
295 | "metadata": {
296 | "collapsed": false,
297 | "deletable": true,
298 | "editable": true
299 | },
300 | "outputs": [],
301 | "source": [
302 | "scale y"
303 | ]
304 | },
305 | {
306 | "cell_type": "code",
307 | "execution_count": null,
308 | "metadata": {
309 | "collapsed": false,
310 | "deletable": true,
311 | "editable": true
312 | },
313 | "outputs": [],
314 | "source": [
315 | "%: +/ *: scale y"
316 | ]
317 | },
318 | {
319 | "cell_type": "markdown",
320 | "metadata": {
321 | "deletable": true,
322 | "editable": true
323 | },
324 | "source": [
325 | "### End of Lab"
326 | ]
327 | },
328 | {
329 | "cell_type": "code",
330 | "execution_count": null,
331 | "metadata": {
332 | "collapsed": false,
333 | "deletable": true,
334 | "editable": true
335 | },
336 | "outputs": [],
337 | "source": []
338 | }
339 | ],
340 | "metadata": {
341 | "kernelspec": {
342 | "display_name": "J",
343 | "language": "J",
344 | "name": "jkernel"
345 | },
346 | "language_info": {
347 | "file_extension": "ijs",
348 | "mimetype": "text/x-J",
349 | "name": "J"
350 | }
351 | },
352 | "nbformat": 4,
353 | "nbformat_minor": 2
354 | }
355 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/math/Frame's_Method.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "deletable": true,
7 | "editable": true
8 | },
9 | "source": [
10 | "# J Labs\n",
11 | "\n",
12 | "### Frame's Method"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {
18 | "deletable": true,
19 | "editable": true
20 | },
21 | "source": [
22 | "### (1 of 8) Introduction\n",
23 | "J. S. Frame developed an iterative method of computing the coefficients of the characteristic polynomial of a matrix (including the determinant) and also the inverse of the matrix. This lab illustrates the method of Frame using two different programming styles."
24 | ]
25 | },
26 | {
27 | "cell_type": "markdown",
28 | "metadata": {
29 | "deletable": true,
30 | "editable": true
31 | },
32 | "source": [
33 | "### (2 of 8) Frame's Method\n",
34 | "This lab shows how to compute the trace of a matrix using J. Then the trace is used in an iterative method, due to J. S. Frame, to compute the other coefficients of the charateristic polynomial of the matrix (including the determinant) and to also compute the inverse of the matrix.\n",
35 | "\n",
36 | "First, enter a sample 3 by 3 matrix M."
37 | ]
38 | },
39 | {
40 | "cell_type": "code",
41 | "execution_count": null,
42 | "metadata": {
43 | "collapsed": false,
44 | "deletable": true,
45 | "editable": true
46 | },
47 | "outputs": [],
48 | "source": [
49 | "M =: 3 3 $ 2 0 _7 3 1 4 0 5 8"
50 | ]
51 | },
52 | {
53 | "cell_type": "code",
54 | "execution_count": null,
55 | "metadata": {
56 | "collapsed": false,
57 | "deletable": true,
58 | "editable": true
59 | },
60 | "outputs": [],
61 | "source": [
62 | "M"
63 | ]
64 | },
65 | {
66 | "cell_type": "markdown",
67 | "metadata": {
68 | "deletable": true,
69 | "editable": true
70 | },
71 | "source": [
72 | "### (3 of 8) Frame's Method (ctd)\n",
73 | "Now we experiment with monadic and dyadic transpose.\n",
74 | "\n",
75 | "Monadic transpose reverses the axes of an array.\n",
76 | "\n",
77 | "In dyadic tranpose, the axes listed in the left argument are moved to the end of the list of axes. For an array of rank 2 (a matrix) the only possibilities are to leave the axes alone (and not change the matrix) or switch the axes, same as the monadic transpose.\n",
78 | "\n",
79 | "But if some axes in the left argument are boxed then those axes are run together, e.g. we get indicies i,i instead of i,j ."
80 | ]
81 | },
82 | {
83 | "cell_type": "code",
84 | "execution_count": null,
85 | "metadata": {
86 | "collapsed": false,
87 | "deletable": true,
88 | "editable": true
89 | },
90 | "outputs": [],
91 | "source": [
92 | " M; (|:M); (0|:M); (1|:M); ((<0 1)|:M)"
93 | ]
94 | },
95 | {
96 | "cell_type": "markdown",
97 | "metadata": {
98 | "deletable": true,
99 | "editable": true
100 | },
101 | "source": [
102 | "### (4 of 8) Frame's Method (ctd)\n",
103 | "Thus the principal diagonal of the matrix can be obtained with the \"pd\" function shown below.\n",
104 | "\n",
105 | "Then the trace is just the sum of the principal diagonal."
106 | ]
107 | },
108 | {
109 | "cell_type": "code",
110 | "execution_count": null,
111 | "metadata": {
112 | "collapsed": false,
113 | "deletable": true,
114 | "editable": true
115 | },
116 | "outputs": [],
117 | "source": [
118 | "pd =: (<0 1)&|:"
119 | ]
120 | },
121 | {
122 | "cell_type": "code",
123 | "execution_count": null,
124 | "metadata": {
125 | "collapsed": false,
126 | "deletable": true,
127 | "editable": true
128 | },
129 | "outputs": [],
130 | "source": [
131 | "sum =: +/"
132 | ]
133 | },
134 | {
135 | "cell_type": "code",
136 | "execution_count": null,
137 | "metadata": {
138 | "collapsed": false,
139 | "deletable": true,
140 | "editable": true
141 | },
142 | "outputs": [],
143 | "source": [
144 | "of =: @"
145 | ]
146 | },
147 | {
148 | "cell_type": "code",
149 | "execution_count": null,
150 | "metadata": {
151 | "collapsed": false,
152 | "deletable": true,
153 | "editable": true
154 | },
155 | "outputs": [],
156 | "source": [
157 | "tr =: sum of pd"
158 | ]
159 | },
160 | {
161 | "cell_type": "code",
162 | "execution_count": null,
163 | "metadata": {
164 | "collapsed": false,
165 | "deletable": true,
166 | "editable": true
167 | },
168 | "outputs": [],
169 | "source": [
170 | "tr M"
171 | ]
172 | },
173 | {
174 | "cell_type": "markdown",
175 | "metadata": {
176 | "deletable": true,
177 | "editable": true
178 | },
179 | "source": [
180 | "### (5 of 8) Frame's Method (ctd)\n",
181 | "The method of Frame is the following iteration.\n",
182 | "\n",
183 | "Let M be a given square matrix of size m by m\n",
184 | "\n",
185 | "Let F0 = I (the n by n identity matrix) and let C0 = 0.\n",
186 | "\n",
187 | "For k = 1 to m let\n",
188 | "\n",
189 | " ```Fk = M x (Fk-1 + Ck-1 x I) and Ck = -(tr Fk)/k```
\n",
190 | "\n",
191 | "Then the coefficients of the characteristic polynomial of M are Cm, ..., C1, 1. In particular, tr M = -C1 and det M = Cm(-1)^m Also, the adjoint of M is Fm-1 + Cm-1 x I and the inverse of M is (Fm-1 + Cm-1 x I)/Cm(-1)^m"
192 | ]
193 | },
194 | {
195 | "cell_type": "code",
196 | "execution_count": null,
197 | "metadata": {
198 | "collapsed": false,
199 | "deletable": true,
200 | "editable": true
201 | },
202 | "outputs": [],
203 | "source": [
204 | "frame =: verb define\n",
205 | "F =. I =. =i.m =. #M =. y\n",
206 | "C =. 0\n",
207 | "for_k. 1+i.m do.\n",
208 | "F =. M +/ . * F1 =. F + ({.C)*I\n",
209 | "C =. (-(tr F)%k),C\n",
210 | "end.\n",
211 | "((}:C),1);F1\n",
212 | ")"
213 | ]
214 | },
215 | {
216 | "cell_type": "markdown",
217 | "metadata": {
218 | "deletable": true,
219 | "editable": true
220 | },
221 | "source": [
222 | "### (6 of 8) Frame's Method (ctd)\n",
223 | "Below is the method of Frame applied to the matrix M. The output is a boxed vector of the coefficients of the characteristic polynomial of M, i.e. of which the first entry is (-1)^m times the determinant of M, followed by a boxed matrix which is the adjoint of the matrix M.\n",
224 | "\n",
225 | "Note that we could easily modify the last line of the program to output the inverse instead of the adjoint: just replace \"F1\" by \"F1%({.C)*(-1)^m\"."
226 | ]
227 | },
228 | {
229 | "cell_type": "code",
230 | "execution_count": null,
231 | "metadata": {
232 | "collapsed": false,
233 | "deletable": true,
234 | "editable": true
235 | },
236 | "outputs": [],
237 | "source": [
238 | "frame M"
239 | ]
240 | },
241 | {
242 | "cell_type": "markdown",
243 | "metadata": {
244 | "deletable": true,
245 | "editable": true
246 | },
247 | "source": [
248 | "### (7 of 8) Frame's Method (ctd)\n",
249 | "It is useful to capture the ouput in variables as shown below. Then the coefficients and adjoint matrix can be used for subsequent calculations.\n",
250 | "\n",
251 | "For example, you can see below that M times M adjoint is the determinant times the identity matrix."
252 | ]
253 | },
254 | {
255 | "cell_type": "code",
256 | "execution_count": null,
257 | "metadata": {
258 | "collapsed": false,
259 | "deletable": true,
260 | "editable": true
261 | },
262 | "outputs": [],
263 | "source": [
264 | "'C Mad' =: frame M"
265 | ]
266 | },
267 | {
268 | "cell_type": "code",
269 | "execution_count": null,
270 | "metadata": {
271 | "collapsed": false,
272 | "deletable": true,
273 | "editable": true
274 | },
275 | "outputs": [],
276 | "source": [
277 | "C"
278 | ]
279 | },
280 | {
281 | "cell_type": "code",
282 | "execution_count": null,
283 | "metadata": {
284 | "collapsed": false,
285 | "deletable": true,
286 | "editable": true
287 | },
288 | "outputs": [],
289 | "source": [
290 | "Mad"
291 | ]
292 | },
293 | {
294 | "cell_type": "code",
295 | "execution_count": null,
296 | "metadata": {
297 | "collapsed": false,
298 | "deletable": true,
299 | "editable": true
300 | },
301 | "outputs": [],
302 | "source": [
303 | "M +/ . * Mad"
304 | ]
305 | },
306 | {
307 | "cell_type": "markdown",
308 | "metadata": {
309 | "deletable": true,
310 | "editable": true
311 | },
312 | "source": [
313 | "### (8 of 8) Frame's Method (ctd)\n",
314 | "Next, we can use the monadic polynomial function \"p.\" to find the roots of the characteristic polynomial, that is, the eigenvalues of the matrix M. Then we can verify that the eigenvalues are zeros of the function\n",
315 | "\n",
316 | " ```det(M - xI)```
"
317 | ]
318 | },
319 | {
320 | "cell_type": "code",
321 | "execution_count": null,
322 | "metadata": {
323 | "collapsed": false,
324 | "deletable": true,
325 | "editable": true
326 | },
327 | "outputs": [],
328 | "source": [
329 | "p. C"
330 | ]
331 | },
332 | {
333 | "cell_type": "code",
334 | "execution_count": null,
335 | "metadata": {
336 | "collapsed": false,
337 | "deletable": true,
338 | "editable": true
339 | },
340 | "outputs": [],
341 | "source": [
342 | "'E1 E2 E3' =: >{:p. C"
343 | ]
344 | },
345 | {
346 | "cell_type": "code",
347 | "execution_count": null,
348 | "metadata": {
349 | "collapsed": false,
350 | "deletable": true,
351 | "editable": true
352 | },
353 | "outputs": [],
354 | "source": [
355 | "det =: -/ . *"
356 | ]
357 | },
358 | {
359 | "cell_type": "code",
360 | "execution_count": null,
361 | "metadata": {
362 | "collapsed": false,
363 | "deletable": true,
364 | "editable": true
365 | },
366 | "outputs": [],
367 | "source": [
368 | "I =: =i.#M"
369 | ]
370 | },
371 | {
372 | "cell_type": "code",
373 | "execution_count": null,
374 | "metadata": {
375 | "collapsed": false,
376 | "deletable": true,
377 | "editable": true
378 | },
379 | "outputs": [],
380 | "source": [
381 | "(det M - E1*I);(det M - E2*I);(det M - E3*I)"
382 | ]
383 | },
384 | {
385 | "cell_type": "markdown",
386 | "metadata": {
387 | "deletable": true,
388 | "editable": true
389 | },
390 | "source": [
391 | "### End of Lab"
392 | ]
393 | },
394 | {
395 | "cell_type": "code",
396 | "execution_count": null,
397 | "metadata": {
398 | "collapsed": false,
399 | "deletable": true,
400 | "editable": true
401 | },
402 | "outputs": [],
403 | "source": []
404 | }
405 | ],
406 | "metadata": {
407 | "kernelspec": {
408 | "display_name": "J",
409 | "language": "J",
410 | "name": "jkernel"
411 | },
412 | "language_info": {
413 | "file_extension": "ijs",
414 | "mimetype": "text/x-J",
415 | "name": "J"
416 | }
417 | },
418 | "nbformat": 4,
419 | "nbformat_minor": 2
420 | }
421 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/math/Binomial_Coefficients.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "deletable": true,
7 | "editable": true
8 | },
9 | "source": [
10 | "# J Labs\n",
11 | "\n",
12 | "### Binomial Coefficients"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {
18 | "deletable": true,
19 | "editable": true
20 | },
21 | "source": [
22 | "### (1 of 6) TABLE OR MATRIX\n",
23 | "\n",
24 | "The expression k ! n produces the kth binomial coefficient of order n, and the function bc=: i. !/ i. may be used to produce a table or matrix of binomial coefficients. For example:"
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": null,
30 | "metadata": {
31 | "collapsed": false,
32 | "deletable": true,
33 | "editable": true
34 | },
35 | "outputs": [],
36 | "source": [
37 | "0!5"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": null,
43 | "metadata": {
44 | "collapsed": false,
45 | "deletable": true,
46 | "editable": true
47 | },
48 | "outputs": [],
49 | "source": [
50 | "1!5"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": null,
56 | "metadata": {
57 | "collapsed": false,
58 | "deletable": true,
59 | "editable": true
60 | },
61 | "outputs": [],
62 | "source": [
63 | "2!5"
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": null,
69 | "metadata": {
70 | "collapsed": false,
71 | "deletable": true,
72 | "editable": true
73 | },
74 | "outputs": [],
75 | "source": [
76 | "bc=: i. !/ i."
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {
83 | "collapsed": false,
84 | "deletable": true,
85 | "editable": true
86 | },
87 | "outputs": [],
88 | "source": [
89 | "bc 6"
90 | ]
91 | },
92 | {
93 | "cell_type": "markdown",
94 | "metadata": {
95 | "deletable": true,
96 | "editable": true
97 | },
98 | "source": [
99 | "### (2 of 6) TABLE OR MATRIX (ctd)\n",
100 | "\n",
101 | "Such a matrix can be used in a variety of interesting ways. For example, its inverse is the matrix of alternating binomials, and its matrix product with a vector of polynomial coefficients (with powers in ascending order) produces the coresponding \"expanded\" coefficients. For example:"
102 | ]
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": null,
107 | "metadata": {
108 | "collapsed": false,
109 | "deletable": true,
110 | "editable": true
111 | },
112 | "outputs": [],
113 | "source": [
114 | "bct=: bc 6"
115 | ]
116 | },
117 | {
118 | "cell_type": "code",
119 | "execution_count": null,
120 | "metadata": {
121 | "collapsed": false,
122 | "deletable": true,
123 | "editable": true
124 | },
125 | "outputs": [],
126 | "source": [
127 | "bct"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": null,
133 | "metadata": {
134 | "collapsed": false,
135 | "deletable": true,
136 | "editable": true
137 | },
138 | "outputs": [],
139 | "source": [
140 | "abct=: %. bct"
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": null,
146 | "metadata": {
147 | "collapsed": false,
148 | "deletable": true,
149 | "editable": true
150 | },
151 | "outputs": [],
152 | "source": [
153 | "abct"
154 | ]
155 | },
156 | {
157 | "cell_type": "code",
158 | "execution_count": null,
159 | "metadata": {
160 | "collapsed": false,
161 | "deletable": true,
162 | "editable": true
163 | },
164 | "outputs": [],
165 | "source": [
166 | "X=: +/ . * NB. The matrix product function"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "metadata": {
173 | "collapsed": false,
174 | "deletable": true,
175 | "editable": true
176 | },
177 | "outputs": [],
178 | "source": [
179 | "bct X abct"
180 | ]
181 | },
182 | {
183 | "cell_type": "code",
184 | "execution_count": null,
185 | "metadata": {
186 | "collapsed": false,
187 | "deletable": true,
188 | "editable": true
189 | },
190 | "outputs": [],
191 | "source": [
192 | "c=: 5 1 4 0 2 2"
193 | ]
194 | },
195 | {
196 | "cell_type": "code",
197 | "execution_count": null,
198 | "metadata": {
199 | "collapsed": false,
200 | "deletable": true,
201 | "editable": true
202 | },
203 | "outputs": [],
204 | "source": [
205 | "d=: bct X c"
206 | ]
207 | },
208 | {
209 | "cell_type": "code",
210 | "execution_count": null,
211 | "metadata": {
212 | "collapsed": false,
213 | "deletable": true,
214 | "editable": true
215 | },
216 | "outputs": [],
217 | "source": [
218 | "x=: 0 1 2 3 4 5 6 7"
219 | ]
220 | },
221 | {
222 | "cell_type": "code",
223 | "execution_count": null,
224 | "metadata": {
225 | "collapsed": false,
226 | "deletable": true,
227 | "editable": true
228 | },
229 | "outputs": [],
230 | "source": [
231 | "c p. x NB. The polynomial with coefficients c"
232 | ]
233 | },
234 | {
235 | "cell_type": "code",
236 | "execution_count": null,
237 | "metadata": {
238 | "collapsed": false,
239 | "deletable": true,
240 | "editable": true
241 | },
242 | "outputs": [],
243 | "source": [
244 | "d p. x"
245 | ]
246 | },
247 | {
248 | "cell_type": "code",
249 | "execution_count": null,
250 | "metadata": {
251 | "collapsed": false,
252 | "deletable": true,
253 | "editable": true
254 | },
255 | "outputs": [],
256 | "source": [
257 | "c p. x+1"
258 | ]
259 | },
260 | {
261 | "cell_type": "markdown",
262 | "metadata": {
263 | "deletable": true,
264 | "editable": true
265 | },
266 | "source": [
267 | "### (3 of 6) TABLE OR MATRIX (ctd)\n",
268 | "\n",
269 | "The alternating binomial coefficients can be used to produce the inverse of expansion. For example:"
270 | ]
271 | },
272 | {
273 | "cell_type": "code",
274 | "execution_count": null,
275 | "metadata": {
276 | "collapsed": false,
277 | "deletable": true,
278 | "editable": true
279 | },
280 | "outputs": [],
281 | "source": [
282 | "abct X d"
283 | ]
284 | },
285 | {
286 | "cell_type": "code",
287 | "execution_count": null,
288 | "metadata": {
289 | "collapsed": false,
290 | "deletable": true,
291 | "editable": true
292 | },
293 | "outputs": [],
294 | "source": [
295 | "c"
296 | ]
297 | },
298 | {
299 | "cell_type": "code",
300 | "execution_count": null,
301 | "metadata": {
302 | "collapsed": false,
303 | "deletable": true,
304 | "editable": true
305 | },
306 | "outputs": [],
307 | "source": [
308 | "c=abct X d"
309 | ]
310 | },
311 | {
312 | "cell_type": "markdown",
313 | "metadata": {
314 | "deletable": true,
315 | "editable": true
316 | },
317 | "source": [
318 | "### (4 of 6) MANUAL METHODS OF EXPANSION\n",
319 | "\n",
320 | "If the vector c is written as a column to the right of the matrix bct, the product bct X c is easily computed by hand. Moreover, such computation may be less prone to error than commonly used methods. Try the experiment of expanding the vector c by by this method and by any others you may know.\n",
321 | "\n",
322 | "Finally, it is easy to jot down the table bct of any order, because each row is obtained from the preceding row by adding it to a shift of itself.\n",
323 | "\n",
324 | "It may also be interesting to compute the sums of the columns of bct and abct (+/ bct and +/ abct), particularly since the result of the latter is commonly mis-stated."
325 | ]
326 | },
327 | {
328 | "cell_type": "markdown",
329 | "metadata": {
330 | "deletable": true,
331 | "editable": true
332 | },
333 | "source": [
334 | "### (5 of 6) IDENTITIES\n",
335 | "\n",
336 | "It is clear that the product bct X bct contains sums over products of various binomial coefficients. If, therefore, one could spot and articulate the pattern of the elements of the result, it could be used to state a host of identities, provided that the pattern holds for larger tables.\n",
337 | "\n",
338 | "Try to state the pattern in the following results:"
339 | ]
340 | },
341 | {
342 | "cell_type": "code",
343 | "execution_count": null,
344 | "metadata": {
345 | "collapsed": false,
346 | "deletable": true,
347 | "editable": true
348 | },
349 | "outputs": [],
350 | "source": [
351 | "bct X bct"
352 | ]
353 | },
354 | {
355 | "cell_type": "code",
356 | "execution_count": null,
357 | "metadata": {
358 | "collapsed": false,
359 | "deletable": true,
360 | "editable": true
361 | },
362 | "outputs": [],
363 | "source": [
364 | "bct X bct X bct"
365 | ]
366 | },
367 | {
368 | "cell_type": "code",
369 | "execution_count": null,
370 | "metadata": {
371 | "collapsed": false,
372 | "deletable": true,
373 | "editable": true
374 | },
375 | "outputs": [],
376 | "source": [
377 | "bct X bct X bct"
378 | ]
379 | },
380 | {
381 | "cell_type": "code",
382 | "execution_count": null,
383 | "metadata": {
384 | "collapsed": false,
385 | "deletable": true,
386 | "editable": true
387 | },
388 | "outputs": [],
389 | "source": [
390 | "bct X bct X bct X bct"
391 | ]
392 | },
393 | {
394 | "cell_type": "markdown",
395 | "metadata": {
396 | "deletable": true,
397 | "editable": true
398 | },
399 | "source": [
400 | "### (6 of 6) IDENTITIES (ctd)\n",
401 | "\n",
402 | "Using the fact that M % N denotes the element-by-element division of the matrix M by the matrix N, and the fact that 0%0 is defined to be 0, try to discern the pattern in the following results:"
403 | ]
404 | },
405 | {
406 | "cell_type": "code",
407 | "execution_count": null,
408 | "metadata": {
409 | "collapsed": false,
410 | "deletable": true,
411 | "editable": true
412 | },
413 | "outputs": [],
414 | "source": [
415 | "(bct X bct) % bct"
416 | ]
417 | },
418 | {
419 | "cell_type": "code",
420 | "execution_count": null,
421 | "metadata": {
422 | "collapsed": false,
423 | "deletable": true,
424 | "editable": true
425 | },
426 | "outputs": [],
427 | "source": [
428 | "(bct X bct X bct) % bct"
429 | ]
430 | },
431 | {
432 | "cell_type": "code",
433 | "execution_count": null,
434 | "metadata": {
435 | "collapsed": false,
436 | "deletable": true,
437 | "editable": true
438 | },
439 | "outputs": [],
440 | "source": [
441 | "(bct X bct X bct) % bct"
442 | ]
443 | },
444 | {
445 | "cell_type": "code",
446 | "execution_count": null,
447 | "metadata": {
448 | "collapsed": false,
449 | "deletable": true,
450 | "editable": true
451 | },
452 | "outputs": [],
453 | "source": [
454 | "(bct X bct X bct X bct) % bct"
455 | ]
456 | },
457 | {
458 | "cell_type": "markdown",
459 | "metadata": {
460 | "deletable": true,
461 | "editable": true
462 | },
463 | "source": [
464 | "### End of Lab"
465 | ]
466 | },
467 | {
468 | "cell_type": "code",
469 | "execution_count": null,
470 | "metadata": {
471 | "collapsed": false,
472 | "deletable": true,
473 | "editable": true
474 | },
475 | "outputs": [],
476 | "source": []
477 | }
478 | ],
479 | "metadata": {
480 | "kernelspec": {
481 | "display_name": "J",
482 | "language": "J",
483 | "name": "jkernel"
484 | },
485 | "language_info": {
486 | "file_extension": "ijs",
487 | "mimetype": "text/x-J",
488 | "name": "J"
489 | }
490 | },
491 | "nbformat": 4,
492 | "nbformat_minor": 2
493 | }
494 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/graphics/Plot_Package.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# J Labs\n",
8 | "\n",
9 | "### Plot Package"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {},
15 | "source": [
16 | "### (1 of 22) Plot Overview\n",
17 | "Plot is a plotting package for J providing business and scientific graphics.\n",
18 | "\n",
19 | "To load, enter:"
20 | ]
21 | },
22 | {
23 | "cell_type": "code",
24 | "execution_count": null,
25 | "metadata": {},
26 | "outputs": [],
27 | "source": [
28 | "load 'plot'"
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "metadata": {},
34 | "source": [
35 | "### (2 of 22) Plot Overview (ctd)\n",
36 | "This loads the package into locale plot, and defines two user functions, \"pd\" (Plot Driver) and \"plot\".\n",
37 | "\n",
38 | "```pd``` - low-level function that handles all calls to Plot, typically used for complex plots.\n",
39 | "\n",
40 | "```plot``` - cover function for pd that will handle most simple uses of Plot.\n",
41 | "\n",
42 | "The examples given below also require the utilities in scripts numeric and trig. Load these as:"
43 | ]
44 | },
45 | {
46 | "cell_type": "code",
47 | "execution_count": null,
48 | "metadata": {},
49 | "outputs": [],
50 | "source": [
51 | "load 'numeric trig'"
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {},
57 | "source": [
58 | "### (3 of 22) Verb \"plot\"\n",
59 | "The form is:\n",
60 | "\n",
61 | " ```opt plot data```
\n",
62 | "\n",
63 | "The right argument is the data to be plotted. The optional left argument specifies various plot options.\n",
64 | "\n",
65 | "In general, 2D plots require x and y values given as a 2-element boxed list, and 3D plots require x, y and z values as a 3-element boxed list.\n",
66 | "\n",
67 | "However, if the right argument is open, it is treated as y values (2D plots) or z values (3D plots) . It should be a matrix of data. A vector is treated as a 1-row matrix. For 2D plots, each row of the matrix is treated as a separate data item."
68 | ]
69 | },
70 | {
71 | "cell_type": "markdown",
72 | "metadata": {},
73 | "source": [
74 | "### (4 of 22) Verb \"plot\" (ctd)\n",
75 | "The next section will plot a list of data. It is treated as y values, and the x values default to i.#y"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {},
81 | "source": [
82 | "### (5 of 22) Verb \"plot\" (ctd)"
83 | ]
84 | },
85 | {
86 | "cell_type": "code",
87 | "execution_count": null,
88 | "metadata": {},
89 | "outputs": [],
90 | "source": [
91 | "plot 1 2 3 5"
92 | ]
93 | },
94 | {
95 | "cell_type": "markdown",
96 | "metadata": {},
97 | "source": [
98 | "### (6 of 22) Verb \"plot\" (ctd)\n",
99 | "The following also plots a list of data, the sin of y where y ranges from 0 to 10 in 100 steps. The data is treated as y values, and the x values again default to i.#y\n",
100 | "\n",
101 | "This time, the default x values are inappropriate - they are shown as in the range 0 to 100, but are actually in the range 0 to 10:"
102 | ]
103 | },
104 | {
105 | "cell_type": "code",
106 | "execution_count": null,
107 | "metadata": {},
108 | "outputs": [],
109 | "source": [
110 | "plot sin steps 0 10 100"
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "### (7 of 22) Verb \"plot\" (ctd)\n",
118 | "The next example provides the correct x values as the first element of a boxed list of x and y values:"
119 | ]
120 | },
121 | {
122 | "cell_type": "code",
123 | "execution_count": null,
124 | "metadata": {},
125 | "outputs": [],
126 | "source": [
127 | "x=: steps 0 10 100"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": null,
133 | "metadata": {},
134 | "outputs": [],
135 | "source": [
136 | "plot x;sin x"
137 | ]
138 | },
139 | {
140 | "cell_type": "markdown",
141 | "metadata": {},
142 | "source": [
143 | "### (8 of 22) Plot\n",
144 | "The above example could have been entered more simply as:"
145 | ]
146 | },
147 | {
148 | "cell_type": "code",
149 | "execution_count": null,
150 | "metadata": {},
151 | "outputs": [],
152 | "source": [
153 | "plot (];sin) steps 0 10 100"
154 | ]
155 | },
156 | {
157 | "cell_type": "markdown",
158 | "metadata": {},
159 | "source": [
160 | "### (9 of 22) Parametric Plot\n",
161 | "The next example provides applies verbs to generate both the x and y values, giving a parametric plot:"
162 | ]
163 | },
164 | {
165 | "cell_type": "code",
166 | "execution_count": null,
167 | "metadata": {},
168 | "outputs": [],
169 | "source": [
170 | "plot (sin;sin*cos) steps 0 10 100"
171 | ]
172 | },
173 | {
174 | "cell_type": "markdown",
175 | "metadata": {},
176 | "source": [
177 | "### (10 of 22) Parametric Plot (ctd)\n",
178 | "It may be seen that all plots are parametric, but in the simpler cases, one of the verbs that generates the x or y values is the identity."
179 | ]
180 | },
181 | {
182 | "cell_type": "markdown",
183 | "metadata": {},
184 | "source": [
185 | "### (11 of 22) Parametric Plot (ctd)\n",
186 | "The next example plots the sin curve, swapping the identity and sin verbs to rotate the plot:"
187 | ]
188 | },
189 | {
190 | "cell_type": "code",
191 | "execution_count": null,
192 | "metadata": {},
193 | "outputs": [],
194 | "source": [
195 | "plot (sin;]) steps 0 10 100"
196 | ]
197 | },
198 | {
199 | "cell_type": "markdown",
200 | "metadata": {},
201 | "source": [
202 | "### (12 of 22) Parametric Plot (ctd)\n",
203 | "The above example could also have been entered as:"
204 | ]
205 | },
206 | {
207 | "cell_type": "code",
208 | "execution_count": null,
209 | "metadata": {},
210 | "outputs": [],
211 | "source": [
212 | "plot |. (];sin) steps 0 10 100"
213 | ]
214 | },
215 | {
216 | "cell_type": "markdown",
217 | "metadata": {},
218 | "source": [
219 | "### (13 of 22) Plot Options\n",
220 | "The left argument to plot specifies one or more options, delimited by semicolons. These are the options that may be given as arguments to pd, see below.\n",
221 | "\n",
222 | "For example, show the x and y axes, and do not show any labels:"
223 | ]
224 | },
225 | {
226 | "cell_type": "code",
227 | "execution_count": null,
228 | "metadata": {},
229 | "outputs": [],
230 | "source": [
231 | "'axes 1 1;labels 0' plot (sin;sin*cos) steps 0 10 100"
232 | ]
233 | },
234 | {
235 | "cell_type": "markdown",
236 | "metadata": {},
237 | "source": [
238 | "### (14 of 22) Plot Options (ctd)\n",
239 | "The next example plots a matrix of sin values. Each row is treated as a separate data item:"
240 | ]
241 | },
242 | {
243 | "cell_type": "code",
244 | "execution_count": null,
245 | "metadata": {},
246 | "outputs": [],
247 | "source": [
248 | "plot sin */~ steps 0 3 50"
249 | ]
250 | },
251 | {
252 | "cell_type": "markdown",
253 | "metadata": {},
254 | "source": [
255 | "### (15 of 22) Surface Plots\n",
256 | "The \"surface\" option displays this as a surface plot:"
257 | ]
258 | },
259 | {
260 | "cell_type": "code",
261 | "execution_count": null,
262 | "metadata": {},
263 | "outputs": [],
264 | "source": [
265 | "'surface' plot sin */~ steps 0 3 50"
266 | ]
267 | },
268 | {
269 | "cell_type": "markdown",
270 | "metadata": {},
271 | "source": [
272 | "### (16 of 22) Surface Plots (ctd)\n",
273 | "In the above example, \"surface\" is short for \"type surface\".\n",
274 | "\n",
275 | "If the first option is a type, the word \"type\" may be omitted.\n",
276 | "\n",
277 | "3D graphics options include viewpoint, viewbox sizing, and the vertical direction. For example:"
278 | ]
279 | },
280 | {
281 | "cell_type": "code",
282 | "execution_count": null,
283 | "metadata": {},
284 | "outputs": [],
285 | "source": [
286 | "Z=: sin */~ steps 0 3 50"
287 | ]
288 | },
289 | {
290 | "cell_type": "code",
291 | "execution_count": null,
292 | "metadata": {},
293 | "outputs": [],
294 | "source": [
295 | "'surface;viewsize 1 1 0.2;viewpoint 1 0 0.7' plot Z"
296 | ]
297 | },
298 | {
299 | "cell_type": "markdown",
300 | "metadata": {},
301 | "source": [
302 | "### (17 of 22) Surface Plots (ctd)\n",
303 | "Surface is the default type when x y and z values are provided in a 3-element boxed list.\n",
304 | "\n",
305 | "The following example shows the standard sombrero:"
306 | ]
307 | },
308 | {
309 | "cell_type": "code",
310 | "execution_count": null,
311 | "metadata": {},
312 | "outputs": [],
313 | "source": [
314 | "X=: Y=: steps _3 3 70"
315 | ]
316 | },
317 | {
318 | "cell_type": "code",
319 | "execution_count": null,
320 | "metadata": {},
321 | "outputs": [],
322 | "source": [
323 | "Z=: (cos % 3&+) X (+/&:*:) Y"
324 | ]
325 | },
326 | {
327 | "cell_type": "code",
328 | "execution_count": null,
329 | "metadata": {},
330 | "outputs": [],
331 | "source": [
332 | "'boxed 0' plot X;Y;Z"
333 | ]
334 | },
335 | {
336 | "cell_type": "markdown",
337 | "metadata": {},
338 | "source": [
339 | "### (18 of 22) Surface Plots (ctd)\n",
340 | "This is the same sombrero, after use as a cushion:"
341 | ]
342 | },
343 | {
344 | "cell_type": "code",
345 | "execution_count": null,
346 | "metadata": {},
347 | "outputs": [],
348 | "source": [
349 | "'boxed 0;viewsize 1 1 0.05' plot X;Y;Z"
350 | ]
351 | },
352 | {
353 | "cell_type": "markdown",
354 | "metadata": {},
355 | "source": [
356 | "### (19 of 22) Business Graphics\n",
357 | "Plots for business graphics include various bar charts, pie charts, and hi-lo close.\n",
358 | "\n",
359 | "For example, a stacked barchart:"
360 | ]
361 | },
362 | {
363 | "cell_type": "code",
364 | "execution_count": null,
365 | "metadata": {},
366 | "outputs": [],
367 | "source": [
368 | "'sbar' plot >:?.>:i.3 5"
369 | ]
370 | },
371 | {
372 | "cell_type": "markdown",
373 | "metadata": {},
374 | "source": [
375 | "### (20 of 22) Business Graphics (ctd)\n",
376 | "Plots for business graphics include various bar charts, pie charts, and hi-lo close.\n",
377 | "\n",
378 | "Floating barchart, with title:"
379 | ]
380 | },
381 | {
382 | "cell_type": "code",
383 | "execution_count": null,
384 | "metadata": {},
385 | "outputs": [],
386 | "source": [
387 | "'fbar;title My Plot' plot >:?>:i.3 5"
388 | ]
389 | },
390 | {
391 | "cell_type": "markdown",
392 | "metadata": {},
393 | "source": [
394 | "### (21 of 22) Verb \"pd\"\n",
395 | "\"pd\" is a monadic function whose argument is either a list of commands or options given as a character string delimited by semicolons, or data given as numeric data.\n",
396 | "\n",
397 | "For example:"
398 | ]
399 | },
400 | {
401 | "cell_type": "code",
402 | "execution_count": null,
403 | "metadata": {},
404 | "outputs": [],
405 | "source": [
406 | "pd 'reset' NB. reset plot"
407 | ]
408 | },
409 | {
410 | "cell_type": "code",
411 | "execution_count": null,
412 | "metadata": {},
413 | "outputs": [],
414 | "source": [
415 | "pd 'type line' NB. set line type"
416 | ]
417 | },
418 | {
419 | "cell_type": "code",
420 | "execution_count": null,
421 | "metadata": {},
422 | "outputs": [],
423 | "source": [
424 | "pd *: i.10 NB. set plot data"
425 | ]
426 | },
427 | {
428 | "cell_type": "code",
429 | "execution_count": null,
430 | "metadata": {},
431 | "outputs": [],
432 | "source": [
433 | "pd 'show' NB. show it"
434 | ]
435 | },
436 | {
437 | "cell_type": "markdown",
438 | "metadata": {},
439 | "source": [
440 | "### (22 of 22) Plot Demo\n",
441 | "For several examples using pd, load the plot demo from menu item Studio|Demos|plot.\n",
442 | "\n",
443 | "In the demo, select menu item Options|View Definition to view and experiment with the definitions."
444 | ]
445 | },
446 | {
447 | "cell_type": "markdown",
448 | "metadata": {},
449 | "source": [
450 | "### End of Lab"
451 | ]
452 | },
453 | {
454 | "cell_type": "code",
455 | "execution_count": null,
456 | "metadata": {},
457 | "outputs": [],
458 | "source": []
459 | }
460 | ],
461 | "metadata": {
462 | "kernelspec": {
463 | "display_name": "J",
464 | "language": "J",
465 | "name": "jkernel"
466 | },
467 | "language_info": {
468 | "file_extension": "ijs",
469 | "mimetype": "text/x-J",
470 | "name": "J"
471 | }
472 | },
473 | "nbformat": 4,
474 | "nbformat_minor": 2
475 | }
476 |
--------------------------------------------------------------------------------
/jkernel/jinter.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env /usr/bin/python3
2 | ###############################################################################
3 | # File: jinter.py
4 | # Author: Martin Saurer, original 30.12.2017, rewrite 23.02.2020
5 | # Description: Call J from Python.
6 | # License: GPL Version 3 (see gpl3.txt)
7 | ###############################################################################
8 | # -*- coding: utf-8 -*-
9 |
10 | ###############################################################################
11 | # Import modules
12 | ###############################################################################
13 |
14 | # Standard Library Imports
15 | import os
16 | import sys
17 | import ctypes
18 | import warnings
19 |
20 | ###############################################################################
21 | # Utility functions
22 | ###############################################################################
23 |
24 | # Get exception info
25 | def get_exception_info():
26 | typ,val,trb = sys.exc_info()
27 | fil = os.path.split(trb.tb_frame.f_code.co_filename)[1]
28 | lin = trb.tb_lineno
29 | est = ('Exception: ' + str(typ) + ': ' + str(val) + ' / in ' + str(fil) +
30 | ':' + str(lin))
31 | return est
32 | # end def
33 |
34 | # Encode string to utf-8 bytes
35 | def string_encode(s):
36 | if isinstance(s,str):
37 | return s.encode('utf-8')
38 | else:
39 | return s
40 | # end if
41 | # end def
42 |
43 | # Decode utf-8 bytes to string
44 | def string_decode(s):
45 | if isinstance(s,str):
46 | return s
47 | else:
48 | return s.decode('utf-8','replace')
49 | # end if
50 | # end def
51 |
52 | # Conmvert byte-encoded integer to int
53 | def bytes_to_int(bytes,byteorder='little'):
54 | r = int.from_bytes(bytes,byteorder)
55 | return r
56 | # end def
57 |
58 | # Encode int to byte-encoded integer
59 | def int_to_bytes(value,
60 | length=ctypes.sizeof(ctypes.c_longlong),
61 | byteorder='little'):
62 | b = int(value).to_bytes(length,byteorder)
63 | return b
64 | # end def
65 |
66 | ###############################################################################
67 | # Internal setup
68 | ###############################################################################
69 |
70 | # We ignore warnings (for now ;-)
71 | #warnings.filterwarnings('ignore')
72 |
73 | ###############################################################################
74 | # J interpreter class
75 | ###############################################################################
76 |
77 | # J interpreter class
78 | class J():
79 |
80 | # Constants
81 | MTYOFM = 1 # Formatted result array output
82 | MTYOER = 2 # Error output
83 | MTYOLOG = 3 # Output log
84 | MTYOSYS = 4 # System assertion failure
85 | MTYOEXIT = 5 # Exit
86 | MTYOFILE = 6 # Output 1!:2[2
87 |
88 | SMWIN = 0 # Windows front end
89 | SMJAVA = 2 # Java front end
90 | SMCON = 3 # Console (or shared library)
91 |
92 | # Constructor
93 | def __init__(self,JInsFol,JBinFol):
94 |
95 | # Members for input/output
96 | self.JInpRdy = False
97 | self.JOutRdy = False
98 | self.JIolRun = True
99 | self.JWForIn = True
100 | self.JCurDir = ''
101 | self.JProStr = ''
102 | self.JInpStr = ''
103 | self.JOutStr = ''
104 |
105 | # J Binaries Folder (absolute or relative (to JInsFol) path)
106 | self.JInsFol = JInsFol
107 | self.JBinFol = JBinFol
108 |
109 | # J user folder
110 | self.JUsrFol = ''
111 |
112 | # J Profile (absolute or relative (to JBinFol) path)
113 | self.JProFil = 'profile.ijs'
114 |
115 | # Declare J variable types for calling JGetM/JSetM
116 | self.JvrType = ctypes.c_longlong(0)
117 | self.JvrRank = ctypes.c_longlong(0)
118 | self.JvrShap = ctypes.c_longlong(0)
119 | self.JvrData = ctypes.c_longlong(0)
120 |
121 | # Build J Dynamic Library name
122 | if sys.platform.startswith('win' ): self.JDynLib = 'j.dll'
123 | elif sys.platform.startswith('darwin'): self.JDynLib = 'libj.dylib'
124 | elif sys.platform.startswith('linux' ): self.JDynLib = 'libj.so'
125 | else: self.JDynLib = ''
126 |
127 | # Build J path names
128 | if os.path.isabs(self.JBinFol):
129 | self.JBin = os.path.join(self.JBinFol)
130 | self.JLib = os.path.join(self.JBinFol,
131 | self.JDynLib)
132 | if os.path.isabs(self.JProFil):
133 | self.JPro = self.JProFil
134 | else:
135 | self.JPro = os.path.join(self.JBinFol,
136 | self.JProFil)
137 | # end if
138 | else:
139 | self.JBin = os.path.join(self.JInsFol,
140 | self.JBinFol)
141 | self.JLib = os.path.join(self.JInsFol,
142 | self.JBinFol,
143 | self.JDynLib)
144 | if os.path.isabs(self.JProFil):
145 | self.JPro = self.JProFil
146 | else:
147 | self.JPro = os.path.join(self.JInsFol,
148 | self.JBinFol,
149 | self.JProFil)
150 | # end if
151 | # end if
152 |
153 | # Declare J callback types
154 | if sys.platform.startswith('win'):
155 |
156 | self.JInputType = ctypes.WINFUNCTYPE(ctypes.c_char_p,
157 | ctypes.c_longlong,
158 | ctypes.c_char_p)
159 |
160 | self.JWdType = ctypes.WINFUNCTYPE(ctypes.c_longlong,
161 | ctypes.c_longlong,
162 | ctypes.c_longlong,
163 | ctypes.c_void_p,
164 | ctypes.c_void_p)
165 |
166 | self.JOutputType = ctypes.WINFUNCTYPE(None,
167 | ctypes.c_longlong,
168 | ctypes.c_longlong,
169 | ctypes.c_char_p)
170 |
171 | else:
172 |
173 | self.JInputType = ctypes.CFUNCTYPE (ctypes.c_char_p,
174 | ctypes.c_longlong,
175 | ctypes.c_char_p)
176 |
177 | self.JWdType = ctypes.CFUNCTYPE (ctypes.c_longlong,
178 | ctypes.c_longlong,
179 | ctypes.c_longlong,
180 | ctypes.c_void_p,
181 | ctypes.c_void_p)
182 |
183 | self.JOutputType = ctypes.CFUNCTYPE (None,
184 | ctypes.c_longlong,
185 | ctypes.c_longlong,
186 | ctypes.c_char_p)
187 |
188 | # end if
189 |
190 | # Declare J callback functions
191 | self.JInputFunc = self.JInputType(self.JInput)
192 | self.JWdFunc = self.JWdType(self.JWd)
193 | self.JOutputFunc = self.JOutputType(self.JOutput)
194 | self.JCallBacks = [
195 | self.JOutputFunc,
196 | self.JWdFunc,
197 | self.JInputFunc,
198 | 0,
199 | ctypes.c_void_p(J.SMCON)
200 | ]
201 | self.JCBArTypes = (ctypes.c_void_p * len(self.JCallBacks))
202 | self.JCBArArray = self.JCBArTypes()
203 | self.JCBArArray[0] = ctypes.cast(self.JCallBacks[0],ctypes.c_void_p)
204 | self.JCBArArray[1] = ctypes.cast(self.JCallBacks[1],ctypes.c_void_p)
205 | self.JCBArArray[2] = ctypes.cast(self.JCallBacks[2],ctypes.c_void_p)
206 | self.JCBArArray[3] = ctypes.c_void_p(self.JCallBacks[3])
207 | self.JCBArArray[4] = self.JCallBacks[4]
208 |
209 | # Load J dynamic link library / shareable object
210 | if sys.platform.startswith('win'):
211 | self.JDll = ctypes.windll.LoadLibrary(self.JLib)
212 | else:
213 | self.JDll = ctypes.cdll.LoadLibrary(self.JLib)
214 | # end if
215 |
216 | # Declare result type of JInit (this is mandatory !!!)
217 | self.JDll.JInit.restype = ctypes.c_void_p
218 |
219 | # Initialize J engine
220 | self.JSession = ctypes.c_void_p(self.JDll.JInit())
221 |
222 | # Register callback functions
223 | self.JDll.JSM(self.JSession,self.JCBArArray)
224 |
225 | # Setup J environment
226 | s = self.JDll.JDo(self.JSession,
227 | string_encode('ARGV_z_ =: \'\''))
228 | s = self.JDll.JDo(self.JSession,
229 | string_encode('BINPATH_z_ =: \'' + self.JBin + '\''))
230 | s = self.JDll.JDo(self.JSession,
231 | string_encode('0!:0 <\'' + self.JPro + '\''))
232 | s = self.JDll.JDo(self.JSession,
233 | string_encode('NB. 9!:37 (0,16384,0,16000)'))
234 | s = self.JDll.JDo(self.JSession,
235 | string_encode('9!:7 (0{Boxes_j_)'))
236 |
237 | # end def __init__(self,JInsFol,JBinFol)
238 |
239 | ###########################################################################
240 | # I/O callback functions
241 | ###########################################################################
242 |
243 | # J input callback
244 | def JInput(self,j,p):
245 | return string_encode(input(p.decode('utf-8')))
246 | # end def
247 |
248 | # J output callback
249 | def JOutput(self,j,t,s):
250 | if t == J.MTYOEXIT:
251 | sys.exit(0)
252 | # end if
253 | self.JOutStr += string_decode(s)
254 | self.JOutRdy = True
255 | # end def
256 |
257 | # J window driver callback
258 | # In fact, we use Jwd as an entry point for custom callbacks, using
259 | # J foreign function 11!:x
260 | # We read x (int) and the string in struct pa
261 | # We do not write anything to struct pz
262 | # Return is always 0
263 | # mode = x: ...
264 | # parm = : String Parameter to 11!:x ''
265 | def JWd(self,j,x,pa,pz):
266 |
267 | # Get mode
268 | mode = x
269 |
270 | # Get string parameter
271 | sptr = ctypes.pointer(
272 | ctypes.c_longlong(pa +
273 | (ctypes.sizeof(ctypes.c_longlong) *
274 | ctypes.sizeof(ctypes.c_longlong))))
275 | parm = ctypes.string_at(sptr.contents.value)
276 | parm = string_decode(parm)
277 |
278 | # Relevant information is in "mode" and "parm",
279 | # but we don't use any of these for now
280 | if mode != 0:
281 | print('JWd: mode=' + str(mode) + ', parm=\"' + parm + '\"')
282 | # end if
283 |
284 | # Return 0 (always)
285 | return 0
286 |
287 | # end def
288 |
289 | ###########################################################################
290 | # Utility functions
291 | ###########################################################################
292 |
293 | # Do a J sentence
294 | def Exec(self,cmd):
295 | s = self.JDll.JDo(self.JSession,ctypes.c_char_p(string_encode(cmd)))
296 | return s
297 | # end def
298 |
299 | # Receive output
300 | def Recv(self):
301 | out = ''
302 | if self.JOutRdy:
303 | out = self.JOutStr
304 | self.JOutStr = ''
305 | self.JOutRdy = False
306 | # end if
307 | return out
308 | # end def
309 |
310 | # Get J string variable
311 | def GetStrVar(self,var):
312 | # Declare J variable types for calling JGetM/JSetM
313 | self.JvrType = ctypes.c_longlong(0)
314 | self.JvrRank = ctypes.c_longlong(0)
315 | self.JvrShap = ctypes.c_longlong(0)
316 | self.JvrData = ctypes.c_longlong(0)
317 | # Get variable
318 | sts = self.JDll.JGetM(self.JSession,
319 | string_encode(var),
320 | ctypes.byref(self.JvrType),
321 | ctypes.byref(self.JvrRank),
322 | ctypes.byref(self.JvrShap),
323 | ctypes.byref(self.JvrData))
324 | if sts == 0:
325 | sln = bytes_to_int(ctypes.string_at(self.JvrShap.value,
326 | ctypes.sizeof(ctypes.c_longlong)))
327 | val = ctypes.string_at(self.JvrData.value,sln)
328 | val = string_decode(val)
329 | return val
330 | else:
331 | return ''
332 | # end if
333 | # end def
334 |
335 | # Set J string variable
336 | def SetStrVar(self,var,val):
337 | typ = ctypes.c_longlong(2)
338 | ran = ctypes.c_longlong(1)
339 | sln = ctypes.c_longlong(len(val))
340 | sha = ctypes.c_char_p(
341 | ctypes.string_at(
342 | ctypes.addressof(sln),ctypes.sizeof(ctypes.c_longlong)))
343 | dat = ctypes.c_char_p(string_encode(val))
344 | sts = self.JDll.JSetM(self.JSession,
345 | string_encode(var),
346 | ctypes.byref(typ),
347 | ctypes.byref(ran),
348 | ctypes.byref(sha),
349 | ctypes.byref(dat))
350 | return sts
351 | # end def
352 |
353 | ###############################################################################
354 | # Main Entry Point
355 | ###############################################################################
356 |
357 | # For testing, here is an example of a Python driven Jconsole
358 | if __name__ == '__main__':
359 |
360 | # Create async J instance
361 | j = J('/home/martin/J901','bin')
362 | #j = J('C:\\Users\\martsa-adm\\J901','bin')
363 |
364 | # Run our I/O loop
365 | while True:
366 |
367 | # Get input
368 | cmd = input(' ')
369 |
370 | # Exec J sentence
371 | j.Exec(cmd)
372 |
373 | # Print output
374 | sys.stdout.write(j.Recv())
375 |
376 | # end while
377 |
378 | # end if
379 |
380 | ###############################################################################
381 | # EOF
382 | ###############################################################################
383 |
384 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/core/A_Taste_of_J_(2).ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "deletable": true,
7 | "editable": true
8 | },
9 | "source": [
10 | "# J Labs\n",
11 | "\n",
12 | "### A Taste of J (2)"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {
18 | "deletable": true,
19 | "editable": true
20 | },
21 | "source": [
22 | "### (1 of 18) First Steps\n",
23 | "Look at the following J sentences; can you figure them out? The sentences are shown indented 3 spaces; the result, if any, is shown aligned to the left margin.\n",
24 | "\n",
25 | "These simple sentences illustrate some of the core facilities of J, that will be described in this lab."
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": null,
31 | "metadata": {
32 | "collapsed": false,
33 | "deletable": true,
34 | "editable": true
35 | },
36 | "outputs": [],
37 | "source": [
38 | "tab=: /~"
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": null,
44 | "metadata": {
45 | "collapsed": false,
46 | "deletable": true,
47 | "editable": true
48 | },
49 | "outputs": [],
50 | "source": [
51 | "(];*.tab;!tab) _2+i.7"
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {
57 | "deletable": true,
58 | "editable": true
59 | },
60 | "source": [
61 | "### (2 of 18) First Steps (ctd)\n",
62 | "To start, note that \"verbs\" (i.e. functions) in J can apply to several data items at once. Indeed, the basic datatype is an array, and J verbs are designed to apply to arrays. For example, the following adds two lists of numbers:"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": null,
68 | "metadata": {
69 | "collapsed": false,
70 | "deletable": true,
71 | "editable": true
72 | },
73 | "outputs": [],
74 | "source": [
75 | "2 3 5 + 10 20 30"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {
81 | "deletable": true,
82 | "editable": true
83 | },
84 | "source": [
85 | "### (3 of 18) Adverbs\n",
86 | "The \"adverb\" in J takes a verb argument and returns another verb, typically related. The behaviour is much like in English: \"run quickly\", is the verb \"run\", modified by the adverb \"quickly\".\n",
87 | "\n",
88 | "The J adverb / results in a verb that applies to each pair of elements, compare with above:"
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": null,
94 | "metadata": {
95 | "collapsed": false,
96 | "deletable": true,
97 | "editable": true
98 | },
99 | "outputs": [],
100 | "source": [
101 | "2 3 5 +/ 10 20 30"
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "metadata": {
107 | "deletable": true,
108 | "editable": true
109 | },
110 | "source": [
111 | "### (4 of 18) Adverbs (ctd)\n",
112 | "Thus, +/ forms an addition table, and similarly, \\*/ forms a multiplication table:"
113 | ]
114 | },
115 | {
116 | "cell_type": "code",
117 | "execution_count": null,
118 | "metadata": {
119 | "collapsed": false,
120 | "deletable": true,
121 | "editable": true
122 | },
123 | "outputs": [],
124 | "source": [
125 | "2 3 5 */ 10 20 30"
126 | ]
127 | },
128 | {
129 | "cell_type": "markdown",
130 | "metadata": {
131 | "deletable": true,
132 | "editable": true
133 | },
134 | "source": [
135 | "### (5 of 18) Adverbs (ctd)\n",
136 | "Try entering:\n",
137 | "\n",
138 | " ```2 3 5 %/ 10 20 30```
"
139 | ]
140 | },
141 | {
142 | "cell_type": "markdown",
143 | "metadata": {
144 | "deletable": true,
145 | "editable": true
146 | },
147 | "source": [
148 | "### (6 of 18) Adverbs (ctd)\n",
149 | "The adverb ~ applies a verb with the same argument on the left as on the right, thus the following two expressions are equivalent:"
150 | ]
151 | },
152 | {
153 | "cell_type": "code",
154 | "execution_count": null,
155 | "metadata": {
156 | "collapsed": false,
157 | "deletable": true,
158 | "editable": true
159 | },
160 | "outputs": [],
161 | "source": [
162 | "0 1 2 3 + 0 1 2 3"
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": null,
168 | "metadata": {
169 | "collapsed": false,
170 | "deletable": true,
171 | "editable": true
172 | },
173 | "outputs": [],
174 | "source": [
175 | "+~ 0 1 2 3"
176 | ]
177 | },
178 | {
179 | "cell_type": "markdown",
180 | "metadata": {
181 | "deletable": true,
182 | "editable": true
183 | },
184 | "source": [
185 | "### (7 of 18) Adverbs (ctd)\n",
186 | "We can combine two adverbs. The following applies the +/ addition table with the same argument on left and right:"
187 | ]
188 | },
189 | {
190 | "cell_type": "code",
191 | "execution_count": null,
192 | "metadata": {
193 | "collapsed": false,
194 | "deletable": true,
195 | "editable": true
196 | },
197 | "outputs": [],
198 | "source": [
199 | "+/~ 0 1 2 3"
200 | ]
201 | },
202 | {
203 | "cell_type": "markdown",
204 | "metadata": {
205 | "deletable": true,
206 | "editable": true
207 | },
208 | "source": [
209 | "### (8 of 18) Adverbs (ctd)\n",
210 | "Since /~ is to be used again, we give it a name \"tab\". This is not required, but is helpful in reading later expressions."
211 | ]
212 | },
213 | {
214 | "cell_type": "code",
215 | "execution_count": null,
216 | "metadata": {
217 | "collapsed": false,
218 | "deletable": true,
219 | "editable": true
220 | },
221 | "outputs": [],
222 | "source": [
223 | "tab=. /~"
224 | ]
225 | },
226 | {
227 | "cell_type": "code",
228 | "execution_count": null,
229 | "metadata": {
230 | "collapsed": false,
231 | "deletable": true,
232 | "editable": true
233 | },
234 | "outputs": [],
235 | "source": [
236 | "+ tab 0 1 2 3"
237 | ]
238 | },
239 | {
240 | "cell_type": "code",
241 | "execution_count": null,
242 | "metadata": {
243 | "collapsed": false,
244 | "deletable": true,
245 | "editable": true
246 | },
247 | "outputs": [],
248 | "source": [
249 | "* tab 0 1 2 3"
250 | ]
251 | },
252 | {
253 | "cell_type": "markdown",
254 | "metadata": {
255 | "deletable": true,
256 | "editable": true
257 | },
258 | "source": [
259 | "### (9 of 18) Adverbs (ctd)\n",
260 | "Try entering:\n",
261 | "\n",
262 | " ```^ tab 0 1 2 3```
"
263 | ]
264 | },
265 | {
266 | "cell_type": "markdown",
267 | "metadata": {
268 | "deletable": true,
269 | "editable": true
270 | },
271 | "source": [
272 | "### (10 of 18) Integer\n",
273 | "The verb i. (integer) generates the first n numbers.\n",
274 | "\n",
275 | "Try entering:\n",
276 | "\n",
277 | " ```i. 3 4```
\n",
278 | "\n",
279 | " ```i. 3 4 5```
"
280 | ]
281 | },
282 | {
283 | "cell_type": "code",
284 | "execution_count": null,
285 | "metadata": {
286 | "collapsed": false,
287 | "deletable": true,
288 | "editable": true
289 | },
290 | "outputs": [],
291 | "source": [
292 | "i.7"
293 | ]
294 | },
295 | {
296 | "cell_type": "markdown",
297 | "metadata": {
298 | "deletable": true,
299 | "editable": true
300 | },
301 | "source": [
302 | "### (11 of 18) Negative Numbers\n",
303 | "Negative numbers are shown with a leading underscore character, which is not the same as \"-\", the minus verb."
304 | ]
305 | },
306 | {
307 | "cell_type": "code",
308 | "execution_count": null,
309 | "metadata": {
310 | "collapsed": false,
311 | "deletable": true,
312 | "editable": true
313 | },
314 | "outputs": [],
315 | "source": [
316 | "_2+ i.7"
317 | ]
318 | },
319 | {
320 | "cell_type": "markdown",
321 | "metadata": {
322 | "deletable": true,
323 | "editable": true
324 | },
325 | "source": [
326 | "### (12 of 18) Combining Verbs\n",
327 | "Now lets look at the expression in parentheses:\n",
328 | "\n",
329 | " ```];*.tab;!tab```
\n",
330 | "\n",
331 | "Ignoring the semicolons for the moment, the expression contains 3 verbs:\n",
332 | "\n",
333 | "] is the identity verb:"
334 | ]
335 | },
336 | {
337 | "cell_type": "code",
338 | "execution_count": null,
339 | "metadata": {
340 | "collapsed": false,
341 | "deletable": true,
342 | "editable": true
343 | },
344 | "outputs": [],
345 | "source": [
346 | "] _2+i.7"
347 | ]
348 | },
349 | {
350 | "cell_type": "markdown",
351 | "metadata": {
352 | "deletable": true,
353 | "editable": true
354 | },
355 | "source": [
356 | "### (13 of 18) Combining Verbs (ctd)\n",
357 | "```*.``` is the least common multiple verb, so ```*.tab``` is the corresponding table. For example, the LCM of 3 and 4 is 12:"
358 | ]
359 | },
360 | {
361 | "cell_type": "code",
362 | "execution_count": null,
363 | "metadata": {
364 | "collapsed": false,
365 | "deletable": true,
366 | "editable": true
367 | },
368 | "outputs": [],
369 | "source": [
370 | "3 *. 4"
371 | ]
372 | },
373 | {
374 | "cell_type": "code",
375 | "execution_count": null,
376 | "metadata": {
377 | "collapsed": false,
378 | "deletable": true,
379 | "editable": true
380 | },
381 | "outputs": [],
382 | "source": [
383 | "*.tab _2+i.7"
384 | ]
385 | },
386 | {
387 | "cell_type": "markdown",
388 | "metadata": {
389 | "deletable": true,
390 | "editable": true
391 | },
392 | "source": [
393 | "### (14 of 18) Combining Verbs (ctd)\n",
394 | "! is the combinations verb. m!n is the number of ways of taking m combinations of n objects; so !tab is the corresponding table. For example, 2!4 is 6.\n",
395 | "\n",
396 | "Note that if you look at the lower right part of the table, you can see a copy of the triangle of Pascal."
397 | ]
398 | },
399 | {
400 | "cell_type": "code",
401 | "execution_count": null,
402 | "metadata": {
403 | "collapsed": false,
404 | "deletable": true,
405 | "editable": true
406 | },
407 | "outputs": [],
408 | "source": [
409 | "2!4"
410 | ]
411 | },
412 | {
413 | "cell_type": "code",
414 | "execution_count": null,
415 | "metadata": {
416 | "collapsed": false,
417 | "deletable": true,
418 | "editable": true
419 | },
420 | "outputs": [],
421 | "source": [
422 | "!tab _2+i.7"
423 | ]
424 | },
425 | {
426 | "cell_type": "markdown",
427 | "metadata": {
428 | "deletable": true,
429 | "editable": true
430 | },
431 | "source": [
432 | "### (15 of 18) Combining Verbs (ctd)\n",
433 | "The expression in parentheses:\n",
434 | "\n",
435 | " ```];*.tab;!tab```
\n",
436 | "\n",
437 | "is therefore seen to be of the form:\n",
438 | "\n",
439 | " ```f;g;h```
\n",
440 | "\n",
441 | "for verbs f g and h. It happens that ; is also a verb, so this expression is a list of 5 verbs!\n",
442 | "\n",
443 | "To understand this, consider a simpler list of 3 verbs commonly seen in mathematics. Suppose f and g are functions, then:\n",
444 | "\n",
445 | " ```(f + g) x```
\n",
446 | "\n",
447 | "is typically defined to be\n",
448 | "\n",
449 | " ```f(x) + g(x)```
\n",
450 | "\n",
451 | "In J, this concept is extended to any type of function. Given verbs f g and h, then:\n",
452 | "\n",
453 | " ```(f g h) x```
\n",
454 | "\n",
455 | "is defined as\n",
456 | "\n",
457 | " ```(f x) g (h x)```
\n",
458 | "\n",
459 | "Example:"
460 | ]
461 | },
462 | {
463 | "cell_type": "code",
464 | "execution_count": null,
465 | "metadata": {
466 | "collapsed": false,
467 | "deletable": true,
468 | "editable": true
469 | },
470 | "outputs": [],
471 | "source": [
472 | "(] + %) 1 2 3 4 NB. % is the reciprocal"
473 | ]
474 | },
475 | {
476 | "cell_type": "markdown",
477 | "metadata": {
478 | "deletable": true,
479 | "editable": true
480 | },
481 | "source": [
482 | "### (16 of 18) Combining Verbs (ctd)\n",
483 | "A list of 3 verbs together is called a fork, and defines a new verb.\n",
484 | "\n",
485 | "Here is another example. The verb ; links its arguments together, putting each in a box. The following is the fork: identity linked with reciprocal."
486 | ]
487 | },
488 | {
489 | "cell_type": "code",
490 | "execution_count": null,
491 | "metadata": {
492 | "collapsed": false,
493 | "deletable": true,
494 | "editable": true
495 | },
496 | "outputs": [],
497 | "source": [
498 | "(] ; %) 1 2 3 4"
499 | ]
500 | },
501 | {
502 | "cell_type": "markdown",
503 | "metadata": {
504 | "deletable": true,
505 | "editable": true
506 | },
507 | "source": [
508 | "### (17 of 18) Combining Verbs (ctd)\n",
509 | "J interprets a list of 5 verbs by creating a fork from the rightmost 3 verbs, then another fork from the new verb and the two remaining verbs.\n",
510 | "\n",
511 | "It may be seen that:\n",
512 | "\n",
513 | " ```(];*.tab;!tab)```
\n",
514 | "\n",
515 | "is a verb that returns the identity; the LCM table; and the combinations table; all linked together.\n",
516 | "\n",
517 | "Lets try it with a different argument:"
518 | ]
519 | },
520 | {
521 | "cell_type": "code",
522 | "execution_count": null,
523 | "metadata": {
524 | "collapsed": false,
525 | "deletable": true,
526 | "editable": true
527 | },
528 | "outputs": [],
529 | "source": [
530 | "(];*.tab;!tab) 3+i.7"
531 | ]
532 | },
533 | {
534 | "cell_type": "markdown",
535 | "metadata": {
536 | "deletable": true,
537 | "editable": true
538 | },
539 | "source": [
540 | "### (18 of 18) Table Utility\n",
541 | "Since verb tables are so useful for exploration, J has a standard utility adverb called \"table\" that creates a table bordered by its arguments.\n",
542 | "\n",
543 | "For example:"
544 | ]
545 | },
546 | {
547 | "cell_type": "code",
548 | "execution_count": null,
549 | "metadata": {
550 | "collapsed": false,
551 | "deletable": true,
552 | "editable": true
553 | },
554 | "outputs": [],
555 | "source": [
556 | "!table 3+i.7 NB. right argument only"
557 | ]
558 | },
559 | {
560 | "cell_type": "code",
561 | "execution_count": null,
562 | "metadata": {
563 | "collapsed": false,
564 | "deletable": true,
565 | "editable": true
566 | },
567 | "outputs": [],
568 | "source": [
569 | "0 1 2 3 !table 3+i.7 NB. left and right arguments"
570 | ]
571 | },
572 | {
573 | "cell_type": "markdown",
574 | "metadata": {
575 | "deletable": true,
576 | "editable": true
577 | },
578 | "source": [
579 | "### End of Lab"
580 | ]
581 | },
582 | {
583 | "cell_type": "code",
584 | "execution_count": null,
585 | "metadata": {
586 | "collapsed": false,
587 | "deletable": true,
588 | "editable": true
589 | },
590 | "outputs": [],
591 | "source": []
592 | }
593 | ],
594 | "metadata": {
595 | "kernelspec": {
596 | "display_name": "J",
597 | "language": "J",
598 | "name": "jkernel"
599 | },
600 | "language_info": {
601 | "file_extension": "ijs",
602 | "mimetype": "text/x-J",
603 | "name": "J"
604 | }
605 | },
606 | "nbformat": 4,
607 | "nbformat_minor": 2
608 | }
609 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/math/Rotations.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "deletable": true,
7 | "editable": true
8 | },
9 | "source": [
10 | "# J Labs\n",
11 | "\n",
12 | "### Rotations"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {
18 | "deletable": true,
19 | "editable": true
20 | },
21 | "source": [
22 | "### (1 of 7) ROTATIONS\n",
23 | "The function:\n",
24 | "\n",
25 | " ```length=: %:@:(+/@:*:)\"1```
\n",
26 | "\n",
27 | "yields the length of a vector to which it is applied, first squaring (*:) the elements, then summing (+/) the squares, and finally taking the square root (%:), thus:"
28 | ]
29 | },
30 | {
31 | "cell_type": "code",
32 | "execution_count": null,
33 | "metadata": {
34 | "collapsed": false,
35 | "deletable": true,
36 | "editable": true
37 | },
38 | "outputs": [],
39 | "source": [
40 | "length=: %:@:(+/@:*:)\"1"
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": null,
46 | "metadata": {
47 | "collapsed": false,
48 | "deletable": true,
49 | "editable": true
50 | },
51 | "outputs": [],
52 | "source": [
53 | "length 3 4"
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": null,
59 | "metadata": {
60 | "collapsed": false,
61 | "deletable": true,
62 | "editable": true
63 | },
64 | "outputs": [],
65 | "source": [
66 | "length 3 4 12"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {
72 | "deletable": true,
73 | "editable": true
74 | },
75 | "source": [
76 | "### (2 of 7) LENGTH\n",
77 | "The function:\n",
78 | "\n",
79 | " ```X=: +/ . \\*```
\n",
80 | "\n",
81 | "is the matrix product.\n",
82 | "\n",
83 | "If m is a matrix, and v is a vector, the result of m X v may differ from v in both length and direction.\n",
84 | "\n",
85 | "However, if m is a matrix whose row and column sums are of length 1, then the result of m X v has the same length as v The operation is called a rotation, and m is called a rotation matrix. For example:"
86 | ]
87 | },
88 | {
89 | "cell_type": "code",
90 | "execution_count": null,
91 | "metadata": {
92 | "collapsed": false,
93 | "deletable": true,
94 | "editable": true
95 | },
96 | "outputs": [],
97 | "source": [
98 | "X=: +/ . *"
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": null,
104 | "metadata": {
105 | "collapsed": false,
106 | "deletable": true,
107 | "editable": true
108 | },
109 | "outputs": [],
110 | "source": [
111 | "v=: 3 4"
112 | ]
113 | },
114 | {
115 | "cell_type": "code",
116 | "execution_count": null,
117 | "metadata": {
118 | "collapsed": false,
119 | "deletable": true,
120 | "editable": true
121 | },
122 | "outputs": [],
123 | "source": [
124 | "m=: > 1 2;2 1"
125 | ]
126 | },
127 | {
128 | "cell_type": "code",
129 | "execution_count": null,
130 | "metadata": {
131 | "collapsed": false,
132 | "deletable": true,
133 | "editable": true
134 | },
135 | "outputs": [],
136 | "source": [
137 | "m"
138 | ]
139 | },
140 | {
141 | "cell_type": "code",
142 | "execution_count": null,
143 | "metadata": {
144 | "collapsed": false,
145 | "deletable": true,
146 | "editable": true
147 | },
148 | "outputs": [],
149 | "source": [
150 | "m X v"
151 | ]
152 | },
153 | {
154 | "cell_type": "code",
155 | "execution_count": null,
156 | "metadata": {
157 | "collapsed": false,
158 | "deletable": true,
159 | "editable": true
160 | },
161 | "outputs": [],
162 | "source": [
163 | "length m X v"
164 | ]
165 | },
166 | {
167 | "cell_type": "code",
168 | "execution_count": null,
169 | "metadata": {
170 | "collapsed": false,
171 | "deletable": true,
172 | "editable": true
173 | },
174 | "outputs": [],
175 | "source": [
176 | "length v"
177 | ]
178 | },
179 | {
180 | "cell_type": "code",
181 | "execution_count": null,
182 | "metadata": {
183 | "collapsed": false,
184 | "deletable": true,
185 | "editable": true
186 | },
187 | "outputs": [],
188 | "source": [
189 | "c=: % %: 2 NB. Reciprocal of square root of 2"
190 | ]
191 | },
192 | {
193 | "cell_type": "code",
194 | "execution_count": null,
195 | "metadata": {
196 | "collapsed": false,
197 | "deletable": true,
198 | "editable": true
199 | },
200 | "outputs": [],
201 | "source": [
202 | "m=: > (c, c);((-c),c)"
203 | ]
204 | },
205 | {
206 | "cell_type": "code",
207 | "execution_count": null,
208 | "metadata": {
209 | "collapsed": false,
210 | "deletable": true,
211 | "editable": true
212 | },
213 | "outputs": [],
214 | "source": [
215 | "m"
216 | ]
217 | },
218 | {
219 | "cell_type": "code",
220 | "execution_count": null,
221 | "metadata": {
222 | "collapsed": false,
223 | "deletable": true,
224 | "editable": true
225 | },
226 | "outputs": [],
227 | "source": [
228 | "length m NB. Lengths of rows of m"
229 | ]
230 | },
231 | {
232 | "cell_type": "code",
233 | "execution_count": null,
234 | "metadata": {
235 | "collapsed": false,
236 | "deletable": true,
237 | "editable": true
238 | },
239 | "outputs": [],
240 | "source": [
241 | "|: m NB. Transpose of m"
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": null,
247 | "metadata": {
248 | "collapsed": false,
249 | "deletable": true,
250 | "editable": true
251 | },
252 | "outputs": [],
253 | "source": [
254 | "length |: m NB. Lengths of columns of m"
255 | ]
256 | },
257 | {
258 | "cell_type": "code",
259 | "execution_count": null,
260 | "metadata": {
261 | "collapsed": false,
262 | "deletable": true,
263 | "editable": true
264 | },
265 | "outputs": [],
266 | "source": [
267 | "m X v"
268 | ]
269 | },
270 | {
271 | "cell_type": "code",
272 | "execution_count": null,
273 | "metadata": {
274 | "collapsed": false,
275 | "deletable": true,
276 | "editable": true
277 | },
278 | "outputs": [],
279 | "source": [
280 | "length m X v"
281 | ]
282 | },
283 | {
284 | "cell_type": "markdown",
285 | "metadata": {
286 | "deletable": true,
287 | "editable": true
288 | },
289 | "source": [
290 | "### (3 of 7) ROTATION\n",
291 | "The function:\n",
292 | "\n",
293 | " ```r=: (sind , -@:cosd) ,. (cosd , sind)```
\n",
294 | "\n",
295 | "produces a rotation matrix. The angle of rotation it produces is determined by the argument of r. For example:"
296 | ]
297 | },
298 | {
299 | "cell_type": "code",
300 | "execution_count": null,
301 | "metadata": {
302 | "collapsed": false,
303 | "deletable": true,
304 | "editable": true
305 | },
306 | "outputs": [],
307 | "source": [
308 | "load 'trig'"
309 | ]
310 | },
311 | {
312 | "cell_type": "code",
313 | "execution_count": null,
314 | "metadata": {
315 | "collapsed": false,
316 | "deletable": true,
317 | "editable": true
318 | },
319 | "outputs": [],
320 | "source": [
321 | "r=: (cosd , -@:sind) ,. (sind , cosd)"
322 | ]
323 | },
324 | {
325 | "cell_type": "code",
326 | "execution_count": null,
327 | "metadata": {
328 | "collapsed": false,
329 | "deletable": true,
330 | "editable": true
331 | },
332 | "outputs": [],
333 | "source": [
334 | "m=: r 45"
335 | ]
336 | },
337 | {
338 | "cell_type": "code",
339 | "execution_count": null,
340 | "metadata": {
341 | "collapsed": false,
342 | "deletable": true,
343 | "editable": true
344 | },
345 | "outputs": [],
346 | "source": [
347 | "m"
348 | ]
349 | },
350 | {
351 | "cell_type": "code",
352 | "execution_count": null,
353 | "metadata": {
354 | "collapsed": false,
355 | "deletable": true,
356 | "editable": true
357 | },
358 | "outputs": [],
359 | "source": [
360 | "m X v"
361 | ]
362 | },
363 | {
364 | "cell_type": "code",
365 | "execution_count": null,
366 | "metadata": {
367 | "collapsed": false,
368 | "deletable": true,
369 | "editable": true
370 | },
371 | "outputs": [],
372 | "source": [
373 | "y=: (r 90) X v"
374 | ]
375 | },
376 | {
377 | "cell_type": "code",
378 | "execution_count": null,
379 | "metadata": {
380 | "collapsed": false,
381 | "deletable": true,
382 | "editable": true
383 | },
384 | "outputs": [],
385 | "source": [
386 | "y"
387 | ]
388 | },
389 | {
390 | "cell_type": "code",
391 | "execution_count": null,
392 | "metadata": {
393 | "collapsed": false,
394 | "deletable": true,
395 | "editable": true
396 | },
397 | "outputs": [],
398 | "source": [
399 | "y X v NB. 90-degree rotation produces a perpendicular vector"
400 | ]
401 | },
402 | {
403 | "cell_type": "markdown",
404 | "metadata": {
405 | "deletable": true,
406 | "editable": true
407 | },
408 | "source": [
409 | "### (4 of 7) ROTATION MATRICES\n",
410 | "If m =. r a is a rotation matrix in 2-space, then the matrix 1 0 0,0 0,.m produces a corresponding rotation about the x axis in 3-space. For example:"
411 | ]
412 | },
413 | {
414 | "cell_type": "code",
415 | "execution_count": null,
416 | "metadata": {
417 | "collapsed": false,
418 | "deletable": true,
419 | "editable": true
420 | },
421 | "outputs": [],
422 | "source": [
423 | "r 30"
424 | ]
425 | },
426 | {
427 | "cell_type": "code",
428 | "execution_count": null,
429 | "metadata": {
430 | "collapsed": false,
431 | "deletable": true,
432 | "editable": true
433 | },
434 | "outputs": [],
435 | "source": [
436 | "rx30=: 1 0 0,0 0,.r 30"
437 | ]
438 | },
439 | {
440 | "cell_type": "code",
441 | "execution_count": null,
442 | "metadata": {
443 | "collapsed": false,
444 | "deletable": true,
445 | "editable": true
446 | },
447 | "outputs": [],
448 | "source": [
449 | "rx30"
450 | ]
451 | },
452 | {
453 | "cell_type": "code",
454 | "execution_count": null,
455 | "metadata": {
456 | "collapsed": false,
457 | "deletable": true,
458 | "editable": true
459 | },
460 | "outputs": [],
461 | "source": [
462 | "w=: 3 4 5"
463 | ]
464 | },
465 | {
466 | "cell_type": "code",
467 | "execution_count": null,
468 | "metadata": {
469 | "collapsed": false,
470 | "deletable": true,
471 | "editable": true
472 | },
473 | "outputs": [],
474 | "source": [
475 | "rx30 X w"
476 | ]
477 | },
478 | {
479 | "cell_type": "code",
480 | "execution_count": null,
481 | "metadata": {
482 | "collapsed": false,
483 | "deletable": true,
484 | "editable": true
485 | },
486 | "outputs": [],
487 | "source": [
488 | "length w"
489 | ]
490 | },
491 | {
492 | "cell_type": "code",
493 | "execution_count": null,
494 | "metadata": {
495 | "collapsed": false,
496 | "deletable": true,
497 | "editable": true
498 | },
499 | "outputs": [],
500 | "source": [
501 | "length rx30 X w"
502 | ]
503 | },
504 | {
505 | "cell_type": "markdown",
506 | "metadata": {
507 | "deletable": true,
508 | "editable": true
509 | },
510 | "source": [
511 | "### (5 of 7) ROTATION IN 3-SPACE\n",
512 | "If the rows and columns of a rotation about x are permuted to bring the 1 to the y or z position, the result is a rotation about the corresponding axis. For example:"
513 | ]
514 | },
515 | {
516 | "cell_type": "code",
517 | "execution_count": null,
518 | "metadata": {
519 | "collapsed": false,
520 | "deletable": true,
521 | "editable": true
522 | },
523 | "outputs": [],
524 | "source": [
525 | "ry45=: 1 0 2 { 1 0 2 ({\"1) 1 0 0,0 0,.r 45"
526 | ]
527 | },
528 | {
529 | "cell_type": "code",
530 | "execution_count": null,
531 | "metadata": {
532 | "collapsed": false,
533 | "deletable": true,
534 | "editable": true
535 | },
536 | "outputs": [],
537 | "source": [
538 | "rz60=: 1 2 0 { 1 2 0 ({\"1) 1 0 0,0 0,.r 60"
539 | ]
540 | },
541 | {
542 | "cell_type": "code",
543 | "execution_count": null,
544 | "metadata": {
545 | "collapsed": false,
546 | "deletable": true,
547 | "editable": true
548 | },
549 | "outputs": [],
550 | "source": [
551 | "ry45"
552 | ]
553 | },
554 | {
555 | "cell_type": "code",
556 | "execution_count": null,
557 | "metadata": {
558 | "collapsed": false,
559 | "deletable": true,
560 | "editable": true
561 | },
562 | "outputs": [],
563 | "source": [
564 | "ry45 X w"
565 | ]
566 | },
567 | {
568 | "cell_type": "code",
569 | "execution_count": null,
570 | "metadata": {
571 | "collapsed": false,
572 | "deletable": true,
573 | "editable": true
574 | },
575 | "outputs": [],
576 | "source": [
577 | "rz60"
578 | ]
579 | },
580 | {
581 | "cell_type": "code",
582 | "execution_count": null,
583 | "metadata": {
584 | "collapsed": false,
585 | "deletable": true,
586 | "editable": true
587 | },
588 | "outputs": [],
589 | "source": [
590 | "rz60 X w"
591 | ]
592 | },
593 | {
594 | "cell_type": "markdown",
595 | "metadata": {
596 | "deletable": true,
597 | "editable": true
598 | },
599 | "source": [
600 | "### (6 of 7) ROTATION ABOUT y AND z\n",
601 | "The matrix product of two rotations is again a rotation, and a general rotation can therefore be produced as a product of rotations about each of the three axes. For example:"
602 | ]
603 | },
604 | {
605 | "cell_type": "code",
606 | "execution_count": null,
607 | "metadata": {
608 | "collapsed": false,
609 | "deletable": true,
610 | "editable": true
611 | },
612 | "outputs": [],
613 | "source": [
614 | "rall=: rx30 X ry45 X rz60"
615 | ]
616 | },
617 | {
618 | "cell_type": "code",
619 | "execution_count": null,
620 | "metadata": {
621 | "collapsed": false,
622 | "deletable": true,
623 | "editable": true
624 | },
625 | "outputs": [],
626 | "source": [
627 | "rall"
628 | ]
629 | },
630 | {
631 | "cell_type": "code",
632 | "execution_count": null,
633 | "metadata": {
634 | "collapsed": false,
635 | "deletable": true,
636 | "editable": true
637 | },
638 | "outputs": [],
639 | "source": [
640 | "length rall"
641 | ]
642 | },
643 | {
644 | "cell_type": "code",
645 | "execution_count": null,
646 | "metadata": {
647 | "collapsed": false,
648 | "deletable": true,
649 | "editable": true
650 | },
651 | "outputs": [],
652 | "source": [
653 | "rall X w"
654 | ]
655 | },
656 | {
657 | "cell_type": "markdown",
658 | "metadata": {
659 | "deletable": true,
660 | "editable": true
661 | },
662 | "source": [
663 | "### (7 of 7) PRODUCT OF ROTATIONS\n",
664 | "We will now define a general rotation function GR whose left argument is a quoted list of axes, such as \"yxz\" or \"yz\" or \"x\"or \"xyxyx\", and whose right argument is a list of angles in degrees. Thus:"
665 | ]
666 | },
667 | {
668 | "cell_type": "code",
669 | "execution_count": null,
670 | "metadata": {
671 | "collapsed": false,
672 | "deletable": true,
673 | "editable": true
674 | },
675 | "outputs": [],
676 | "source": [
677 | "GR=: 4 : 0\n",
678 | "res=: (i. =/ i.) 3 NB. Initialize res as identity matrix\n",
679 | "p=: >0 1 2;1 0 2;1 2 0 NB. Permutations for axes\n",
680 | "while. 0<# x do.\n",
681 | "cp=. ('xyz'i.{:x){p NB. Current permutation\n",
682 | "cr=. cp {\"1 cp { 1 0 0,0 0,.r {: y NB. Current rotation\n",
683 | "res =. cr X res\n",
684 | "x=. }: x\n",
685 | "y=. }: y\n",
686 | "end.\n",
687 | "res\n",
688 | ")"
689 | ]
690 | },
691 | {
692 | "cell_type": "code",
693 | "execution_count": null,
694 | "metadata": {
695 | "collapsed": false,
696 | "deletable": true,
697 | "editable": true
698 | },
699 | "outputs": [],
700 | "source": [
701 | "'xyz' GR 30 45 60"
702 | ]
703 | },
704 | {
705 | "cell_type": "code",
706 | "execution_count": null,
707 | "metadata": {
708 | "collapsed": false,
709 | "deletable": true,
710 | "editable": true
711 | },
712 | "outputs": [],
713 | "source": [
714 | "'yx' GR 45 60"
715 | ]
716 | },
717 | {
718 | "cell_type": "code",
719 | "execution_count": null,
720 | "metadata": {
721 | "collapsed": false,
722 | "deletable": true,
723 | "editable": true
724 | },
725 | "outputs": [],
726 | "source": [
727 | "'y' GR 45"
728 | ]
729 | },
730 | {
731 | "cell_type": "code",
732 | "execution_count": null,
733 | "metadata": {
734 | "collapsed": false,
735 | "deletable": true,
736 | "editable": true
737 | },
738 | "outputs": [],
739 | "source": [
740 | "'xyxyx' GR 1 2 3 4 5"
741 | ]
742 | },
743 | {
744 | "cell_type": "markdown",
745 | "metadata": {
746 | "deletable": true,
747 | "editable": true
748 | },
749 | "source": [
750 | "### End of Lab"
751 | ]
752 | },
753 | {
754 | "cell_type": "code",
755 | "execution_count": null,
756 | "metadata": {
757 | "collapsed": false,
758 | "deletable": true,
759 | "editable": true
760 | },
761 | "outputs": [],
762 | "source": []
763 | }
764 | ],
765 | "metadata": {
766 | "kernelspec": {
767 | "display_name": "J",
768 | "language": "J",
769 | "name": "jkernel"
770 | },
771 | "language_info": {
772 | "file_extension": "ijs",
773 | "mimetype": "text/x-J",
774 | "name": "J"
775 | }
776 | },
777 | "nbformat": 4,
778 | "nbformat_minor": 2
779 | }
780 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/math/Iteration_and_the_Power_Operator.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "deletable": true,
7 | "editable": true
8 | },
9 | "source": [
10 | "# J Labs\n",
11 | "\n",
12 | "### Iteration and the Power Operator"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {
18 | "deletable": true,
19 | "editable": true
20 | },
21 | "source": [
22 | "### (1 of 10) ITERATION\n",
23 | "\n",
24 | "The repeated application of a function, such as doubling or halving, is called iteration. For example:"
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": null,
30 | "metadata": {
31 | "collapsed": false,
32 | "deletable": true,
33 | "editable": true
34 | },
35 | "outputs": [],
36 | "source": [
37 | "x=: 3"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": null,
43 | "metadata": {
44 | "collapsed": false,
45 | "deletable": true,
46 | "editable": true
47 | },
48 | "outputs": [],
49 | "source": [
50 | "+: x"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": null,
56 | "metadata": {
57 | "collapsed": false,
58 | "deletable": true,
59 | "editable": true
60 | },
61 | "outputs": [],
62 | "source": [
63 | "+: +: x"
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": null,
69 | "metadata": {
70 | "collapsed": false,
71 | "deletable": true,
72 | "editable": true
73 | },
74 | "outputs": [],
75 | "source": [
76 | "+: +: +: x"
77 | ]
78 | },
79 | {
80 | "cell_type": "code",
81 | "execution_count": null,
82 | "metadata": {
83 | "collapsed": false,
84 | "deletable": true,
85 | "editable": true
86 | },
87 | "outputs": [],
88 | "source": [
89 | "-: x"
90 | ]
91 | },
92 | {
93 | "cell_type": "code",
94 | "execution_count": null,
95 | "metadata": {
96 | "collapsed": false,
97 | "deletable": true,
98 | "editable": true
99 | },
100 | "outputs": [],
101 | "source": [
102 | "-: -: x"
103 | ]
104 | },
105 | {
106 | "cell_type": "markdown",
107 | "metadata": {
108 | "deletable": true,
109 | "editable": true
110 | },
111 | "source": [
112 | "### (2 of 10) POWER OPERATOR\n",
113 | "\n",
114 | "The power operator ^: can be used to produce any specified number of iterations. For example:"
115 | ]
116 | },
117 | {
118 | "cell_type": "code",
119 | "execution_count": null,
120 | "metadata": {
121 | "collapsed": false,
122 | "deletable": true,
123 | "editable": true
124 | },
125 | "outputs": [],
126 | "source": [
127 | "+:^:2 x"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": null,
133 | "metadata": {
134 | "collapsed": false,
135 | "deletable": true,
136 | "editable": true
137 | },
138 | "outputs": [],
139 | "source": [
140 | "+:^:3 x"
141 | ]
142 | },
143 | {
144 | "cell_type": "code",
145 | "execution_count": null,
146 | "metadata": {
147 | "collapsed": false,
148 | "deletable": true,
149 | "editable": true
150 | },
151 | "outputs": [],
152 | "source": [
153 | "+:^:0 1 2 3 4 x"
154 | ]
155 | },
156 | {
157 | "cell_type": "code",
158 | "execution_count": null,
159 | "metadata": {
160 | "collapsed": false,
161 | "deletable": true,
162 | "editable": true
163 | },
164 | "outputs": [],
165 | "source": [
166 | "i=: 0 1 2 3 4"
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "metadata": {
173 | "collapsed": false,
174 | "deletable": true,
175 | "editable": true
176 | },
177 | "outputs": [],
178 | "source": [
179 | "+:^:i x"
180 | ]
181 | },
182 | {
183 | "cell_type": "code",
184 | "execution_count": null,
185 | "metadata": {
186 | "collapsed": false,
187 | "deletable": true,
188 | "editable": true
189 | },
190 | "outputs": [],
191 | "source": [
192 | "v=: 3 4 5"
193 | ]
194 | },
195 | {
196 | "cell_type": "code",
197 | "execution_count": null,
198 | "metadata": {
199 | "collapsed": false,
200 | "deletable": true,
201 | "editable": true
202 | },
203 | "outputs": [],
204 | "source": [
205 | "+: v"
206 | ]
207 | },
208 | {
209 | "cell_type": "code",
210 | "execution_count": null,
211 | "metadata": {
212 | "collapsed": false,
213 | "deletable": true,
214 | "editable": true
215 | },
216 | "outputs": [],
217 | "source": [
218 | "+:^:i v"
219 | ]
220 | },
221 | {
222 | "cell_type": "markdown",
223 | "metadata": {
224 | "deletable": true,
225 | "editable": true
226 | },
227 | "source": [
228 | "### (3 of 10) POWER OPERATOR (ctd)\n",
229 | "\n",
230 | "We will illustrate the use of the power operator on other functions, including the square (^&2), subtotals (+/\\), and permutations or anagrams (k&A.) .\n",
231 | "\n",
232 | "Further information on any of these expressions may be found by pressing the function key F1 to display the vocabulary, and then clicking the mouse on the desired item:"
233 | ]
234 | },
235 | {
236 | "cell_type": "code",
237 | "execution_count": null,
238 | "metadata": {
239 | "collapsed": false,
240 | "deletable": true,
241 | "editable": true
242 | },
243 | "outputs": [],
244 | "source": [
245 | "^&2 ^: i i"
246 | ]
247 | },
248 | {
249 | "cell_type": "code",
250 | "execution_count": null,
251 | "metadata": {
252 | "collapsed": false,
253 | "deletable": true,
254 | "editable": true
255 | },
256 | "outputs": [],
257 | "source": [
258 | "+/\\ ^: i i"
259 | ]
260 | },
261 | {
262 | "cell_type": "code",
263 | "execution_count": null,
264 | "metadata": {
265 | "collapsed": false,
266 | "deletable": true,
267 | "editable": true
268 | },
269 | "outputs": [],
270 | "source": [
271 | "3&A.^: i i"
272 | ]
273 | },
274 | {
275 | "cell_type": "code",
276 | "execution_count": null,
277 | "metadata": {
278 | "collapsed": false,
279 | "deletable": true,
280 | "editable": true
281 | },
282 | "outputs": [],
283 | "source": [
284 | "3&A.^: i 'ABCDE'"
285 | ]
286 | },
287 | {
288 | "cell_type": "markdown",
289 | "metadata": {
290 | "deletable": true,
291 | "editable": true
292 | },
293 | "source": [
294 | "### (4 of 10) POWER OPERATOR (ctd)\n",
295 | "\n",
296 | "The larger powers in the table ```^&2 ^: i i``` appeared in \"scientific\" or exponential form. Such large numbers may be produced in \"extended precision\" as illustrated below:"
297 | ]
298 | },
299 | {
300 | "cell_type": "code",
301 | "execution_count": null,
302 | "metadata": {
303 | "collapsed": false,
304 | "deletable": true,
305 | "editable": true
306 | },
307 | "outputs": [],
308 | "source": [
309 | "!! i"
310 | ]
311 | },
312 | {
313 | "cell_type": "code",
314 | "execution_count": null,
315 | "metadata": {
316 | "collapsed": false,
317 | "deletable": true,
318 | "editable": true
319 | },
320 | "outputs": [],
321 | "source": [
322 | "!! x:i"
323 | ]
324 | },
325 | {
326 | "cell_type": "code",
327 | "execution_count": null,
328 | "metadata": {
329 | "collapsed": false,
330 | "deletable": true,
331 | "editable": true
332 | },
333 | "outputs": [],
334 | "source": [
335 | "^&2 ^: i x:i"
336 | ]
337 | },
338 | {
339 | "cell_type": "markdown",
340 | "metadata": {
341 | "deletable": true,
342 | "editable": true
343 | },
344 | "source": [
345 | "### (5 of 10) BINOMIAL COEFFICIENTS\n",
346 | "\n",
347 | "A table of binomial coefficients is often presented as a triangle (Pascals triangle) by suppressing the zeros that result from the number of ways that n elements can be chosen from a lesser number of items. Thus:\n",
348 | "\n",
349 | " ```1```
\n",
350 | " ```1 1```
\n",
351 | " ```1 2 1```
\n",
352 | " ```1 3 3 1```
\n",
353 | " ```1 4 6 4 1```
\n",
354 | "\n",
355 | "A row of these coefficients can be simply obtained from the preceding row, as illustrated below:"
356 | ]
357 | },
358 | {
359 | "cell_type": "code",
360 | "execution_count": null,
361 | "metadata": {
362 | "collapsed": false,
363 | "deletable": true,
364 | "editable": true
365 | },
366 | "outputs": [],
367 | "source": [
368 | "r2=: 1 2 1"
369 | ]
370 | },
371 | {
372 | "cell_type": "code",
373 | "execution_count": null,
374 | "metadata": {
375 | "collapsed": false,
376 | "deletable": true,
377 | "editable": true
378 | },
379 | "outputs": [],
380 | "source": [
381 | "0,r2"
382 | ]
383 | },
384 | {
385 | "cell_type": "code",
386 | "execution_count": null,
387 | "metadata": {
388 | "collapsed": false,
389 | "deletable": true,
390 | "editable": true
391 | },
392 | "outputs": [],
393 | "source": [
394 | "r2,0"
395 | ]
396 | },
397 | {
398 | "cell_type": "code",
399 | "execution_count": null,
400 | "metadata": {
401 | "collapsed": false,
402 | "deletable": true,
403 | "editable": true
404 | },
405 | "outputs": [],
406 | "source": [
407 | "(0,r2)+(r2,0)"
408 | ]
409 | },
410 | {
411 | "cell_type": "markdown",
412 | "metadata": {
413 | "deletable": true,
414 | "editable": true
415 | },
416 | "source": [
417 | "### (6 of 10) BINOMIAL COEFFICIENTS (ctd)\n",
418 | "\n",
419 | "A function for this process may be defined and iterated as follows:"
420 | ]
421 | },
422 | {
423 | "cell_type": "code",
424 | "execution_count": null,
425 | "metadata": {
426 | "collapsed": false,
427 | "deletable": true,
428 | "editable": true
429 | },
430 | "outputs": [],
431 | "source": [
432 | "next=: 0&, + ,&0"
433 | ]
434 | },
435 | {
436 | "cell_type": "code",
437 | "execution_count": null,
438 | "metadata": {
439 | "collapsed": false,
440 | "deletable": true,
441 | "editable": true
442 | },
443 | "outputs": [],
444 | "source": [
445 | "next r2"
446 | ]
447 | },
448 | {
449 | "cell_type": "code",
450 | "execution_count": null,
451 | "metadata": {
452 | "collapsed": false,
453 | "deletable": true,
454 | "editable": true
455 | },
456 | "outputs": [],
457 | "source": [
458 | "next 1"
459 | ]
460 | },
461 | {
462 | "cell_type": "code",
463 | "execution_count": null,
464 | "metadata": {
465 | "collapsed": false,
466 | "deletable": true,
467 | "editable": true
468 | },
469 | "outputs": [],
470 | "source": [
471 | "next next 1"
472 | ]
473 | },
474 | {
475 | "cell_type": "code",
476 | "execution_count": null,
477 | "metadata": {
478 | "collapsed": false,
479 | "deletable": true,
480 | "editable": true
481 | },
482 | "outputs": [],
483 | "source": [
484 | "bct=: next ^: i 1"
485 | ]
486 | },
487 | {
488 | "cell_type": "code",
489 | "execution_count": null,
490 | "metadata": {
491 | "collapsed": false,
492 | "deletable": true,
493 | "editable": true
494 | },
495 | "outputs": [],
496 | "source": [
497 | "bct"
498 | ]
499 | },
500 | {
501 | "cell_type": "markdown",
502 | "metadata": {
503 | "deletable": true,
504 | "editable": true
505 | },
506 | "source": [
507 | "### (7 of 10) BINOMIAL COEFFICIENTS (ctd)\n",
508 | "\n",
509 | "The operations of matrix algebra can be applied to this matrix of binomial coefficients in useful and interesting ways, as developed in a companion lab. For example, the inverse yields a table of alternating binomial coefficients:"
510 | ]
511 | },
512 | {
513 | "cell_type": "code",
514 | "execution_count": null,
515 | "metadata": {
516 | "collapsed": false,
517 | "deletable": true,
518 | "editable": true
519 | },
520 | "outputs": [],
521 | "source": [
522 | "abct=: %. bct"
523 | ]
524 | },
525 | {
526 | "cell_type": "code",
527 | "execution_count": null,
528 | "metadata": {
529 | "collapsed": false,
530 | "deletable": true,
531 | "editable": true
532 | },
533 | "outputs": [],
534 | "source": [
535 | "abct"
536 | ]
537 | },
538 | {
539 | "cell_type": "code",
540 | "execution_count": null,
541 | "metadata": {
542 | "collapsed": false,
543 | "deletable": true,
544 | "editable": true
545 | },
546 | "outputs": [],
547 | "source": [
548 | "mp=: +/ . * NB. Matrix product"
549 | ]
550 | },
551 | {
552 | "cell_type": "code",
553 | "execution_count": null,
554 | "metadata": {
555 | "collapsed": false,
556 | "deletable": true,
557 | "editable": true
558 | },
559 | "outputs": [],
560 | "source": [
561 | "bct mp abct"
562 | ]
563 | },
564 | {
565 | "cell_type": "markdown",
566 | "metadata": {
567 | "deletable": true,
568 | "editable": true
569 | },
570 | "source": [
571 | "### (8 of 10) NEGATIVE POWERS\n",
572 | "\n",
573 | "Negative powers of a function yield powers of its inverse. For example:"
574 | ]
575 | },
576 | {
577 | "cell_type": "code",
578 | "execution_count": null,
579 | "metadata": {
580 | "collapsed": false,
581 | "deletable": true,
582 | "editable": true
583 | },
584 | "outputs": [],
585 | "source": [
586 | "+: ^: _1 i"
587 | ]
588 | },
589 | {
590 | "cell_type": "code",
591 | "execution_count": null,
592 | "metadata": {
593 | "collapsed": false,
594 | "deletable": true,
595 | "editable": true
596 | },
597 | "outputs": [],
598 | "source": [
599 | "+: ^: _2 i"
600 | ]
601 | },
602 | {
603 | "cell_type": "code",
604 | "execution_count": null,
605 | "metadata": {
606 | "collapsed": false,
607 | "deletable": true,
608 | "editable": true
609 | },
610 | "outputs": [],
611 | "source": [
612 | "+/\\ ^: i i"
613 | ]
614 | },
615 | {
616 | "cell_type": "code",
617 | "execution_count": null,
618 | "metadata": {
619 | "collapsed": false,
620 | "deletable": true,
621 | "editable": true
622 | },
623 | "outputs": [],
624 | "source": [
625 | "+/\\ ^: (-i) 0 1 6 21 56"
626 | ]
627 | },
628 | {
629 | "cell_type": "markdown",
630 | "metadata": {
631 | "deletable": true,
632 | "editable": true
633 | },
634 | "source": [
635 | "### (9 of 10) LIMITS\n",
636 | "\n",
637 | "An iteration may approach a limiting value such that further applications of the function produce no discernible change. The cosine applied to 1 has such a property:"
638 | ]
639 | },
640 | {
641 | "cell_type": "code",
642 | "execution_count": null,
643 | "metadata": {
644 | "collapsed": false,
645 | "deletable": true,
646 | "editable": true
647 | },
648 | "outputs": [],
649 | "source": [
650 | "Cos=: 2&o."
651 | ]
652 | },
653 | {
654 | "cell_type": "code",
655 | "execution_count": null,
656 | "metadata": {
657 | "collapsed": false,
658 | "deletable": true,
659 | "editable": true
660 | },
661 | "outputs": [],
662 | "source": [
663 | "0 1r4p1 1p1 3r4p1 2p1 NB. Multiples of pi"
664 | ]
665 | },
666 | {
667 | "cell_type": "code",
668 | "execution_count": null,
669 | "metadata": {
670 | "collapsed": false,
671 | "deletable": true,
672 | "editable": true
673 | },
674 | "outputs": [],
675 | "source": [
676 | "Cos 0 1r4p1 1p1 3r4p1 2p1"
677 | ]
678 | },
679 | {
680 | "cell_type": "code",
681 | "execution_count": null,
682 | "metadata": {
683 | "collapsed": false,
684 | "deletable": true,
685 | "editable": true
686 | },
687 | "outputs": [],
688 | "source": [
689 | "i=: 0 1 2 3 4"
690 | ]
691 | },
692 | {
693 | "cell_type": "code",
694 | "execution_count": null,
695 | "metadata": {
696 | "collapsed": false,
697 | "deletable": true,
698 | "editable": true
699 | },
700 | "outputs": [],
701 | "source": [
702 | "Cos^:i 1"
703 | ]
704 | },
705 | {
706 | "cell_type": "code",
707 | "execution_count": null,
708 | "metadata": {
709 | "collapsed": false,
710 | "deletable": true,
711 | "editable": true
712 | },
713 | "outputs": [],
714 | "source": [
715 | "k=: i.4 5"
716 | ]
717 | },
718 | {
719 | "cell_type": "code",
720 | "execution_count": null,
721 | "metadata": {
722 | "collapsed": false,
723 | "deletable": true,
724 | "editable": true
725 | },
726 | "outputs": [],
727 | "source": [
728 | "k"
729 | ]
730 | },
731 | {
732 | "cell_type": "code",
733 | "execution_count": null,
734 | "metadata": {
735 | "collapsed": false,
736 | "deletable": true,
737 | "editable": true
738 | },
739 | "outputs": [],
740 | "source": [
741 | "Cos^: k 1"
742 | ]
743 | },
744 | {
745 | "cell_type": "code",
746 | "execution_count": null,
747 | "metadata": {
748 | "collapsed": false,
749 | "deletable": true,
750 | "editable": true
751 | },
752 | "outputs": [],
753 | "source": [
754 | "y=: Cos^: _ (1)"
755 | ]
756 | },
757 | {
758 | "cell_type": "code",
759 | "execution_count": null,
760 | "metadata": {
761 | "collapsed": false,
762 | "deletable": true,
763 | "editable": true
764 | },
765 | "outputs": [],
766 | "source": [
767 | "y"
768 | ]
769 | },
770 | {
771 | "cell_type": "code",
772 | "execution_count": null,
773 | "metadata": {
774 | "collapsed": false,
775 | "deletable": true,
776 | "editable": true
777 | },
778 | "outputs": [],
779 | "source": [
780 | "Cos y"
781 | ]
782 | },
783 | {
784 | "cell_type": "code",
785 | "execution_count": null,
786 | "metadata": {
787 | "collapsed": false,
788 | "deletable": true,
789 | "editable": true
790 | },
791 | "outputs": [],
792 | "source": [
793 | "y=Cos y"
794 | ]
795 | },
796 | {
797 | "cell_type": "markdown",
798 | "metadata": {
799 | "deletable": true,
800 | "editable": true
801 | },
802 | "source": [
803 | "### (10 of 10) LIMITS (ctd)\n",
804 | "\n",
805 | "Since ```_``` denotes infinity, the expression Cos ^: ```_``` signifies an infinite number of iterations, but terminates automatically when two successive results agree. Consequently, the result y agrees with Cos y, and is therefore a solution of the equation expressed by the final line."
806 | ]
807 | },
808 | {
809 | "cell_type": "markdown",
810 | "metadata": {
811 | "deletable": true,
812 | "editable": true
813 | },
814 | "source": [
815 | "### End of Lab"
816 | ]
817 | },
818 | {
819 | "cell_type": "code",
820 | "execution_count": null,
821 | "metadata": {
822 | "collapsed": false,
823 | "deletable": true,
824 | "editable": true
825 | },
826 | "outputs": [],
827 | "source": []
828 | }
829 | ],
830 | "metadata": {
831 | "kernelspec": {
832 | "display_name": "J",
833 | "language": "J",
834 | "name": "jkernel"
835 | },
836 | "language_info": {
837 | "file_extension": "ijs",
838 | "mimetype": "text/x-J",
839 | "name": "J"
840 | }
841 | },
842 | "nbformat": 4,
843 | "nbformat_minor": 2
844 | }
845 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/math/Best_Fit.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "deletable": true,
7 | "editable": true
8 | },
9 | "source": [
10 | "# J Labs\n",
11 | "\n",
12 | "### Best Fit"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {
18 | "deletable": true,
19 | "editable": true
20 | },
21 | "source": [
22 | "### (1 of 12) Best Fit to a Monomial\n",
23 | "This lab is based on an article [1] in the Computer Corner section of The College Mathematics Journal.\n",
24 | "\n",
25 | "The article deals with two methods of fitting a curve of the form y = f(x) = ax^k to a set of data points using least squares.\n",
26 | "\n",
27 | "The original article has numerical examples done with the Mathematica computer package.\n",
28 | "\n",
29 | "In this lab we show how to do the computations using the J programming language.\n",
30 | "\n",
31 | "[1] Helen Skala: \"Will the Real Best Fit Curve\n",
32 | " ```Please Stand Up?\"```
\n",
33 | " ```College Math. Journal```
\n",
34 | " ```Vol. 27, May 1996```
"
35 | ]
36 | },
37 | {
38 | "cell_type": "markdown",
39 | "metadata": {
40 | "deletable": true,
41 | "editable": true
42 | },
43 | "source": [
44 | "### (2 of 12) Two Methods\n",
45 | "Given a set of data points S = {(x```_```i,y```_```i) | i=1,...,n}, we wish to fit a curve y = f(x) = ax^k. What are the best values of a and k? We will select a and k to satisfy a least squares condition.\n",
46 | "\n",
47 | "Method 1: linear least squares on the logs of the data Because log y = log a + k log x, we can try to fit the logs of the data to a straight line with equation y = b + mx where b = log a and m = k. The least squares problem is:\n",
48 | "\n",
49 | " ```minimize sum_{i=1 to n}(b + k log x_i - log y_i)^2```
\n",
50 | "\n",
51 | "Method 2: nonlinear least squares on the original data\n",
52 | "\n",
53 | " ```minimize sum_{i=1 to n}(f(x_i) - y_i)^2```
\n",
54 | "\n",
55 | "where f(x) = ax^k"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {
61 | "deletable": true,
62 | "editable": true
63 | },
64 | "source": [
65 | "### (3 of 12) Method 1:\n",
66 | "Let the given data be\n",
67 | "\n",
68 | " ```vx = 1, 2, 3, 4, 5, 10, 20```
\n",
69 | " ```vy = 6.1, 9.2, 14.1, 21.2, 30.3, 105.1, 405.2```
\n",
70 | "\n",
71 | "Compute the logs. We will use the same notation as the article and store the logs in variables xlg and ylg."
72 | ]
73 | },
74 | {
75 | "cell_type": "code",
76 | "execution_count": null,
77 | "metadata": {
78 | "collapsed": false,
79 | "deletable": true,
80 | "editable": true
81 | },
82 | "outputs": [],
83 | "source": [
84 | "vx =: 1 2 3 4 5 10 20"
85 | ]
86 | },
87 | {
88 | "cell_type": "code",
89 | "execution_count": null,
90 | "metadata": {
91 | "collapsed": false,
92 | "deletable": true,
93 | "editable": true
94 | },
95 | "outputs": [],
96 | "source": [
97 | "vy =: 6.1 9.2 14.1 21.2 30.3 105.1 405.2"
98 | ]
99 | },
100 | {
101 | "cell_type": "code",
102 | "execution_count": null,
103 | "metadata": {
104 | "collapsed": false,
105 | "deletable": true,
106 | "editable": true
107 | },
108 | "outputs": [],
109 | "source": [
110 | "log =: ^. NB. Give the natural log function the name log"
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": null,
116 | "metadata": {
117 | "collapsed": false,
118 | "deletable": true,
119 | "editable": true
120 | },
121 | "outputs": [],
122 | "source": [
123 | "[xlg =: log vx"
124 | ]
125 | },
126 | {
127 | "cell_type": "code",
128 | "execution_count": null,
129 | "metadata": {
130 | "collapsed": false,
131 | "deletable": true,
132 | "editable": true
133 | },
134 | "outputs": [],
135 | "source": [
136 | "[ylg =: log vy"
137 | ]
138 | },
139 | {
140 | "cell_type": "markdown",
141 | "metadata": {
142 | "deletable": true,
143 | "editable": true
144 | },
145 | "source": [
146 | "### (4 of 12) Method 1: (ctd)\n",
147 | "The formulas for linear least squares are well known. They are quoted in the article and then programmed in Mathematica.\n",
148 | "\n",
149 | "Here is the J version: [see below]\n",
150 | "\n",
151 | "Thus the best monomial fit is y = 3.74x^1.44 [see below]"
152 | ]
153 | },
154 | {
155 | "cell_type": "code",
156 | "execution_count": null,
157 | "metadata": {
158 | "collapsed": false,
159 | "deletable": true,
160 | "editable": true
161 | },
162 | "outputs": [],
163 | "source": [
164 | "e =: ^ 1 NB. e = exp(1) is Euler's number"
165 | ]
166 | },
167 | {
168 | "cell_type": "code",
169 | "execution_count": null,
170 | "metadata": {
171 | "collapsed": false,
172 | "deletable": true,
173 | "editable": true
174 | },
175 | "outputs": [],
176 | "source": [
177 | "n =: #vx NB. n is the number of data points"
178 | ]
179 | },
180 | {
181 | "cell_type": "code",
182 | "execution_count": null,
183 | "metadata": {
184 | "collapsed": false,
185 | "deletable": true,
186 | "editable": true
187 | },
188 | "outputs": [],
189 | "source": [
190 | "num =: (+/xlg*ylg)-(+/xlg)*(+/ylg)%n NB. +/ is summation"
191 | ]
192 | },
193 | {
194 | "cell_type": "code",
195 | "execution_count": null,
196 | "metadata": {
197 | "collapsed": false,
198 | "deletable": true,
199 | "editable": true
200 | },
201 | "outputs": [],
202 | "source": [
203 | "den =: (+/xlg*xlg)-((+/xlg)^2)%n NB. % is division"
204 | ]
205 | },
206 | {
207 | "cell_type": "code",
208 | "execution_count": null,
209 | "metadata": {
210 | "collapsed": false,
211 | "deletable": true,
212 | "editable": true
213 | },
214 | "outputs": [],
215 | "source": [
216 | "[k =: num%den"
217 | ]
218 | },
219 | {
220 | "cell_type": "code",
221 | "execution_count": null,
222 | "metadata": {
223 | "collapsed": false,
224 | "deletable": true,
225 | "editable": true
226 | },
227 | "outputs": [],
228 | "source": [
229 | "b =: ((+/ylg)-k*(+/xlg))%n"
230 | ]
231 | },
232 | {
233 | "cell_type": "code",
234 | "execution_count": null,
235 | "metadata": {
236 | "collapsed": false,
237 | "deletable": true,
238 | "editable": true
239 | },
240 | "outputs": [],
241 | "source": [
242 | "[a =: e^b"
243 | ]
244 | },
245 | {
246 | "cell_type": "markdown",
247 | "metadata": {
248 | "deletable": true,
249 | "editable": true
250 | },
251 | "source": [
252 | "### (5 of 12) Method 1: (ctd)\n",
253 | "To check the quality of the fit, we can calculate the points predicted by the curve\n",
254 | "\n",
255 | " ```yp = ax^k```
\n",
256 | "\n",
257 | "and then sum of squares of the errors\n",
258 | "\n",
259 | " ```yp-vy```
\n",
260 | "\n",
261 | "The value, over 15,000, is quite large. [see below]\n",
262 | "\n",
263 | "At any time, you can interact with the lab. For example, to see the predicted values just type\n",
264 | "\n",
265 | " ```yp```
\n",
266 | "\n",
267 | "To see a list of the errors, type\n",
268 | "\n",
269 | " ```yp-vy```
"
270 | ]
271 | },
272 | {
273 | "cell_type": "code",
274 | "execution_count": null,
275 | "metadata": {
276 | "collapsed": false,
277 | "deletable": true,
278 | "editable": true
279 | },
280 | "outputs": [],
281 | "source": [
282 | "yp =: a*vx^k"
283 | ]
284 | },
285 | {
286 | "cell_type": "code",
287 | "execution_count": null,
288 | "metadata": {
289 | "collapsed": false,
290 | "deletable": true,
291 | "editable": true
292 | },
293 | "outputs": [],
294 | "source": [
295 | "+/(yp-vy)^2"
296 | ]
297 | },
298 | {
299 | "cell_type": "markdown",
300 | "metadata": {
301 | "deletable": true,
302 | "editable": true
303 | },
304 | "source": [
305 | "### (6 of 12) Shortcut for Method 1:\n",
306 | "J has a built-in linear least squares facility which we can use as an alternative to the formulas given above.\n",
307 | "\n",
308 | "Consider the matrix equation AX = B where A and B are given matrices and X is an unknown matrix. If A is a square nonsingular matrix then X = A^(-1)B. In J, the above computation of X from A and B would be written as\n",
309 | "\n",
310 | " ```X =: B %. A```
\n",
311 | "\n",
312 | "and the operation \"%.\" is called \"matrix divide\". More generally, if A has more rows than columns then B %. A is the least squares best approximation to a solution X of AX = B.\n",
313 | "\n",
314 | "With the use of matrix divide we can get a useful shortcut in method 1."
315 | ]
316 | },
317 | {
318 | "cell_type": "markdown",
319 | "metadata": {
320 | "deletable": true,
321 | "editable": true
322 | },
323 | "source": [
324 | "### (7 of 12) Shortcut for Method 1: (ctd)\n",
325 | "In our case, we have n equations of the form\n",
326 | "\n",
327 | " ```(1)b + (log x_i)k = y_i```
\n",
328 | "\n",
329 | "in the two unknowns b and k. Thus to apply matrix divide:\n",
330 | "\n",
331 | " ```A = [1, log x_i], X = [b k], and B = [y_i]```
\n",
332 | "\n",
333 | "[The J code is shown below. Note that we get the same values for a and k that we had previously obtained.]"
334 | ]
335 | },
336 | {
337 | "cell_type": "code",
338 | "execution_count": null,
339 | "metadata": {
340 | "collapsed": false,
341 | "deletable": true,
342 | "editable": true
343 | },
344 | "outputs": [],
345 | "source": [
346 | "A =: 1,.xlg"
347 | ]
348 | },
349 | {
350 | "cell_type": "code",
351 | "execution_count": null,
352 | "metadata": {
353 | "collapsed": false,
354 | "deletable": true,
355 | "editable": true
356 | },
357 | "outputs": [],
358 | "source": [
359 | "'b k' =: ylg %. A"
360 | ]
361 | },
362 | {
363 | "cell_type": "code",
364 | "execution_count": null,
365 | "metadata": {
366 | "collapsed": false,
367 | "deletable": true,
368 | "editable": true
369 | },
370 | "outputs": [],
371 | "source": [
372 | "[a =: e^b"
373 | ]
374 | },
375 | {
376 | "cell_type": "code",
377 | "execution_count": null,
378 | "metadata": {
379 | "collapsed": false,
380 | "deletable": true,
381 | "editable": true
382 | },
383 | "outputs": [],
384 | "source": [
385 | "k"
386 | ]
387 | },
388 | {
389 | "cell_type": "markdown",
390 | "metadata": {
391 | "deletable": true,
392 | "editable": true
393 | },
394 | "source": [
395 | "### (8 of 12) Method 2:\n",
396 | "For the nonlinear least squares version, we cannot rely on standard formulas; but we can minimize using calculus.\n",
397 | "\n",
398 | "We regard the sum of squares as a function of two variables, a and k. To minimize this function, we set the partial derivatives with respect to a and k equal to zero. This gives two equations for the two unknowns a and k.\n",
399 | "\n",
400 | "In the article, the first equation i.e. from the partial with respect to a, is solved algebraically for a in terms of k. The resulting expression is plugged into the second equation to give a single equation for k. This equation is then solved numerically using the Mathematica program FindRoot. Below is the J version for this approach."
401 | ]
402 | },
403 | {
404 | "cell_type": "markdown",
405 | "metadata": {
406 | "deletable": true,
407 | "editable": true
408 | },
409 | "source": [
410 | "### (9 of 12) Method 2: (ctd)\n",
411 | "First we create a program FindRoot, an implementation of Newtons Method in J. Newtons Method applied to f involves iterating the function\n",
412 | "\n",
413 | " ```N(x) = x - f(x)/f'(x)```
\n",
414 | "\n",
415 | "starting with an initial approximation x0 to the root. Thus for some power p,\n",
416 | "\n",
417 | " ```N^p(x0)```
\n",
418 | "\n",
419 | "is an acceptable approximation to the root.\n",
420 | "\n",
421 | "In J, a function f is called a \"verb\". We define an \"adverb\" \"Nwtn\" that modifies f so that \"f Nwtn\" is the function N.\n",
422 | "\n",
423 | "We then iterate an infinite number of times. J will automatically stop the iteration when successive approximations agree to machine tolerance."
424 | ]
425 | },
426 | {
427 | "cell_type": "code",
428 | "execution_count": null,
429 | "metadata": {
430 | "collapsed": false,
431 | "deletable": true,
432 | "editable": true
433 | },
434 | "outputs": [],
435 | "source": [
436 | "Nwtn =: adverb def 'y - (u y)%(u D.1 y)'"
437 | ]
438 | },
439 | {
440 | "cell_type": "markdown",
441 | "metadata": {
442 | "deletable": true,
443 | "editable": true
444 | },
445 | "source": [
446 | "f Nwtn x does one iteration of Newtons method\n",
447 | "y represents the right argument x\n",
448 | "u represents the left argument f\n",
449 | "D.1 is first derivative"
450 | ]
451 | },
452 | {
453 | "cell_type": "code",
454 | "execution_count": null,
455 | "metadata": {
456 | "collapsed": false,
457 | "deletable": true,
458 | "editable": true
459 | },
460 | "outputs": [],
461 | "source": [
462 | "FindRoot =: adverb def 'u Nwtn ^: _'"
463 | ]
464 | },
465 | {
466 | "cell_type": "markdown",
467 | "metadata": {
468 | "deletable": true,
469 | "editable": true
470 | },
471 | "source": [
472 | "^: is power of a function (iteration)\n",
473 | "```_``` is the 'number' infinity"
474 | ]
475 | },
476 | {
477 | "cell_type": "markdown",
478 | "metadata": {
479 | "deletable": true,
480 | "editable": true
481 | },
482 | "source": [
483 | "### (10 of 12) Method 2: (ctd)\n",
484 | "Next we define the function f according to the formula developed in the article. We want to solve f(k) = 0.\n",
485 | "\n",
486 | "We run the FindRoot procedure starting at 2, i.e. as was done with Mathematica in the article. The best fit curve is y = 1.36x^1.90 and the error criterion is 66.5 which is much better than the result of method 1. [See below]"
487 | ]
488 | },
489 | {
490 | "cell_type": "code",
491 | "execution_count": null,
492 | "metadata": {
493 | "collapsed": false,
494 | "deletable": true,
495 | "editable": true
496 | },
497 | "outputs": [],
498 | "source": [
499 | "f =: verb define\n",
500 | "k =. y NB. y is the argument of f, renamed (local) to k\n",
501 | "c =. ((+/vy*vx^k)%(+/vx^(2*k)))*vx^k\n",
502 | "+/(c-vy)*c*xlg\n",
503 | ")"
504 | ]
505 | },
506 | {
507 | "cell_type": "code",
508 | "execution_count": null,
509 | "metadata": {
510 | "collapsed": false,
511 | "deletable": true,
512 | "editable": true
513 | },
514 | "outputs": [],
515 | "source": [
516 | "[k =: f FindRoot 2"
517 | ]
518 | },
519 | {
520 | "cell_type": "code",
521 | "execution_count": null,
522 | "metadata": {
523 | "collapsed": false,
524 | "deletable": true,
525 | "editable": true
526 | },
527 | "outputs": [],
528 | "source": [
529 | "[a =: (+/vy*vx^k)%(+/vx^2*k)"
530 | ]
531 | },
532 | {
533 | "cell_type": "code",
534 | "execution_count": null,
535 | "metadata": {
536 | "collapsed": false,
537 | "deletable": true,
538 | "editable": true
539 | },
540 | "outputs": [],
541 | "source": [
542 | "yp =: a*vx^k"
543 | ]
544 | },
545 | {
546 | "cell_type": "code",
547 | "execution_count": null,
548 | "metadata": {
549 | "collapsed": false,
550 | "deletable": true,
551 | "editable": true
552 | },
553 | "outputs": [],
554 | "source": [
555 | "+/(yp-vy)^2"
556 | ]
557 | },
558 | {
559 | "cell_type": "markdown",
560 | "metadata": {
561 | "deletable": true,
562 | "editable": true
563 | },
564 | "source": [
565 | "### (11 of 12) Shortcut for Method 2:\n",
566 | "The article solved the nonlinear least squares problem by a mixture of algebraic work and numerical computer code. The purpose of the algebra was to reduce two equations in two unknowns to one equation in one unknown.\n",
567 | "\n",
568 | "It is possible to solve the problem directly on the computer by applying the Newton-Raphson method to the pair of equations. The only change necessary in the FindRoot program is to replace % (divide) by %. (matrix divide) in the Nwtn adverb. The details are shown below."
569 | ]
570 | },
571 | {
572 | "cell_type": "code",
573 | "execution_count": null,
574 | "metadata": {
575 | "collapsed": false,
576 | "deletable": true,
577 | "editable": true
578 | },
579 | "outputs": [],
580 | "source": [
581 | "Nwtn =: adverb def 'y - (u y)%.(u D.1 y)'"
582 | ]
583 | },
584 | {
585 | "cell_type": "markdown",
586 | "metadata": {
587 | "deletable": true,
588 | "editable": true
589 | },
590 | "source": [
591 | "f D.1 is a vector of partial of partial derivatives\n",
592 | "f D.1 D.1 is Hessian matrix of partial derivatives"
593 | ]
594 | },
595 | {
596 | "cell_type": "code",
597 | "execution_count": null,
598 | "metadata": {
599 | "collapsed": false,
600 | "deletable": true,
601 | "editable": true
602 | },
603 | "outputs": [],
604 | "source": [
605 | "f =: verb define\n",
606 | "'a k' =. y\n",
607 | "yp =. a*vx^k\n",
608 | "+/(yp-vy)^2\n",
609 | ")"
610 | ]
611 | },
612 | {
613 | "cell_type": "code",
614 | "execution_count": null,
615 | "metadata": {
616 | "collapsed": false,
617 | "deletable": true,
618 | "editable": true
619 | },
620 | "outputs": [],
621 | "source": [
622 | "['a k' =: f D.1 FindRoot 1 2"
623 | ]
624 | },
625 | {
626 | "cell_type": "markdown",
627 | "metadata": {
628 | "deletable": true,
629 | "editable": true
630 | },
631 | "source": [
632 | "### (12 of 12) Some Limitations:\n",
633 | "We have presented FindRoot as an implementation of Newtons Method. Unfortunately, Newtons Method (especially the higher dimensional version) is very sensitive to the initial approximation. For example, the statement\n",
634 | "\n",
635 | " ```['a k' =: f D.1 FindRoot 3 2```
\n",
636 | "\n",
637 | "will not converge to finite values.\n",
638 | "\n",
639 | "We will not go into the general topic of algorithms for solving systems of nonlinear equations; but there is a simple modification of Newtons Method that helps us - we can reduce the step length of Newtons Method. This makes it slower but more stable.\n",
640 | "\n",
641 | "Let alpha be a parameter between zero and one. For alpha=1 we have the normal step length; for alpha=0.5 the step length is halved."
642 | ]
643 | },
644 | {
645 | "cell_type": "code",
646 | "execution_count": null,
647 | "metadata": {
648 | "collapsed": false,
649 | "deletable": true,
650 | "editable": true
651 | },
652 | "outputs": [],
653 | "source": [
654 | "alpha =: 0.2"
655 | ]
656 | },
657 | {
658 | "cell_type": "code",
659 | "execution_count": null,
660 | "metadata": {
661 | "collapsed": false,
662 | "deletable": true,
663 | "editable": true
664 | },
665 | "outputs": [],
666 | "source": [
667 | "Nwtn =: adverb def 'y - alpha*(u y)%.(u D.1 y)'"
668 | ]
669 | },
670 | {
671 | "cell_type": "markdown",
672 | "metadata": {
673 | "deletable": true,
674 | "editable": true
675 | },
676 | "source": [
677 | "Search for the nonlinear solution starting\n",
678 | "at the 'linear' solution found in Method 1"
679 | ]
680 | },
681 | {
682 | "cell_type": "code",
683 | "execution_count": null,
684 | "metadata": {
685 | "collapsed": false,
686 | "deletable": true,
687 | "editable": true
688 | },
689 | "outputs": [],
690 | "source": [
691 | "['a k' =: f D.1 FindRoot 3.7 1.4"
692 | ]
693 | },
694 | {
695 | "cell_type": "markdown",
696 | "metadata": {
697 | "deletable": true,
698 | "editable": true
699 | },
700 | "source": [
701 | "### End of Lab"
702 | ]
703 | }
704 | ],
705 | "metadata": {
706 | "kernelspec": {
707 | "display_name": "J",
708 | "language": "J",
709 | "name": "jkernel"
710 | },
711 | "language_info": {
712 | "file_extension": "ijs",
713 | "mimetype": "text/x-J",
714 | "name": "J"
715 | }
716 | },
717 | "nbformat": 4,
718 | "nbformat_minor": 2
719 | }
720 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/general/The_Tower_of_Hanoi.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "deletable": true,
7 | "editable": true
8 | },
9 | "source": [
10 | "# J Labs\n",
11 | "\n",
12 | "### The Tower of Hanoi"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {
18 | "deletable": true,
19 | "editable": true
20 | },
21 | "source": [
22 | "### (1 of 9) The Problem\n",
23 | "The Tower of Hanoi problem is to move a set of n\n",
24 | "different-sized disks from one peg to another,\n",
25 | "moving one disk at a time, using an intermediate\n",
26 | "peg if necessary. At all times no larger disk may\n",
27 | "sit on top of a smaller disk.\n",
28 | "\n",
29 | "For example, moving 3 disks from peg 0 to peg 1\n",
30 | "can be done as follows:\n",
31 | "\n",
32 | " ```move disk 0 from peg 0 to peg 1```
\n",
33 | " ```move disk 1 from peg 0 to peg 2```
\n",
34 | " ```move disk 0 from peg 1 to peg 2```
\n",
35 | " ```move disk 2 from peg 0 to peg 1```
\n",
36 | " ```move disk 0 from peg 2 to peg 0```
\n",
37 | " ```move disk 1 from peg 2 to peg 1```
\n",
38 | " ```move disk 0 from peg 0 to peg 1```
\n",
39 | "\n",
40 | "The description of the moves can be shortened if\n",
41 | "we observed that in moving a disk from peg A to\n",
42 | "peg B, it is always the top disk on peg A that\n",
43 | "is moved. Thus the 3-disk problem can be solved\n",
44 | "as follows:\n",
45 | "\n",
46 | " ```0 1```
\n",
47 | " ```0 2```
\n",
48 | " ```1 2```
\n",
49 | " ```0 1```
\n",
50 | " ```2 0```
\n",
51 | " ```2 1```
\n",
52 | " ```0 1```
\n",
53 | "\n",
54 | "Legend has it that a group of priests has been\n",
55 | "solving the 64-disk problem since the beginning\n",
56 | "of time, and when they finish, the world will\n",
57 | "come to an end."
58 | ]
59 | },
60 | {
61 | "cell_type": "markdown",
62 | "metadata": {
63 | "deletable": true,
64 | "editable": true
65 | },
66 | "source": [
67 | "### (2 of 9) An Initial Solution\n",
68 | "There is a simple recursive solution to the n-disk\n",
69 | "problem: First, move disks 0 to n-2 from peg 0 to\n",
70 | "peg 2, then move disk n-1 from peg 0 to peg 1,\n",
71 | "then move disks 0 to n-2 from peg 2 to peg 1.\n",
72 | "If there is just one disk, the one disk can be\n",
73 | "moved from peg 0 to peg 1 straightaway.\n",
74 | "\n",
75 | "This can be implemented as a dyadic verb: the right\n",
76 | "argument is the number of disks; the left argument\n",
77 | "are 3 integers of the pegs (from, to, via)."
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "execution_count": null,
83 | "metadata": {
84 | "collapsed": false,
85 | "deletable": true,
86 | "editable": true
87 | },
88 | "outputs": [],
89 | "source": [
90 | "H=: 4 : 0\n",
91 | " if. 1>:y do.\n",
92 | " (y,2)$x\n",
93 | " else.\n",
94 | " ((0 2 1{x) H y-1), (2{.x), ((2 1 0{x) H y-1)\n",
95 | " end.\n",
96 | ")"
97 | ]
98 | },
99 | {
100 | "cell_type": "code",
101 | "execution_count": null,
102 | "metadata": {
103 | "collapsed": false,
104 | "deletable": true,
105 | "editable": true
106 | },
107 | "outputs": [],
108 | "source": [
109 | "0 1 2 H 3"
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {
115 | "deletable": true,
116 | "editable": true
117 | },
118 | "source": [
119 | "### (3 of 9) An Initial Solution (ctd)\n",
120 | "From the definition of H, it is easy to see that\n",
121 | "the n-disk problem requires <:2^n moves. If n=1,\n",
122 | "there is one move (1=<:2^1). If n=k-1 required\n",
123 | "<:2^k-1 moves, then n=k requires the following\n",
124 | "numbers of moves:\n",
125 | "\n",
126 | " ```<:2^k-1 ((0 2 1{x) H y-1)```
\n",
127 | " ```1 (2{.x)```
\n",
128 | " ```<:2^k-1 ((2 1 0{x) H y-1)```
\n",
129 | "\n",
130 | "for a total of <:2^k moves. A similar argument\n",
131 | "shows that the n-disk problem requires <:2^n calls\n",
132 | "of the verb H ."
133 | ]
134 | },
135 | {
136 | "cell_type": "code",
137 | "execution_count": null,
138 | "metadata": {
139 | "collapsed": false,
140 | "deletable": true,
141 | "editable": true
142 | },
143 | "outputs": [],
144 | "source": [
145 | "0 1 2 #@H\"1 0 i.10"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "metadata": {
152 | "collapsed": false,
153 | "deletable": true,
154 | "editable": true
155 | },
156 | "outputs": [],
157 | "source": [
158 | "<: 2 ^ i.10"
159 | ]
160 | },
161 | {
162 | "cell_type": "markdown",
163 | "metadata": {
164 | "deletable": true,
165 | "editable": true
166 | },
167 | "source": [
168 | "### (4 of 9) Singly Recursive Solutions\n",
169 | "The two recursive steps in H differ only in the\n",
170 | "labelling of the pegs. Therefore we can replace\n",
171 | "them with a single recursive call, and do two\n",
172 | "relabellings of the pegs to get the effect of two\n",
173 | "recursions. That is verb H1 below.\n",
174 | "\n",
175 | "Moreover, in verb H1 the left argument is unchanged\n",
176 | "in the recursion; that is, the left argument is\n",
177 | "always 0 1 2, and can be elided.\n",
178 | "\n",
179 | "We saw previously that on the n-disk problem the\n",
180 | "doubly recursive H required <:2^n calls. In the\n",
181 | "singly recursive H1 and H2, the n-disk problem\n",
182 | "requires n calls. Benchmarks on the 10-disk\n",
183 | "problem demonstrate the difference this makes."
184 | ]
185 | },
186 | {
187 | "cell_type": "code",
188 | "execution_count": null,
189 | "metadata": {
190 | "collapsed": false,
191 | "deletable": true,
192 | "editable": true
193 | },
194 | "outputs": [],
195 | "source": [
196 | "H1=: 4 : 0\n",
197 | " if. 1>:y do.\n",
198 | " (y,2)$0 1{x\n",
199 | " else.\n",
200 | " ({&0 2 1 , 0 1\"_ , {&2 1 0) x H1 y-1\n",
201 | " end.\n",
202 | ")"
203 | ]
204 | },
205 | {
206 | "cell_type": "code",
207 | "execution_count": null,
208 | "metadata": {
209 | "collapsed": false,
210 | "deletable": true,
211 | "editable": true
212 | },
213 | "outputs": [],
214 | "source": [
215 | "H2=: 3 : 0\n",
216 | " if. 1>:y do.\n",
217 | " i.y,2\n",
218 | " else.\n",
219 | " ({&0 2 1 , 0 1\"_ , {&2 1 0) H2 y-1\n",
220 | " end.\n",
221 | ")"
222 | ]
223 | },
224 | {
225 | "cell_type": "code",
226 | "execution_count": null,
227 | "metadata": {
228 | "collapsed": false,
229 | "deletable": true,
230 | "editable": true
231 | },
232 | "outputs": [],
233 | "source": [
234 | "0 1 2 (H -: H1)\"1 0 i.10"
235 | ]
236 | },
237 | {
238 | "cell_type": "code",
239 | "execution_count": null,
240 | "metadata": {
241 | "collapsed": false,
242 | "deletable": true,
243 | "editable": true
244 | },
245 | "outputs": [],
246 | "source": [
247 | "(0 1 2&H -: H2)\"0 i.10"
248 | ]
249 | },
250 | {
251 | "cell_type": "code",
252 | "execution_count": null,
253 | "metadata": {
254 | "collapsed": false,
255 | "deletable": true,
256 | "editable": true
257 | },
258 | "outputs": [],
259 | "source": [
260 | "ts=: 6!:2 , 7!:2@] NB. time and space"
261 | ]
262 | },
263 | {
264 | "cell_type": "code",
265 | "execution_count": null,
266 | "metadata": {
267 | "collapsed": false,
268 | "deletable": true,
269 | "editable": true
270 | },
271 | "outputs": [],
272 | "source": [
273 | "ts '0 1 2 H 10'"
274 | ]
275 | },
276 | {
277 | "cell_type": "code",
278 | "execution_count": null,
279 | "metadata": {
280 | "collapsed": false,
281 | "deletable": true,
282 | "editable": true
283 | },
284 | "outputs": [],
285 | "source": [
286 | "ts '0 1 2 H1 10'"
287 | ]
288 | },
289 | {
290 | "cell_type": "code",
291 | "execution_count": null,
292 | "metadata": {
293 | "collapsed": false,
294 | "deletable": true,
295 | "editable": true
296 | },
297 | "outputs": [],
298 | "source": [
299 | "ts 'H2 10'"
300 | ]
301 | },
302 | {
303 | "cell_type": "markdown",
304 | "metadata": {
305 | "deletable": true,
306 | "editable": true
307 | },
308 | "source": [
309 | "### (5 of 9) Non-Recursive Solutions\n",
310 | "We now proceed to derive non-recursive solutions\n",
311 | "to the problem.\n",
312 | "\n",
313 | "The results of verbs H, H1, and H2 are rows of the\n",
314 | "6-row matrix A (the 6 different ways of moving from\n",
315 | "peg i to peg j where i and j can be 0, 1, or 2).\n",
316 | "Thus a more efficient representation for the\n",
317 | "solutions is to encode the moves as row indices\n",
318 | "of A, the integers from 0 to 5."
319 | ]
320 | },
321 | {
322 | "cell_type": "code",
323 | "execution_count": null,
324 | "metadata": {
325 | "collapsed": false,
326 | "deletable": true,
327 | "editable": true
328 | },
329 | "outputs": [],
330 | "source": [
331 | "A=: 6 2 $ 0 1 0 2 1 0 1 2 2 0 2 1"
332 | ]
333 | },
334 | {
335 | "cell_type": "code",
336 | "execution_count": null,
337 | "metadata": {
338 | "collapsed": false,
339 | "deletable": true,
340 | "editable": true
341 | },
342 | "outputs": [],
343 | "source": [
344 | "A"
345 | ]
346 | },
347 | {
348 | "cell_type": "code",
349 | "execution_count": null,
350 | "metadata": {
351 | "collapsed": false,
352 | "deletable": true,
353 | "editable": true
354 | },
355 | "outputs": [],
356 | "source": [
357 | "A i. H2 1"
358 | ]
359 | },
360 | {
361 | "cell_type": "code",
362 | "execution_count": null,
363 | "metadata": {
364 | "collapsed": false,
365 | "deletable": true,
366 | "editable": true
367 | },
368 | "outputs": [],
369 | "source": [
370 | "A i. H2 2"
371 | ]
372 | },
373 | {
374 | "cell_type": "code",
375 | "execution_count": null,
376 | "metadata": {
377 | "collapsed": false,
378 | "deletable": true,
379 | "editable": true
380 | },
381 | "outputs": [],
382 | "source": [
383 | "A i. H2 3"
384 | ]
385 | },
386 | {
387 | "cell_type": "code",
388 | "execution_count": null,
389 | "metadata": {
390 | "collapsed": false,
391 | "deletable": true,
392 | "editable": true
393 | },
394 | "outputs": [],
395 | "source": [
396 | "A i. H2 4"
397 | ]
398 | },
399 | {
400 | "cell_type": "code",
401 | "execution_count": null,
402 | "metadata": {
403 | "collapsed": false,
404 | "deletable": true,
405 | "editable": true
406 | },
407 | "outputs": [],
408 | "source": [
409 | "A i. H2 5"
410 | ]
411 | },
412 | {
413 | "cell_type": "markdown",
414 | "metadata": {
415 | "deletable": true,
416 | "editable": true
417 | },
418 | "source": [
419 | "### (6 of 9) Non-Recursive Solutions (ctd)\n",
420 | "Judicious alignment of the indices reveals a pattern:\n",
421 | "\n",
422 | " ```1: 0```
\n",
423 | " ```2: 1 0 5```
\n",
424 | "\n",
425 | " ```2: 1 0 5```
\n",
426 | " ```3: 0 1 3 0 4 5 0```
\n",
427 | "\n",
428 | " ```3: 0 1 3 0 4 5 0```
\n",
429 | " ```4: 1 0 5 1 2 3 1 0 5 4 2 5 1 0 5```
\n",
430 | "\n",
431 | " ```4: 1 0 5 1 2 3 1 0 5 4 2 5 1 0 5```
\n",
432 | " ```5: 0 1 3 0 4 5 0 1 3 2 4 3 0 1 3 0 4 5 0 4 3 2 4 5 0 1 3 0 4 5 0```
\n",
433 | "\n",
434 | "To get from A i. H2 n-1 to A i. H2 n , merge\n",
435 | "(intersperse) the result for n with 1 5 2 if n is\n",
436 | "even and with 0 3 4 if n is odd. Thus:"
437 | ]
438 | },
439 | {
440 | "cell_type": "code",
441 | "execution_count": null,
442 | "metadata": {
443 | "collapsed": false,
444 | "deletable": true,
445 | "editable": true
446 | },
447 | "outputs": [],
448 | "source": [
449 | "H3=: 3 : 0\n",
450 | " if. 1>:y do.\n",
451 | " y$0\n",
452 | " else.\n",
453 | " }: , ((2^y-1)$(2|y){1 5 2,:0 3 4) ,. 0,~H3 y-1\n",
454 | " end.\n",
455 | ")"
456 | ]
457 | },
458 | {
459 | "cell_type": "code",
460 | "execution_count": null,
461 | "metadata": {
462 | "collapsed": false,
463 | "deletable": true,
464 | "editable": true
465 | },
466 | "outputs": [],
467 | "source": [
468 | "H3 3"
469 | ]
470 | },
471 | {
472 | "cell_type": "code",
473 | "execution_count": null,
474 | "metadata": {
475 | "collapsed": false,
476 | "deletable": true,
477 | "editable": true
478 | },
479 | "outputs": [],
480 | "source": [
481 | "(A i. H2 3) -: H3 3"
482 | ]
483 | },
484 | {
485 | "cell_type": "code",
486 | "execution_count": null,
487 | "metadata": {
488 | "collapsed": false,
489 | "deletable": true,
490 | "editable": true
491 | },
492 | "outputs": [],
493 | "source": [
494 | "(A&i.@H2 -: H3)\"0 i.10"
495 | ]
496 | },
497 | {
498 | "cell_type": "markdown",
499 | "metadata": {
500 | "deletable": true,
501 | "editable": true
502 | },
503 | "source": [
504 | "### (7 of 9) Non-Recursive Solutions (ctd)\n",
505 | "H3 n works by appending an atom to the result of\n",
506 | "H3 n-1 ; then stitching a list, repetitions of\n",
507 | "1 5 2 or 0 3 4; then ravelling; then dropping the\n",
508 | "last (previously appended) atom.\n",
509 | "\n",
510 | "The list of numbers to be stitched (repetitions of\n",
511 | "0 3 4 or 1 5 2) depends only on n, and on H3 n-1\n",
512 | "not at all. This suggests a different method of\n",
513 | "directing the computation: Compute the lists xi\n",
514 | "of numbers to be stitched for 1, 2, 3, ..., up to n,\n",
515 | "and then apply an appropriate verb f between them:\n",
516 | "\n",
517 | " ```xn f ... f x3 f x2 f x1```
\n",
518 | " ```> f&.> / xn ; ... ; x3 ; x2 ; x1```
\n",
519 | "\n",
520 | "Moreover, we can avoid incorporating into f the\n",
521 | "appending and dropping of atoms, if we start out\n",
522 | "with an \"extra\" atom and drop it only at the end:\n",
523 | "\n",
524 | " ```> f&.> / xn ; ... ; x3 ; x2 ; x1```
\n",
525 | " ```}: > g&.> / xn ; ... ; x3 ; x2 ; x1 ; atom```
\n",
526 | "\n",
527 | "In H4 below, the verb g is ,@,. (ravel stitch)."
528 | ]
529 | },
530 | {
531 | "cell_type": "code",
532 | "execution_count": null,
533 | "metadata": {
534 | "collapsed": false,
535 | "deletable": true,
536 | "editable": true
537 | },
538 | "outputs": [],
539 | "source": [
540 | "H4 =: }: @ > @ (,@,.&.>/) @ (< ,~ 2&^@i. $&.>&|. $&(0 3 4;1 5 2))"
541 | ]
542 | },
543 | {
544 | "cell_type": "code",
545 | "execution_count": null,
546 | "metadata": {
547 | "collapsed": false,
548 | "deletable": true,
549 | "editable": true
550 | },
551 | "outputs": [],
552 | "source": [
553 | "(H3 -: H4)\"0 i.10"
554 | ]
555 | },
556 | {
557 | "cell_type": "code",
558 | "execution_count": null,
559 | "metadata": {
560 | "collapsed": false,
561 | "deletable": true,
562 | "editable": true
563 | },
564 | "outputs": [],
565 | "source": [
566 | "arg=: < ,~ 2&^@i. $&.>&|. $&(0 3 4;1 5 2)"
567 | ]
568 | },
569 | {
570 | "cell_type": "code",
571 | "execution_count": null,
572 | "metadata": {
573 | "collapsed": false,
574 | "deletable": true,
575 | "editable": true
576 | },
577 | "outputs": [],
578 | "source": [
579 | "arg 1"
580 | ]
581 | },
582 | {
583 | "cell_type": "code",
584 | "execution_count": null,
585 | "metadata": {
586 | "collapsed": false,
587 | "deletable": true,
588 | "editable": true
589 | },
590 | "outputs": [],
591 | "source": [
592 | "arg 2"
593 | ]
594 | },
595 | {
596 | "cell_type": "code",
597 | "execution_count": null,
598 | "metadata": {
599 | "collapsed": false,
600 | "deletable": true,
601 | "editable": true
602 | },
603 | "outputs": [],
604 | "source": [
605 | "arg 3"
606 | ]
607 | },
608 | {
609 | "cell_type": "code",
610 | "execution_count": null,
611 | "metadata": {
612 | "collapsed": false,
613 | "deletable": true,
614 | "editable": true
615 | },
616 | "outputs": [],
617 | "source": [
618 | "arg 4"
619 | ]
620 | },
621 | {
622 | "cell_type": "code",
623 | "execution_count": null,
624 | "metadata": {
625 | "collapsed": false,
626 | "deletable": true,
627 | "editable": true
628 | },
629 | "outputs": [],
630 | "source": [
631 | "arg 5"
632 | ]
633 | },
634 | {
635 | "cell_type": "markdown",
636 | "metadata": {
637 | "deletable": true,
638 | "editable": true
639 | },
640 | "source": [
641 | "### (8 of 9) Non-Recursive Solutions (ctd)\n",
642 | "There is another possibility. The pattern in H4 is:\n",
643 | "\n",
644 | " ```}: > g&.> / xn ; ... ; x3 ; x2 ; x1 ; atom```
\n",
645 | "\n",
646 | "In an intermediate stage, when g is being applied,\n",
647 | "\n",
648 | " ```xi g yi```
\n",
649 | "\n",
650 | "g \"knows\" from yi alone what xi has to be:\n",
651 | "the length of yi determines the length of xi,\n",
652 | "and the leading atom of yi (0 or 1) determines\n",
653 | "whether 1 5 2 or 0 3 4 should be ravel-stitched.\n",
654 | "This suggests another solution: a monad is applied\n",
655 | "n times to the atom 1."
656 | ]
657 | },
658 | {
659 | "cell_type": "code",
660 | "execution_count": null,
661 | "metadata": {
662 | "collapsed": false,
663 | "deletable": true,
664 | "editable": true
665 | },
666 | "outputs": [],
667 | "source": [
668 | "H5=: [: }: (,@,.~ # $ {. { (1 5 2,:0 3 4)\"_)^:(]`1:)"
669 | ]
670 | },
671 | {
672 | "cell_type": "code",
673 | "execution_count": null,
674 | "metadata": {
675 | "collapsed": false,
676 | "deletable": true,
677 | "editable": true
678 | },
679 | "outputs": [],
680 | "source": [
681 | "(H4 -: H5)\"0 i.10"
682 | ]
683 | },
684 | {
685 | "cell_type": "code",
686 | "execution_count": null,
687 | "metadata": {
688 | "collapsed": false,
689 | "deletable": true,
690 | "editable": true
691 | },
692 | "outputs": [],
693 | "source": [
694 | "rsa=: ,@,.~ # $ {. { (1 5 2,:0 3 4)\"_"
695 | ]
696 | },
697 | {
698 | "cell_type": "code",
699 | "execution_count": null,
700 | "metadata": {
701 | "collapsed": false,
702 | "deletable": true,
703 | "editable": true
704 | },
705 | "outputs": [],
706 | "source": [
707 | "rsa 1"
708 | ]
709 | },
710 | {
711 | "cell_type": "code",
712 | "execution_count": null,
713 | "metadata": {
714 | "collapsed": false,
715 | "deletable": true,
716 | "editable": true
717 | },
718 | "outputs": [],
719 | "source": [
720 | "rsa rsa 1"
721 | ]
722 | },
723 | {
724 | "cell_type": "code",
725 | "execution_count": null,
726 | "metadata": {
727 | "collapsed": false,
728 | "deletable": true,
729 | "editable": true
730 | },
731 | "outputs": [],
732 | "source": [
733 | "rsa rsa rsa 1"
734 | ]
735 | },
736 | {
737 | "cell_type": "code",
738 | "execution_count": null,
739 | "metadata": {
740 | "collapsed": false,
741 | "deletable": true,
742 | "editable": true
743 | },
744 | "outputs": [],
745 | "source": [
746 | "rsa^:(3) 1"
747 | ]
748 | },
749 | {
750 | "cell_type": "code",
751 | "execution_count": null,
752 | "metadata": {
753 | "collapsed": false,
754 | "deletable": true,
755 | "editable": true
756 | },
757 | "outputs": [],
758 | "source": [
759 | "H5 3"
760 | ]
761 | },
762 | {
763 | "cell_type": "markdown",
764 | "metadata": {
765 | "deletable": true,
766 | "editable": true
767 | },
768 | "source": [
769 | "### (9 of 9) Conclusion\n",
770 | "The Tower of Hanoi problem can be solved in a\n",
771 | "variety of ways, with a wide variation in efficiency.\n",
772 | "\n",
773 | " ```H double recursion```
\n",
774 | " ```H1 single recursion```
\n",
775 | " ```H2 single recursion monad```
\n",
776 | " ```H3 single recursion, atomic representation```
\n",
777 | " ```H4 non-recursive, insert```
\n",
778 | " ```H5 non-recursive, power```
"
779 | ]
780 | },
781 | {
782 | "cell_type": "code",
783 | "execution_count": null,
784 | "metadata": {
785 | "collapsed": false,
786 | "deletable": true,
787 | "editable": true
788 | },
789 | "outputs": [],
790 | "source": [
791 | "0j8 0 \": ts;._1 '/0 1 2 H 10/0 1 2 H1 10/H2 10/H3 10/H4 10/H5 10'"
792 | ]
793 | },
794 | {
795 | "cell_type": "markdown",
796 | "metadata": {
797 | "deletable": true,
798 | "editable": true
799 | },
800 | "source": [
801 | "### End of Lab"
802 | ]
803 | },
804 | {
805 | "cell_type": "code",
806 | "execution_count": null,
807 | "metadata": {
808 | "collapsed": false,
809 | "deletable": true,
810 | "editable": true
811 | },
812 | "outputs": [],
813 | "source": []
814 | }
815 | ],
816 | "metadata": {
817 | "kernelspec": {
818 | "display_name": "J",
819 | "language": "J",
820 | "name": "jkernel"
821 | },
822 | "language_info": {
823 | "file_extension": "ijs",
824 | "mimetype": "text/x-J",
825 | "name": "J"
826 | }
827 | },
828 | "nbformat": 4,
829 | "nbformat_minor": 2
830 | }
831 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/general/Huffman_Coding.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "deletable": true,
7 | "editable": true
8 | },
9 | "source": [
10 | "# J Labs\n",
11 | "\n",
12 | "### Huffman Coding"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {
18 | "deletable": true,
19 | "editable": true
20 | },
21 | "source": [
22 | "### (1 of 8) Introduction\n",
23 | "\n",
24 | "Huffman coding assigns codes to words in a text based on the\n",
25 | "frequency (probability, weight) of occurrence of the words,\n",
26 | "to reduce the space needed to represent the text. It exploits\n",
27 | "the disparity in word frequencies by assigning short codes\n",
28 | "to the more frequently occurring words, and conversely longer\n",
29 | "codes to the less frequently occurring words.\n",
30 | "\n",
31 | "A simplified version is presented here where the \"words\" are\n",
32 | "letters and codes are binary (lists of 0s and 1s)."
33 | ]
34 | },
35 | {
36 | "cell_type": "markdown",
37 | "metadata": {
38 | "deletable": true,
39 | "editable": true
40 | },
41 | "source": [
42 | "### (2 of 8) Encoding\n",
43 | "\n",
44 | "The assigning of codes is done by constructing a binary tree\n",
45 | "with minimum weighted path lengths with the words at the\n",
46 | "leaves. The paths are the codes.\n",
47 | "\n",
48 | "The method is due to David A. Huffman (Kenneth E. Iverson, A\n",
49 | "Programming Language, Wiley, 1962, Section 3.4, Example 3.2;\n",
50 | "Donald Knuth, The Art of Computer Programming, Volume 1,\n",
51 | "Addison-Wesley, 1973, Section 2.3.4.5). The main logic is\n",
52 | "embodied in the recursive verb hc below. The arguments are a\n",
53 | "list of weights and a list of the corresponding subtrees.\n",
54 | "hc takes the two subtrees with the smallest weights and makes\n",
55 | "a new subtree from them, whose weight is the sum of the two\n",
56 | "weights. Initially the weights are the original frequencies\n",
57 | "and the subtrees are the original words. The recursion stops\n",
58 | "when there is just one subtree (and one weight)."
59 | ]
60 | },
61 | {
62 | "cell_type": "code",
63 | "execution_count": null,
64 | "metadata": {
65 | "collapsed": false,
66 | "deletable": true,
67 | "editable": true
68 | },
69 | "outputs": [],
70 | "source": [
71 | "hc=: 4 : 0\n",
72 | " if. 1=#x do. y\n",
73 | " else. ((i{x),+/j{x) hc (i{y),: L.y NB. words are boxed not more than once\n",
91 | " w=. ,&.> y NB. standardized words\n",
92 | " assert. w -: ~.w NB. words are unique\n",
93 | " t=. 0 {:: x hc w NB. minimal weight binary tree\n",
94 | " ((< S: 0 t) i. w) { <@(1&=)@; S: 1 {:: t\n",
95 | ")"
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {
101 | "deletable": true,
102 | "editable": true
103 | },
104 | "source": [
105 | "### (3 of 8) Encoding (ctd)\n",
106 | "\n",
107 | "We use a small example to illustrate the workings of the\n",
108 | "Huffman encoding algorithm. The letters are a b c d e f\n",
109 | "and the corresponding frequencies are 3 1 4 1 5 9.\n",
110 | "\n",
111 | "hc constructs the minimum weighted binary tree t with\n",
112 | "the words at the leaves.\n",
113 | "\n",
114 | "< S: 0 t gives the words in left first traversal.\n",
115 | "\n",
116 | "{:: t gives the paths to the words.\n",
117 | "\n",
118 | "<@(1&=)@; S: 1 {:: t makes a list of the paths in left\n",
119 | "first order. (The 1&= makes the numbers boolean.)\n",
120 | "\n",
121 | "A final index gives the Huffman codes."
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": null,
127 | "metadata": {
128 | "collapsed": false,
129 | "deletable": true,
130 | "editable": true
131 | },
132 | "outputs": [],
133 | "source": [
134 | "A=: 'abcdef' NB. letters"
135 | ]
136 | },
137 | {
138 | "cell_type": "code",
139 | "execution_count": null,
140 | "metadata": {
141 | "collapsed": false,
142 | "deletable": true,
143 | "editable": true
144 | },
145 | "outputs": [],
146 | "source": [
147 | "F=: 3 1 4 1 5 9 NB. corresponding frequencies"
148 | ]
149 | },
150 | {
151 | "cell_type": "code",
152 | "execution_count": null,
153 | "metadata": {
154 | "collapsed": false,
155 | "deletable": true,
156 | "editable": true
157 | },
158 | "outputs": [],
159 | "source": [
160 | "] t=: 0 {:: F hc ,&.>A NB. minimum weighted binary tree"
161 | ]
162 | },
163 | {
164 | "cell_type": "code",
165 | "execution_count": null,
166 | "metadata": {
167 | "collapsed": false,
168 | "deletable": true,
169 | "editable": true
170 | },
171 | "outputs": [],
172 | "source": [
173 | "] a=: < S: 0 t NB. the words in left first traversal"
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": null,
179 | "metadata": {
180 | "collapsed": false,
181 | "deletable": true,
182 | "editable": true
183 | },
184 | "outputs": [],
185 | "source": [
186 | "{:: t NB. paths to the words"
187 | ]
188 | },
189 | {
190 | "cell_type": "code",
191 | "execution_count": null,
192 | "metadata": {
193 | "collapsed": false,
194 | "deletable": true,
195 | "editable": true
196 | },
197 | "outputs": [],
198 | "source": [
199 | "] p=: <@(1&=)@; S: 1 {:: t NB. paths in standard form"
200 | ]
201 | },
202 | {
203 | "cell_type": "code",
204 | "execution_count": null,
205 | "metadata": {
206 | "collapsed": false,
207 | "deletable": true,
208 | "editable": true
209 | },
210 | "outputs": [],
211 | "source": [
212 | "((;a) i. A) { p NB. Huffman codes for a b c d e f"
213 | ]
214 | },
215 | {
216 | "cell_type": "code",
217 | "execution_count": null,
218 | "metadata": {
219 | "collapsed": false,
220 | "deletable": true,
221 | "editable": true
222 | },
223 | "outputs": [],
224 | "source": [
225 | "] H=: F hcodes A NB. Huffman codes for a b c d e f"
226 | ]
227 | },
228 | {
229 | "cell_type": "markdown",
230 | "metadata": {
231 | "deletable": true,
232 | "editable": true
233 | },
234 | "source": [
235 | "### (4 of 8) Encoding (ctd)\n",
236 | "\n",
237 | "To encode a given text, find the location of each letter in\n",
238 | "the alphabet A and then index into the list of Huffman\n",
239 | "codes H. The raze of these codes is the Huffman encoding."
240 | ]
241 | },
242 | {
243 | "cell_type": "code",
244 | "execution_count": null,
245 | "metadata": {
246 | "collapsed": false,
247 | "deletable": true,
248 | "editable": true
249 | },
250 | "outputs": [],
251 | "source": [
252 | "hencode=: 4 : '(>{.x) ;@:{~ (>{:x) i. y'"
253 | ]
254 | },
255 | {
256 | "cell_type": "code",
257 | "execution_count": null,
258 | "metadata": {
259 | "collapsed": false,
260 | "deletable": true,
261 | "editable": true
262 | },
263 | "outputs": [],
264 | "source": [
265 | "(A i. 'cab') { H"
266 | ]
267 | },
268 | {
269 | "cell_type": "code",
270 | "execution_count": null,
271 | "metadata": {
272 | "collapsed": false,
273 | "deletable": true,
274 | "editable": true
275 | },
276 | "outputs": [],
277 | "source": [
278 | "; (A i. 'cab') { H"
279 | ]
280 | },
281 | {
282 | "cell_type": "code",
283 | "execution_count": null,
284 | "metadata": {
285 | "collapsed": false,
286 | "deletable": true,
287 | "editable": true
288 | },
289 | "outputs": [],
290 | "source": [
291 | "HA=: H;A"
292 | ]
293 | },
294 | {
295 | "cell_type": "code",
296 | "execution_count": null,
297 | "metadata": {
298 | "collapsed": false,
299 | "deletable": true,
300 | "editable": true
301 | },
302 | "outputs": [],
303 | "source": [
304 | "HA hencode 'cab'"
305 | ]
306 | },
307 | {
308 | "cell_type": "markdown",
309 | "metadata": {
310 | "deletable": true,
311 | "editable": true
312 | },
313 | "source": [
314 | "### (5 of 8) Decoding\n",
315 | "\n",
316 | "The dyad ;: (sequential machine) facilitates conversion from\n",
317 | "Huffman codes back into the original text. The verb hst\n",
318 | "computes S and B required to effect the decoding.\n",
319 | "\n",
320 | "S is the state transition and output table (\"state table\"\n",
321 | "for short), a key item in the left argument for ;: .\n",
322 | "\n",
323 | "B is the list such that ```_```2]\\B are the letters that correspond\n",
324 | "to the entries in S. B has '```_```' for entries in S that do not\n",
325 | "correspond to any letter."
326 | ]
327 | },
328 | {
329 | "cell_type": "markdown",
330 | "metadata": {
331 | "deletable": true,
332 | "editable": true
333 | },
334 | "source": [
335 | "### (6 of 8) Decoding (ctd)\n",
336 | "\n",
337 | "Each entry of the state table S is a pair of numbers of the\n",
338 | "new state and output code. The table has outer shape s,2,\n",
339 | "where s is the number of possible states and 2 is the number\n",
340 | "of possible values in Huffman codes (0 and 1).\n",
341 | "\n",
342 | "The table is constructed by considering all possible prefixes\n",
343 | "of the Huffman codes, sorted by length and value. This is\n",
344 | "the quantity p in the verb hst. (The sorting is for esthetic\n",
345 | "purposes and is not required for the correct functioning of\n",
346 | "the decoding.) 0 and 1 are then separately appended to each\n",
347 | "prefix, q in the verb hst. These correspond to the entries\n",
348 | "in S.\n",
349 | "\n",
350 | "If an entry of q is an actual Huffman code, the output code\n",
351 | "is 3 (terminate the current code word) and the new state is 0\n",
352 | "(scan for a new code word); if it does not, then the output\n",
353 | "code is 0 (continue building the current code word) and the\n",
354 | "new state is the row in q that corresponds to the abuilding\n",
355 | "code word.\n",
356 | "\n",
357 | "The last phrase below shows the correspondence between q S B;\n",
358 | "respectively, the code words, the state table (with the new\n",
359 | "state and output codes), and the original letters."
360 | ]
361 | },
362 | {
363 | "cell_type": "code",
364 | "execution_count": null,
365 | "metadata": {
366 | "collapsed": false,
367 | "deletable": true,
368 | "editable": true
369 | },
370 | "outputs": [],
371 | "source": [
372 | "type =: 3!:0"
373 | ]
374 | },
375 | {
376 | "cell_type": "code",
377 | "execution_count": null,
378 | "metadata": {
379 | "collapsed": false,
380 | "deletable": true,
381 | "editable": true
382 | },
383 | "outputs": [],
384 | "source": [
385 | "nullc=: '_' NB. illegal character (use {:a. in practice)"
386 | ]
387 | },
388 | {
389 | "cell_type": "code",
390 | "execution_count": null,
391 | "metadata": {
392 | "collapsed": false,
393 | "deletable": true,
394 | "editable": true
395 | },
396 | "outputs": [],
397 | "source": [
398 | "hst=: 3 : 0 NB. Huffman decode state transition table\n",
399 | " 'H A'=. y\n",
400 | " assert. H-:A\n",
401 | " assert. (1=#$A)*. 2=type A NB. letters\n",
402 | " assert. (1=#$H)*.32=type H NB. corresponding Huffman codes\n",
403 | " assert. (1=#@$&>H)*.1=type&>H NB. H-codes are boolean lists\n",
404 | " assert. H -: ~.H NB. H-codes must be unique\n",
405 | " assert. -. a: e. H NB. H-codes must be non-empty\n",
406 | " p=. ~. a: , ; <\\@}:&.>H NB. all possible prefixes\n",
407 | " p=. p /: (#&.>p),.p NB. sorted by length and value\n",
408 | " q=. p ,&.>/ 0;1 NB. code words corresponding to S\n",
409 | " assert. H e. ,q NB. should contain all the H-codes\n",
410 | " B=. (H i.,q){A,nullc NB. plain letter for each state\n",
411 | " b=. q e. H NB. 1 iff an actual Huffman code\n",
412 | " e=. 1, }. 3 * b NB. output codes\n",
413 | " s=. (-.b) * p i. q NB. state transitions\n",
414 | " assert. -. (,&.>0 1) e. H NB. nonce error if (,0) or (,1) are H-codes\n",
415 | " S=. s,\"0 e\n",
416 | " S;B\n",
417 | ")"
418 | ]
419 | },
420 | {
421 | "cell_type": "code",
422 | "execution_count": null,
423 | "metadata": {
424 | "collapsed": false,
425 | "deletable": true,
426 | "editable": true
427 | },
428 | "outputs": [],
429 | "source": [
430 | "'S B'=: SB=: hst HA"
431 | ]
432 | },
433 | {
434 | "cell_type": "code",
435 | "execution_count": null,
436 | "metadata": {
437 | "collapsed": false,
438 | "deletable": true,
439 | "editable": true
440 | },
441 | "outputs": [],
442 | "source": [
443 | "$S"
444 | ]
445 | },
446 | {
447 | "cell_type": "code",
448 | "execution_count": null,
449 | "metadata": {
450 | "collapsed": false,
451 | "deletable": true,
452 | "editable": true
453 | },
454 | "outputs": [],
455 | "source": [
456 | "#B"
457 | ]
458 | },
459 | {
460 | "cell_type": "code",
461 | "execution_count": null,
462 | "metadata": {
463 | "collapsed": false,
464 | "deletable": true,
465 | "editable": true
466 | },
467 | "outputs": [],
468 | "source": [
469 | "(#B) = */ 2{.$S"
470 | ]
471 | },
472 | {
473 | "cell_type": "code",
474 | "execution_count": null,
475 | "metadata": {
476 | "collapsed": false,
477 | "deletable": true,
478 | "editable": true
479 | },
480 | "outputs": [],
481 | "source": [
482 | "p=: ~. a: , ; <\\@}:&.>H NB. all possible prefixes"
483 | ]
484 | },
485 | {
486 | "cell_type": "code",
487 | "execution_count": null,
488 | "metadata": {
489 | "collapsed": false,
490 | "deletable": true,
491 | "editable": true
492 | },
493 | "outputs": [],
494 | "source": [
495 | "p=: p /: (#&.>p),.p NB. sorted by length and value"
496 | ]
497 | },
498 | {
499 | "cell_type": "code",
500 | "execution_count": null,
501 | "metadata": {
502 | "collapsed": false,
503 | "deletable": true,
504 | "editable": true
505 | },
506 | "outputs": [],
507 | "source": [
508 | "q=: p ,&.>/ 0;1 NB. code words corresponding to S"
509 | ]
510 | },
511 | {
512 | "cell_type": "markdown",
513 | "metadata": {
514 | "deletable": true,
515 | "editable": true
516 | },
517 | "source": [
518 | "code words, new state and output codes, original letters"
519 | ]
520 | },
521 | {
522 | "cell_type": "code",
523 | "execution_count": null,
524 | "metadata": {
525 | "collapsed": false,
526 | "deletable": true,
527 | "editable": true
528 | },
529 | "outputs": [],
530 | "source": [
531 | "(\":q),.' ',.(\":<\"1 S),.' ',.\": <\"0 ] _2 ]\\B"
532 | ]
533 | },
534 | {
535 | "cell_type": "markdown",
536 | "metadata": {
537 | "deletable": true,
538 | "editable": true
539 | },
540 | "source": [
541 | "### (7 of 8) Decoding (ctd)\n",
542 | "\n",
543 | "Having the state table and corresponding letters in hand,\n",
544 | "it is a simple matter to recover the original text: run the\n",
545 | "sequential machine using function code 3 -- return as result\n",
546 | "the state table indices at the time of output -- and use\n",
547 | "the indices to index into B."
548 | ]
549 | },
550 | {
551 | "cell_type": "code",
552 | "execution_count": null,
553 | "metadata": {
554 | "collapsed": false,
555 | "deletable": true,
556 | "editable": true
557 | },
558 | "outputs": [],
559 | "source": [
560 | "hdecode=: 4 : '(>{:x) {~ (3;{.x);:y'"
561 | ]
562 | },
563 | {
564 | "cell_type": "code",
565 | "execution_count": null,
566 | "metadata": {
567 | "collapsed": false,
568 | "deletable": true,
569 | "editable": true
570 | },
571 | "outputs": [],
572 | "source": [
573 | "SB hdecode HA hencode 'cabbed'"
574 | ]
575 | },
576 | {
577 | "cell_type": "markdown",
578 | "metadata": {
579 | "deletable": true,
580 | "editable": true
581 | },
582 | "source": [
583 | "### (8 of 8) Example\n",
584 | "\n",
585 | "Here we use a more extended example. A is a list of the\n",
586 | "space and the letters of the alphabet. F is a list of the\n",
587 | "corresponding frequencies based on the book of Isaiah in\n",
588 | "the NIV bible.\n",
589 | "\n",
590 | "For example, the space occurs 34511 times, the letter a\n",
591 | "occurs 10413 times, b 2041 times, etc. The letter z\n",
592 | "occurs 161 times, much less frequently than the letter a.\n",
593 | "\n",
594 | "H is a list of the Huffman codes for the letters A whose\n",
595 | "frequencies are F. Thus:\n",
596 | "\n",
597 | " ```letter freq hcode```
\n",
598 | "\n",
599 | " ```space 34511 0 0```
\n",
600 | " ```a 10413 1 0 0 1```
\n",
601 | " ```b 2041 0 1 1 0 0 0```
\n",
602 | " ```z 161 1 1 0 0 1 0 1 0 0 1```
\n",
603 | "\n",
604 | "The benchmarks show that hencode and hdecode are quite\n",
605 | "efficient."
606 | ]
607 | },
608 | {
609 | "cell_type": "code",
610 | "execution_count": null,
611 | "metadata": {
612 | "collapsed": false,
613 | "deletable": true,
614 | "editable": true
615 | },
616 | "outputs": [],
617 | "source": [
618 | "A=: ' ',(97+i.26){a."
619 | ]
620 | },
621 | {
622 | "cell_type": "code",
623 | "execution_count": null,
624 | "metadata": {
625 | "collapsed": false,
626 | "deletable": true,
627 | "editable": true
628 | },
629 | "outputs": [],
630 | "source": [
631 | "F=: 34511 10413 2041 2339 6059 17277 3241 2668 9437 9454 292 1199 7690 3306 8723 11885 2110 39 8739 8780 11621 3883 1351 3953 53 3564 161"
632 | ]
633 | },
634 | {
635 | "cell_type": "code",
636 | "execution_count": null,
637 | "metadata": {
638 | "collapsed": false,
639 | "deletable": true,
640 | "editable": true
641 | },
642 | "outputs": [],
643 | "source": [
644 | "(#A) = #F"
645 | ]
646 | },
647 | {
648 | "cell_type": "code",
649 | "execution_count": null,
650 | "metadata": {
651 | "collapsed": false,
652 | "deletable": true,
653 | "editable": true
654 | },
655 | "outputs": [],
656 | "source": [
657 | "H=: F hcodes A"
658 | ]
659 | },
660 | {
661 | "cell_type": "code",
662 | "execution_count": null,
663 | "metadata": {
664 | "collapsed": false,
665 | "deletable": true,
666 | "editable": true
667 | },
668 | "outputs": [],
669 | "source": [
670 | "H {~ A i. ' abz'"
671 | ]
672 | },
673 | {
674 | "cell_type": "code",
675 | "execution_count": null,
676 | "metadata": {
677 | "collapsed": false,
678 | "deletable": true,
679 | "editable": true
680 | },
681 | "outputs": [],
682 | "source": [
683 | "HA=: H;A"
684 | ]
685 | },
686 | {
687 | "cell_type": "code",
688 | "execution_count": null,
689 | "metadata": {
690 | "collapsed": false,
691 | "deletable": true,
692 | "editable": true
693 | },
694 | "outputs": [],
695 | "source": [
696 | "t=: 'the quick brown fox jumps over the lazy dog '"
697 | ]
698 | },
699 | {
700 | "cell_type": "code",
701 | "execution_count": null,
702 | "metadata": {
703 | "collapsed": false,
704 | "deletable": true,
705 | "editable": true
706 | },
707 | "outputs": [],
708 | "source": [
709 | "HA hencode t"
710 | ]
711 | },
712 | {
713 | "cell_type": "code",
714 | "execution_count": null,
715 | "metadata": {
716 | "collapsed": false,
717 | "deletable": true,
718 | "editable": true
719 | },
720 | "outputs": [],
721 | "source": [
722 | "SB=: hst HA"
723 | ]
724 | },
725 | {
726 | "cell_type": "code",
727 | "execution_count": null,
728 | "metadata": {
729 | "collapsed": false,
730 | "deletable": true,
731 | "editable": true
732 | },
733 | "outputs": [],
734 | "source": [
735 | "SB hdecode HA hencode t"
736 | ]
737 | },
738 | {
739 | "cell_type": "code",
740 | "execution_count": null,
741 | "metadata": {
742 | "collapsed": false,
743 | "deletable": true,
744 | "editable": true
745 | },
746 | "outputs": [],
747 | "source": [
748 | "x=: 1e6 $ t"
749 | ]
750 | },
751 | {
752 | "cell_type": "code",
753 | "execution_count": null,
754 | "metadata": {
755 | "collapsed": false,
756 | "deletable": true,
757 | "editable": true
758 | },
759 | "outputs": [],
760 | "source": [
761 | "# y=: HA hencode x"
762 | ]
763 | },
764 | {
765 | "cell_type": "code",
766 | "execution_count": null,
767 | "metadata": {
768 | "collapsed": false,
769 | "deletable": true,
770 | "editable": true
771 | },
772 | "outputs": [],
773 | "source": [
774 | "x -: SB hdecode y"
775 | ]
776 | },
777 | {
778 | "cell_type": "code",
779 | "execution_count": null,
780 | "metadata": {
781 | "collapsed": false,
782 | "deletable": true,
783 | "editable": true
784 | },
785 | "outputs": [],
786 | "source": [
787 | "ts=: 6!:2 , 7!:2@]"
788 | ]
789 | },
790 | {
791 | "cell_type": "code",
792 | "execution_count": null,
793 | "metadata": {
794 | "collapsed": false,
795 | "deletable": true,
796 | "editable": true
797 | },
798 | "outputs": [],
799 | "source": [
800 | "ts 'HA hencode x'"
801 | ]
802 | },
803 | {
804 | "cell_type": "code",
805 | "execution_count": null,
806 | "metadata": {
807 | "collapsed": false,
808 | "deletable": true,
809 | "editable": true
810 | },
811 | "outputs": [],
812 | "source": [
813 | "ts 'SB hdecode y'"
814 | ]
815 | },
816 | {
817 | "cell_type": "markdown",
818 | "metadata": {
819 | "deletable": true,
820 | "editable": true
821 | },
822 | "source": [
823 | "### End of Lab"
824 | ]
825 | },
826 | {
827 | "cell_type": "code",
828 | "execution_count": null,
829 | "metadata": {
830 | "collapsed": false,
831 | "deletable": true,
832 | "editable": true
833 | },
834 | "outputs": [],
835 | "source": []
836 | }
837 | ],
838 | "metadata": {
839 | "kernelspec": {
840 | "display_name": "J",
841 | "language": "J",
842 | "name": "jkernel"
843 | },
844 | "language_info": {
845 | "file_extension": "ijs",
846 | "mimetype": "text/x-J",
847 | "name": "J"
848 | }
849 | },
850 | "nbformat": 4,
851 | "nbformat_minor": 2
852 | }
853 |
--------------------------------------------------------------------------------
/Jupyter_Notebook_J_Labs/math/Catalan_Numbers.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "deletable": true,
7 | "editable": true
8 | },
9 | "source": [
10 | "# J Labs\n",
11 | "\n",
12 | "### Catalan Numbers"
13 | ]
14 | },
15 | {
16 | "cell_type": "markdown",
17 | "metadata": {
18 | "deletable": true,
19 | "editable": true
20 | },
21 | "source": [
22 | "### (1 of 24) Introduction\n",
23 | "Catalan numbers appear in several areas of mathematics. For example, the nth Catalan number is the number of planar binary trees with n nodes, and is the number of ways of cutting up a polygon with n+2 sides into triangles by drawing non-intersecting diagonals.\n",
24 | "\n",
25 | "Catalan numbers 0-8 are: 1 1 2 5 14 42 132 429 1430\n",
26 | "\n",
27 | "The question we will look at here is how to calculate the nth Catalan number, for n taking values of 5, 10, 1000, 10000 and up."
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {
33 | "deletable": true,
34 | "editable": true
35 | },
36 | "source": [
37 | "### (2 of 24) Basic Formula\n",
38 | "The formula in conventional math notation is:\n",
39 | "\n",
40 | "$$\n",
41 | "\\frac{2n!}{n!(n+1)!} \\\\\n",
42 | "$$\n",
43 | "\n",
44 | "A direct translation of the formula into J is given below, evaluated for n=5. Note that the factorial function is written !n"
45 | ]
46 | },
47 | {
48 | "cell_type": "code",
49 | "execution_count": null,
50 | "metadata": {
51 | "collapsed": false,
52 | "deletable": true,
53 | "editable": true
54 | },
55 | "outputs": [],
56 | "source": [
57 | "n=: 5"
58 | ]
59 | },
60 | {
61 | "cell_type": "code",
62 | "execution_count": null,
63 | "metadata": {
64 | "collapsed": false,
65 | "deletable": true,
66 | "editable": true
67 | },
68 | "outputs": [],
69 | "source": [
70 | "(!2*n) % (!n) * (!n+1)"
71 | ]
72 | },
73 | {
74 | "cell_type": "markdown",
75 | "metadata": {
76 | "deletable": true,
77 | "editable": true
78 | },
79 | "source": [
80 | "### (3 of 24) Basic Formula (ctd)\n",
81 | "For a more efficient solution, rewrite the formula as:\n",
82 | "\n",
83 | "$$\n",
84 | "\\frac{2n!}{n!n!} \\frac{1}{(n+1)}\\\\\n",
85 | "$$\n",
86 | "\n",
87 | "and note that the first expression is the number of ways of choosing n things from 2n, which in J is the binomial coefficent: n!2*n"
88 | ]
89 | },
90 | {
91 | "cell_type": "markdown",
92 | "metadata": {
93 | "deletable": true,
94 | "editable": true
95 | },
96 | "source": [
97 | "### (4 of 24) Basic Formula (ctd)\n",
98 | "A direct translation of this formula into J is:"
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": null,
104 | "metadata": {
105 | "collapsed": false,
106 | "deletable": true,
107 | "editable": true
108 | },
109 | "outputs": [],
110 | "source": [
111 | "(n ! 2*n) % n+1"
112 | ]
113 | },
114 | {
115 | "cell_type": "markdown",
116 | "metadata": {
117 | "deletable": true,
118 | "editable": true
119 | },
120 | "source": [
121 | "### (5 of 24) Basic Formula (ctd)\n",
122 | "This can be simplified using +: (double) and >: (increment) as follows:"
123 | ]
124 | },
125 | {
126 | "cell_type": "code",
127 | "execution_count": null,
128 | "metadata": {
129 | "collapsed": false,
130 | "deletable": true,
131 | "editable": true
132 | },
133 | "outputs": [],
134 | "source": [
135 | "(n ! +: n) % >: n"
136 | ]
137 | },
138 | {
139 | "cell_type": "markdown",
140 | "metadata": {
141 | "deletable": true,
142 | "editable": true
143 | },
144 | "source": [
145 | "### (6 of 24) Basic Formula (ctd)\n",
146 | "Try this with other values for n:"
147 | ]
148 | },
149 | {
150 | "cell_type": "code",
151 | "execution_count": null,
152 | "metadata": {
153 | "collapsed": false,
154 | "deletable": true,
155 | "editable": true
156 | },
157 | "outputs": [],
158 | "source": [
159 | "n=: i.8"
160 | ]
161 | },
162 | {
163 | "cell_type": "code",
164 | "execution_count": null,
165 | "metadata": {
166 | "collapsed": false,
167 | "deletable": true,
168 | "editable": true
169 | },
170 | "outputs": [],
171 | "source": [
172 | "(n ! +: n) % >: n"
173 | ]
174 | },
175 | {
176 | "cell_type": "markdown",
177 | "metadata": {
178 | "deletable": true,
179 | "editable": true
180 | },
181 | "source": [
182 | "### (7 of 24) First Solution\n",
183 | "We can now define our first Catalan verb, by removing references to the argument n in the expression:\n",
184 | "\n",
185 | " ```(n ! +: n) % >: n```
\n",
186 | "\n",
187 | "and assigning the result to cat1."
188 | ]
189 | },
190 | {
191 | "cell_type": "code",
192 | "execution_count": null,
193 | "metadata": {
194 | "collapsed": false,
195 | "deletable": true,
196 | "editable": true
197 | },
198 | "outputs": [],
199 | "source": [
200 | "cat1=: (! +:) % >:"
201 | ]
202 | },
203 | {
204 | "cell_type": "code",
205 | "execution_count": null,
206 | "metadata": {
207 | "collapsed": false,
208 | "deletable": true,
209 | "editable": true
210 | },
211 | "outputs": [],
212 | "source": [
213 | "cat1 i.8"
214 | ]
215 | },
216 | {
217 | "cell_type": "markdown",
218 | "metadata": {
219 | "deletable": true,
220 | "editable": true
221 | },
222 | "source": [
223 | "### (8 of 24) First Solution (ctd)\n",
224 | "To display a table of numbers, join n with cat1 n, as below:"
225 | ]
226 | },
227 | {
228 | "cell_type": "code",
229 | "execution_count": null,
230 | "metadata": {
231 | "collapsed": false,
232 | "deletable": true,
233 | "editable": true
234 | },
235 | "outputs": [],
236 | "source": [
237 | "n=: i.8"
238 | ]
239 | },
240 | {
241 | "cell_type": "code",
242 | "execution_count": null,
243 | "metadata": {
244 | "collapsed": false,
245 | "deletable": true,
246 | "editable": true
247 | },
248 | "outputs": [],
249 | "source": [
250 | "n ,. cat1 n"
251 | ]
252 | },
253 | {
254 | "cell_type": "code",
255 | "execution_count": null,
256 | "metadata": {
257 | "collapsed": false,
258 | "deletable": true,
259 | "editable": true
260 | },
261 | "outputs": [],
262 | "source": [
263 | "(,. cat1) i.8"
264 | ]
265 | },
266 | {
267 | "cell_type": "markdown",
268 | "metadata": {
269 | "deletable": true,
270 | "editable": true
271 | },
272 | "source": [
273 | "### (9 of 24) First Solution (ctd)\n",
274 | "Lets now try this with n=100. This results in a big number that exceeds the standard integer representation.\n",
275 | "\n",
276 | "To calculate it accurately, use x: to convert the argument to an extended integer."
277 | ]
278 | },
279 | {
280 | "cell_type": "code",
281 | "execution_count": null,
282 | "metadata": {
283 | "collapsed": false,
284 | "deletable": true,
285 | "editable": true
286 | },
287 | "outputs": [],
288 | "source": [
289 | "cat1 100"
290 | ]
291 | },
292 | {
293 | "cell_type": "code",
294 | "execution_count": null,
295 | "metadata": {
296 | "collapsed": false,
297 | "deletable": true,
298 | "editable": true
299 | },
300 | "outputs": [],
301 | "source": [
302 | "cat1 x: 100"
303 | ]
304 | },
305 | {
306 | "cell_type": "markdown",
307 | "metadata": {
308 | "deletable": true,
309 | "editable": true
310 | },
311 | "source": [
312 | "### (10 of 24) Second Solution\n",
313 | "This suggests a new verb cat2, which applies x: followed by cat1."
314 | ]
315 | },
316 | {
317 | "cell_type": "code",
318 | "execution_count": null,
319 | "metadata": {
320 | "collapsed": false,
321 | "deletable": true,
322 | "editable": true
323 | },
324 | "outputs": [],
325 | "source": [
326 | "cat2=: cat1 @ x:"
327 | ]
328 | },
329 | {
330 | "cell_type": "code",
331 | "execution_count": null,
332 | "metadata": {
333 | "collapsed": false,
334 | "deletable": true,
335 | "editable": true
336 | },
337 | "outputs": [],
338 | "source": [
339 | "cat2 100"
340 | ]
341 | },
342 | {
343 | "cell_type": "code",
344 | "execution_count": null,
345 | "metadata": {
346 | "collapsed": false,
347 | "deletable": true,
348 | "editable": true
349 | },
350 | "outputs": [],
351 | "source": [
352 | "(,. cat2) 100+i.10"
353 | ]
354 | },
355 | {
356 | "cell_type": "markdown",
357 | "metadata": {
358 | "deletable": true,
359 | "editable": true
360 | },
361 | "source": [
362 | "### (11 of 24) Second Solution (ctd)\n",
363 | "The 1,000th catalan number has 598 digits:"
364 | ]
365 | },
366 | {
367 | "cell_type": "code",
368 | "execution_count": null,
369 | "metadata": {
370 | "collapsed": false,
371 | "deletable": true,
372 | "editable": true
373 | },
374 | "outputs": [],
375 | "source": [
376 | "cat2 1000"
377 | ]
378 | },
379 | {
380 | "cell_type": "code",
381 | "execution_count": null,
382 | "metadata": {
383 | "collapsed": false,
384 | "deletable": true,
385 | "editable": true
386 | },
387 | "outputs": [],
388 | "source": [
389 | "$\":cat2 1000"
390 | ]
391 | },
392 | {
393 | "cell_type": "markdown",
394 | "metadata": {
395 | "deletable": true,
396 | "editable": true
397 | },
398 | "source": [
399 | "### (12 of 24) Second Solution (ctd)\n",
400 | "This can be formatted using the xfmt (extended format) utility:"
401 | ]
402 | },
403 | {
404 | "cell_type": "code",
405 | "execution_count": null,
406 | "metadata": {
407 | "collapsed": false,
408 | "deletable": true,
409 | "editable": true
410 | },
411 | "outputs": [],
412 | "source": [
413 | "load 'general/misc/format'"
414 | ]
415 | },
416 | {
417 | "cell_type": "code",
418 | "execution_count": null,
419 | "metadata": {
420 | "collapsed": false,
421 | "deletable": true,
422 | "editable": true
423 | },
424 | "outputs": [],
425 | "source": [
426 | "xfmt cat2 1000"
427 | ]
428 | },
429 | {
430 | "cell_type": "markdown",
431 | "metadata": {
432 | "deletable": true,
433 | "editable": true
434 | },
435 | "source": [
436 | "### (13 of 24) Second Solution (ctd)\n",
437 | "Can cat2 be used to generate the 10,000th Catalan number?\n",
438 | "\n",
439 | "Yes - with a fast PC and enough memory. On the authors PC, this calculation takes just under a second and results in a number with 6,015 digits. However, it is near the limit of what can be achieved using this simple formula. If you try this, you might find that your PC runs out of memory, and starts paging memory to hard disk. This slows the calculation down enormously, and should be avoided."
440 | ]
441 | },
442 | {
443 | "cell_type": "markdown",
444 | "metadata": {
445 | "deletable": true,
446 | "editable": true
447 | },
448 | "source": [
449 | "### (14 of 24) Third Solution\n",
450 | "It turns out that you can calculate !n by calculating the exponents in !n of each prime up to n, and this leads to a more efficient technique for computing the Catalan numbers where n is very large.\n",
451 | "\n",
452 | "The idea is that for each prime p up to n, you calculate a list, lp, of the prime powers of p up to n, and then the exponent of p in !n is given by:\n",
453 | "\n",
454 | " ```+/ <. n % lp```
\n",
455 | "\n",
456 | "To keep numbers small, We will illustrate this for the calculation of !100."
457 | ]
458 | },
459 | {
460 | "cell_type": "markdown",
461 | "metadata": {
462 | "deletable": true,
463 | "editable": true
464 | },
465 | "source": [
466 | "### (15 of 24) Third Solution (ctd)\n",
467 | "For any prime p, the maximum power of p less than or equal to n is:\n",
468 | "\n",
469 | " ```<. p ^. n```
\n",
470 | "\n",
471 | "For example, the maximum power of 3 less than or equal to 100 is 4, and the corresponding maximum power of 7 is 2:"
472 | ]
473 | },
474 | {
475 | "cell_type": "code",
476 | "execution_count": null,
477 | "metadata": {
478 | "collapsed": false,
479 | "deletable": true,
480 | "editable": true
481 | },
482 | "outputs": [],
483 | "source": [
484 | "<. 3 ^. 100"
485 | ]
486 | },
487 | {
488 | "cell_type": "code",
489 | "execution_count": null,
490 | "metadata": {
491 | "collapsed": false,
492 | "deletable": true,
493 | "editable": true
494 | },
495 | "outputs": [],
496 | "source": [
497 | "3 ^ 1 2 3 4 5"
498 | ]
499 | },
500 | {
501 | "cell_type": "code",
502 | "execution_count": null,
503 | "metadata": {
504 | "collapsed": false,
505 | "deletable": true,
506 | "editable": true
507 | },
508 | "outputs": [],
509 | "source": [
510 | "<. 7 ^. 100"
511 | ]
512 | },
513 | {
514 | "cell_type": "code",
515 | "execution_count": null,
516 | "metadata": {
517 | "collapsed": false,
518 | "deletable": true,
519 | "editable": true
520 | },
521 | "outputs": [],
522 | "source": [
523 | "7 ^ 1 2 3"
524 | ]
525 | },
526 | {
527 | "cell_type": "markdown",
528 | "metadata": {
529 | "deletable": true,
530 | "editable": true
531 | },
532 | "source": [
533 | "### (16 of 24) Third Solution (ctd)\n",
534 | "The exponent of p in !n is then:\n",
535 | "\n",
536 | " ```+/ <. n % p ^ >: i. <. p ^. n```
\n",
537 | "\n",
538 | "For example:"
539 | ]
540 | },
541 | {
542 | "cell_type": "code",
543 | "execution_count": null,
544 | "metadata": {
545 | "collapsed": false,
546 | "deletable": true,
547 | "editable": true
548 | },
549 | "outputs": [],
550 | "source": [
551 | "+/ <. 100 % 3 ^ >: i. <. 3 ^. 100"
552 | ]
553 | },
554 | {
555 | "cell_type": "markdown",
556 | "metadata": {
557 | "deletable": true,
558 | "editable": true
559 | },
560 | "source": [
561 | "### (17 of 24) Third Solution (ctd)\n",
562 | "As confirmation, note that 3^48 evenly divides !100, but 3^49 does not:"
563 | ]
564 | },
565 | {
566 | "cell_type": "code",
567 | "execution_count": null,
568 | "metadata": {
569 | "collapsed": false,
570 | "deletable": true,
571 | "editable": true
572 | },
573 | "outputs": [],
574 | "source": [
575 | "a=: !100x"
576 | ]
577 | },
578 | {
579 | "cell_type": "code",
580 | "execution_count": null,
581 | "metadata": {
582 | "collapsed": false,
583 | "deletable": true,
584 | "editable": true
585 | },
586 | "outputs": [],
587 | "source": [
588 | "b=: 3^48x"
589 | ]
590 | },
591 | {
592 | "cell_type": "code",
593 | "execution_count": null,
594 | "metadata": {
595 | "collapsed": false,
596 | "deletable": true,
597 | "editable": true
598 | },
599 | "outputs": [],
600 | "source": [
601 | "a -: b * a <.@% b"
602 | ]
603 | },
604 | {
605 | "cell_type": "code",
606 | "execution_count": null,
607 | "metadata": {
608 | "collapsed": false,
609 | "deletable": true,
610 | "editable": true
611 | },
612 | "outputs": [],
613 | "source": [
614 | "b=: 3^49x"
615 | ]
616 | },
617 | {
618 | "cell_type": "code",
619 | "execution_count": null,
620 | "metadata": {
621 | "collapsed": false,
622 | "deletable": true,
623 | "editable": true
624 | },
625 | "outputs": [],
626 | "source": [
627 | "a -: b * a <.@% b"
628 | ]
629 | },
630 | {
631 | "cell_type": "markdown",
632 | "metadata": {
633 | "deletable": true,
634 | "editable": true
635 | },
636 | "source": [
637 | "### (18 of 24) Third Solution (ctd)\n",
638 | "The formula for each prime used (as above) is:\n",
639 | "\n",
640 | " ```+/ <. n % p ^ >: i. <. p ^. n```
\n",
641 | "\n",
642 | "Since n may be an extended integer, we rewrite this to avoid floating point results as:\n",
643 | "\n",
644 | " ```+/ n <.@% p ^ >: i. p <.@^. n```
\n",
645 | "\n",
646 | "and define a corresponding verb pexp:"
647 | ]
648 | },
649 | {
650 | "cell_type": "code",
651 | "execution_count": null,
652 | "metadata": {
653 | "collapsed": false,
654 | "deletable": true,
655 | "editable": true
656 | },
657 | "outputs": [],
658 | "source": [
659 | "pexp=: [: +/ ] <.@% [ ^ >: @ i. @ (<.@^.)"
660 | ]
661 | },
662 | {
663 | "cell_type": "code",
664 | "execution_count": null,
665 | "metadata": {
666 | "collapsed": false,
667 | "deletable": true,
668 | "editable": true
669 | },
670 | "outputs": [],
671 | "source": [
672 | "3 pexp 100"
673 | ]
674 | },
675 | {
676 | "cell_type": "code",
677 | "execution_count": null,
678 | "metadata": {
679 | "collapsed": false,
680 | "deletable": true,
681 | "editable": true
682 | },
683 | "outputs": [],
684 | "source": [
685 | "7 pexp 100"
686 | ]
687 | },
688 | {
689 | "cell_type": "markdown",
690 | "metadata": {
691 | "deletable": true,
692 | "editable": true
693 | },
694 | "source": [
695 | "### (19 of 24) Third Solution (ctd)\n",
696 | "The list of primes less than or equal to n can be found using the inverse of p: the prime-producing verb.\n",
697 | "\n",
698 | "Define a verb, ple, to produce this list."
699 | ]
700 | },
701 | {
702 | "cell_type": "code",
703 | "execution_count": null,
704 | "metadata": {
705 | "collapsed": false,
706 | "deletable": true,
707 | "editable": true
708 | },
709 | "outputs": [],
710 | "source": [
711 | "p: 7 NB. 7th prime"
712 | ]
713 | },
714 | {
715 | "cell_type": "code",
716 | "execution_count": null,
717 | "metadata": {
718 | "collapsed": false,
719 | "deletable": true,
720 | "editable": true
721 | },
722 | "outputs": [],
723 | "source": [
724 | "p: inverse 19 NB. which prime is 19?"
725 | ]
726 | },
727 | {
728 | "cell_type": "code",
729 | "execution_count": null,
730 | "metadata": {
731 | "collapsed": false,
732 | "deletable": true,
733 | "editable": true
734 | },
735 | "outputs": [],
736 | "source": [
737 | "p: i. p: inverse 19 NB. primes 0-6 (=i.7)"
738 | ]
739 | },
740 | {
741 | "cell_type": "code",
742 | "execution_count": null,
743 | "metadata": {
744 | "collapsed": false,
745 | "deletable": true,
746 | "editable": true
747 | },
748 | "outputs": [],
749 | "source": [
750 | "p: i. p: inverse 20 NB. primes 0-7 (=i.8)"
751 | ]
752 | },
753 | {
754 | "cell_type": "code",
755 | "execution_count": null,
756 | "metadata": {
757 | "collapsed": false,
758 | "deletable": true,
759 | "editable": true
760 | },
761 | "outputs": [],
762 | "source": [
763 | "ple=: p: @ i. @ (p: inverse) @ >:"
764 | ]
765 | },
766 | {
767 | "cell_type": "code",
768 | "execution_count": null,
769 | "metadata": {
770 | "collapsed": false,
771 | "deletable": true,
772 | "editable": true
773 | },
774 | "outputs": [],
775 | "source": [
776 | "ple 19"
777 | ]
778 | },
779 | {
780 | "cell_type": "markdown",
781 | "metadata": {
782 | "deletable": true,
783 | "editable": true
784 | },
785 | "source": [
786 | "### (20 of 24) Third Solution (ctd)\n",
787 | "The exponents of each prime p in !n are then given by:\n",
788 | "\n",
789 | " ```(ple n) pexp\"0 n```
\n",
790 | "\n",
791 | "Rank 0 is used to evaluate pexp on each prime in the left argument, rather than the list of primes as a whole."
792 | ]
793 | },
794 | {
795 | "cell_type": "code",
796 | "execution_count": null,
797 | "metadata": {
798 | "collapsed": false,
799 | "deletable": true,
800 | "editable": true
801 | },
802 | "outputs": [],
803 | "source": [
804 | "n=: 100"
805 | ]
806 | },
807 | {
808 | "cell_type": "code",
809 | "execution_count": null,
810 | "metadata": {
811 | "collapsed": false,
812 | "deletable": true,
813 | "editable": true
814 | },
815 | "outputs": [],
816 | "source": [
817 | "ple n"
818 | ]
819 | },
820 | {
821 | "cell_type": "code",
822 | "execution_count": null,
823 | "metadata": {
824 | "collapsed": false,
825 | "deletable": true,
826 | "editable": true
827 | },
828 | "outputs": [],
829 | "source": [
830 | "(ple n) pexp\"0 n"
831 | ]
832 | },
833 | {
834 | "cell_type": "markdown",
835 | "metadata": {
836 | "deletable": true,
837 | "editable": true
838 | },
839 | "source": [
840 | "### (21 of 24) Third Solution (ctd)\n",
841 | "The calculation of:\n",
842 | "\n",
843 | "$$\n",
844 | "\\frac{2n!}{n!(n+1)!} \\\\\n",
845 | "$$\n",
846 | "\n",
847 | "can now be done by calculating the exponents of the numerator less the exponents of the denominator, for each prime up to 2n, then taking the product of the prime powers."
848 | ]
849 | },
850 | {
851 | "cell_type": "markdown",
852 | "metadata": {
853 | "deletable": true,
854 | "editable": true
855 | },
856 | "source": [
857 | "### (22 of 24) Third Solution (ctd)\n",
858 | "Therefore we define cat3 as below, and check it matches cat2:"
859 | ]
860 | },
861 | {
862 | "cell_type": "code",
863 | "execution_count": null,
864 | "metadata": {
865 | "collapsed": false,
866 | "deletable": true,
867 | "editable": true
868 | },
869 | "outputs": [],
870 | "source": [
871 | "cat3=: 3 : 0\n",
872 | "p=. ple +: y\n",
873 | "e1=. p pexp\"0 +: y\n",
874 | "e2=. p pexp\"0 y\n",
875 | "e3=. p pexp\"0 >: y\n",
876 | "*/ p ^ x: e1-e2+e3\n",
877 | ")"
878 | ]
879 | },
880 | {
881 | "cell_type": "code",
882 | "execution_count": null,
883 | "metadata": {
884 | "collapsed": false,
885 | "deletable": true,
886 | "editable": true
887 | },
888 | "outputs": [],
889 | "source": [
890 | "(cat2 1000) -: cat3 1000"
891 | ]
892 | },
893 | {
894 | "cell_type": "markdown",
895 | "metadata": {
896 | "deletable": true,
897 | "editable": true
898 | },
899 | "source": [
900 | "### (23 of 24) Third Solution (ctd)\n",
901 | "cat3 can be used to calculate the 10,000th Catalan number.\n",
902 | "\n",
903 | "You can try larger numbers, but be warned this may take a long time, or run out of memory. On the PC of the author, cat3 100,000 takes just under 1 second and returns a result with 60,199 digits.\n",
904 | "\n",
905 | "The next section calculates cat3 10000."
906 | ]
907 | },
908 | {
909 | "cell_type": "markdown",
910 | "metadata": {
911 | "deletable": true,
912 | "editable": true
913 | },
914 | "source": [
915 | "### (24 of 24) Third Solution (ctd)\n",
916 | "To see the answer in full, enter:\n",
917 | "\n",
918 | " ```xfmt a```
"
919 | ]
920 | },
921 | {
922 | "cell_type": "code",
923 | "execution_count": null,
924 | "metadata": {
925 | "collapsed": false,
926 | "deletable": true,
927 | "editable": true
928 | },
929 | "outputs": [],
930 | "source": [
931 | "a=: cat3 10000"
932 | ]
933 | },
934 | {
935 | "cell_type": "code",
936 | "execution_count": null,
937 | "metadata": {
938 | "collapsed": false,
939 | "deletable": true,
940 | "editable": true
941 | },
942 | "outputs": [],
943 | "source": [
944 | "$\":a"
945 | ]
946 | },
947 | {
948 | "cell_type": "markdown",
949 | "metadata": {
950 | "deletable": true,
951 | "editable": true
952 | },
953 | "source": [
954 | "### End of Lab"
955 | ]
956 | },
957 | {
958 | "cell_type": "code",
959 | "execution_count": null,
960 | "metadata": {
961 | "collapsed": false,
962 | "deletable": true,
963 | "editable": true
964 | },
965 | "outputs": [],
966 | "source": []
967 | }
968 | ],
969 | "metadata": {
970 | "kernelspec": {
971 | "display_name": "J",
972 | "language": "J",
973 | "name": "jkernel"
974 | },
975 | "language_info": {
976 | "file_extension": "ijs",
977 | "mimetype": "text/x-J",
978 | "name": "J"
979 | }
980 | },
981 | "nbformat": 4,
982 | "nbformat_minor": 2
983 | }
984 |
--------------------------------------------------------------------------------