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
