jmath

Exploring mathematics with J.


Project maintained by mlliarm Hosted on GitHub Pages — Theme by mattgraham

01. Exploring infinity

Introduction

J supports infinities, as entities.

For example, if we divide one with zero we get positive infinity:

   1%0
_

And if we divide minus one with zero we get negative infinity:

   _1%0
__

So, positive infinity has the symbol underscore and the negative infinity the symbol double underscore.

Indeterminate form

There is also a symbol for the indeterminate form, the underscore dot character. If we recall from high school, the indetermimnate form is a result of operations such as: infinity - infinity, infinity/infinity, 0^0, 0/0, infinity^infinity (taken from Wolfram Mathworld). Let’s try those out in J:

   0%0             NB. 0/0
0                  NB. Result: 0, should have been _.

   0*_             NB. 0*Infinity
0                  NB. Result: 0, should have been _.

   _%_             NB. Infinity/Infinity
|NaN error         NB. Result: NaN error, should have been _.
|   _    %_

   _-_             NB. Infinity - Infinity
|NaN error         NB. Result: NaN error, should have been _.
|   _    -_

   0^0             NB. 0^0
1                  NB. Result: 1, should have been _.

   _^0             NB. Infinity^0.
1                  NB. Result: 1, should have been _.

   1^_             NB. 1^Infinity
1                  NB. Result: 1, should have been _.

So we see that currently there are some issues with j903 regarding infinities, or more specifically, the indeterminate form doesn’t arise in places where it did in mathematics. It seems that this was designed like that on purpose (see this lemma from the jdictionary), so it’s working as expected.

Infinities

That being said, we can still play around with infinities successfully, with results that match our mathematical expectations:

   1-_              NB. 1 - Infinity
__                  NB. Result: -Infinity, correct.

   1+_              NB. 1 + Infinity
_                   NB. Result: Infinity, correct.

   1%0              NB. 1/0
_                   NB. Result: Infinity, correct.

   _1%0             NB. -1/0
__                  NB. Result: -Infinity, correct.


   1%_              NB. 1/Infinity
0                   NB. Result: 0, correct.

   _+_              NB. Infinity + Infinity
_                   NB. Result: Infinity, correct.

   _-__             NB. Infinity - (-Infinity)
_                   NB. Infinity, correct.

   _*_              NB. Infinity*Infinity
_                   NB. Infinity, correct (I guess).

More on indeterminate forms

Reading further the article shared earlier on indeterminate forms, we understand that the correct J code should use the underdot character only as a flag for badly formed data in our dataset. An example taken from that page due to Ian Clark follows:

NB. Creating a string of an array that contains bad data inside.
   z=: '.2 0.2 2.45 3E56 3F56 _1 _0 77'
z=: '.2 0.2 2.45 3E56 3F56 _1 _0 77'

NB. (".) accepts non-J-numerals like '.2' and '3E56' but not '3F56'.
   ".z
|ill-formed number
|   .2 0.2 2.45 3E56 3F56 _1 _0 77
|    ^
|       ".z

NB. Replacing ill formed numbers with indeterminate form _.
   _. ".z
0.2 0.2 2.45 3e56 _. _1 0 77

NB. replace bad-numerals by ZERO
   0 ".z
0.2 0.2 2.45 3e56 0 _1 0 77

NB. replace bad-numerals by INFINITY
   _ ".z
0.2 0.2 2.45 3e56 _ _1 0 77

Ideas from the community

A user (u/Godspiral) that commented under my post in the r/apljk community at Reddit, gave an example where _. can arise:

   (% :: (_."_))/ 2  0 _
_

   (% :: (_."_))/ 2  0 _ _
_.

If we dissect a bit more the above, it pretty much is an expression created by the verb (% :: (_."_)), / (reduce) and acts on two lists: 2 0 _ and 2 0 _ _. Let’s take it step by step.

   % 2 0 _        NB. Calculate 1%2 1%0 1%_
0.5 _ 0

   % 2 0 _ _      NB. Calculate 1%2 1%0 1%_ 1%_
0.5 _ 0 0

If we use the reduce verb together just before the division verb:

   % / 2 0 _      NB. Is the same as 2%0%_ which is 2%(0%_) so it gives in math notation 2/(0/Inf.) = 2/0 = Inf.
_

   % / 2 0 _ _    NB. Is the same as 2%0%_%_ which is 2%(0%(_%_)) so it gives a NaN error, because that's what _%_ gives 
|NaN error
|       %/2 0 _ _

Now, when we have expressions that return errors related to bad calculations as the above, we can do two things:

The old style

Replace the badly formatted result with some other number, like done in the previous example, with the indeterminate form _., with zero 0, or with infinity _. Let’s do that.

   (% _. "_)/ 2 0 _ _   NB. Apply division `%` to the nouns on the left, and if you encounter NaN replace with `_.`
_.

Let’s see what happens if we try to replace the result of _%_ that gives us headaches with _ instead:

   (% _ "_)/ 2 0 _ _   NB. Apply division `%` to the nouns on the left, and if you encounter NaN replace with `_`
|NaN error
|       (%_"_)/2 0 _ _

Still producing NaN error for some reason.

Now, if we replace the result of _%_ with zero 0 we get:


   (% 0 "_)/ 2 0 _ _   NB. Apply division `%` to the nouns on the left, and if you encounter NaN replace with `0`
_

which makes sense, because this is what happens: 2%0%_%_ --> 2%0%0 --> 2%(0%0) --> 2%0 --> _.

The new style

The new style uses the coco verb ::. Let’s see a simple example first:

   ". '1 2 3 4 mlliarm'   NB. If what's on the rhs of `".` is a number return the number. If not, throw an error.
|syntax error
|       1 2 3 4 mlliarm

Now if we use the coco verb, we can make the result instead of throwing a syntax error in our face, to return a more gentle message:

   (". :: 'error, please remove non-numbers from your data') '1 2 3 4 mlliarm'
error, please remove non-numbers from your data

We now understand that the suggestion u/Godspiral gave, combined both the old and the new way. In their solution they used the new way to catch the NaN error, and then replace the final result of the expression with the indeterminate form _..

Thanks

Readings

The interested reader can further their knowledge on infinities and indeterminate forms reading the following articles:

  1. Roger Hui: an essay on the indeterminate forms, 2008.
  2. E.E. McDonnell, Jeffrey O. Shallit, APL 80 Conference Proceedings, 1980 6 24.
  3. R. W.W. Taylor, Indexing infinite arrays: Non-finite mathematics in APL, 1982.
  4. Harvey Davies, Infinity arithmetic, comparisons and J, 1995.
  5. Eugene McDonnell, Zero divided by zero, APL ‘76 22 September 1976.