I was investigating the code on this page
http://www.jsoftware.com/jwiki/EwartShaw/N01CdfInv

It calculates the inverse of the standard normal CDF for a number.
It does that by determining the range that the number fits into and then 
applying an appropriate verb for that range using agenda (@.).
VERB     RANGE
__"0     Less than or equal to 0
_:       Greater than or equal to 1
nd1      Not close to 0 or 1
nd2fr    Close to 0 or 1
nd3fr    Very close to 0 or 1

...However the verb chosen by agenda is applied to the whole right argument so 
the main verb (n01cdfinv) is defined as rank 0 to get around that.

nd=. nd1 ` ([EMAIL PROTECTED] * (nd2fr`nd3fr @. test2)@r2fp) @. test1
in01=. >&0 * 1 + <&1   NB. test for y in range
n01cdfinv=: (__"0 ` _: `nd @. in01)"0 f.

To enable the verb to operate on arrays of higher rank, I came up with the 
explicit versions below, with corresponding improvements in speed, but was 
wondering how to do something similar using tacit.

Here is an idea using key (/.) that might be adapted to work, but I think 
getting the result in the appropriate form will be a bit clumsy?
Any other ideas?

   cat=: 7&< + 2&<  NB. Determine range
   v1=: <@:+:
   v2=: <@:-:
   v3=: <@:%:
   (cat v1`v2`v3/. ]) 1 4 2 6 3 12
+---+-------+------------+
|2 4|2 3 1.5|3.4641016151|
+---+-------+------------+

NB.===================================================================
NB. Here are my explicit versions of n01cdfinv
NB. Note that the following definitions need to be defined
NB. globally (=: not =.) in the original wiki script for
NB. the explicit verbs below to work.
NB. SPLIT1, SPLIT2, qfp, r2fp, nd1, nd2fr, nd3fr

NB.ndx v explicit version of tacit nd
ndx=: 3 : 0
  s=. ($y)$0
  msk=. (SPLIT1 < |@qfp) y  NB. is y pretty close to 0 or 1?
  s=. (nd1 (-.msk)#y) (I.-.msk)}s  NB. no
  st=. r2fp msk#y                  NB. yes pretty close
  msk2=. st > SPLIT2        NB. is y really close to 0 or 1?
  st=. (nd2fr (-.msk2)#st) (I. -.msk2)}st NB. no
  st=. (nd3fr    msk2 #st)   (I. msk2)}st NB. yes very close
  st=. (st * [EMAIL PROTECTED]) msk#y
  s=. st (I. msk)}s
)

NB. n01cdfinvx v explicit equivalent of tacit version
n01cdfinvx=: 3 : 0
  z=. ,y
  tst=. (>&0 * 1 + <&1) z
  z=. tst}__,_,:z   NB. not in-place operation
  n=. ndx (msk=. 2 = tst)#z
  z=. n (I. msk)}z  NB. amend values to z
  ($y)$z
)

NB.*n01cdfinvx1 v explicit translation that signals error if
NB. y outside 0-1 inclusive. Uses in-place amends for efficiency.
n01cdfinvx1=: 3 : 0
  z=. ,y
  msk=. (0&< *. 1&>) z     NB. between 0 & 1
  assert. msk +. z e. 0 1  NB. y outside meaningful bounds
  z=. __ (I. z=0)} z
  z=. _ (I. z=1)} z
  n=. ndx msk#z
  z=. n (I. msk)}z   NB. amend values to z
  ($y)$z
)
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to