2 USING: errors kernel sequences math sequences-internals namespaces arrays ;
4 : deg>rad pi * 180 / ; inline
5 : rad>deg 180 * pi / ; inline
8 #! Smallest integer such that c/a and c/b are both integers.
9 2dup gcd nip >r * r> /i ; foldable
11 : mod-inv ( x n -- y )
12 #! Compute the multiplicative inverse of x mod n.
13 gcd 1 = [ "Non-trivial divisor found" throw ] unless ;
16 : each-bit ( n quot -- )
17 over zero? pick -1 number= or [
20 2dup >r >r >r 1 bitand r> call r> -1 shift r> each-bit
23 : (^mod) ( n z w -- z^w )
25 1 number= [ dupd * pick mod ] when >r sq over mod r>
26 ] each-bit 2nip ; inline
28 : ^mod ( z w n -- z^w )
31 [ >r neg r> ^mod ] keep mod-inv
36 : powers ( n x -- { 1 x x^2 x^3 ... } )
37 #! Output sequence has n elements.
38 <array> 1 [ * ] accumulate ;
40 : ** ( u v -- u*v' ) conjugate * ; inline
43 #! Complex inner product.
47 #! Orthogonal projection of u onto v.
48 [ [ v. ] keep norm-sq v/n ] keep n*v ;
50 : minmax ( seq -- min max )
51 #! find the min and max of a seq in one pass
52 1./0. -1./0. rot [ dup pick max -rot nip pick min -rot nip ] each ;
54 : absminmax ( seq -- min max )
55 #! find the absolute values of the min and max of a seq in one pass
56 minmax 2dup [ abs ] 2apply > [ swap ] when ;
58 SYMBOL: almost=-precision .000001 almost=-precision set-global
59 : almost= ( a b -- bool )
60 - abs almost=-precision get < ;
62 TUPLE: frange from step length ;
64 C: frange ( from step to -- seq )
65 #! example: 0 .01 10 <frange> >array
66 >r pick - swap [ / ceiling 1+ ] keep -rot swapd r>
67 [ set-frange-length ] keep
68 [ set-frange-step ] keep
69 [ set-frange-from ] keep ;
71 : decrement-length ( frange -- )
72 [ frange-length 1- ] keep set-frange-length ;
74 : <frange-no-endpt> ( from step length -- seq )
75 <frange> dup decrement-length ;
77 M: frange length ( frange -- n )
80 : increment-start ( frange -- )
81 [ [ frange-from ] keep frange-step + ] keep set-frange-from ;
83 : frange-range ( frange -- range )
84 [ frange-step ] keep frange-length 1- * ;
86 M: frange nth ( n frange -- obj )
87 [ frange-step * ] keep frange-from + ;
89 ! : pivot ( left right index seq -- )
90 ! [ nth ] keep [ exchange ] 3keep ;
92 SYMBOL: step-size .01 step-size set ! base on arguments
93 : (limit) ( count diff quot -- x quot )
94 pick 10 > [ "Not converging fast enough" throw ] when
95 [ call ] keep >r 2dup swap - 0 < [ "not converging" throw ] when
96 2dup almost= rot drop r>
97 swap [ step-size [ 2 / ] change rot 1+ -rot (limit) ] unless ;
100 .1 step-size set [ call ] keep step-size [ 2 / ] change 0 -rot (limit) 2drop ;
102 : nth-rand ( seq -- elem ) [ length random-int ] keep nth ;
104 : count-end ( seq quot -- count )
105 >r [ length ] keep r> find-last drop dup -1 = [ 2drop 0 ] [ - 1- ] if ;