Merge branch 'master' of git://factorcode.org/git/factor
commit
3eb058aa70
basis
checksums/md5
promises
core
checksums
sequences
extra/parser-combinators
|
@ -4,7 +4,8 @@ USING: kernel io io.binary io.files io.streams.byte-array math
|
|||
math.functions math.parser namespaces splitting grouping strings
|
||||
sequences byte-arrays locals sequences.private macros fry
|
||||
io.encodings.binary math.bitwise checksums accessors
|
||||
checksums.common checksums.stream combinators combinators.smart ;
|
||||
checksums.common checksums.stream combinators combinators.smart
|
||||
specialized-arrays.uint literals ;
|
||||
IN: checksums.md5
|
||||
|
||||
SINGLETON: md5
|
||||
|
@ -16,7 +17,7 @@ TUPLE: md5-state < checksum-state state old-state ;
|
|||
: <md5-state> ( -- md5 )
|
||||
md5-state new-checksum-state
|
||||
64 >>block-size
|
||||
{ HEX: 67452301 HEX: efcdab89 HEX: 98badcfe HEX: 10325476 }
|
||||
uint-array{ HEX: 67452301 HEX: efcdab89 HEX: 98badcfe HEX: 10325476 }
|
||||
[ clone >>state ] [ >>old-state ] bi ;
|
||||
|
||||
M: md5 initialize-checksum-state drop <md5-state> ;
|
||||
|
@ -29,8 +30,10 @@ M: md5 initialize-checksum-state drop <md5-state> ;
|
|||
[ state>> ] [ old-state>> v-w+ dup clone ] [ ] tri
|
||||
[ (>>old-state) ] [ (>>state) ] bi ; inline
|
||||
|
||||
: T ( N -- Y )
|
||||
sin abs 32 2^ * >integer ; inline
|
||||
CONSTANT: T
|
||||
$[
|
||||
80 iota [ sin abs 32 2^ * >integer ] uint-array{ } map-as
|
||||
]
|
||||
|
||||
:: F ( X Y Z -- FXYZ )
|
||||
#! F(X,Y,Z) = XY v not(X) Z
|
||||
|
@ -70,22 +73,22 @@ CONSTANT: b 1
|
|||
CONSTANT: c 2
|
||||
CONSTANT: d 3
|
||||
|
||||
:: (ABCD) ( x V a b c d k s i quot -- )
|
||||
:: (ABCD) ( x state a b c d k s i quot -- )
|
||||
#! a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
|
||||
a V [
|
||||
b V nth
|
||||
c V nth
|
||||
d V nth quot call w+
|
||||
k x nth w+
|
||||
i T w+
|
||||
a state [
|
||||
b state nth-unsafe
|
||||
c state nth-unsafe
|
||||
d state nth-unsafe quot call w+
|
||||
k x nth-unsafe w+
|
||||
i T nth-unsafe w+
|
||||
s bitroll-32
|
||||
b V nth w+
|
||||
] change-nth ; inline
|
||||
b state nth-unsafe w+ 32 bits
|
||||
] change-nth-unsafe ; inline
|
||||
|
||||
MACRO: with-md5-round ( ops quot -- )
|
||||
'[ [ _ (ABCD) ] compose ] map '[ _ 2cleave ] ;
|
||||
|
||||
: (process-md5-block-F) ( block v -- )
|
||||
: (process-md5-block-F) ( block state -- )
|
||||
{
|
||||
[ a b c d 0 S11 1 ]
|
||||
[ d a b c 1 S12 2 ]
|
||||
|
@ -105,7 +108,7 @@ MACRO: with-md5-round ( ops quot -- )
|
|||
[ b c d a 15 S14 16 ]
|
||||
} [ F ] with-md5-round ; inline
|
||||
|
||||
: (process-md5-block-G) ( block v -- )
|
||||
: (process-md5-block-G) ( block state -- )
|
||||
{
|
||||
[ a b c d 1 S21 17 ]
|
||||
[ d a b c 6 S22 18 ]
|
||||
|
@ -125,7 +128,7 @@ MACRO: with-md5-round ( ops quot -- )
|
|||
[ b c d a 12 S24 32 ]
|
||||
} [ G ] with-md5-round ; inline
|
||||
|
||||
: (process-md5-block-H) ( block v -- )
|
||||
: (process-md5-block-H) ( block state -- )
|
||||
{
|
||||
[ a b c d 5 S31 33 ]
|
||||
[ d a b c 8 S32 34 ]
|
||||
|
@ -145,7 +148,7 @@ MACRO: with-md5-round ( ops quot -- )
|
|||
[ b c d a 2 S34 48 ]
|
||||
} [ H ] with-md5-round ; inline
|
||||
|
||||
: (process-md5-block-I) ( block v -- )
|
||||
: (process-md5-block-I) ( block state -- )
|
||||
{
|
||||
[ a b c d 0 S41 49 ]
|
||||
[ d a b c 7 S42 50 ]
|
||||
|
@ -167,7 +170,7 @@ MACRO: with-md5-round ( ops quot -- )
|
|||
|
||||
M: md5-state checksum-block ( block state -- )
|
||||
[
|
||||
[ 4 <groups> [ le> ] map ] [ state>> ] bi* {
|
||||
[ byte-array>uint-array ] [ state>> ] bi* {
|
||||
[ (process-md5-block-F) ]
|
||||
[ (process-md5-block-G) ]
|
||||
[ (process-md5-block-H) ]
|
||||
|
@ -177,8 +180,7 @@ M: md5-state checksum-block ( block state -- )
|
|||
nip update-md5
|
||||
] 2bi ;
|
||||
|
||||
: md5>checksum ( md5 -- bytes )
|
||||
state>> [ 4 >le ] map B{ } concat-as ;
|
||||
: md5>checksum ( md5 -- bytes ) state>> underlying>> ;
|
||||
|
||||
M: md5-state clone ( md5 -- new-md5 )
|
||||
call-next-method
|
||||
|
|
|
@ -33,7 +33,7 @@ ARTICLE: { "lists.lazy" "construction" } "Constructing lazy lists"
|
|||
{ $subsection 1lazy-list }
|
||||
{ $subsection 2lazy-list }
|
||||
{ $subsection 3lazy-list }
|
||||
{ $subsection seq>list }
|
||||
{ $subsection sequence-tail>list }
|
||||
{ $subsection >list }
|
||||
{ $subsection lfrom } ;
|
||||
|
||||
|
@ -105,15 +105,15 @@ HELP: lfrom
|
|||
{ $values { "n" "an integer" } { "list" "a lazy list of integers" } }
|
||||
{ $description "Return an infinite lazy list of incrementing integers starting from n." } ;
|
||||
|
||||
HELP: seq>list
|
||||
HELP: sequence-tail>list
|
||||
{ $values { "index" "an integer 0 or greater" } { "seq" "a sequence" } { "list" "a list" } }
|
||||
{ $description "Convert the sequence into a list, starting from " { $snippet "index" } "." }
|
||||
{ $see-also >list } ;
|
||||
|
||||
HELP: >list
|
||||
{ $values { "object" "an object" } { "list" "a list" } }
|
||||
{ $description "Convert the object into a list. Existing lists are passed through intact, sequences are converted using " { $link seq>list } " and other objects cause an error to be thrown." }
|
||||
{ $see-also seq>list } ;
|
||||
{ $description "Convert the object into a list. Existing lists are passed through intact, sequences are converted using " { $link sequence-tail>list } " and other objects cause an error to be thrown." }
|
||||
{ $see-also sequence-tail>list } ;
|
||||
|
||||
{ leach foldl lazy-map ltake lfilter lappend lfrom lfrom-by lconcat lcartesian-product lcartesian-product* lcomp lcomp* lmerge lwhile luntil } related-words
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
! Copyright (C) 2006 Matthew Willis and Chris Double.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: lists lists.lazy tools.test kernel math io sequences ;
|
||||
USING: io io.encodings.utf8 io.files kernel lists lists.lazy
|
||||
math sequences tools.test ;
|
||||
IN: lists.lazy.tests
|
||||
|
||||
[ { 1 2 3 4 } ] [
|
||||
|
@ -33,3 +34,6 @@ IN: lists.lazy.tests
|
|||
[ [ drop ] foldl ] must-infer
|
||||
[ [ drop ] leach ] must-infer
|
||||
[ lnth ] must-infer
|
||||
|
||||
[ ] [ "resource:license.txt" utf8 <file-reader> llines list>array drop ] unit-test
|
||||
[ ] [ "resource:license.txt" utf8 <file-reader> lcontents list>array drop ] unit-test
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
! Copyright (C) 2004, 2008 Chris Double, Matthew Willis, James Cash.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: kernel sequences math vectors arrays namespaces make
|
||||
quotations promises combinators io lists accessors ;
|
||||
USING: accessors arrays combinators io kernel lists math
|
||||
promises quotations sequences summary vectors ;
|
||||
IN: lists.lazy
|
||||
|
||||
M: promise car ( promise -- car )
|
||||
|
@ -10,16 +10,16 @@ M: promise car ( promise -- car )
|
|||
M: promise cdr ( promise -- cdr )
|
||||
force cdr ;
|
||||
|
||||
M: promise nil? ( cons -- bool )
|
||||
M: promise nil? ( cons -- ? )
|
||||
force nil? ;
|
||||
|
||||
|
||||
! Both 'car' and 'cdr' are promises
|
||||
TUPLE: lazy-cons car cdr ;
|
||||
|
||||
: lazy-cons ( car cdr -- promise )
|
||||
[ promise ] bi@ \ lazy-cons boa
|
||||
T{ promise f f t f } clone
|
||||
swap >>value ;
|
||||
[ T{ promise f f t f } clone ] 2dip
|
||||
[ promise ] bi@ \ lazy-cons boa
|
||||
>>value ;
|
||||
|
||||
M: lazy-cons car ( lazy-cons -- car )
|
||||
car>> force ;
|
||||
|
@ -27,7 +27,7 @@ M: lazy-cons car ( lazy-cons -- car )
|
|||
M: lazy-cons cdr ( lazy-cons -- cdr )
|
||||
cdr>> force ;
|
||||
|
||||
M: lazy-cons nil? ( lazy-cons -- bool )
|
||||
M: lazy-cons nil? ( lazy-cons -- ? )
|
||||
nil eq? ;
|
||||
|
||||
: 1lazy-list ( a -- lazy-cons )
|
||||
|
@ -41,11 +41,9 @@ M: lazy-cons nil? ( lazy-cons -- bool )
|
|||
|
||||
TUPLE: memoized-cons original car cdr nil? ;
|
||||
|
||||
: not-memoized ( -- obj )
|
||||
{ } ;
|
||||
: not-memoized ( -- obj ) { } ;
|
||||
|
||||
: not-memoized? ( obj -- bool )
|
||||
not-memoized eq? ;
|
||||
: not-memoized? ( obj -- ? ) not-memoized eq? ;
|
||||
|
||||
: <memoized-cons> ( cons -- memoized-cons )
|
||||
not-memoized not-memoized not-memoized
|
||||
|
@ -65,7 +63,7 @@ M: memoized-cons cdr ( memoized-cons -- cdr )
|
|||
cdr>>
|
||||
] if ;
|
||||
|
||||
M: memoized-cons nil? ( memoized-cons -- bool )
|
||||
M: memoized-cons nil? ( memoized-cons -- ? )
|
||||
dup nil?>> not-memoized? [
|
||||
dup original>> nil? [ >>nil? drop ] keep
|
||||
] [
|
||||
|
@ -80,14 +78,12 @@ C: <lazy-map> lazy-map
|
|||
over nil? [ 2drop nil ] [ <lazy-map> <memoized-cons> ] if ;
|
||||
|
||||
M: lazy-map car ( lazy-map -- car )
|
||||
[ cons>> car ] keep
|
||||
quot>> call( old -- new ) ;
|
||||
[ cons>> car ] [ quot>> call( old -- new ) ] bi ;
|
||||
|
||||
M: lazy-map cdr ( lazy-map -- cdr )
|
||||
[ cons>> cdr ] keep
|
||||
quot>> lazy-map ;
|
||||
[ cons>> cdr ] [ quot>> lazy-map ] bi ;
|
||||
|
||||
M: lazy-map nil? ( lazy-map -- bool )
|
||||
M: lazy-map nil? ( lazy-map -- ? )
|
||||
cons>> nil? ;
|
||||
|
||||
TUPLE: lazy-take n cons ;
|
||||
|
@ -95,7 +91,7 @@ TUPLE: lazy-take n cons ;
|
|||
C: <lazy-take> lazy-take
|
||||
|
||||
: ltake ( n list -- result )
|
||||
over zero? [ 2drop nil ] [ <lazy-take> ] if ;
|
||||
over zero? [ 2drop nil ] [ <lazy-take> ] if ;
|
||||
|
||||
M: lazy-take car ( lazy-take -- car )
|
||||
cons>> car ;
|
||||
|
@ -104,12 +100,8 @@ M: lazy-take cdr ( lazy-take -- cdr )
|
|||
[ n>> 1- ] keep
|
||||
cons>> cdr ltake ;
|
||||
|
||||
M: lazy-take nil? ( lazy-take -- bool )
|
||||
dup n>> zero? [
|
||||
drop t
|
||||
] [
|
||||
cons>> nil?
|
||||
] if ;
|
||||
M: lazy-take nil? ( lazy-take -- ? )
|
||||
dup n>> zero? [ drop t ] [ cons>> nil? ] if ;
|
||||
|
||||
TUPLE: lazy-until cons quot ;
|
||||
|
||||
|
@ -125,7 +117,7 @@ M: lazy-until cdr ( lazy-until -- cdr )
|
|||
[ cons>> unswons ] keep quot>> tuck call( elt -- ? )
|
||||
[ 2drop nil ] [ luntil ] if ;
|
||||
|
||||
M: lazy-until nil? ( lazy-until -- bool )
|
||||
M: lazy-until nil? ( lazy-until -- ? )
|
||||
drop f ;
|
||||
|
||||
TUPLE: lazy-while cons quot ;
|
||||
|
@ -141,7 +133,7 @@ M: lazy-while car ( lazy-while -- car )
|
|||
M: lazy-while cdr ( lazy-while -- cdr )
|
||||
[ cons>> cdr ] keep quot>> lwhile ;
|
||||
|
||||
M: lazy-while nil? ( lazy-while -- bool )
|
||||
M: lazy-while nil? ( lazy-while -- ? )
|
||||
[ car ] keep quot>> call( elt -- ? ) not ;
|
||||
|
||||
TUPLE: lazy-filter cons quot ;
|
||||
|
@ -167,7 +159,7 @@ M: lazy-filter cdr ( lazy-filter -- cdr )
|
|||
dup skip cdr
|
||||
] if ;
|
||||
|
||||
M: lazy-filter nil? ( lazy-filter -- bool )
|
||||
M: lazy-filter nil? ( lazy-filter -- ? )
|
||||
dup cons>> nil? [
|
||||
drop t
|
||||
] [
|
||||
|
@ -189,10 +181,9 @@ M: lazy-append car ( lazy-append -- car )
|
|||
list1>> car ;
|
||||
|
||||
M: lazy-append cdr ( lazy-append -- cdr )
|
||||
[ list1>> cdr ] keep
|
||||
list2>> lappend ;
|
||||
[ list1>> cdr ] [ list2>> ] bi lappend ;
|
||||
|
||||
M: lazy-append nil? ( lazy-append -- bool )
|
||||
M: lazy-append nil? ( lazy-append -- ? )
|
||||
drop f ;
|
||||
|
||||
TUPLE: lazy-from-by n quot ;
|
||||
|
@ -209,7 +200,7 @@ M: lazy-from-by cdr ( lazy-from-by -- cdr )
|
|||
[ n>> ] keep
|
||||
quot>> [ call( old -- new ) ] keep lfrom-by ;
|
||||
|
||||
M: lazy-from-by nil? ( lazy-from-by -- bool )
|
||||
M: lazy-from-by nil? ( lazy-from-by -- ? )
|
||||
drop f ;
|
||||
|
||||
TUPLE: lazy-zip list1 list2 ;
|
||||
|
@ -226,14 +217,14 @@ M: lazy-zip car ( lazy-zip -- car )
|
|||
M: lazy-zip cdr ( lazy-zip -- cdr )
|
||||
[ list1>> cdr ] keep list2>> cdr lzip ;
|
||||
|
||||
M: lazy-zip nil? ( lazy-zip -- bool )
|
||||
M: lazy-zip nil? ( lazy-zip -- ? )
|
||||
drop f ;
|
||||
|
||||
TUPLE: sequence-cons index seq ;
|
||||
|
||||
C: <sequence-cons> sequence-cons
|
||||
|
||||
: seq>list ( index seq -- list )
|
||||
: sequence-tail>list ( index seq -- list )
|
||||
2dup length >= [
|
||||
2drop nil
|
||||
] [
|
||||
|
@ -241,21 +232,24 @@ C: <sequence-cons> sequence-cons
|
|||
] if ;
|
||||
|
||||
M: sequence-cons car ( sequence-cons -- car )
|
||||
[ index>> ] keep
|
||||
seq>> nth ;
|
||||
[ index>> ] [ seq>> nth ] bi ;
|
||||
|
||||
M: sequence-cons cdr ( sequence-cons -- cdr )
|
||||
[ index>> 1+ ] keep
|
||||
seq>> seq>list ;
|
||||
[ index>> 1+ ] [ seq>> sequence-tail>list ] bi ;
|
||||
|
||||
M: sequence-cons nil? ( sequence-cons -- bool )
|
||||
M: sequence-cons nil? ( sequence-cons -- ? )
|
||||
drop f ;
|
||||
|
||||
ERROR: list-conversion-error object ;
|
||||
|
||||
M: list-conversion-error summary
|
||||
drop "Could not convert object to list" ;
|
||||
|
||||
: >list ( object -- list )
|
||||
{
|
||||
{ [ dup sequence? ] [ 0 swap seq>list ] }
|
||||
{ [ dup list? ] [ ] }
|
||||
[ "Could not convert object to a list" throw ]
|
||||
{ [ dup sequence? ] [ 0 swap sequence-tail>list ] }
|
||||
{ [ dup list? ] [ ] }
|
||||
[ list-conversion-error ]
|
||||
} cond ;
|
||||
|
||||
TUPLE: lazy-concat car cdr ;
|
||||
|
@ -265,18 +259,10 @@ C: <lazy-concat> lazy-concat
|
|||
DEFER: lconcat
|
||||
|
||||
: (lconcat) ( car cdr -- list )
|
||||
over nil? [
|
||||
nip lconcat
|
||||
] [
|
||||
<lazy-concat>
|
||||
] if ;
|
||||
over nil? [ nip lconcat ] [ <lazy-concat> ] if ;
|
||||
|
||||
: lconcat ( list -- result )
|
||||
dup nil? [
|
||||
drop nil
|
||||
] [
|
||||
uncons (lconcat)
|
||||
] if ;
|
||||
dup nil? [ drop nil ] [ uncons (lconcat) ] if ;
|
||||
|
||||
M: lazy-concat car ( lazy-concat -- car )
|
||||
car>> car ;
|
||||
|
@ -284,12 +270,8 @@ M: lazy-concat car ( lazy-concat -- car )
|
|||
M: lazy-concat cdr ( lazy-concat -- cdr )
|
||||
[ car>> cdr ] keep cdr>> (lconcat) ;
|
||||
|
||||
M: lazy-concat nil? ( lazy-concat -- bool )
|
||||
dup car>> nil? [
|
||||
cdr>> nil?
|
||||
] [
|
||||
drop f
|
||||
] if ;
|
||||
M: lazy-concat nil? ( lazy-concat -- ? )
|
||||
dup car>> nil? [ cdr>> nil? ] [ drop f ] if ;
|
||||
|
||||
: lcartesian-product ( list1 list2 -- result )
|
||||
swap [ swap [ 2array ] with lazy-map ] with lazy-map lconcat ;
|
||||
|
@ -298,7 +280,9 @@ M: lazy-concat nil? ( lazy-concat -- bool )
|
|||
dup nil? [
|
||||
drop nil
|
||||
] [
|
||||
[ car ] keep cdr [ car lcartesian-product ] keep cdr list>array swap [
|
||||
[ car ] [ cdr ] bi
|
||||
[ car lcartesian-product ] [ cdr ] bi
|
||||
list>array swap [
|
||||
swap [ swap [ suffix ] with lazy-map ] with lazy-map lconcat
|
||||
] reduce
|
||||
] if ;
|
||||
|
@ -322,9 +306,9 @@ DEFER: lmerge
|
|||
|
||||
: lmerge ( list1 list2 -- result )
|
||||
{
|
||||
{ [ over nil? ] [ nip ] }
|
||||
{ [ dup nil? ] [ drop ] }
|
||||
{ [ t ] [ (lmerge) ] }
|
||||
{ [ over nil? ] [ nip ] }
|
||||
{ [ dup nil? ] [ drop ] }
|
||||
{ [ t ] [ (lmerge) ] }
|
||||
} cond ;
|
||||
|
||||
TUPLE: lazy-io stream car cdr quot ;
|
||||
|
@ -338,30 +322,29 @@ C: <lazy-io> lazy-io
|
|||
f f [ stream-readln ] <lazy-io> ;
|
||||
|
||||
M: lazy-io car ( lazy-io -- car )
|
||||
dup car>> dup [
|
||||
dup car>> [
|
||||
nip
|
||||
] [
|
||||
drop dup stream>> over quot>>
|
||||
call( stream -- value )
|
||||
>>car
|
||||
] if ;
|
||||
[ ] [ stream>> ] [ quot>> ] tri
|
||||
call( stream -- value ) [ >>car ] [ drop nil ] if*
|
||||
] if* ;
|
||||
|
||||
M: lazy-io cdr ( lazy-io -- cdr )
|
||||
dup cdr>> dup [
|
||||
nip
|
||||
] [
|
||||
drop dup
|
||||
[ stream>> ] keep
|
||||
[ quot>> ] keep
|
||||
car [
|
||||
[ stream>> ]
|
||||
[ quot>> ]
|
||||
[ car ] tri [
|
||||
[ f f ] dip <lazy-io> [ >>cdr drop ] keep
|
||||
] [
|
||||
3drop nil
|
||||
] if
|
||||
] if ;
|
||||
|
||||
M: lazy-io nil? ( lazy-io -- bool )
|
||||
car not ;
|
||||
M: lazy-io nil? ( lazy-io -- ? )
|
||||
car nil? ;
|
||||
|
||||
INSTANCE: sequence-cons list
|
||||
INSTANCE: memoized-cons list
|
||||
|
|
|
@ -2,26 +2,26 @@ USING: help.markup help.syntax debugger ;
|
|||
IN: math.statistics
|
||||
|
||||
HELP: geometric-mean
|
||||
{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
|
||||
{ $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
|
||||
{ $description "Computes the geometric mean of all elements in " { $snippet "seq" } ". The geometric mean measures the central tendency of a data set that minimizes the effects of extreme values." }
|
||||
{ $examples { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } geometric-mean ." "1.81712059283214" } }
|
||||
{ $errors "Throws a " { $link signal-error. } " (square-root of 0) if the sequence is empty." } ;
|
||||
|
||||
HELP: harmonic-mean
|
||||
{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
|
||||
{ $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
|
||||
{ $description "Computes the harmonic mean of the elements in " { $snippet "seq" } ". The harmonic mean is appropriate when the average of rates is desired." }
|
||||
{ $notes "Positive reals only." }
|
||||
{ $examples { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } harmonic-mean ." "6/11" } }
|
||||
{ $errors "Throws a " { $link signal-error. } " (divide by zero) if the sequence is empty." } ;
|
||||
|
||||
HELP: mean
|
||||
{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
|
||||
{ $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
|
||||
{ $description "Computes the arithmetic mean of all elements in " { $snippet "seq" } "." }
|
||||
{ $examples { $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } mean ." "2" } }
|
||||
{ $errors "Throws a " { $link signal-error. } " (divide by zero) if the sequence is empty." } ;
|
||||
|
||||
HELP: median
|
||||
{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
|
||||
{ $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
|
||||
{ $description "Computes the median of " { $snippet "seq" } " by sorting the sequence from lowest value to highest and outputting the middle one. If there is an even number of elements in the sequence, the median is not unique, so the mean of the two middle values is outputted." }
|
||||
{ $examples
|
||||
{ $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } median ." "2" }
|
||||
|
@ -29,7 +29,7 @@ HELP: median
|
|||
{ $errors "Throws a " { $link signal-error. } " (divide by zero) if the sequence is empty." } ;
|
||||
|
||||
HELP: range
|
||||
{ $values { "seq" "a sequence of numbers" } { "n" "a non-negative real number"} }
|
||||
{ $values { "seq" "a sequence of numbers" } { "x" "a non-negative real number"} }
|
||||
{ $description "Computes the distance of the maximum and minimum values in " { $snippet "seq" } "." }
|
||||
{ $examples
|
||||
{ $example "USING: math.statistics prettyprint ;" "{ 1 2 3 } range ." "2" }
|
||||
|
|
|
@ -13,6 +13,24 @@ IN: math.statistics.tests
|
|||
[ 2 ] [ { 1 2 3 } median ] unit-test
|
||||
[ 5/2 ] [ { 1 2 3 4 } median ] unit-test
|
||||
|
||||
[ { } median ] must-fail
|
||||
[ { } upper-median ] must-fail
|
||||
[ { } lower-median ] must-fail
|
||||
|
||||
[ 2 ] [ { 1 2 3 4 } lower-median ] unit-test
|
||||
[ 3 ] [ { 1 2 3 4 } upper-median ] unit-test
|
||||
[ 3 ] [ { 1 2 3 4 5 } lower-median ] unit-test
|
||||
[ 3 ] [ { 1 2 3 4 5 } upper-median ] unit-test
|
||||
|
||||
|
||||
[ 1 ] [ { 1 } lower-median ] unit-test
|
||||
[ 1 ] [ { 1 } upper-median ] unit-test
|
||||
[ 1 ] [ { 1 } median ] unit-test
|
||||
|
||||
[ 1 ] [ { 1 2 } lower-median ] unit-test
|
||||
[ 2 ] [ { 1 2 } upper-median ] unit-test
|
||||
[ 3/2 ] [ { 1 2 } median ] unit-test
|
||||
|
||||
[ 1 ] [ { 1 2 3 } var ] unit-test
|
||||
[ 1.0 ] [ { 1 2 3 } std ] unit-test
|
||||
[ t ] [ { 1 2 3 4 } ste 0.6454972243679028 - .0001 < ] unit-test
|
||||
|
|
|
@ -1,30 +1,66 @@
|
|||
! Copyright (C) 2008 Doug Coleman, Michael Judge.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: arrays combinators kernel math math.analysis
|
||||
math.functions math.order sequences sorting ;
|
||||
math.functions math.order sequences sorting locals
|
||||
sequences.private ;
|
||||
IN: math.statistics
|
||||
|
||||
: mean ( seq -- n )
|
||||
: mean ( seq -- x )
|
||||
[ sum ] [ length ] bi / ;
|
||||
|
||||
: geometric-mean ( seq -- n )
|
||||
: geometric-mean ( seq -- x )
|
||||
[ length ] [ product ] bi nth-root ;
|
||||
|
||||
: harmonic-mean ( seq -- n )
|
||||
: harmonic-mean ( seq -- x )
|
||||
[ recip ] sigma recip ;
|
||||
|
||||
: median ( seq -- n )
|
||||
natural-sort dup length even? [
|
||||
[ midpoint@ dup 1 - 2array ] keep nths mean
|
||||
] [
|
||||
[ midpoint@ ] keep nth
|
||||
] if ;
|
||||
:: kth-smallest ( seq k -- elt )
|
||||
#! Wirth's method, Algorithm's + Data structues = Programs p. 84
|
||||
#! The algorithm modifiers seq, so we clone it
|
||||
seq clone :> seq
|
||||
0 :> i!
|
||||
0 :> j!
|
||||
0 :> l!
|
||||
0 :> x!
|
||||
seq length 1 - :> m!
|
||||
[ l m < ]
|
||||
[
|
||||
k seq nth x!
|
||||
l i!
|
||||
m j!
|
||||
[ i j <= ]
|
||||
[
|
||||
[ i seq nth-unsafe x < ] [ i 1 + i! ] while
|
||||
[ x j seq nth-unsafe < ] [ j 1 - j! ] while
|
||||
i j <= [
|
||||
i j seq exchange
|
||||
i 1 + i!
|
||||
j 1 - j!
|
||||
] when
|
||||
] do while
|
||||
|
||||
j k < [ i l! ] when
|
||||
k i < [ j m! ] when
|
||||
] while
|
||||
k seq nth ; inline
|
||||
|
||||
: lower-median ( seq -- elt )
|
||||
dup dup length odd? [ midpoint@ ] [ midpoint@ 1 - ] if kth-smallest ;
|
||||
|
||||
: upper-median ( seq -- elt )
|
||||
dup midpoint@ kth-smallest ;
|
||||
|
||||
: medians ( seq -- lower upper )
|
||||
[ lower-median ] [ upper-median ] bi ;
|
||||
|
||||
: median ( seq -- x )
|
||||
dup length odd? [ lower-median ] [ medians + 2 / ] if ;
|
||||
|
||||
: minmax ( seq -- min max )
|
||||
#! find the min and max of a seq in one pass
|
||||
[ 1/0. -1/0. ] dip [ [ min ] [ max ] bi-curry bi* ] each ;
|
||||
|
||||
: range ( seq -- n )
|
||||
: range ( seq -- x )
|
||||
minmax swap - ;
|
||||
|
||||
: var ( seq -- x )
|
||||
|
@ -32,15 +68,13 @@ IN: math.statistics
|
|||
dup length 1 <= [
|
||||
drop 0
|
||||
] [
|
||||
[ [ mean ] keep [ - sq ] with sigma ] keep
|
||||
length 1 - /
|
||||
[ [ mean ] keep [ - sq ] with sigma ]
|
||||
[ length 1 - ] bi /
|
||||
] if ;
|
||||
|
||||
: std ( seq -- x )
|
||||
var sqrt ;
|
||||
: std ( seq -- x ) var sqrt ;
|
||||
|
||||
: ste ( seq -- x )
|
||||
[ std ] [ length ] bi sqrt / ;
|
||||
: ste ( seq -- x ) [ std ] [ length ] bi sqrt / ;
|
||||
|
||||
: ((r)) ( mean(x) mean(y) {x} {y} -- (r) )
|
||||
! finds sigma((xi-mean(x))(yi-mean(y))
|
||||
|
@ -64,4 +98,3 @@ IN: math.statistics
|
|||
[ (r) ] 2keep ! stack is mean(x) mean(y) r sx sy
|
||||
swap / * ! stack is mean(x) mean(y) beta
|
||||
[ swapd * - ] keep ;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
! Copyright (C) 2004, 2006 Chris Double, Matthew Willis.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: arrays kernel sequences math arrays namespaces
|
||||
parser effects generalizations fry words accessors ;
|
||||
USING: accessors arrays effects fry generalizations kernel math
|
||||
namespaces parser sequences words ;
|
||||
IN: promises
|
||||
|
||||
TUPLE: promise quot forced? value ;
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
! Copyright (c) 2008 Slava Pestov
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors io io.backend io.files kernel math math.parser
|
||||
sequences vectors quotations ;
|
||||
sequences byte-arrays byte-vectors quotations ;
|
||||
IN: checksums
|
||||
|
||||
MIXIN: checksum
|
||||
|
||||
TUPLE: checksum-state bytes-read block-size bytes ;
|
||||
TUPLE: checksum-state
|
||||
{ bytes-read integer } { block-size integer } { bytes byte-vector } ;
|
||||
|
||||
: new-checksum-state ( class -- checksum-state )
|
||||
new
|
||||
0 >>bytes-read
|
||||
V{ } clone >>bytes ; inline
|
||||
BV{ } clone >>bytes ; inline
|
||||
|
||||
M: checksum-state clone
|
||||
call-next-method
|
||||
|
@ -27,11 +27,13 @@ GENERIC: get-checksum ( checksum -- value )
|
|||
over bytes>> [ push-all ] keep
|
||||
[ dup length pick block-size>> >= ]
|
||||
[
|
||||
64 cut-slice [
|
||||
64 cut-slice [ >byte-array ] dip [
|
||||
over [ checksum-block ]
|
||||
[ [ 64 + ] change-bytes-read drop ] bi
|
||||
] dip
|
||||
] while >vector [ >>bytes ] [ length [ + ] curry change-bytes-read ] bi ;
|
||||
] while
|
||||
>byte-vector
|
||||
[ >>bytes ] [ length [ + ] curry change-bytes-read ] bi ;
|
||||
|
||||
: add-checksum-stream ( checksum-state stream -- checksum-state )
|
||||
[
|
||||
|
|
|
@ -88,6 +88,9 @@ M: sequence set-nth bounds-check set-nth-unsafe ;
|
|||
M: sequence nth-unsafe nth ;
|
||||
M: sequence set-nth-unsafe set-nth ;
|
||||
|
||||
: change-nth-unsafe ( i seq quot -- )
|
||||
[ [ nth-unsafe ] dip call ] 3keep drop set-nth-unsafe ; inline
|
||||
|
||||
! The f object supports the sequence protocol trivially
|
||||
M: f length drop 0 ;
|
||||
M: f nth-unsafe nip ;
|
||||
|
|
|
@ -172,7 +172,7 @@ M: or-parser parse ( input parser1 -- list )
|
|||
#! Return the combined list resulting from the parses
|
||||
#! of parser1 and parser2 being applied to the same
|
||||
#! input. This implements the choice parsing operator.
|
||||
parsers>> 0 swap seq>list
|
||||
parsers>> sequence>list
|
||||
[ parse ] with lazy-map lconcat ;
|
||||
|
||||
: trim-head-slice ( string -- string )
|
||||
|
|
Loading…
Reference in New Issue