factor/libs/math/utils.factor

93 lines
2.6 KiB
Factor
Raw Permalink Normal View History

IN: math-contrib
USING: errors kernel sequences math sequences-internals namespaces arrays ;
2005-10-21 03:42:38 -04:00
: deg>rad pi * 180 / ; inline
: rad>deg 180 * pi / ; inline
: lcm ( a b -- c )
#! Smallest integer such that c/a and c/b are both integers.
2006-11-14 01:34:21 -05:00
[ * ] 2keep gcd nip /i ; foldable
2005-10-21 03:42:38 -04:00
: mod-inv ( x n -- y )
#! Compute the multiplicative inverse of x mod n.
gcd 1 = [ "Non-trivial divisor found" throw ] unless ;
foldable
2006-08-18 00:54:39 -04:00
: each-bit ( n quot -- )
over zero? pick -1 number= or [
2drop
] [
2dup >r >r >r 1 bitand r> call r> -1 shift r> each-bit
] if ; inline
2005-10-21 03:42:38 -04:00
: (^mod) ( n z w -- z^w )
1 swap [
1 number= [ dupd * pick mod ] when >r sq over mod r>
] each-bit 2nip ; inline
: ^mod ( z w n -- z^w )
#! Compute z^w mod n.
over 0 < [
[ >r neg r> ^mod ] keep mod-inv
] [
-rot (^mod)
] if ; foldable
2006-10-19 14:12:47 -04:00
: powers ( n x -- seq )
#! Output sequence has n elements, { 1 x x^2 x^3 ... }
2006-11-14 01:34:21 -05:00
<array> 1 [ * ] accumulate nip ;
2005-12-07 19:43:29 -05:00
2005-10-21 03:42:38 -04:00
: ** ( u v -- u*v' ) conjugate * ; inline
: c. ( v v -- x )
#! Complex inner product.
0 [ ** + ] 2reduce ;
2005-11-07 20:26:32 -05:00
2005-12-10 01:02:13 -05:00
: proj ( u v -- w )
#! Orthogonal projection of u onto v.
[ [ v. ] keep norm-sq v/n ] keep n*v ;
: minmax ( seq -- min max )
#! find the min and max of a seq in one pass
2006-01-27 10:17:32 -05:00
1./0. -1./0. rot [ dup pick max -rot nip pick min -rot nip ] each ;
: absminmax ( seq -- min max )
2005-11-17 04:31:36 -05:00
#! find the absolute values of the min and max of a seq in one pass
minmax 2dup [ abs ] 2apply > [ swap ] when ;
2006-09-28 02:05:43 -04:00
SYMBOL: almost=-precision .000001 almost=-precision set-global
: almost= ( a b -- bool )
2006-08-18 12:57:46 -04:00
- abs almost=-precision get < ;
2005-11-07 20:26:32 -05:00
TUPLE: frange from step length ;
C: frange ( from step to -- seq )
#! example: 0 .01 10 <frange> >array
2006-11-15 13:36:57 -05:00
>r pick - swap [ / ceiling 1+ >bignum ] keep r>
2005-11-07 20:26:32 -05:00
[ set-frange-step ] keep
2006-11-15 13:36:57 -05:00
[ set-frange-length ] keep
2005-11-07 20:26:32 -05:00
[ set-frange-from ] keep ;
2006-11-15 13:36:57 -05:00
: <frange-no-endpt> ( from step to -- seq )
over - <frange> ;
2006-11-15 13:36:57 -05:00
M: frange length ( frange -- n ) frange-length ;
M: frange nth ( n frange -- obj ) [ frange-step * ] keep frange-from + ;
2005-11-07 20:26:32 -05:00
2005-11-09 17:48:55 -05:00
: frange-range ( frange -- range )
[ frange-step ] keep frange-length 1- * ;
2006-11-15 13:36:57 -05:00
SYMBOL: step-size .01 step-size set-global ! TODO: base on arguments
: (limit) ( count diff quot -- x quot )
pick 10 > [ "Not converging fast enough" throw ] when
[ call ] keep >r 2dup swap - 0 < [ "not converging" throw ] when
2dup almost= rot drop r>
swap [ step-size [ 2 / ] change rot 1+ -rot (limit) ] unless ;
: limit ( quot -- x )
2006-11-15 13:36:57 -05:00
.1 step-size set [ call ] keep
step-size [ 2 / ] change 0 -rot (limit) 2drop ;
2006-09-28 01:11:47 -04:00
: nth-rand ( seq -- elem ) [ length random-int ] keep nth ;
2006-01-23 18:53:58 -05:00