jsoftware / jsource

J engine source mirror
Other
645 stars 91 forks source link

why (9 o. _.j0) sentence throws domain error? #189

Open jip opened 3 months ago

jip commented 3 months ago
   JVERSION
Engine: j9.6.0-beta4/j64avx2/linux
Build: commercial/2024-03-19T00:51:21/clang-11-0-0/SLEEF=1
Library: 9.6.5
Qt IDE: 2.5.3/5.12.8(5.15.8)
OS Ver: openSUSE Leap 15.5 5.14.21-150500.55.52-default
Platform: Linux 64
Installer: j9.6 install
InstallPath: /home/user/j9.6.0-beta4_j64avx2
Contact: www.jsoftware.com

   9 o. _.  NB. [1]
_.
   +. _.j0  NB. [2]
_. 0

   NB. question # 1
   9 o. _.j0  NB. [3]
|domain error, executing dyad o.
|   9     o._.
   11 o. 0j_.  NB. [4]
|domain error, executing dyad o.
|   11     o.0j_.

   NB. question # 2
   9 o. 0j_.  NB. [5]
0
   11 o. _.j0  NB. [6]
0

Questions:

  1. Why "domain error" in [3,4]? If a primitive judges it results to NaN from input not containing NaN then "NaN error" should be thrown. But this is not the case, it's just extracting NaN from compound already containing NaN.
  2. If computations must propagate NaN, then shouldn't [5,6] result to NaN?
LdBeth commented 6 days ago

The following explanation is based on read the source code and take a bold guess of what it does.

There are a few interesting rules, for o., if left argument is integer and right argument is double float, the cirID function is called, if any of the arguments are complex number, both argument are converted to complex and the cirZZ function is called instead.

cirZZ, defined using a C macro https://github.com/jsoftware/jsource/blob/f14e8c59ca9062c8a8fc8cb74302496da2b919ae/jsrc/va.h#L288

, calls the zcir function which dispatches the argument to various complex trigonometry functions.

https://github.com/jsoftware/jsource/blob/f14e8c59ca9062c8a8fc8cb74302496da2b919ae/jsrc/vm.c#L48

while cirID is another function https://github.com/jsoftware/jsource/blob/f14e8c59ca9062c8a8fc8cb74302496da2b919ae/jsrc/vm.c#L486

does not seem invoke check on result value

So if wrote 9j0 o. _. the same domain error would be raised.

I did not find exactly where domain error was raised, but a possible explanation is by default zcir returns a complex number, but J would try to retract the complex number result to double float if possible, which only happens if left arguments are 9, 10, 11, and when the result is NaN the retraction to double float array would fail and that raises domain error.

To prove that, this example prevents the result been retracted to float and although the complex version of circle function is used, no domain error is detected.

   9j0 7j0 o. _. _. NB. need j903
_. _.j_.
   9j0 _9j0 o. _. _.j_.
_. _.j_.

It is reasonable to have such kind of check given most o. functions now no longer allows _. and the use of NaN is discourage, but I think theirs is also a good reason to remove such a kind of unnecessary restriction if the same logic is not used elsewhere.