NYCJUG/2021-02-09

From J Wiki
Jump to navigation Jump to search

Meeting Agenda for NYCJUG 20210209

Show-and-tell

We have a few topics this month.

Rationalizing Newton

In updating the essay on Newton's Method to use the new calculus add-on instead of the old built-in derivative adverb, we encountered an issue with extending the method to rational numbers.

A New Version of Jig


Jig is an application that extends the standard textual output of J using SVG (Scalable Vector Graphics) to provide far more information for users.

  • As an example, in a Jig display, nouns with a shape of 1 2 can be easily distinguished from nouns with shape 2 as noun shapes with leading 1's are lightly shaded.
Jig visual for 1 2 $ 7 versus 2 $ 7














  • Jig also solves the issue of ragged edged boxes when dealing with unicode, since the size of the box is calculated according to its displayed contents rather than the number of monotype characters.
Boxed Unicode: J textual display versus Jig display













  • Many nouns that cannot be distinguished in the textual format are easily discerned with Jig. Examples are '1'(literal) and 1 (boolean)
or 2 (integer) and 2.1 - 0.1 (floating)
Jig display of Literal versus Boolean types
Jig display of Integer versus Floating types

























  • Interaction provides the user with additional information. By hovering over the display it is possible to quickly retrieve the utf-8, unicode and unicode4 encodings of text.
Encodings for Literal, Unicode and Unicode4 using tooltips













  • For some of the more esoteric types such as sparse arrays and symbols there is more useful information available through interaction.
Sparse and Symbol Representations with Jig using tooltips













  • Jig's most recent feature is the display of the depth and the path in the boxed components of boxed structures.
Depth and Path information shown for Boxed Structures using tooltips













If you would like to use the F6 function key to enable a Jig view in Jqt environment then:

  • Choose Edit | Configure | User Keys from the Jqt menu and add this line to the user keys.cfg file when it appears
  F6|0|Jig Augmented Display|((1 ; coname '') visual_jig_ 0)  
  • Close the Jqt session and restart
  • Now the Jig window should appear for any line that your cursor is on when you press F6


In this presentation we will explore this new version of Jig and also consider the possibilities of Jig in the JHS environment.

Drawing a Hexagonal Grid

If we want to draw a grid of regular hexagons, there are a few things we have to figure out. One initial issue is choosing the right aspect ratio to draw a symmetric-looking hexagon. TL;DR: use an aspect ratio of 0.9 for a hexagon with the appearance of equal-length sides.

Finding the Unit Hexagon

We want to be able to tile a plane with unit hexagons because a unit hexagon would seem to be a natural size for this sort of thing.

So, what is the unit hexagon? It's the hexagon with an area of one. To figure out the dimensions of its outline, we have to figure out how do we calculate the area of a hexagon? Let's take the easy way out and just look it up.

This diagram is from here.

Calculate regular hexagon area from side length.png

In J,

   hexagonArea=: 3 : '3*y*(-:y)*%:3'  NB. Where y is side length

This re-arranges the formula above to isolate the square root of three since it will complicate extending these calculations to extended precision.

This is perhaps a slightly better representation by collapsing the (s^2)/2:

   hexagonArea=: 3 : '3*(-:*:y)*%:3'  NB. Where y is side length

Let's try this out and use it to figure out the length of the side of the unit hexagon by trial and error:

   hexagonArea 20
1039.23
   hexagonArea 1
2.59808
   hexagonArea 0.5
0.649519
   hexagonArea 0.75
1.46142
   hexagonArea 0.625
1.01487
   hexagonArea 0.62
0.9987
   hexagonArea 0.622
1.00515

Continuing in this vein, we get to

   hexagonArea 0.620402
0.999996
   hexagonArea 0.620403
0.999999
   hexagonArea 0.620404
1
   NB. So a unit-area regular hexagon has a side of length 0.620404
   hexagonArea x: 0.620404
1
   hexagonArea 620404r1000000
1
   18j16": hexagonArea 620404r1000000
1.0000024519506610
   18j16": hexagonArea 620402r1000000
0.9999960045335581

This is good to almost six digits. This is good enough for our initial effort but what are the circumstances for which we would require greater precision?

Extending Precision

There are circumstances which might require higher precision than this, so what's a reasonable extreme to test? Here we see what we have to change to calculate this to higher precision.

Looking at hexagonArea makes it plain where the limits of our precision lie:

   hexagonArea=: 3 : '3*(-:*:y)*%:3'  NB. Where y is side length
   hexagonArea=: 3 * 1.73205080756887719 * [: -: *:  NB. Tacit version 

The big ugly number that sticks out is the square root of three. If we replace that with a tacit version of higher accuracy, we extend the possible precision of the function.

Square Root of Three

One way to calculate this is by solving (x-3)^2 for a zero. A quickly converging way to do this is by using Newton's Method.

   sqrt3=. (_3 + 2 ^~ ]) Nr ^:6 ] 1x
   sqrt3
4307767635496326392644439779565460175481280566394250993989768870429310390730431673249143075907027289283295682102651182528607225375518343448596002326121583409225890121276833167493893135307896639147767692469125252351719254820328695634815840725252005668915972...
   0j_50":*:sqrt3                     NB. Check precision
3.00000000000000000000000724137956735811679499831053e0
   <:0 i.~'0'=2}.0j_50":*:sqrt3       NB. Number of digits past decimal
22
   sqrt3=. (_3 + 2 ^~ ]) Nr ^:7 ] 1x  NB. For greater precision
   <:0 i.~'0'=2}.0j_50":*:sqrt3       NB. Check number of digits past decimal
29

Re-arrange the definition of hexagonArea to be dyadic so we can easily bind our 3*square root as the left argument

   hexagonArea=: sqrt3&(3x * ] * [ * [: -: [: x: ])
   hexagonArea
3711372507424014871702504441607867812327025099945860439802791916796091134008195852995609157155870269764444532476420480023731617418930992933342261381411927363123031302591699557553724306309679225456953956331623787463057768695479822424014599977918925156943758...

This number is so long it obscures the display of the function definition. Is there a shorter number that still has about 25 digits past the decimal point?

It turns out that using continued fractions gives us much more compact representation.

   6!:2 'sqrt3cf=. >:(%`+)/100$2x   NB. sqrt 3 by continued fraction'
0.0035191
   0j25":3-*:sqrt3cf
0.0000000000000000000000000
   0j50":3-*:sqrt3cf
0.00000000000000000000000000008125616509663820263995
   #":sqrt3cf
31
   ":sqrt3cf
271736178976085r156886956080403

So, substituting one ugly number for another, more precise one, we get

   6!:2 'sqrt3cf=. >:(%`+)/100$2x   NB. sqrt 3 by continued fraction'
0.0001856
   hexagonArea=: (3*sqrt3cf)&(] * [ * [: -: [: x: ])
   hexagonArea
271736178976085r52295652026801&(] * [ * [: -: [: x: ])

Length of Side of Unit Hexagon to Greater Precision

Using this more precise version of the area function, let's determine the length of the side of the regular unit hexagon to greater precision.

We can use Newton's method as we did above for the square root of three:

   hexSide=. (1-hexagonArea) Nr ^:6 ] 1x
   #":hexSide
1789
   0j25": 1-hexagonArea hexSide
_0.0000000000000000000000022
   hexSide=. (1-hexagonArea) Nr ^:7 ] 1x   NB. Add some precision
   0j35": 1-hexagonArea hexSide
_0.00000000000000000000000000000017396
   #":hexSide
3591

This is quite a lengthy number. We can come up with a shorter version by successive approximations.

   0j27": 1-hexagonArea 6204032394013997326274791645r10000000000000000000000000000
0.000000000000000000000000000
   0j27": 1-hexagonArea 6204032394013997326274791648r10000000000000000000000000000
_0.000000000000000000000000001
   0j27": 1-hexagonArea 6204032394013997326274791647r10000000000000000000000000000
0.000000000000000000000000000
   sideOfUnitHexagon=: 6204032394013997326274791647r10000000000000000000000000000
   #":sideOfUnitHexagon
58

Corners of Unit Hexagon Centered at Origin

If we draw a triangle from the center of a regular hexagon to two adjacent corners, we can see that this is an equilateral triangle because each of its angles is 60° since you could fit six of these into the hexagon without overlap.

Regular Unit Hexagon Centered at Origin-calculate radius.png

The corners are equally-spaced around the origin, so there are 60 degrees (=360%6) or 2p1%6 radians between each adjacent one. We can express the position of each corner most simply in polar coordinates by starting with corner zero (rightmost one) and proceeding counter-clockwise like this:

   sideOfUnitHexagon,0    NB. Polar co-ordinate of corner 0 from center as (r, θ)
6204032394013997326274791647r10000000000000000000000000000 0

Since the display of rationals is unwieldy, we will ignore the extended precision from here on.

So, with the help of a polar to Cartesian converter, we can find the co-ordinates of the corners of a regular unit hexagon centered on the origin:

   c2p=: ({. , 2p1&|@{:)@:(*.@(j./))      NB. Cartesian to polar (2D)
   p2c=: +.@(r./)                         NB. Polar to Cartesian (2D)
   ]hexCorners=. p2c"1 ] sideOfUnitHexagon,.(2p1%6)*i.6   NB. Cartesian co-ordinates of corners
 0.620403           0
 0.310202    0.537285
_0.310202    0.537285
_0.620403 7.59775e_17                     NB. This small number is really zero
_0.310202   _0.537285
 0.310202   _0.537285

The basis of the illustration above started with the output of this plot; note that we have to adjust the aspect ratio of the plot lest it be distorted.

'title Regular Unit Hexagon Centered at Origin;type line;pensize 2; aspect 0.86' plot (],{.) j./"1 hexCorners

Adding Layers

At this point, since we convert our point matrix to a table of complex numbers in order to plot it, we will simply work with the complex numbers directly to reduce the dimensionality of what follows to a simple matrix of complex numbers.

Looking at the above diagram, how should we add more hexagons? An obvious way is to start with side zero - the rightmost, upper edge - and put a hexagon there. How do we calculate its points?

One way is to figure out the offset from the original hexagon. How we do this will be more clear if we number both hexagons starting with the rightmost vertex and proceeding counter-clockwise.

Add hexagon 0 to origin.png

The origin hexagon has single digit numbers; hexagon zero has two-digit numbers with an initial zero for each.

Jumping Ahead

There are a number of steps to explain here but, for now, let's just take a look at our grid after we have added many layers.

Hexagon multi-color layers 24.png

Promoting J

We will take a look at this AI-based model-building system that is written in J.

Miscellaneous

Working Memory in Programming

Here is an interesting paper on "The Role of Working Memory in Program Tracing". This relates to a possible advantage of array-based methods that shift the cognitive load from tracing through code, especially with conditional sections, versus putting more of the burden on arrays which reduces the amount of code that has to be considered. For an example of how array methods reduce our cognitive load, take a look at this section of an essay.

From the abstract of this paper:

In this work, we examine the influence of short-term working memory (WM) on a person's ability to remember program state during tracing. We first confirm that previous findings in cognitive psychology transfer to the programming domain: people can keep about 7 variable/value pairs in WM, and people will accidentally swap associations between variables due to WM load. ... We use a restricted focus viewing interface to further analyze the strategies people use to trace through programs, and the relationship of tracing strategy to WM. Given a straight-line program, we find half of our participants traced a program from the top-down line-by-line (linearly), and the other half start at the bottom and trace upward based on data dependencies (on-demand). Participants with an on-demand strategy made more WM errors while tracing straight-line code than with a linear strategy, but the two strategies contained an equal number of WM errors when tracing code with functions.

Brain-monitoring Tattoos

Just in case you forgot that we are living in the future, here is an article about using a graphene tattoo to continuously monitor brainwaves.

Applying graphene tatoo to head to monitor brainwaves.png

Baruch “Boris” Goldstein, the co-founder and executive chairman of a company called Brain Scientific, Inc., is an aspiring tattooist. ... Goldstein’s tattoos come with a few conditions: They’re on your head, they’re done using an ink made of all-around wonder material graphene, and they’re capable of reading your brainwaves. ... To be clear, Brain Scientific’s new Brain E-Tattoo doesn’t resemble any piece of ink you’ve seen before. It’s a small patch, about the size of a postage stamp that looks, for all intents and purposes, like a microchip wafer affixed above the ear of the wearer. While the company uses the word “tattoo” to describe it, it’s more accurately referred to as a minimally invasive, implantable, 4-channel, micro electroencephalography (EEG) with graphene electrodes for continuous brain monitoring. ... Once printed, this tattoo is intended to monitor brain wave activity [constantly]...connected to [a]... micro EEG that processes signals from its sensors, and wirelessly transmits this data to the cloud.

File:

Hex7CenterFirst.png