diff options
Diffstat (limited to 'slib_5.html')
-rw-r--r-- | slib_5.html | 6100 |
1 files changed, 6100 insertions, 0 deletions
diff --git a/slib_5.html b/slib_5.html new file mode 100644 index 0000000..b3ef4b8 --- /dev/null +++ b/slib_5.html @@ -0,0 +1,6100 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html40/loose.dtd"> +<HTML> +<!-- Created on January, 10 2005 by texi2html 1.66 --> +<!-- +Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author) + Karl Berry <karl@freefriends.org> + Olaf Bachmann <obachman@mathematik.uni-kl.de> + and many others. +Maintained by: Many creative people <dev@texi2html.cvshome.org> +Send bugs and suggestions to <users@texi2html.cvshome.org> + +--> +<HEAD> +<TITLE>SLIB: Mathematical Packages</TITLE> + +<META NAME="description" CONTENT="SLIB: Mathematical Packages"> +<META NAME="keywords" CONTENT="SLIB: Mathematical Packages"> +<META NAME="resource-type" CONTENT="document"> +<META NAME="distribution" CONTENT="global"> +<META NAME="Generator" CONTENT="texi2html 1.66"> + +</HEAD> + +<BODY LANG="en" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"> + +<A NAME="SEC88"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC87"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC89"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_4.html#SEC45"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H1> 5. Mathematical Packages </H1> +<!--docid::SEC88::--> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC89">5.1 Bit-Twiddling</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'logical</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC95">5.2 Modular Arithmetic</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'modular</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC96">5.3 Prime Numbers</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'factor</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC97">5.4 Random Numbers</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'random</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC100">5.5 Fast Fourier Transform</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'fft</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC101">5.6 Cyclic Checksum</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'crc</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC102">5.7 Graphing</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC112">5.8 Solid Modeling</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">VRML97</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC118">5.9 Color</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC134">5.10 Root Finding</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'root</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC135">5.11 Minimizing</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'minimize</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC136">5.12 Commutative Rings</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'commutative-ring</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC139">5.15 Matrix Algebra</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'determinant</TD></TR> +</TABLE> +<P> + +<A NAME="Bit-Twiddling"></A> +<HR SIZE="6"> +<A NAME="SEC89"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC90"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.1 Bit-Twiddling </H2> +<!--docid::SEC89::--> +<P> + +<CODE>(require 'logical)</CODE> +<A NAME="IDX476"></A> +</P> +<P> + +The bit-twiddling functions are made available through the use of the +<CODE>logical</CODE> package. <CODE>logical</CODE> is loaded by inserting +<CODE>(require 'logical)</CODE> before the code that uses these +<A NAME="IDX477"></A> +functions. These functions behave as though operating on integers +in two's-complement representation. +</P> +<P> + +<HR SIZE="6"> +<A NAME="SEC90"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC89"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC91"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.1.1 Bitwise Operations </H3> +<!--docid::SEC90::--> +<P> + +<A NAME="IDX478"></A> +</P> +<DL> +<DT><U>Function:</U> <B>logand</B> <I>n1 n1</I> +<DD>Returns the integer which is the bit-wise AND of the two integer +arguments. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(number->string (logand #b1100 #b1010) 2) + => "1000" +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX479"></A> +</P> +<DL> +<DT><U>Function:</U> <B>logior</B> <I>n1 n2</I> +<DD>Returns the integer which is the bit-wise OR of the two integer +arguments. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(number->string (logior #b1100 #b1010) 2) + => "1110" +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX480"></A> +</P> +<DL> +<DT><U>Function:</U> <B>logxor</B> <I>n1 n2</I> +<DD>Returns the integer which is the bit-wise XOR of the two integer +arguments. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(number->string (logxor #b1100 #b1010) 2) + => "110" +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX481"></A> +</P> +<DL> +<DT><U>Function:</U> <B>lognot</B> <I>n</I> +<DD>Returns the integer which is the 2s-complement of the integer argument. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(number->string (lognot #b10000000) 2) + => "-10000001" +(number->string (lognot #b0) 2) + => "-1" +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX482"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bitwise-if</B> <I>mask n0 n1</I> +<DD>Returns an integer composed of some bits from integer <VAR>n0</VAR> and some +from integer <VAR>n1</VAR>. A bit of the result is taken from <VAR>n0</VAR> if the +corresponding bit of integer <VAR>mask</VAR> is 1 and from <VAR>n1</VAR> if that bit +of <VAR>mask</VAR> is 0. +</DL> +<P> + +<A NAME="IDX483"></A> +</P> +<DL> +<DT><U>Function:</U> <B>logtest</B> <I>j k</I> +<DD><TABLE><tr><td> </td><td class=example><pre>(logtest j k) == (not (zero? (logand j k))) + +(logtest #b0100 #b1011) => #f +(logtest #b0100 #b0111) => #t +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX484"></A> +</P> +<DL> +<DT><U>Function:</U> <B>logcount</B> <I>n</I> +<DD>Returns the number of bits in integer <VAR>n</VAR>. If integer is positive, +the 1-bits in its binary representation are counted. If negative, the +0-bits in its two's-complement binary representation are counted. If 0, +0 is returned. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(logcount #b10101010) + => 4 +(logcount 0) + => 0 +(logcount -2) + => 1 +</pre></td></tr></table></DL> +<P> + +<HR SIZE="6"> +<A NAME="SEC91"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC90"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC92"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.1.2 Bit Within Word </H3> +<!--docid::SEC91::--> +<P> + +<A NAME="IDX485"></A> +</P> +<DL> +<DT><U>Function:</U> <B>logbit?</B> <I>index j</I> +<DD><TABLE><tr><td> </td><td class=example><pre>(logbit? index j) == (logtest (integer-expt 2 index) j) + +(logbit? 0 #b1101) => #t +(logbit? 1 #b1101) => #f +(logbit? 2 #b1101) => #t +(logbit? 3 #b1101) => #t +(logbit? 4 #b1101) => #f +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX486"></A> +</P> +<DL> +<DT><U>Function:</U> <B>copy-bit</B> <I>index from bit</I> +<DD>Returns an integer the same as <VAR>from</VAR> except in the <VAR>index</VAR>th bit, +which is 1 if <VAR>bit</VAR> is <CODE>#t</CODE> and 0 if <VAR>bit</VAR> is <CODE>#f</CODE>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(number->string (copy-bit 0 0 #t) 2) => "1" +(number->string (copy-bit 2 0 #t) 2) => "100" +(number->string (copy-bit 2 #b1111 #f) 2) => "1011" +</pre></td></tr></table></DL> +<P> + +<HR SIZE="6"> +<A NAME="SEC92"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC91"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC93"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.1.3 Fields of Bits </H3> +<!--docid::SEC92::--> +<P> + +<A NAME="IDX487"></A> +</P> +<DL> +<DT><U>Function:</U> <B>logical:ones</B> <I>n</I> +<DD>Returns the smallest non-negative integer having <VAR>n</VAR> binary ones. +</DL> +<P> + +<A NAME="IDX488"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bit-field</B> <I>n start end</I> +<DD>Returns the integer composed of the <VAR>start</VAR> (inclusive) through +<VAR>end</VAR> (exclusive) bits of <VAR>n</VAR>. The <VAR>start</VAR>th bit becomes +the 0-th bit in the result. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(number->string (bit-field #b1101101010 0 4) 2) + => "1010" +(number->string (bit-field #b1101101010 4 9) 2) + => "10110" +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX489"></A> +</P> +<DL> +<DT><U>Function:</U> <B>copy-bit-field</B> <I>to start end from</I> +<DD>Returns an integer the same as <VAR>to</VAR> except possibly in the +<VAR>start</VAR> (inclusive) through <VAR>end</VAR> (exclusive) bits, which are +the same as those of <VAR>from</VAR>. The 0-th bit of <VAR>from</VAR> becomes the +<VAR>start</VAR>th bit of the result. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(number->string (copy-bit-field #b1101101010 0 4 0) 2) + => "1101100000" +(number->string (copy-bit-field #b1101101010 0 4 -1) 2) + => "1101101111" +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX490"></A> +</P> +<DL> +<DT><U>Function:</U> <B>ash</B> <I>n count</I> +<DD>Returns an integer equivalent to +<CODE>(inexact->exact (floor (* <VAR>n</VAR> (expt 2 <VAR>count</VAR>))))</CODE>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(number->string (ash #b1 3) 2) + => "1000" +(number->string (ash #b1010 -1) 2) + => "101" +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX491"></A> +</P> +<DL> +<DT><U>Function:</U> <B>integer-length</B> <I>n</I> +<DD>Returns the number of bits neccessary to represent <VAR>n</VAR>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(integer-length #b10101010) + => 8 +(integer-length 0) + => 0 +(integer-length #b1111) + => 4 +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX492"></A> +</P> +<DL> +<DT><U>Function:</U> <B>integer-expt</B> <I>n k</I> +<DD>Returns <VAR>n</VAR> raised to the non-negative integer exponent <VAR>k</VAR>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(integer-expt 2 5) + => 32 +(integer-expt -3 3) + => -27 +</pre></td></tr></table></DL> +<P> + +<HR SIZE="6"> +<A NAME="SEC93"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC92"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC94"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.1.4 Bit order and Lamination </H3> +<!--docid::SEC93::--> +<P> + +<A NAME="IDX493"></A> +</P> +<DL> +<DT><U>Function:</U> <B>logical:rotate</B> <I>k count len</I> +<DD>Returns the low-order <VAR>len</VAR> bits of <VAR>k</VAR> cyclically permuted +<VAR>count</VAR> bits towards high-order. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(number->string (logical:rotate #b0100 3 4) 2) +=> "10" +(number->string (logical:rotate #b0100 -1 4) 2) +=> "10" +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX494"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bit-reverse</B> <I>k n</I> +<DD>Returns the low-order <VAR>k</VAR> bits of <VAR>n</VAR> with the bit order +reversed. The low-order bit of <VAR>n</VAR> is the high order bit of the +returned value. +<P> + +<TABLE><tr><td> </td><td class=example><pre>(number->string (bit-reverse 8 #xa7) 16) + => "e5" +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX495"></A> +</P> +<DL> +<DT><U>Function:</U> <B>integer->list</B> <I>k len</I> +<DD><A NAME="IDX496"></A> +<DT><U>Function:</U> <B>integer->list</B> <I>k</I> +<DD><CODE>integer->list</CODE> returns a list of <VAR>len</VAR> booleans corresponding +to each bit of the given integer. #t is coded for each 1; #f for 0. +The <VAR>len</VAR> argument defaults to <CODE>(integer-length <VAR>k</VAR>)</CODE>. +<P> + +<A NAME="IDX497"></A> +<DT><U>Function:</U> <B>list->integer</B> <I>list</I> +<DD><CODE>list->integer</CODE> returns an integer formed from the booleans in the +list <VAR>list</VAR>, which must be a list of booleans. A 1 bit is coded for +each #t; a 0 bit for #f. +</P> +<P> + +<CODE>integer->list</CODE> and <CODE>list->integer</CODE> are inverses so far as +<CODE>equal?</CODE> is concerned. +</P> +</DL> +<P> + +<A NAME="IDX498"></A> +</P> +<DL> +<DT><U>Function:</U> <B>booleans->integer</B> <I>bool1 <small>...</small></I> +<DD>Returns the integer coded by the <VAR>bool1</VAR> <small>...</small> arguments. +</DL> +<P> + +<A NAME="IDX499"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bitwise:laminate</B> <I>k1 <small>...</small></I> +<DD>Returns an integer composed of the bits of <VAR>k1</VAR> <small>...</small> interlaced +in argument order. Given <VAR>k1</VAR>, <small>...</small> <VAR>kn</VAR>, the n low-order +bits of the returned value will be the lowest-order bit of each +argument. +<P> + +<A NAME="IDX500"></A> +<DT><U>Function:</U> <B>bitwise:delaminate</B> <I>count k</I> +<DD>Returns a list of <VAR>count</VAR> integers comprised of every <VAR>count</VAR>h +bit of the integer <VAR>k</VAR>. +</P> +<P> + +For any non-negative integers <VAR>k</VAR> and <VAR>count</VAR>: +<TABLE><tr><td> </td><td class=example><pre>(eqv? k (bitwise:laminate (bitwise:delaminate count k))) +</pre></td></tr></table></DL> +<P> + +<HR SIZE="6"> +<A NAME="SEC94"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC93"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC95"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.1.5 Gray code </H3> +<!--docid::SEC94::--> +<P> + +<A NAME="IDX501"></A> +A <EM>Gray code</EM> is an ordering of non-negative integers in which +exactly one bit differs between each pair of successive elements. There +are multiple Gray codings. An n-bit Gray code corresponds to a +Hamiltonian cycle on an n-dimensional hypercube. +</P> +<P> + +Gray codes find use communicating incrementally changing values between +asynchronous agents. De-laminated Gray codes comprise the coordinates +of Peano-Hilbert space-filling curves. +</P> +<P> + +<A NAME="IDX502"></A> +</P> +<DL> +<DT><U>Function:</U> <B>integer->gray-code</B> <I>k</I> +<DD>Converts <VAR>k</VAR> to a Gray code of the same <CODE>integer-length</CODE> as +<VAR>k</VAR>. +<P> + +<A NAME="IDX503"></A> +<DT><U>Function:</U> <B>gray-code->integer</B> <I>k</I> +<DD>Converts the Gray code <VAR>k</VAR> to an integer of the same +<CODE>integer-length</CODE> as <VAR>k</VAR>. +</P> +<P> + +For any non-negative integer <VAR>k</VAR>, +<TABLE><tr><td> </td><td class=example><pre>(eqv? k (gray-code->integer (integer->gray-code k))) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX504"></A> +</P> +<DL> +<DT><U>Function:</U> <B>=</B> <I>k1 k2</I> +<DD><A NAME="IDX505"></A> +<DT><U>Function:</U> <B>gray-code<?</B> <I>k1 k2</I> +<DD><A NAME="IDX506"></A> +<DT><U>Function:</U> <B>gray-code>?</B> <I>k1 k2</I> +<DD><A NAME="IDX507"></A> +<DT><U>Function:</U> <B>gray-code<=?</B> <I>k1 k2</I> +<DD><A NAME="IDX508"></A> +<DT><U>Function:</U> <B>gray-code>=?</B> <I>k1 k2</I> +<DD>These procedures return #t if their Gray code arguments are +(respectively): equal, monotonically increasing, monotonically +decreasing, monotonically nondecreasing, or monotonically nonincreasing. +<P> + +For any non-negative integers <VAR>k1</VAR> and <VAR>k2</VAR>, the Gray code +predicate of <CODE>(integer->gray-code k1)</CODE> and +<CODE>(integer->gray-code k2)</CODE> will return the same value as the +corresponding predicate of <VAR>k1</VAR> and <VAR>k2</VAR>. +</P> +</DL> +<P> + +<A NAME="Modular Arithmetic"></A> +<HR SIZE="6"> +<A NAME="SEC95"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC94"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC96"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.2 Modular Arithmetic </H2> +<!--docid::SEC95::--> +<P> + +<CODE>(require 'modular)</CODE> +<A NAME="IDX509"></A> +</P> +<P> + +<A NAME="IDX510"></A> +</P> +<DL> +<DT><U>Function:</U> <B>mod</B> <I>x1 x2</I> +<DD><A NAME="IDX511"></A> +<DT><U>Function:</U> <B>rem</B> <I>x1 x2</I> +<DD><P> + +These procedures implement the Common-Lisp functions of the same names. +The real number <VAR>x2</VAR> must be non-zero. +<CODE>mod</CODE> returns <CODE>(- <VAR>x1</VAR> (* <VAR>x2</VAR> (floor (/ <VAR>x1</VAR> <VAR>x2</VAR>))))</CODE>. +<CODE>rem</CODE> returns <CODE>(- <VAR>x1</VAR> (* <VAR>x2</VAR> (truncate (/ <VAR>x1</VAR> <VAR>x2</VAR>))))</CODE>. +</P> +<P> + +If <VAR>x1</VAR> and <VAR>x2</VAR> are integers, then <CODE>mod</CODE> behaves like +<CODE>modulo</CODE> and <CODE>rem</CODE> behaves like <CODE>remainder</CODE>. +</P> +<P> + +<TABLE><tr><td> </td><td class=display><pre style="font-family: serif"><TT>(mod -90 360) => 270 +(rem -90 180) => -90 + +(mod 540 360) => 180 +(rem 540 360) => 180 + +(mod (* 5/2 pi) (* 2 pi)) => 1.5707963267948965 +(rem (* -5/2 pi) (* 2 pi)) => -1.5707963267948965 +</TT> +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX512"></A> +</P> +<DL> +<DT><U>Function:</U> <B>extended-euclid</B> <I>n1 n2</I> +<DD><P> + +Returns a list of 3 integers <CODE>(d x y)</CODE> such that d = gcd(<VAR>n1</VAR>, +<VAR>n2</VAR>) = <VAR>n1</VAR> * x + <VAR>n2</VAR> * y. +</P> +</DL> +<P> + +<A NAME="IDX513"></A> +</P> +<DL> +<DT><U>Function:</U> <B>symmetric:modulus</B> <I>n</I> +<DD><P> + +Returns <CODE>(quotient (+ -1 n) -2)</CODE> for positive odd integer <VAR>n</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX514"></A> +</P> +<DL> +<DT><U>Function:</U> <B>modulus->integer</B> <I>modulus</I> +<DD><P> + +Returns the non-negative integer characteristic of the ring formed when +<VAR>modulus</VAR> is used with <CODE>modular:</CODE> procedures. +</P> +</DL> +<P> + +<A NAME="IDX515"></A> +</P> +<DL> +<DT><U>Function:</U> <B>modular:normalize</B> <I>modulus n</I> +<DD><P> + +Returns the integer <CODE>(modulo <VAR>n</VAR> (modulus->integer +<VAR>modulus</VAR>))</CODE> in the representation specified by <VAR>modulus</VAR>. +</P> +</DL> +The rest of these functions assume normalized arguments; That is, the +arguments are constrained by the following table: +<P> + +For all of these functions, if the first argument (<VAR>modulus</VAR>) is: +</P> +<DL COMPACT> +<DT><CODE>positive?</CODE> +<DD>Work as before. The result is between 0 and <VAR>modulus</VAR>. +<P> + +</P> +<DT><CODE>zero?</CODE> +<DD>The arguments are treated as integers. An integer is returned. +<P> + +</P> +<DT><CODE>negative?</CODE> +<DD>The arguments and result are treated as members of the integers modulo +<CODE>(+ 1 (* -2 <VAR>modulus</VAR>))</CODE>, but with <EM>symmetric</EM> +<A NAME="IDX516"></A> +representation; i.e. <CODE>(<= (- <VAR>modulus</VAR>) <VAR>n</VAR> +<VAR>modulus</VAR>)</CODE>. +</DL> +<P> + +If all the arguments are fixnums the computation will use only fixnums. +</P> +<P> + +<A NAME="IDX517"></A> +</P> +<DL> +<DT><U>Function:</U> <B>modular:invertable?</B> <I>modulus k</I> +<DD><P> + +Returns <CODE>#t</CODE> if there exists an integer n such that <VAR>k</VAR> * n +== 1 mod <VAR>modulus</VAR>, and <CODE>#f</CODE> otherwise. +</P> +</DL> +<P> + +<A NAME="IDX518"></A> +</P> +<DL> +<DT><U>Function:</U> <B>modular:invert</B> <I>modulus n2</I> +<DD><P> + +Returns an integer n such that 1 = (n * <VAR>n2</VAR>) mod <VAR>modulus</VAR>. If +<VAR>n2</VAR> has no inverse mod <VAR>modulus</VAR> an error is signaled. +</P> +</DL> +<P> + +<A NAME="IDX519"></A> +</P> +<DL> +<DT><U>Function:</U> <B>modular:negate</B> <I>modulus n2</I> +<DD><P> + +Returns (-<VAR>n2</VAR>) mod <VAR>modulus</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX520"></A> +</P> +<DL> +<DT><U>Function:</U> <B>modular:+</B> <I>modulus n2 n3</I> +<DD><P> + +Returns (<VAR>n2</VAR> + <VAR>n3</VAR>) mod <VAR>modulus</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX521"></A> +</P> +<DL> +<DT><U>Function:</U> <B>modular:-</B> <I>modulus n2 n3</I> +<DD><P> + +Returns (<VAR>n2</VAR> - <VAR>n3</VAR>) mod <VAR>modulus</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX522"></A> +</P> +<DL> +<DT><U>Function:</U> <B>modular:*</B> <I>modulus n2 n3</I> +<DD><P> + +Returns (<VAR>n2</VAR> * <VAR>n3</VAR>) mod <VAR>modulus</VAR>. +</P> +<P> + +The Scheme code for <CODE>modular:*</CODE> with negative <VAR>modulus</VAR> is +not completed for fixnum-only implementations. +</P> +</DL> +<P> + +<A NAME="IDX523"></A> +</P> +<DL> +<DT><U>Function:</U> <B>modular:expt</B> <I>modulus n2 n3</I> +<DD><P> + +Returns (<VAR>n2</VAR> ^ <VAR>n3</VAR>) mod <VAR>modulus</VAR>. +</P> +</DL> +<P> + +<A NAME="Prime Numbers"></A> +<HR SIZE="6"> +<A NAME="SEC96"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC95"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC97"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.3 Prime Numbers </H2> +<!--docid::SEC96::--> +<P> + +<CODE>(require 'factor)</CODE> +<A NAME="IDX524"></A> +<A NAME="IDX525"></A> +</P> +<P> + +<A NAME="IDX526"></A> +</P> +<DL> +<DT><U>Variable:</U> <B>prime:prngs</B> +<DD><P> + +<VAR>prime:prngs</VAR> is the random-state (see section <A HREF="slib_5.html#SEC97">5.4 Random Numbers</A>) used by these +procedures. If you call these procedures from more than one thread +(or from interrupt), <CODE>random</CODE> may complain about reentrant +calls. +</P> +</DL> +<EM>Note:</EM> The prime test and generation procedures implement (or +use) the Solovay-Strassen primality test. See +<P> + +<UL> +<LI>Robert Solovay and Volker Strassen, +<CITE>A Fast Monte-Carlo Test for Primality</CITE>, +SIAM Journal on Computing, 1977, pp 84-85. +</UL> +<P> + +<A NAME="IDX527"></A> +</P> +<DL> +<DT><U>Function:</U> <B>jacobi-symbol</B> <I>p q</I> +<DD><P> + +Returns the value (+1, -1, or 0) of the Jacobi-Symbol of +exact non-negative integer <VAR>p</VAR> and exact positive odd integer <VAR>q</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX528"></A> +</P> +<DL> +<DT><U>Variable:</U> <B>prime:trials</B> +<DD><P> + +<VAR>prime:trials</VAR> the maxinum number of iterations of Solovay-Strassen that will +be done to test a number for primality. +</P> +</DL> +<P> + +<A NAME="IDX529"></A> +</P> +<DL> +<DT><U>Function:</U> <B>prime?</B> <I>n</I> +<DD><P> + +Returns <CODE>#f</CODE> if <VAR>n</VAR> is composite; <CODE>#t</CODE> if <VAR>n</VAR> is prime. +There is a slight chance <CODE>(expt 2 (- prime:trials))</CODE> that a +composite will return <CODE>#t</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX530"></A> +</P> +<DL> +<DT><U>Function:</U> <B>primes<</B> <I>start count</I> +<DD><P> + +Returns a list of the first <VAR>count</VAR> prime numbers less than +<VAR>start</VAR>. If there are fewer than <VAR>count</VAR> prime numbers +less than <VAR>start</VAR>, then the returned list will have fewer than +<VAR>start</VAR> elements. +</P> +</DL> +<P> + +<A NAME="IDX531"></A> +</P> +<DL> +<DT><U>Function:</U> <B>primes></B> <I>start count</I> +<DD><P> + +Returns a list of the first <VAR>count</VAR> prime numbers greater than <VAR>start</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX532"></A> +</P> +<DL> +<DT><U>Function:</U> <B>factor</B> <I>k</I> +<DD><P> + +Returns a list of the prime factors of <VAR>k</VAR>. The order of the +factors is unspecified. In order to obtain a sorted list do +<CODE>(sort! (factor <VAR>k</VAR>) <)</CODE>. +</P> +</DL> +<P> + +<A NAME="Random Numbers"></A> +<HR SIZE="6"> +<A NAME="SEC97"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC96"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC98"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.4 Random Numbers </H2> +<!--docid::SEC97::--> +<P> + +<A NAME="IDX533"></A> +<A NAME="IDX534"></A> +A pseudo-random number generator is only as good as the tests it passes. +George Marsaglia of Florida State University developed a battery of +tests named <EM>DIEHARD</EM> (<A HREF="http://stat.fsu.edu/~geo/diehard.html">http://stat.fsu.edu/~geo/diehard.html</A>). +`<TT>diehard.c</TT>' has a bug which the patch +<A HREF="http://swissnet.ai.mit.edu/ftpdir/users/jaffer/diehard.c.pat">http://swissnet.ai.mit.edu/ftpdir/users/jaffer/diehard.c.pat</A> corrects. +</P> +<P> + +SLIB's PRNG generates 8 bits at a time. With the degenerate seed +`<SAMP>0</SAMP>', the numbers generated pass DIEHARD; but when bits are +combined from sequential bytes, tests fail. With the seed +`<SAMP>http://swissnet.ai.mit.edu/~jaffer/SLIB.html</SAMP>', all of those +tests pass. +</P> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC98">5.4.1 Exact Random Numbers</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'random</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC99">5.4.2 Inexact Random Numbers</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'random-inexact</TD></TR> +</TABLE> +<P> + +<A NAME="Exact Random Numbers"></A> +<HR SIZE="6"> +<A NAME="SEC98"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC97"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC99"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC97"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.4.1 Exact Random Numbers </H3> +<!--docid::SEC98::--> +<P> + +<CODE>(require 'random)</CODE> +<A NAME="IDX535"></A> +</P> +<P> + +<A NAME="IDX536"></A> +</P> +<DL> +<DT><U>Function:</U> <B>random</B> <I>n state</I> +<DD><P> + +<A NAME="IDX537"></A> +<DT><U>Function:</U> <B>random</B> <I>n</I> +<DD></P> +<P> + +<VAR>n</VAR> must be an exact positive integer. <CODE>random</CODE> returns an exact integer +between zero (inclusive) and <VAR>n</VAR> (exclusive). The values returned by +<CODE>random</CODE> are uniformly distributed from 0 to <VAR>n</VAR>. +</P> +<P> + +The optional argument <VAR>state</VAR> must be of the type returned by +<CODE>(seed->random-state)</CODE> or <CODE>(make-random-state)</CODE>. It +defaults to the value of the variable <CODE>*random-state*</CODE>. This +object is used to maintain the state of the pseudo-random-number +generator and is altered as a side effect of calls to <CODE>random</CODE>. +</P> +</DL> +<A NAME="IDX538"></A> +<DL> +<DT><U>Variable:</U> <B>*random-state*</B> +<DD>Holds a data structure that encodes the internal state of the +random-number generator that <CODE>random</CODE> uses by default. The nature +of this data structure is implementation-dependent. It may be printed +out and successfully read back in, but may or may not function correctly +as a random-number state object in another implementation. +</DL> +<P> + +<A NAME="IDX539"></A> +</P> +<DL> +<DT><U>Function:</U> <B>copy-random-state</B> <I>state</I> +<DD><P> + +Returns a new copy of argument <VAR>state</VAR>. +</P> +<P> + +<A NAME="IDX540"></A> +<DT><U>Function:</U> <B>copy-random-state</B> +<DD>Returns a new copy of <CODE>*random-state*</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX541"></A> +</P> +<DL> +<DT><U>Function:</U> <B>seed->random-state</B> <I>seed</I> +<DD><P> + +Returns a new object of type suitable for use as the value of the +variable <CODE>*random-state*</CODE> or as a second argument to <CODE>random</CODE>. +The number or string <VAR>seed</VAR> is used to initialize the state. If +<CODE>seed->random-state</CODE> is called twice with arguments which are +<CODE>equal?</CODE>, then the returned data structures will be <CODE>equal?</CODE>. +Calling <CODE>seed->random-state</CODE> with unequal arguments will nearly +always return unequal states. +</P> +</DL> +<P> + +<A NAME="IDX542"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-random-state</B> +<DD><P> + +<A NAME="IDX543"></A> +<DT><U>Function:</U> <B>make-random-state</B> <I>obj</I> +<DD>Returns a new object of type suitable for use as the value of the +variable <CODE>*random-state*</CODE> or as a second argument to <CODE>random</CODE>. +If the optional argument <VAR>obj</VAR> is given, it should be a printable +Scheme object; the first 50 characters of its printed representation +will be used as the seed. Otherwise the value of <CODE>*random-state*</CODE> +is used as the seed. +</P> +</DL> +<P> + +<A NAME="Inexact Random Numbers"></A> +<HR SIZE="6"> +<A NAME="SEC99"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC98"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC100"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC97"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.4.2 Inexact Random Numbers </H3> +<!--docid::SEC99::--> +<P> + +<CODE>(require 'random-inexact)</CODE> +<A NAME="IDX544"></A> +</P> +<P> + +<A NAME="IDX545"></A> +</P> +<DL> +<DT><U>Function:</U> <B>random:uniform</B> +<DD><P> + +<A NAME="IDX546"></A> +<DT><U>Function:</U> <B>random:uniform</B> <I>state</I> +<DD>Returns an uniformly distributed inexact real random number in the +range between 0 and 1. +</P> +</DL> +<P> + +<A NAME="IDX547"></A> +</P> +<DL> +<DT><U>Function:</U> <B>random:exp</B> +<DD><P> + +<A NAME="IDX548"></A> +<DT><U>Function:</U> <B>random:exp</B> <I>state</I> +<DD>Returns an inexact real in an exponential distribution with mean 1. For +an exponential distribution with mean <VAR>u</VAR> use +<CODE>(* <VAR>u</VAR> (random:exp))</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX549"></A> +</P> +<DL> +<DT><U>Function:</U> <B>random:normal</B> +<DD><P> + +<A NAME="IDX550"></A> +<DT><U>Function:</U> <B>random:normal</B> <I>state</I> +<DD>Returns an inexact real in a normal distribution with mean 0 and +standard deviation 1. For a normal distribution with mean <VAR>m</VAR> and +standard deviation <VAR>d</VAR> use +<CODE>(+ <VAR>m</VAR> (* <VAR>d</VAR> (random:normal)))</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX551"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>random:normal-vector!</B> <I>vect</I> +<DD><P> + +<A NAME="IDX552"></A> +<DT><U>Procedure:</U> <B>random:normal-vector!</B> <I>vect state</I> +<DD>Fills <VAR>vect</VAR> with inexact real random numbers which are independent +and standard normally distributed (i.e., with mean 0 and variance 1). +</P> +</DL> +<P> + +<A NAME="IDX553"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>random:hollow-sphere!</B> <I>vect</I> +<DD><P> + +<A NAME="IDX554"></A> +<DT><U>Procedure:</U> <B>random:hollow-sphere!</B> <I>vect state</I> +<DD>Fills <VAR>vect</VAR> with inexact real random numbers the sum of whose +squares is equal to 1.0. Thinking of <VAR>vect</VAR> as coordinates in space +of dimension n = <CODE>(vector-length <VAR>vect</VAR>)</CODE>, the coordinates are +uniformly distributed over the surface of the unit n-shere. +</P> +</DL> +<P> + +<A NAME="IDX555"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>random:solid-sphere!</B> <I>vect</I> +<DD><P> + +<A NAME="IDX556"></A> +<DT><U>Procedure:</U> <B>random:solid-sphere!</B> <I>vect state</I> +<DD>Fills <VAR>vect</VAR> with inexact real random numbers the sum of whose +squares is less than 1.0. Thinking of <VAR>vect</VAR> as coordinates in +space of dimension <VAR>n</VAR> = <CODE>(vector-length <VAR>vect</VAR>)</CODE>, the +coordinates are uniformly distributed within the unit <VAR>n</VAR>-shere. +The sum of the squares of the numbers is returned. +</P> +</DL> +<P> + +<A NAME="Fast Fourier Transform"></A> +<HR SIZE="6"> +<A NAME="SEC100"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC99"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC101"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.5 Fast Fourier Transform </H2> +<!--docid::SEC100::--> +<P> + +<CODE>(require 'fft)</CODE> +<A NAME="IDX557"></A> +</P> +<P> + +<A NAME="IDX558"></A> +</P> +<DL> +<DT><U>Function:</U> <B>fft</B> <I>array</I> +<DD><P> + +<VAR>array</VAR> is an array of <CODE>(expt 2 n)</CODE> numbers. <CODE>fft</CODE> +returns an array of complex numbers comprising the +<EM>Discrete Fourier Transform</EM> of <VAR>array</VAR>. +<A NAME="IDX559"></A> +</P> +</DL> +<P> + +<A NAME="IDX560"></A> +</P> +<DL> +<DT><U>Function:</U> <B>fft-1</B> <I>array</I> +<DD><P> + +<CODE>fft-1</CODE> returns an array of complex numbers comprising the +inverse Discrete Fourier Transform of <VAR>array</VAR>. +</P> +</DL> +<CODE>(fft-1 (fft <VAR>array</VAR>))</CODE> will return an array of values close to +<VAR>array</VAR>. +<P> + +<TABLE><tr><td> </td><td class=example><pre>(fft '#(1 0+i -1 0-i 1 0+i -1 0-i)) => + +#(0.0 0.0 0.0+628.0783185208527e-18i 0.0 + 0.0 0.0 8.0-628.0783185208527e-18i 0.0) + +(fft-1 '#(0 0 0 0 0 0 8 0)) => + +#(1.0 -61.23031769111886e-18+1.0i -1.0 61.23031769111886e-18-1.0i + 1.0 -61.23031769111886e-18+1.0i -1.0 61.23031769111886e-18-1.0i) +</pre></td></tr></table><P> + +<A NAME="Cyclic Checksum"></A> +<HR SIZE="6"> +<A NAME="SEC101"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC100"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC102"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.6 Cyclic Checksum </H2> +<!--docid::SEC101::--> +<P> + +<CODE>(require 'crc)</CODE> +<A NAME="IDX561"></A> +Cyclic Redundancy Checks using Galois field GF(2) polynomial +arithmetic are used for error detection in many data transmission +and storage applications. +</P> +<P> + +The generator polynomials for various CRC protocols are availble +from many sources. But the polynomial is just one of many +parameters which must match in order for a CRC implementation to +interoperate with existing systems: +</P> +<P> + +<UL> + +<LI> +the byte-order and bit-order of the data stream; +<P> + +</P> +<LI> +whether the CRC or its inverse is being calculated; +<P> + +</P> +<LI> +the initial CRC value; and +<P> + +</P> +<LI> +whether and where the CRC value is appended (inverted +or non-inverted) to the data stream. +<P> + +</UL> +<P> + +There is even some controversy over the polynomials themselves. +</P> +<P> + +<A NAME="IDX562"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>crc-32-polynomial</B> +<DD>For CRC-32, http://www2.sis.pitt.edu/~jkabara/tele-2100/lect08.html +gives x^32+x^26+x^23+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+1. +<P> + +But +http://www.cs.ncl.ac.uk/people/harry.whitfield/home.formal/CRCs.html, +http://duchon.umuc.edu/Web_Pages/duchon/99_f_cm435/ShiftRegister.htm, +http://spinroot.com/spin/Doc/Book91_PDF/ch3.pdf, +http://www.erg.abdn.ac.uk/users/gorry/course/dl-pages/crc.html, +http://www.rad.com/networks/1994/err_con/crc_most.htm, and +http://www.gpfn.sk.ca/~rhg/csc8550s02/crc.html, +http://www.nobugconsulting.ro/crc.php give +x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. +</P> +<P> + +SLIB <CODE>crc-32-polynomial</CODE> uses the latter definition. +</P> +</DL> +<P> + +<A NAME="IDX563"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>crc-ccitt-polynomial</B> +<DD><P> + +http://www.math.grin.edu/~rebelsky/Courses/CS364/2000S/Outlines/outline.12.html, +http://duchon.umuc.edu/Web_Pages/duchon/99_f_cm435/ShiftRegister.htm, +http://www.cs.ncl.ac.uk/people/harry.whitfield/home.formal/CRCs.html, +http://www2.sis.pitt.edu/~jkabara/tele-2100/lect08.html, and +http://www.gpfn.sk.ca/~rhg/csc8550s02/crc.html give +CRC-CCITT: x^16+x^12+x^5+1. +</P> +</DL> +<P> + +<A NAME="IDX564"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>crc-16-polynomial</B> +<DD><P> + +http://www.math.grin.edu/~rebelsky/Courses/CS364/2000S/Outlines/outline.12.html, +http://duchon.umuc.edu/Web_Pages/duchon/99_f_cm435/ShiftRegister.htm, +http://www.cs.ncl.ac.uk/people/harry.whitfield/home.formal/CRCs.html, +http://www.gpfn.sk.ca/~rhg/csc8550s02/crc.html, and +http://www.usb.org/developers/data/crcdes.pdf give +CRC-16: x^16+x^15+x^2+1. +</P> +</DL> +<P> + +<A NAME="IDX565"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>crc-12-polynomial</B> +<DD><P> + +http://www.math.grin.edu/~rebelsky/Courses/CS364/2000S/Outlines/outline.12.html, +http://www.cs.ncl.ac.uk/people/harry.whitfield/home.formal/CRCs.html, +http://www.it.iitb.ac.in/it605/lectures/link/node4.html, and +http://spinroot.com/spin/Doc/Book91_PDF/ch3.pdf give +CRC-12: x^12+x^11+x^3+x^2+1. +</P> +<P> + +But +http://www.ffldusoe.edu/Faculty/Denenberg/Topics/Networks/Error_Detection_Correction/crc.html, +http://duchon.umuc.edu/Web_Pages/duchon/99_f_cm435/ShiftRegister.htm, +http://www.eng.uwi.tt/depts/elec/staff/kimal/errorcc.html, +http://www.ee.uwa.edu.au/~roberto/teach/itc314/java/CRC/, +http://www.gpfn.sk.ca/~rhg/csc8550s02/crc.html, and +http://www.efg2.com/Lab/Mathematics/CRC.htm give +CRC-12: x^12+x^11+x^3+x^2+x+1. +</P> +<P> + +These differ in bit 1 and calculations using them return different +values. With citations near evenly split, it is hard to know which is +correct. +</P> +</DL> +<P> + +<A NAME="IDX566"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>crc-10-polynomial</B> +<DD><P> + +http://www.math.grin.edu/~rebelsky/Courses/CS364/2000S/Outlines/outline.12.html gives +CRC-10: x^10+x^9+x^5+x^4+1; +but +http://cell-relay.indiana.edu/cell-relay/publications/software/CRC/crc10.html, +http://www.it.iitb.ac.in/it605/lectures/link/node4.html, +http://www.gpfn.sk.ca/~rhg/csc8550s02/crc.html, +http://www.techfest.com/networking/atm/atm.htm, +http://www.protocols.com/pbook/atmcell2.htm, and +http://www.nobugconsulting.ro/crc.php give +CRC-10: x^10+x^9+x^5+x^4+x+1. +</P> +</DL> +<P> + +<A NAME="IDX567"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>crc-08-polynomial</B> +<DD><P> + +http://www.math.grin.edu/~rebelsky/Courses/CS364/2000S/Outlines/outline.12.html, +http://www.cs.ncl.ac.uk/people/harry.whitfield/home.formal/CRCs.html, +http://www.it.iitb.ac.in/it605/lectures/link/node4.html, and +http://www.nobugconsulting.ro/crc.php give +CRC-8: x^8+x^2+x^1+1 +</P> +</DL> +<P> + +<A NAME="IDX568"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>atm-hec-polynomial</B> +<DD><P> + +http://cell-relay.indiana.edu/cell-relay/publications/software/CRC/32bitCRC.tutorial.html and +http://www.gpfn.sk.ca/~rhg/csc8550s02/crc.html give +ATM HEC: x^8+x^2+x+1. +</P> +</DL> +<P> + +<A NAME="IDX569"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>dowcrc-polynomial</B> +<DD><P> + +http://www.cs.ncl.ac.uk/people/harry.whitfield/home.formal/CRCs.html gives +DOWCRC: x^8+x^5+x^4+1. +</P> +</DL> +<P> + +<A NAME="IDX570"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>usb-token-polynomial</B> +<DD><P> + +http://www.usb.org/developers/data/crcdes.pdf and +http://www.nobugconsulting.ro/crc.php give +USB-token: x^5+x^2+1. +</P> +</DL> +<P> + +Each of these polynomial constants is a string of `<SAMP>1</SAMP>'s and +`<SAMP>0</SAMP>'s, the exponent of each power of <VAR>x</VAR> in descending order. +</P> +<P> + +<A NAME="IDX571"></A> +</P> +<DL> +<DT><U>Function:</U> <B>crc:make-table</B> <I>poly</I> +<DD><P> + +<VAR>poly</VAR> must be string of `<SAMP>1</SAMP>'s and `<SAMP>0</SAMP>'s beginning with +`<SAMP>1</SAMP>' and having length greater than 8. <CODE>crc:make-table</CODE> +returns a vector of 256 integers, such that: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(set! <VAR>crc</VAR> + (logxor (ash (logand (+ -1 (ash 1 (- <VAR>deg</VAR> 8))) <VAR>crc</VAR>) 8) + (vector-ref <VAR>crc-table</VAR> + (logxor (ash <VAR>crc</VAR> (- 8 <VAR>deg</VAR>)) <VAR>byte</VAR>)))) +</pre></td></tr></table><P> + +will compute the <VAR>crc</VAR> with the 8 additional bits in <VAR>byte</VAR>; +where <VAR>crc</VAR> is the previous accumulated CRC value, <VAR>deg</VAR> is +the degree of <VAR>poly</VAR>, and <VAR>crc-table</VAR> is the vector returned +by <CODE>crc:make-table</CODE>. +</P> +<P> + +If the implementation does not support <VAR>deg</VAR>-bit integers, then +<CODE>crc:make-table</CODE> returns #f. +</P> +<P> + +</P> +</DL> +<P> + +<A NAME="IDX572"></A> +</P> +<DL> +<DT><U>Function:</U> <B>cksum</B> <I>file</I> +<DD><P> + +Computes the P1003.2/D11.2 (POSIX.2) 32-bit checksum of <VAR>file</VAR>. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'crc) +<A NAME="IDX573"></A>(cksum (in-vicinity (library-vicinity) "ratize.scm")) +=> 157103930 +</pre></td></tr></table><P> + +<A NAME="IDX574"></A> +<DT><U>Function:</U> <B>cksum</B> <I>port</I> +<DD>Computes the checksum of the bytes read from <VAR>port</VAR> until the +end-of-file. +</P> +<P> + +</P> +</DL> +<P> + +<A NAME="IDX575"></A> +<CODE>cksum-string</CODE>, which returns the P1003.2/D11.2 (POSIX.2) 32-bit +checksum of the bytes in <VAR>str</VAR>, can be defined as follows: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'string-port) +(define (cksum-string str) (call-with-input-string str cksum)) +</pre></td></tr></table><P> + +<A NAME="IDX576"></A> +</P> +<DL> +<DT><U>Function:</U> <B>crc16</B> <I>file</I> +<DD><P> + +Computes the USB data-packet (16-bit) CRC of <VAR>file</VAR>. +</P> +<P> + +<A NAME="IDX577"></A> +<DT><U>Function:</U> <B>crc16</B> <I>port</I> +<DD>Computes the USB data-packet (16-bit) CRC of the bytes read from +<VAR>port</VAR> until the end-of-file. +</P> +<P> + +<CODE>crc16</CODE> calculates the same values as the crc16.pl program given +in http://www.usb.org/developers/data/crcdes.pdf. +</P> +<P> + +</P> +</DL> +<P> + +<A NAME="IDX578"></A> +</P> +<DL> +<DT><U>Function:</U> <B>crc5</B> <I>file</I> +<DD><P> + +Computes the USB token (5-bit) CRC of <VAR>file</VAR>. +</P> +<P> + +<A NAME="IDX579"></A> +<DT><U>Function:</U> <B>crc5</B> <I>port</I> +<DD>Computes the USB token (5-bit) CRC of the bytes read from +<VAR>port</VAR> until the end-of-file. +</P> +<P> + +<CODE>crc5</CODE> calculates the same values as the crc5.pl program given +in http://www.usb.org/developers/data/crcdes.pdf. +</P> +<P> + +</P> +</DL> +<P> + +<A NAME="Graphing"></A> +<HR SIZE="6"> +<A NAME="SEC102"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC101"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC103"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.7 Graphing </H2> +<!--docid::SEC102::--> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC103">5.7.1 Character Plotting</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC104">5.7.2 PostScript Graphing</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +</TABLE> +<P> + +<A NAME="Character Plotting"></A> +<HR SIZE="6"> +<A NAME="SEC103"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC102"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC104"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC102"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.7.1 Character Plotting </H3> +<!--docid::SEC103::--> +<P> + +<CODE>(require 'charplot)</CODE> +<A NAME="IDX580"></A> +</P> +<P> + +<A NAME="IDX581"></A> +</P> +<DL> +<DT><U>Variable:</U> <B>charplot:dimensions</B> +<DD>A list of the maximum height (number of lines) and maximum width (number +of columns) for the graph, its scales, and labels. +<P> + +The default value for <VAR>charplot:dimensions</VAR> is the +<CODE>output-port-height</CODE> and <CODE>output-port-width</CODE> of +<CODE>current-output-port</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX582"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>plot</B> <I>coords x-label y-label</I> +<DD><VAR>coords</VAR> is a list or vector of coordinates, lists of x and y +coordinates. <VAR>x-label</VAR> and <VAR>y-label</VAR> are strings with which to +label the x and y axes. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(require 'charplot) +<A NAME="IDX583"></A>(set! charplot:dimensions '(20 55)) + +(define (make-points n) + (if (zero? n) + '() + (cons (list (/ n 6) (sin (/ n 6))) (make-points (1- n))))) + +(plot (make-points 40) "x" "Sin(x)") +-| + Sin(x) _________________________________________ + 1|- **** | + | ** ** | + 0.75|- * * | + | * * | + 0.5|- * * | + | * *| + 0.25|- * * | + | * * | + 0|-------------------*------------------*--| + | * | + -0.25|- * * | + | * * | + -0.5|- * | + | * * | + -0.75|- * * | + | ** ** | + -1|- **** | + |:_____._____:_____._____:_____._____:____| + x 2 4 6 +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX584"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>plot</B> <I>func x1 x2</I> +<DD><A NAME="IDX585"></A> +<DT><U>Procedure:</U> <B>plot</B> <I>func x1 x2 npts</I> +<DD>Plots the function of one argument <VAR>func</VAR> over the range <VAR>x1</VAR> to +<VAR>x2</VAR>. If the optional integer argument <VAR>npts</VAR> is supplied, it +specifies the number of points to evaluate <VAR>func</VAR> at. +<P> + +<TABLE><tr><td> </td><td class=example><pre>(plot sin 0 (* 2 pi)) +-| + _________________________________________ + 1|-: **** | + | : ** ** | + 0.75|-: * * | + | : * * | + 0.5|-: ** ** | + | : * * | + 0.25|-:** ** | + | :* * | + 0|-*------------------*--------------------| + | : * * | + -0.25|-: ** ** | + | : * * | + -0.5|-: * ** | + | : * * | + -0.75|-: * ** | + | : ** ** | + -1|-: **** | + |_:_____._____:_____._____:_____._____:___| + 0 2 4 6 +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX586"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>histograph</B> <I>data label</I> +<DD>Creates and displays a histogram of the numerical values contained in +vector or list <VAR>data</VAR> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'random-inexact) +(histograph (do ((idx 99 (+ -1 idx)) + (lst '() (cons (* .02 (random:normal)) lst))) + ((negative? idx) lst)) + "normal") +-| + _________________________________________ + 8|- : I | + | : I | + 7|- I I : I | + | I I : I | + 6|- III I :I I | + | III I :I I | + 5|- IIIIIIIIII I | + | IIIIIIIIII I | + 4|- IIIIIIIIIIII | + | IIIIIIIIIIII | + 3|-I I I IIIIIIIIIIII II I | + | I I I IIIIIIIIIIII II I | + 2|-I I I IIIIIIIIIIIIIIIII I | + | I I I IIIIIIIIIIIIIIIII I | + 1|-II I I IIIIIIIIIIIIIIIIIIIII I I I | + | II I I IIIIIIIIIIIIIIIIIIIII I I I | + 0|-IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII----| + |__.____:____.____:____.____:____.____:___| + normal -0.025 0 0.025 0.05 +</pre></td></tr></table></DL> +<P> + +<A NAME="PostScript Graphing"></A> +<HR SIZE="6"> +<A NAME="SEC104"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC103"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC105"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC102"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.7.2 PostScript Graphing </H3> +<!--docid::SEC104::--> +<P> + +<CODE>(require 'eps-graph)</CODE> +</P> +<P> + +This is a graphing package creating encapsulated-PostScript files. +Its motivations and design choice are described in +<A HREF="http://swissnet.ai.mit.edu/~jaffer/Docupage/grapheps">http://swissnet.ai.mit.edu/~jaffer/Docupage/grapheps</A> +</P> +<P> + +A dataset to be plotted is taken from a 2-dimensional array. +Corresponding coordinates are in rows. Coordinates from any +pair of columns can be plotted. +</P> +<P> + +<A NAME="IDX587"></A> +</P> +<DL> +<DT><U>Function:</U> <B>create-postscript-graph</B> <I>filename.eps size elt1 <small>...</small></I> +<DD><P> + +<VAR>filename.eps</VAR> should be a string naming an output file to be created. <VAR>size</VAR> +should be an exact integer, a list of two exact integers, or #f. +<VAR>elt1</VAR>, ... are values returned by graphing primitives described here. +</P> +<P> + +<CODE>create-postscript-graph</CODE> creates an <EM>Encapsulated-PostScript</EM> file named <VAR>filename.eps</VAR> containing +<A NAME="IDX588"></A> +graphs as directed by the <VAR>elt1</VAR>, ... arguments. +</P> +<P> + +The size of the graph is determined by the <VAR>size</VAR> argument. If a list +of two integers, they specify the width and height. If one integer, +then that integer is the width and the height is 3/4 of the width. +If #f, the graph will be 800 by 600. +</P> +</DL> +These graphing procedures should be called as arguments to +<CODE>create-postscript-graph</CODE>. The order of these arguments is +significant; PostScript graphics state is affected serially from the +first <VAR>elt</VAR> argument to the last. +<P> + +<A NAME="IDX589"></A> +</P> +<DL> +<DT><U>Function:</U> <B>whole-page</B> +<DD><P> + +Pushes a rectangle for the whole encapsulated page onto the +PostScript stack. This pushed rectangle is an implicit argument to +<CODE>partition-page</CODE> or <CODE>setup-plot</CODE>. +</P> +</DL> +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC105">5.7.2.1 Column Ranges</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC106">5.7.2.2 Drawing the Graph</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC107">5.7.2.3 Graphics Context</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC108">5.7.2.4 Rectangles</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC109">5.7.2.5 Legending</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC110">5.7.2.6 Legacy Plotting</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC111">5.7.2.7 Example Graph</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +</TABLE> +<P> + +<A NAME="Column Ranges"></A> +<HR SIZE="6"> +<A NAME="SEC105"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC104"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC106"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC104"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 5.7.2.1 Column Ranges </H4> +<!--docid::SEC105::--> +<P> + +A <EM>range</EM> is a list of two numbers, the minimum and the maximum. +<A NAME="IDX590"></A> +<A NAME="IDX591"></A> +Ranges can be given explicity or computed in PostScript by +<CODE>column-range</CODE>. +</P> +<P> + +<A NAME="IDX592"></A> +</P> +<DL> +<DT><U>Function:</U> <B>column-range</B> <I>array k</I> +<DD><P> + +Returns the range of values in 2-dimensional <VAR>array</VAR> column <VAR>k</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX593"></A> +</P> +<DL> +<DT><U>Function:</U> <B>pad-range</B> <I>range p</I> +<DD><P> + +Expands <VAR>range</VAR> by <VAR>p</VAR>/100 on each end. +</P> +</DL> +<P> + +<A NAME="IDX594"></A> +</P> +<DL> +<DT><U>Function:</U> <B>snap-range</B> <I>range</I> +<DD><P> + +Expands <VAR>range</VAR> to round number of ticks. +</P> +</DL> +<P> + +<A NAME="IDX595"></A> +</P> +<DL> +<DT><U>Function:</U> <B>combine-ranges</B> <I>range1 range2 <small>...</small></I> +<DD><P> + +Returns the minimal range covering all <VAR>range1</VAR>, <VAR>range2</VAR>, ... +</P> +</DL> +<P> + +<A NAME="IDX596"></A> +</P> +<DL> +<DT><U>Function:</U> <B>setup-plot</B> <I>x-range y-range pagerect</I> +<DD><P> + +<A NAME="IDX597"></A> +<DT><U>Function:</U> <B>setup-plot</B> <I>x-range y-range</I> +<DD><VAR>x-range</VAR> and <VAR>y-range</VAR> should each be a list of two numbers or the value returned +by <CODE>pad-range</CODE>, <CODE>snap-range</CODE>, or <CODE>combine-range</CODE>. +<VAR>pagerect</VAR> is the rectangle bounding the graph to be drawn; if missing, the +rectangle from the top of the PostScript stack is popped and used. +</P> +<P> + +Based on the given ranges, <CODE>setup-plot</CODE> sets up scaling and margins for making +a graph. The margins are sized proportional to the <VAR>fontheight</VAR> +value at the time of the call to setup-plot. <CODE>setup-plot</CODE> sets two variables: +</P> +<P> + +</P> +<DL COMPACT> +<DT><VAR>plotrect</VAR> +<DD>The region where data points will be plotted. +<DT><VAR>graphrect</VAR> +<DD>The <VAR>pagerect</VAR> argument to <CODE>setup-plot</CODE>. Includes plotrect, legends, etc. +</DL> +</DL> +<A NAME="Drawing the Graph"></A> +<HR SIZE="6"> +<A NAME="SEC106"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC105"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC107"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC104"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 5.7.2.2 Drawing the Graph </H4> +<!--docid::SEC106::--> +<P> + +<A NAME="IDX598"></A> +</P> +<DL> +<DT><U>Function:</U> <B>plot-column</B> <I>array x-column y-column proc3s</I> +<DD><P> + +Plots points with x coordinate in <VAR>x-column</VAR> of <VAR>array</VAR> and y coordinate <VAR>y-column</VAR> of +<VAR>array</VAR>. The symbol <VAR>proc3s</VAR> specifies the type of glyph or drawing style for +presenting these coordinates. +</P> +</DL> +The glyphs and drawing styles available are: +<P> + +</P> +<DL COMPACT> +<DT><CODE>line</CODE> +<DD>Draws line connecting points in order. +<DT><CODE>mountain</CODE> +<DD>Fill area below line connecting points. +<DT><CODE>cloud</CODE> +<DD>Fill area above line connecting points. +<DT><CODE>impulse</CODE> +<DD>Draw line from x-axis to each point. +<DT><CODE>bargraph</CODE> +<DD>Draw rectangle from x-axis to each point. +<DT><CODE>disc</CODE> +<DD>Solid round dot. +<DT><CODE>point</CODE> +<DD>Minimal point -- invisible if linewidth is 0. +<DT><CODE>square</CODE> +<DD>Square box. +<DT><CODE>diamond</CODE> +<DD>Square box at 45.o +<DT><CODE>plus</CODE> +<DD>Plus sign. +<DT><CODE>cross</CODE> +<DD>X sign. +<DT><CODE>triup</CODE> +<DD>Triangle pointing upward +<DT><CODE>tridown</CODE> +<DD>Triangle pointing downward +<DT><CODE>pentagon</CODE> +<DD>Five sided polygon +<DT><CODE>circle</CODE> +<DD>Hollow circle +</DL> +<P> + +<A NAME="Graphics Context"></A> +<HR SIZE="6"> +<A NAME="SEC107"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC106"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC108"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC104"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 5.7.2.3 Graphics Context </H4> +<!--docid::SEC107::--> +<P> + +<A NAME="IDX599"></A> +</P> +<DL> +<DT><U>Function:</U> <B>in-graphic-context</B> <I>arg <small>...</small></I> +<DD><P> + +Saves the current graphics state, executes <VAR>args</VAR>, then restores +to saved graphics state. +</P> +</DL> +<P> + +<A NAME="IDX600"></A> +</P> +<DL> +<DT><U>Function:</U> <B>set-color</B> <I>color</I> +<DD><P> + +<VAR>color</VAR> should be a string naming a Resene color, a saturate color, or a +number between 0 and 100. +</P> +<P> + +<CODE>set-color</CODE> sets the PostScript color to the color of the given string, or a +grey value between black (0) and white (100). +</P> +</DL> +<P> + +<A NAME="IDX601"></A> +</P> +<DL> +<DT><U>Function:</U> <B>set-font</B> <I>name fontheight</I> +<DD><P> + +<VAR>name</VAR> should be a (case-sensitive) string naming a PostScript font. +<VAR>fontheight</VAR> should be a positive real number. +</P> +<P> + +<CODE>set-font</CODE> Changes the current PostScript font to <VAR>name</VAR> with height equal to +<VAR>fontheight</VAR>. The default font is Helvetica (12pt). +</P> +</DL> +The base set of PostScript fonts is: +<P> + +</P> +<TABLE> +<TR><TD>Times </TD><TD> Times-Italic </TD><TD> Times-Bold </TD><TD> Times-BoldItalic</TD> +</TR> +<TR><TD>Helvetica </TD><TD> Helvetica-Oblique </TD><TD> Helvetica-Bold </TD><TD> Helvetica-BoldOblique</TD> +</TR> +<TR><TD>Courier </TD><TD> Courier-Oblique </TD><TD> Courier-Bold </TD><TD> Courier-BoldOblique</TD> +</TR> +<TR><TD>Symbol</TD> +</TR></TABLE> +<P> + +Line parameters do no affect fonts; they do effect glyphs. +</P> +<P> + +<A NAME="IDX602"></A> +</P> +<DL> +<DT><U>Function:</U> <B>set-linewidth</B> <I>w</I> +<DD><P> + +The default linewidth is 1. Setting it to 0 makes the lines drawn +as skinny as possible. Linewidth must be much smaller than +glyphsize for readable glyphs. +</P> +</DL> +<P> + +<A NAME="IDX603"></A> +</P> +<DL> +<DT><U>Function:</U> <B>set-linedash</B> <I>j k</I> +<DD><P> + +Lines are drawn <VAR>j</VAR>-on <VAR>k</VAR>-off. +</P> +<P> + +<A NAME="IDX604"></A> +<DT><U>Function:</U> <B>set-linedash</B> <I>j</I> +<DD>Lines are drawn <VAR>j</VAR>-on <VAR>j</VAR>-off. +</P> +<P> + +<A NAME="IDX605"></A> +<DT><U>Function:</U> <B>set-linedash</B> +<DD>Turns off dashing. +</P> +</DL> +<P> + +<A NAME="IDX606"></A> +</P> +<DL> +<DT><U>Function:</U> <B>set-glyphsize</B> <I>w</I> +<DD><P> + +Sets the (PostScript) variable glyphsize to <VAR>w</VAR>. The default +glyphsize is 6. +</P> +</DL> +The effects of <CODE>clip-to-rect</CODE> are also part of the graphic +context. +<P> + +<A NAME="Rectangles"></A> +<HR SIZE="6"> +<A NAME="SEC108"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC107"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC109"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC104"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 5.7.2.4 Rectangles </H4> +<!--docid::SEC108::--> +<P> + +A <EM>rectangle</EM> is a list of 4 numbers; the first two elements are +<A NAME="IDX607"></A> +the x and y coordinates of lower left corner of the rectangle. The +other two elements are the width and height of the rectangle. +</P> +<P> + +<A NAME="IDX608"></A> +</P> +<DL> +<DT><U>Function:</U> <B>whole-page</B> +<DD><P> + +Pushes a rectangle for the whole encapsulated page onto the +PostScript stack. This pushed rectangle is an implicit argument to +<CODE>partition-page</CODE> or <CODE>setup-plot</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX609"></A> +</P> +<DL> +<DT><U>Function:</U> <B>partition-page</B> <I>xparts yparts</I> +<DD><P> + +Pops the rectangle currently on top of the stack and pushes <VAR>xparts</VAR> * <VAR>yparts</VAR> +sub-rectangles onto the stack in decreasing y and increasing x order. +If you are drawing just one graph, then you don't need <CODE>partition-page</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX610"></A> +</P> +<DL> +<DT><U>Variable:</U> <B>plotrect</B> +<DD><P> + +The rectangle where data points should be plotted. <VAR>plotrect</VAR> is set by +<CODE>setup-plot</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX611"></A> +</P> +<DL> +<DT><U>Variable:</U> <B>graphrect</B> +<DD><P> + +The <VAR>pagerect</VAR> argument of the most recent call to +<CODE>setup-plot</CODE>. Includes plotrect, legends, etc. +</P> +</DL> +<P> + +<A NAME="IDX612"></A> +</P> +<DL> +<DT><U>Function:</U> <B>fill-rect</B> <I>rect</I> +<DD><P> + +fills <VAR>rect</VAR> with the current color. +</P> +</DL> +<P> + +<A NAME="IDX613"></A> +</P> +<DL> +<DT><U>Function:</U> <B>outline-rect</B> <I>rect</I> +<DD><P> + +Draws the perimiter of <VAR>rect</VAR> in the current color. +</P> +</DL> +<P> + +<A NAME="IDX614"></A> +</P> +<DL> +<DT><U>Function:</U> <B>clip-to-rect</B> <I>rect</I> +<DD><P> + +Modifies the current graphics-state so that nothing will be drawn +outside of the rectangle <VAR>rect</VAR>. Use <CODE>in-graphic-context</CODE> to limit +the extent of <CODE>clip-to-rect</CODE>. +</P> +</DL> +<A NAME="Legending"></A> +<HR SIZE="6"> +<A NAME="SEC109"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC108"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC110"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC104"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 5.7.2.5 Legending </H4> +<!--docid::SEC109::--> +<P> + +<A NAME="IDX615"></A> +</P> +<DL> +<DT><U>Function:</U> <B>title-top</B> <I>title subtitle</I> +<DD><P> + +<A NAME="IDX616"></A> +<DT><U>Function:</U> <B>title-top</B> <I>title</I> +<DD>Puts a <VAR>title</VAR> line and an optional <VAR>subtitle</VAR> line above the <CODE>graphrect</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX617"></A> +</P> +<DL> +<DT><U>Function:</U> <B>title-bottom</B> <I>title subtitle</I> +<DD><P> + +<A NAME="IDX618"></A> +<DT><U>Function:</U> <B>title-bottom</B> <I>title</I> +<DD>Puts a <VAR>title</VAR> line and an optional <VAR>subtitle</VAR> line below the <CODE>graphrect</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX619"></A> +</P> +<DL> +<DT><U>Variable:</U> <B>topedge</B> +<DD><A NAME="IDX620"></A> +<DT><U>Variable:</U> <B>bottomedge</B> +<DD><P> + +These edge coordinates of <CODE>graphrect</CODE> are suitable for passing +as the first argument to <CODE>rule-horizontal</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX621"></A> +</P> +<DL> +<DT><U>Variable:</U> <B>leftedge</B> +<DD><A NAME="IDX622"></A> +<DT><U>Variable:</U> <B>rightedge</B> +<DD><P> + +These edge coordinates of <CODE>graphrect</CODE> are suitable for passing +as the first argument to <CODE>rule-vertical</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX623"></A> +</P> +<DL> +<DT><U>Function:</U> <B>rule-vertical</B> <I>x-coord text tick-width</I> +<DD><P> + +Draws a vertical ruler with X coordinate <VAR>x-coord</VAR> and labeled with string +<VAR>text</VAR>. If <VAR>tick-width</VAR> is positive, then the ticks are <VAR>tick-width</VAR> long on the right side +of <VAR>x-coord</VAR>; and <VAR>text</VAR> and numeric legends are on the left. If <VAR>tick-width</VAR> is +negative, then the ticks are -<VAR>tick-width</VAR> long on the left side of <VAR>x-coord</VAR>; and <VAR>text</VAR> +and numeric legends are on the right. +</P> +</DL> +<P> + +<A NAME="IDX624"></A> +</P> +<DL> +<DT><U>Function:</U> <B>rule-horizontal</B> <I>x-coord text tick-height</I> +<DD><P> + +Draws a horizontal ruler with X coordinate <VAR>x-coord</VAR> and labeled with +string <VAR>text</VAR>. If <VAR>tick-height</VAR> is positive, then the ticks are <VAR>tick-height</VAR> long on the +right side of <VAR>x-coord</VAR>; and <VAR>text</VAR> and numeric legends are on the left. If <VAR>tick-height</VAR> +is negative, then the ticks are -<VAR>tick-height</VAR> long on the left side of <VAR>x-coord</VAR>; and +<VAR>text</VAR> and numeric legends are on the right. +</P> +</DL> +<P> + +<A NAME="IDX625"></A> +</P> +<DL> +<DT><U>Function:</U> <B>y-axis</B> +<DD><P> + +Draws the y-axis. +</P> +</DL> +<P> + +<A NAME="IDX626"></A> +</P> +<DL> +<DT><U>Function:</U> <B>x-axis</B> +<DD><P> + +Draws the x-axis. +</P> +</DL> +<P> + +<A NAME="IDX627"></A> +</P> +<DL> +<DT><U>Function:</U> <B>grid-verticals</B> +<DD><P> + +Draws vertical lines through <CODE>graphrect</CODE> at each tick on the +vertical ruler. +</P> +</DL> +<P> + +<A NAME="IDX628"></A> +</P> +<DL> +<DT><U>Function:</U> <B>grid-horizontals</B> +<DD><P> + +Draws horizontal lines through <CODE>graphrect</CODE> at each tick on the +horizontal ruler. +</P> +</DL> +<A NAME="Legacy Plotting"></A> +<HR SIZE="6"> +<A NAME="SEC110"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC109"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC111"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC104"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 5.7.2.6 Legacy Plotting </H4> +<!--docid::SEC110::--> +<P> + +<A NAME="IDX629"></A> +</P> +<DL> +<DT><U>Variable:</U> <B>graph:dimensions</B> +<DD><P> + +A list of the width and height of the graph to be plotted using +<CODE>plot</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX630"></A> +</P> +<DL> +<DT><U>Function:</U> <B>plot</B> <I>func x1 x2 npts</I> +<DD><P> + +<A NAME="IDX631"></A> +<DT><U>Function:</U> <B>plot</B> <I>func x1 x2</I> +<DD>Creates and displays using <CODE>(system "gv tmp.eps")</CODE> an +encapsulated PostScript graph of the function of one argument <VAR>func</VAR> +over the range <VAR>x1</VAR> to <VAR>x2</VAR>. If the optional integer argument <VAR>npts</VAR> is +supplied, it specifies the number of points to evaluate <VAR>func</VAR> at. +</P> +<P> + +<A NAME="IDX632"></A> +<DT><U>Function:</U> <B>plot</B> <I>coords x-label y-label</I> +<DD><VAR>coords</VAR> is a list or vector of coordinates, lists of x and y +coordinates. <VAR>x-label</VAR> and <VAR>y-label</VAR> are strings with which +to label the x and y axes. +</P> +</DL> +<A NAME="Example Graph"></A> +<HR SIZE="6"> +<A NAME="SEC111"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC110"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC112"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC104"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 5.7.2.7 Example Graph </H4> +<!--docid::SEC111::--> +<P> + +The file `<TT>am1.5.html</TT>', a table of solar irradiance, is fetched +with `<SAMP>wget</SAMP>' if it isn't already in the working directory. The +file is read and stored into an array, <VAR>irradiance</VAR>. +</P> +<P> + +<CODE>create-postscript-graph</CODE> is then called to create an +encapsulated-PostScript file, `<TT>solarad.eps</TT>'. The size of the +page is set to 600 by 300. <CODE>whole-page</CODE> is called and leaves +the rectangle on the PostScript stack. <CODE>setup-plot</CODE> is called +with a literal range for x and computes the range for column 1. +</P> +<P> + +Two calls to <CODE>top-title</CODE> are made so a different font can be +used for the lower half. <CODE>in-graphic-context</CODE> is used to limit +the scope of the font change. The graphing area is outlined and a +rule drawn on the left side. +</P> +<P> + +Because the X range was intentionally reduced, +<CODE>in-graphic-context</CODE> is called and <CODE>clip-to-rect</CODE> limits +drawing to the plotting area. A black line is drawn from data +column 1. That line is then overlayed with a mountain plot of the +same column colored "Bright Sun". +</P> +<P> + +After returning from the <CODE>in-graphic-context</CODE>, the bottom ruler +is drawn. Had it been drawn earlier, all its ticks would have been +painted over by the mountain plot. +</P> +<P> + +The color is then changed to `<SAMP>seagreen</SAMP>' and the same graphrect +is setup again, this time with a different Y scale, 0 to 1000. The +graphic context is again clipped to <VAR>plotrect</VAR>, linedash is set, +and column 2 is plotted as a dashed line. Finally the rightedge is +ruled. Having the line and its scale both in green helps +disambiguate the scales. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'eps-graph) +(require 'line-i/o) +(require 'string-port) + +(define irradiance + (let ((url "http://www.pv.unsw.edu.au/am1.5.html") + (file "am1.5.html")) + (define (read->list line) + (define elts '()) + (call-with-input-string line + (lambda (iprt) (do ((elt (read iprt) (read iprt))) + ((eof-object? elt) elts) + (set! elts (cons elt elts)))))) + (if (not (file-exists? file)) + (system (string-append "wget -c -O" file " " url))) + (call-with-input-file file + (lambda (iprt) + (define lines '()) + (do ((line (read-line iprt) (read-line iprt))) + ((eof-object? line) + (let ((nra (create-array (Ar64) + (length lines) + (length (car lines))))) + (do ((lns lines (cdr lns)) + (idx (+ -1 (length lines)) (+ -1 idx))) + ((null? lns) nra) + (do ((kdx (+ -1 (length (car lines))) (+ -1 kdx)) + (lst (car lns) (cdr lst))) + ((null? lst)) + (array-set! nra (car lst) idx kdx))))) + (if (and (positive? (string-length line)) + (char-numeric? (string-ref line 0))) + (set! lines (cons (read->list line) lines)))))))) + +(let ((xrange '(.25 2.5))) + (create-postscript-graph + "solarad.eps" '(600 300) + (whole-page) + (setup-plot xrange (column-range irradiance 1)) + (title-top + "Solar Irradiance http://www.pv.unsw.edu.au/am1.5.html") + (in-graphic-context + (set-font "Helvetica-Oblique" 12) + (title-top + "" + "Key Centre for Photovoltaic Engineering UNSW - Air Mass 1.5 Global Spectrum")) + (outline-rect plotrect) + (rule-vertical leftedge "W/(m^2.um)" 10) + (in-graphic-context (clip-to-rect plotrect) + (plot-column irradiance 0 1 'line) + (set-color "Bright Sun") + (plot-column irradiance 0 1 'mountain) + ) + (rule-horizontal bottomedge "Wavelength in .um" 5) + (set-color 'seagreen) + + (setup-plot xrange '(0 1000) graphrect) + (in-graphic-context (clip-to-rect plotrect) + (set-linedash 5 2) + (plot-column irradiance 0 2 'line)) + (rule-vertical rightedge "Integrated .W/(m^2)" -10) + )) + +(system "gv solarad.eps") +</pre></td></tr></table><P> + +<A NAME="Solid Modeling"></A> +<HR SIZE="6"> +<A NAME="SEC112"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC111"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC118"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.8 Solid Modeling </H2> +<!--docid::SEC112::--> +<P> + +<A NAME="Solid"> +<CODE>(require 'solid)</CODE> +</A> +<A NAME="IDX633"></A> +<A NAME="IDX634"></A> +<A NAME="IDX635"></A> +</P> +<P> + +<A HREF="http://swissnet.ai.mit.edu/~jaffer/Solid/#Example">http://swissnet.ai.mit.edu/~jaffer/Solid/#Example</A> gives an +example use of this package. +</P> +<P> + +<A NAME="IDX636"></A> +</P> +<DL> +<DT><U>Function:</U> <B>vrml</B> <I>node <small>...</small></I> +<DD>Returns the VRML97 string (including header) of the concatenation +of strings <VAR>nodes</VAR>, <small>...</small>. +</DL> +<P> + +<A NAME="IDX637"></A> +</P> +<DL> +<DT><U>Function:</U> <B>vrml-append</B> <I>node1 node2 <small>...</small></I> +<DD>Returns the concatenation with interdigitated newlines of +strings <VAR>node1</VAR>, <VAR>node2</VAR>, <small>...</small>. +</DL> +<P> + +<A NAME="IDX638"></A> +</P> +<DL> +<DT><U>Function:</U> <B>vrml-to-file</B> <I>file node <small>...</small></I> +<DD>Writes to file named <VAR>file</VAR> the VRML97 string (including header) of +the concatenation of strings <VAR>nodes</VAR>, <small>...</small>. +</DL> +<P> + +<A NAME="IDX639"></A> +</P> +<DL> +<DT><U>Function:</U> <B>world:info</B> <I>title info <small>...</small></I> +<DD>Returns a VRML97 string setting the title of the file in which +it appears to <VAR>title</VAR>. Additional strings <VAR>info</VAR>, <small>...</small> are comments. +</DL> +<P> + +VRML97 strings passed to <CODE>vrml</CODE> and <CODE>vrml-to-file</CODE> as +arguments will appear in the resulting VRML code. This string turns +off the headlight at the viewpoint: +<TABLE><tr><td> </td><td class=example><pre>" NavigationInfo {headlight FALSE}" +</pre></td></tr></table><P> + +<A NAME="IDX640"></A> +</P> +<DL> +<DT><U>Function:</U> <B>scene:panorama</B> <I>front right back left top bottom</I> +<DD>Specifies the distant images on the inside faces of the cube +enclosing the virtual world. +</DL> +<P> + +<A NAME="IDX641"></A> +</P> +<DL> +<DT><U>Function:</U> <B>scene:sphere</B> <I>colors angles</I> +<DD><P> + +<VAR>colors</VAR> is a list of color objects. Each may be of type <A HREF="slib_5.html#SEC119">color</A>, a 24-bit sRGB integer, or a list of 3 numbers +between 0.0 and 1.0. +</P> +<P> + +<VAR>angles</VAR> is a list of non-increasing angles the same length as +<VAR>colors</VAR>. Each angle is between 90 and -90 degrees. If 90 or -90 are not +elements of <VAR>angles</VAR>, then the color at the zenith and nadir are taken from +the colors paired with the angles nearest them. +</P> +<P> + +<CODE>scene:sphere</CODE> fills horizontal bands with interpolated colors on the backgroud +sphere encasing the world. +</P> +</DL> +<P> + +<A NAME="IDX642"></A> +</P> +<DL> +<DT><U>Function:</U> <B>scene:sky-and-dirt</B> +<DD>Returns a blue and brown backgroud sphere encasing the world. +</DL> +<P> + +<A NAME="IDX643"></A> +</P> +<DL> +<DT><U>Function:</U> <B>scene:sky-and-grass</B> +<DD>Returns a blue and green backgroud sphere encasing the world. +</DL> +<P> + +<A NAME="IDX644"></A> +</P> +<DL> +<DT><U>Function:</U> <B>scene:sun</B> <I>latitude julian-day hour turbidity strength</I> +<DD><P> + +<A NAME="IDX645"></A> +<DT><U>Function:</U> <B>scene:sun</B> <I>latitude julian-day hour turbidity</I> +<DD></P> +<P> + +<VAR>latitude</VAR> is the virtual place's latitude in degrees. <VAR>julian-day</VAR> is an integer from +0 to 366, the day of the year. <VAR>hour</VAR> is a real number from 0 to 24 for +the time of day; 12 is noon. <VAR>turbidity</VAR> is the degree of fogginess described +in See section <A HREF="slib_5.html#SEC133">turbidity</A>. +</P> +<P> + +<CODE>scene:sun</CODE> returns a bright yellow, distant sphere where the sun would be at +<VAR>hour</VAR> on <VAR>julian-day</VAR> at <VAR>latitude</VAR>. If <VAR>strength</VAR> is positive, included is a light source of <VAR>strength</VAR> +(default 1). +</P> +</DL> +<P> + +<A NAME="IDX646"></A> +</P> +<DL> +<DT><U>Function:</U> <B>scene:overcast</B> <I>latitude julian-day hour turbidity strength</I> +<DD><P> + +<A NAME="IDX647"></A> +<DT><U>Function:</U> <B>scene:overcast</B> <I>latitude julian-day hour turbidity</I> +<DD></P> +<P> + +<VAR>latitude</VAR> is the virtual place's latitude in degrees. <VAR>julian-day</VAR> is an integer from +0 to 366, the day of the year. <VAR>hour</VAR> is a real number from 0 to 24 for +the time of day; 12 is noon. <VAR>turbidity</VAR> is the degree of cloudiness described +in See section <A HREF="slib_5.html#SEC133">turbidity</A>. +</P> +<P> + +<CODE>scene:overcast</CODE> returns an overcast sky as it might look at <VAR>hour</VAR> on <VAR>julian-day</VAR> at <VAR>latitude</VAR>. If <VAR>strength</VAR> +is positive, included is an ambient light source of <VAR>strength</VAR> (default 1). +</P> +</DL> +Viewpoints are objects in the virtual world, and can be transformed +individually or with solid objects. +<P> + +<A NAME="IDX648"></A> +</P> +<DL> +<DT><U>Function:</U> <B>scene:viewpoint</B> <I>name distance compass pitch</I> +<DD><P> + +<A NAME="IDX649"></A> +<DT><U>Function:</U> <B>scene:viewpoint</B> <I>name distance compass</I> +<DD>Returns a viewpoint named <VAR>name</VAR> facing the origin and placed <VAR>distance</VAR> from it. +<VAR>compass</VAR> is a number from 0 to 360 giving the compass heading. <VAR>pitch</VAR> is a +number from -90 to 90, defaulting to 0, specifying the angle from the +horizontal. +</P> +</DL> +<P> + +<A NAME="IDX650"></A> +</P> +<DL> +<DT><U>Function:</U> <B>scene:viewpoints</B> <I>proximity</I> +<DD>Returns 6 viewpoints, one at the center of each face of a cube +with sides 2 * <VAR>proximity</VAR>, centered on the origin. +</DL> +<A NAME="SEC113"></A> +<H3> Light Sources </H3> +<!--docid::SEC113::--> +<P> + +In VRML97, lights shine only on objects within the same children node +and descendants of that node. Although it would have been convenient +to let light direction be rotated by <CODE>solid:rotation</CODE>, this +restricts a rotated light's visibility to objects rotated with it. +</P> +<P> + +To workaround this limitation, these directional light source +procedures accept either Cartesian or spherical coordinates for +direction. A spherical coordinate is a list <CODE>(<VAR>theta</VAR> +<VAR>azimuth</VAR>)</CODE>; where <VAR>theta</VAR> is the angle in degrees from the +zenith, and <VAR>azimuth</VAR> is the angle in degrees due west of south. +</P> +<P> + +It is sometimes useful for light sources to be brighter than `<SAMP>1</SAMP>'. +When <VAR>intensity</VAR> arguments are greater than 1, these functions +gang multiple sources to reach the desired strength. +</P> +<P> + +<A NAME="IDX651"></A> +</P> +<DL> +<DT><U>Function:</U> <B>light:ambient</B> <I>color intensity</I> +<DD><P> + +<A NAME="IDX652"></A> +<DT><U>Function:</U> <B>light:ambient</B> <I>color</I> +<DD>Ambient light shines on all surfaces with which it is grouped. +</P> +<P> + +<VAR>color</VAR> is a an object of type <A HREF="slib_5.html#SEC119">color</A>, a 24-bit sRGB +integer, or a list of 3 numbers between 0.0 and 1.0. If <VAR>color</VAR> is #f, +then the default color will be used. <VAR>intensity</VAR> is a real non-negative number +defaulting to `<SAMP>1</SAMP>'. +</P> +<P> + +<CODE>light:ambient</CODE> returns a light source or sources of <VAR>color</VAR> with total strength of <VAR>intensity</VAR> +(or 1 if omitted). +</P> +</DL> +<P> + +<A NAME="IDX653"></A> +</P> +<DL> +<DT><U>Function:</U> <B>light:directional</B> <I>color direction intensity</I> +<DD><P> + +<A NAME="IDX654"></A> +<DT><U>Function:</U> <B>light:directional</B> <I>color direction</I> +<DD></P> +<P> + +<A NAME="IDX655"></A> +<DT><U>Function:</U> <B>light:directional</B> <I>color</I> +<DD>Directional light shines parallel rays with uniform intensity on all +objects with which it is grouped. +</P> +<P> + +<VAR>color</VAR> is a an object of type <A HREF="slib_5.html#SEC119">color</A>, a 24-bit sRGB +integer, or a list of 3 numbers between 0.0 and 1.0. If <VAR>color</VAR> is #f, +then the default color will be used. +</P> +<P> + +<VAR>direction</VAR> must be a list or vector of 2 or 3 numbers specifying the direction +to this light. If <VAR>direction</VAR> has 2 numbers, then these numbers are the angle +from zenith and the azimuth in degrees; if <VAR>direction</VAR> has 3 numbers, then +these are taken as a Cartesian vector specifying the direction to the +light source. The default direction is upwards; thus its light will +shine down. +</P> +<P> + +<VAR>intensity</VAR> is a real non-negative number defaulting to `<SAMP>1</SAMP>'. +</P> +<P> + +<CODE>light:directional</CODE> returns a light source or sources of <VAR>color</VAR> with total strength of <VAR>intensity</VAR>, +shining from <VAR>direction</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX656"></A> +</P> +<DL> +<DT><U>Function:</U> <B>light:beam</B> <I>attenuation radius aperture peak</I> +<DD><P> + +<A NAME="IDX657"></A> +<DT><U>Function:</U> <B>light:beam</B> <I>attenuation radius aperture</I> +<DD></P> +<P> + +<A NAME="IDX658"></A> +<DT><U>Function:</U> <B>light:beam</B> <I>attenuation radius</I> +<DD></P> +<P> + +<A NAME="IDX659"></A> +<DT><U>Function:</U> <B>light:beam</B> <I>attenuation</I> +<DD></P> +<P> + +<VAR>attenuation</VAR> is a list or vector of three nonnegative real numbers specifying +the reduction of intensity, the reduction of intensity with distance, +and the reduction of intensity as the square of distance. <VAR>radius</VAR> is the +distance beyond which the light does not shine. <VAR>radius</VAR> defaults to +`<SAMP>100</SAMP>'. +</P> +<P> + +<VAR>aperture</VAR> is a real number between 0 and 180, the angle centered on the +light's axis through which it sheds some light. <VAR>peak</VAR> is a real number +between 0 and 90, the angle of greatest illumination. +</P> +</DL> +<P> + +<A NAME="IDX660"></A> +</P> +<DL> +<DT><U>Function:</U> <B>light:point</B> <I>location color intensity beam</I> +<DD><P> + +<A NAME="IDX661"></A> +<DT><U>Function:</U> <B>light:point</B> <I>location color intensity</I> +<DD></P> +<P> + +<A NAME="IDX662"></A> +<DT><U>Function:</U> <B>light:point</B> <I>location color</I> +<DD></P> +<P> + +<A NAME="IDX663"></A> +<DT><U>Function:</U> <B>light:point</B> <I>location</I> +<DD></P> +<P> + +Point light radiates from <VAR>location</VAR>, intensity decreasing with distance, +towards all objects with which it is grouped. +</P> +<P> + +<VAR>color</VAR> is a an object of type <A HREF="slib_5.html#SEC119">color</A>, a 24-bit sRGB +integer, or a list of 3 numbers between 0.0 and 1.0. If <VAR>color</VAR> is #f, +then the default color will be used. <VAR>intensity</VAR> is a real non-negative number +defaulting to `<SAMP>1</SAMP>'. <VAR>beam</VAR> is a structure returned by +<CODE>light:beam</CODE> or #f. +</P> +<P> + +<CODE>light:point</CODE> returns a light source or sources at <VAR>location</VAR> of <VAR>color</VAR> with total strength +<VAR>intensity</VAR> and <VAR>beam</VAR> properties. Note that the pointlight itself is not visible. +To make it so, place an object with emissive appearance at <VAR>location</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX664"></A> +</P> +<DL> +<DT><U>Function:</U> <B>light:spot</B> <I>location direction color intensity beam</I> +<DD><P> + +<A NAME="IDX665"></A> +<DT><U>Function:</U> <B>light:spot</B> <I>location direction color intensity</I> +<DD></P> +<P> + +<A NAME="IDX666"></A> +<DT><U>Function:</U> <B>light:spot</B> <I>location direction color</I> +<DD></P> +<P> + +<A NAME="IDX667"></A> +<DT><U>Function:</U> <B>light:spot</B> <I>location direction</I> +<DD></P> +<P> + +<A NAME="IDX668"></A> +<DT><U>Function:</U> <B>light:spot</B> <I>location</I> +<DD></P> +<P> + +Spot light radiates from <VAR>location</VAR> towards <VAR>direction</VAR>, intensity decreasing with +distance, illuminating objects with which it is grouped. +</P> +<P> + +<VAR>direction</VAR> must be a list or vector of 2 or 3 numbers specifying the direction +to this light. If <VAR>direction</VAR> has 2 numbers, then these numbers are the angle +from zenith and the azimuth in degrees; if <VAR>direction</VAR> has 3 numbers, then +these are taken as a Cartesian vector specifying the direction to the +light source. The default direction is upwards; thus its light will +shine down. +</P> +<P> + +<VAR>color</VAR> is a an object of type <A HREF="slib_5.html#SEC119">color</A>, a 24-bit sRGB +integer, or a list of 3 numbers between 0.0 and 1.0. If <VAR>color</VAR> is #f, +then the default color will be used. +</P> +<P> + +<VAR>intensity</VAR> is a real non-negative number defaulting to `<SAMP>1</SAMP>'. +</P> +<P> + +<CODE>light:spot</CODE> returns a light source or sources at <VAR>location</VAR> of <VAR>direction</VAR> with total strength +<VAR>color</VAR>. Note that the spotlight itself is not visible. To make it so, +place an object with emissive appearance at <VAR>location</VAR>. +</P> +</DL> +<A NAME="SEC114"></A> +<H3> Object Primitives </H3> +<!--docid::SEC114::--> +<P> + +<A NAME="IDX669"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:box</B> <I>geometry appearance</I> +<DD><P> + +<A NAME="IDX670"></A> +<DT><U>Function:</U> <B>solid:box</B> <I>geometry</I> +<DD><VAR>geometry</VAR> must be a number or a list or vector of three numbers. If <VAR>geometry</VAR> is a +number, the <CODE>solid:box</CODE> returns a cube with sides of length <VAR>geometry</VAR> centered on the +origin. Otherwise, <CODE>solid:box</CODE> returns a rectangular box with dimensions <VAR>geometry</VAR> +centered on the origin. <VAR>appearance</VAR> determines the surface properties of the +returned object. +</P> +</DL> +<P> + +<A NAME="IDX671"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:cylinder</B> <I>radius height appearance</I> +<DD><P> + +<A NAME="IDX672"></A> +<DT><U>Function:</U> <B>solid:cylinder</B> <I>radius height</I> +<DD>Returns a right cylinder with dimensions <VAR>radius</VAR> and <CODE>(abs <VAR>height</VAR>)</CODE> +centered on the origin. If <VAR>height</VAR> is positive, then the cylinder ends +will be capped. <VAR>appearance</VAR> determines the surface properties of the returned +object. +</P> +</DL> +<P> + +<A NAME="IDX673"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:disk</B> <I>radius thickness appearance</I> +<DD><P> + +<A NAME="IDX674"></A> +<DT><U>Function:</U> <B>solid:disk</B> <I>radius thickness</I> +<DD><VAR>thickness</VAR> must be a positive real number. <CODE>solid:disk</CODE> returns a circular disk +with dimensions <VAR>radius</VAR> and <VAR>thickness</VAR> centered on the origin. <VAR>appearance</VAR> determines the +surface properties of the returned object. +</P> +</DL> +<P> + +<A NAME="IDX675"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:cone</B> <I>radius height appearance</I> +<DD><P> + +<A NAME="IDX676"></A> +<DT><U>Function:</U> <B>solid:cone</B> <I>radius height</I> +<DD>Returns an isosceles cone with dimensions <VAR>radius</VAR> and <VAR>height</VAR> centered on +the origin. <VAR>appearance</VAR> determines the surface properties of the returned +object. +</P> +</DL> +<P> + +<A NAME="IDX677"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:pyramid</B> <I>side height appearance</I> +<DD><P> + +<A NAME="IDX678"></A> +<DT><U>Function:</U> <B>solid:pyramid</B> <I>side height</I> +<DD>Returns an isosceles pyramid with dimensions <VAR>side</VAR> and <VAR>height</VAR> centered on +the origin. <VAR>appearance</VAR> determines the surface properties of the returned +object. +</P> +</DL> +<P> + +<A NAME="IDX679"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:sphere</B> <I>radius appearance</I> +<DD><P> + +<A NAME="IDX680"></A> +<DT><U>Function:</U> <B>solid:sphere</B> <I>radius</I> +<DD>Returns a sphere of radius <VAR>radius</VAR> centered on the origin. <VAR>appearance</VAR> determines +the surface properties of the returned object. +</P> +</DL> +<P> + +<A NAME="IDX681"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:ellipsoid</B> <I>geometry appearance</I> +<DD><P> + +<A NAME="IDX682"></A> +<DT><U>Function:</U> <B>solid:ellipsoid</B> <I>geometry</I> +<DD><VAR>geometry</VAR> must be a number or a list or vector of three numbers. If <VAR>geometry</VAR> is a +number, the <CODE>solid:ellipsoid</CODE> returns a sphere of diameter <VAR>geometry</VAR> centered on the origin. +Otherwise, <CODE>solid:ellipsoid</CODE> returns an ellipsoid with diameters <VAR>geometry</VAR> centered on the +origin. <VAR>appearance</VAR> determines the surface properties of the returned object. +</P> +</DL> +<P> + +<A NAME="IDX683"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:basrelief</B> <I>width height depth colorray appearance</I> +<DD><P> + +<A NAME="IDX684"></A> +<DT><U>Function:</U> <B>solid:basrelief</B> <I>width height depth appearance</I> +<DD></P> +<P> + +<A NAME="IDX685"></A> +<DT><U>Function:</U> <B>solid:basrelief</B> <I>width height depth</I> +<DD>One of <VAR>width</VAR>, <VAR>height</VAR>, or <VAR>depth</VAR> must be a 2-dimensional array; the others must +be real numbers giving the length of the basrelief in those +dimensions. The rest of this description assumes that <VAR>height</VAR> is an +array of heights. +</P> +<P> + +<CODE>solid:basrelief</CODE> returns a <VAR>width</VAR> by <VAR>depth</VAR> basrelief solid with heights per array <VAR>height</VAR> with +the buttom surface centered on the origin. +</P> +<P> + +If present, <VAR>appearance</VAR> determines the surface properties of the returned +object. If present, <VAR>colorray</VAR> must be an array of objects of type +<A HREF="slib_5.html#SEC119">color</A>, 24-bit sRGB integers or lists of 3 +numbers between 0.0 and 1.0. +</P> +<P> + +If <VAR>colorray</VAR>'s dimensions match <VAR>height</VAR>, then each element of <VAR>colorray</VAR> paints its +corresponding vertex of <VAR>height</VAR>. If <VAR>colorray</VAR> has all dimensions one smaller +than <VAR>height</VAR>, then each element of <VAR>colorray</VAR> paints the corresponding face of +<VAR>height</VAR>. Other dimensions for <VAR>colorray</VAR> are in error. +</P> +</DL> +<A NAME="SEC115"></A> +<H3> Surface Attributes </H3> +<!--docid::SEC115::--> +<P> + +<A NAME="IDX686"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:color</B> <I>diffuseColor ambientIntensity specularColor shininess emissiveColor transparency</I> +<DD><P> + +<A NAME="IDX687"></A> +<DT><U>Function:</U> <B>solid:color</B> <I>diffuseColor ambientIntensity specularColor shininess emissiveColor</I> +<DD></P> +<P> + +<A NAME="IDX688"></A> +<DT><U>Function:</U> <B>solid:color</B> <I>diffuseColor ambientIntensity specularColor shininess</I> +<DD></P> +<P> + +<A NAME="IDX689"></A> +<DT><U>Function:</U> <B>solid:color</B> <I>diffuseColor ambientIntensity specularColor</I> +<DD></P> +<P> + +<A NAME="IDX690"></A> +<DT><U>Function:</U> <B>solid:color</B> <I>diffuseColor ambientIntensity</I> +<DD></P> +<P> + +<A NAME="IDX691"></A> +<DT><U>Function:</U> <B>solid:color</B> <I>diffuseColor</I> +<DD></P> +<P> + +Returns an <EM>appearance</EM>, the optical properties of the objects +<A NAME="IDX692"></A> +with which it is associated. <VAR>ambientIntensity</VAR>, <VAR>shininess</VAR>, and <VAR>transparency</VAR> must be numbers between 0 +and 1. <VAR>diffuseColor</VAR>, <VAR>specularColor</VAR>, and <VAR>emissiveColor</VAR> are objects of type <A HREF="slib_5.html#SEC119">color</A>, +24-bit sRGB integers or lists of 3 numbers between 0.0 and 1.0. +If a color argument is omitted or #f, then the default color will be used. +</P> +</DL> +<P> + +<A NAME="IDX693"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:texture</B> <I>image color scale rotation center translation</I> +<DD><P> + +<A NAME="IDX694"></A> +<DT><U>Function:</U> <B>solid:texture</B> <I>image color scale rotation center</I> +<DD></P> +<P> + +<A NAME="IDX695"></A> +<DT><U>Function:</U> <B>solid:texture</B> <I>image color scale rotation</I> +<DD></P> +<P> + +<A NAME="IDX696"></A> +<DT><U>Function:</U> <B>solid:texture</B> <I>image color scale</I> +<DD></P> +<P> + +<A NAME="IDX697"></A> +<DT><U>Function:</U> <B>solid:texture</B> <I>image color</I> +<DD></P> +<P> + +<A NAME="IDX698"></A> +<DT><U>Function:</U> <B>solid:texture</B> <I>image</I> +<DD></P> +<P> + +Returns an <EM>appearance</EM>, the optical properties of the objects +<A NAME="IDX699"></A> +with which it is associated. <VAR>image</VAR> is a string naming a JPEG or PNG +image resource. <VAR>color</VAR> is #f, a color, or the string returned by +<CODE>solid:color</CODE>. The rest of the optional arguments specify +2-dimensional transforms applying to the <VAR>image</VAR>. +</P> +<P> + +<VAR>scale</VAR> must be #f, a number, or list or vector of 2 numbers specifying the +scale to apply to <VAR>image</VAR>. <VAR>rotation</VAR> must be #f or the number of degrees to +rotate <VAR>image</VAR>. <VAR>center</VAR> must be #f or a list or vector of 2 numbers specifying +the center of <VAR>image</VAR> relative to the <VAR>image</VAR> dimensions. <VAR>translation</VAR> must be #f or a +list or vector of 2 numbers specifying the translation to apply to <VAR>image</VAR>. +</P> +</DL> +<A NAME="SEC116"></A> +<H3> Aggregating Objects </H3> +<!--docid::SEC116::--> +<P> + +<A NAME="IDX700"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:center-row-of</B> <I>number solid spacing</I> +<DD>Returns a row of <VAR>number</VAR> <VAR>solid</VAR> objects spaced evenly <VAR>spacing</VAR> apart. +</DL> +<P> + +<A NAME="IDX701"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:center-array-of</B> <I>number-a number-b solid spacing-a spacing-b</I> +<DD>Returns <VAR>number-b</VAR> rows, <VAR>spacing-b</VAR> apart, of <VAR>number-a</VAR> <VAR>solid</VAR> objects <VAR>spacing-a</VAR> apart. +</DL> +<P> + +<A NAME="IDX702"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:center-pile-of</B> <I>number-a number-b number-c solid spacing-a spacing-b spacing-c</I> +<DD>Returns <VAR>number-c</VAR> planes, <VAR>spacing-c</VAR> apart, of <VAR>number-b</VAR> rows, <VAR>spacing-b</VAR> apart, of <VAR>number-a</VAR> <VAR>solid</VAR> objects <VAR>spacing-a</VAR> apart. +</DL> +<P> + +<A NAME="IDX703"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:arrow</B> <I>center</I> +<DD><P> + +<VAR>center</VAR> must be a list or vector of three numbers. Returns an upward +pointing metallic arrow centered at <VAR>center</VAR>. +</P> +<P> + +<A NAME="IDX704"></A> +<DT><U>Function:</U> <B>solid:arrow</B> +<DD>Returns an upward pointing metallic arrow centered at the origin. +</P> +</DL> +<A NAME="SEC117"></A> +<H3> Spatial Transformations </H3> +<!--docid::SEC117::--> +<P> + +<A NAME="IDX705"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:translation</B> <I>center solid <small>...</small></I> +<DD><VAR>center</VAR> must be a list or vector of three numbers. <CODE>solid:translation</CODE> Returns an +aggregate of <VAR>solids</VAR>, <small>...</small> with their origin moved to <VAR>center</VAR>. +</DL> +<P> + +<A NAME="IDX706"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:scale</B> <I>scale solid <small>...</small></I> +<DD><VAR>scale</VAR> must be a number or a list or vector of three numbers. <CODE>solid:scale</CODE> +Returns an aggregate of <VAR>solids</VAR>, <small>...</small> scaled per <VAR>scale</VAR>. +</DL> +<P> + +<A NAME="IDX707"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solid:rotation</B> <I>axis angle solid <small>...</small></I> +<DD><VAR>axis</VAR> must be a list or vector of three numbers. <CODE>solid:rotation</CODE> Returns an +aggregate of <VAR>solids</VAR>, <small>...</small> rotated <VAR>angle</VAR> degrees around the axis <VAR>axis</VAR>. +</DL> +<P> + +<A NAME="Color"></A> +<HR SIZE="6"> +<A NAME="SEC118"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC112"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC119"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.9 Color </H2> +<!--docid::SEC118::--> +<P> + +<A NAME="Color"></A> +</P> +<P> + +<A HREF="http://swissnet.ai.mit.edu/~jaffer/Color">http://swissnet.ai.mit.edu/~jaffer/Color</A> +</P> +<P> + +The goals of this package are to provide methods to specify, compute, +and transform colors in a core set of additive color spaces. The color +spaces supported should be sufficient for working with the color data +encountered in practice and the literature. +</P> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC119">5.9.1 Color Data-Type</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'color</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC122">5.9.2 Color Spaces</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">XYZ, L*a*b*, L*u*v*, L*C*h, RGB709, sRGB</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC127">5.9.3 Spectra</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Color Temperatures and CIEXYZ(1931)</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC128">5.9.4 Color Difference Metrics</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Society of Dyers and Colorists</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC129">5.9.5 Color Conversions</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Low-level</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC130">5.9.6 Color Names</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">in relational databases</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_5.html#SEC133">5.9.7 Daylight</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Sunlight and sky colors</TD></TR> +</TABLE> +<P> + +<A NAME="Color Data-Type"></A> +<HR SIZE="6"> +<A NAME="SEC119"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC118"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC120"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC118"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.9.1 Color Data-Type </H3> +<!--docid::SEC119::--> +<P> + +<A NAME="Color_Data-Type"></A> +<CODE>(require 'color)</CODE> +</P> +<P> + +<A NAME="IDX708"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color?</B> <I>obj</I> +<DD>Returns #t if <VAR>obj</VAR> is a color. +<P> + +<A NAME="IDX709"></A> +<DT><U>Function:</U> <B>color?</B> <I>obj typ</I> +<DD>Returns #t if <VAR>obj</VAR> is a color of color-space <VAR>typ</VAR>. The symbol +<VAR>typ</VAR> must be one of: +</P> +<P> + +<UL> +<LI> +CIEXYZ +<LI> +RGB709 +<LI> +L*a*b* +<LI> +L*u*v* +<LI> +sRGB +<LI> +e-sRGB +<LI> +L*C*h +</UL> +</DL> +<P> + +<A NAME="IDX710"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-color</B> <I>space arg <small>...</small></I> +<DD>Returns a color of type <VAR>space</VAR>. +</DL> +<P> + +<A NAME="IDX711"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color-space</B> <I>color</I> +<DD>Returns the symbol for the color-space in which <VAR>color</VAR> is embedded. +</DL> +<P> + +<A NAME="IDX712"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color-precision</B> <I>color</I> +<DD>For colors in digital color-spaces, <CODE>color-precision</CODE> returns the +number of bits used for each of the R, G, and B channels of the +encoding. Otherwise, <CODE>color-precision</CODE> returns #f +</DL> +<P> + +<A NAME="IDX713"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color-white-point</B> <I>color</I> +<DD>Returns the white-point of <VAR>color</VAR> in all color-spaces except CIEXYZ. +</DL> +<P> + +<A NAME="IDX714"></A> +</P> +<DL> +<DT><U>Function:</U> <B>convert-color</B> <I>color space white-point</I> +<DD><A NAME="IDX715"></A> +<DT><U>Function:</U> <B>convert-color</B> <I>color space</I> +<DD><A NAME="IDX716"></A> +<DT><U>Function:</U> <B>convert-color</B> <I>color e-sRGB precision</I> +<DD>Converts <VAR>color</VAR> into <VAR>space</VAR> at optional <VAR>white-point</VAR>. +</DL> +<P> + +<HR SIZE="6"> +<A NAME="SEC120"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC119"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC121"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC118"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 5.9.1.1 External Representation </H4> +<!--docid::SEC120::--> +<P> + +Each color encoding has an external, case-insensitive representation. +To ensure portability, the white-point for all color strings is D65. +<A NAME="DOCF4" HREF="slib_fot.html#FOOT4">(4)</A> +</P> +<P> + +</P> +<TABLE> +<TR><TD>Color Space</TD> +</TD><TD> External Representation +</TR> +<TR><TD>CIEXYZ</TD> +</TD><TD> CIEXYZ:<I><X></I>/<I><Y></I>/<I><Z></I> +</TR> +<TR><TD>RGB709</TD> +</TD><TD> RGBi:<I><R></I>/<I><G></I>/<I><B></I> +</TR> +<TR><TD>L*a*b*</TD> +</TD><TD> CIELAB:<I><L></I>/<I><a></I>/<I><b></I> +</TR> +<TR><TD>L*u*v*</TD> +</TD><TD> CIELuv:<I><L></I>/<I><u></I>/<I><v></I> +</TR> +<TR><TD>L*C*h</TD> +</TD><TD> CIELCh:<I><L></I>/<I><C></I>/<I><h></I> +</TR></TABLE> +<P> + +The <VAR>X</VAR>, <VAR>Y</VAR>, <VAR>Z</VAR>, <VAR>L</VAR>, <VAR>a</VAR>, <VAR>b</VAR>, <VAR>u</VAR>, +<VAR>v</VAR>, <VAR>C</VAR>, <VAR>h</VAR>, <VAR>R</VAR>, <VAR>G</VAR>, and <VAR>B</VAR> fields are +(Scheme) real numbers within the appropriate ranges. +</P> +<P> + +</P> +<TABLE> +<TR><TD>Color Space</TD> +</TD><TD> External Representation +</TR> +<TR><TD>sRGB</TD> +</TD><TD> sRGB:<I><R></I>/<I><G></I>/<I><B></I> +</TR> +<TR><TD>e-sRGB10</TD> +</TD><TD> e-sRGB10:<I><R></I>/<I><G></I>/<I><B></I> +</TR> +<TR><TD>e-sRGB12</TD> +</TD><TD> e-sRGB12:<I><R></I>/<I><G></I>/<I><B></I> +</TR> +<TR><TD>e-sRGB16</TD> +</TD><TD> e-sRGB16:<I><R></I>/<I><G></I>/<I><B></I> +</TR></TABLE> +<P> + +The <VAR>R</VAR>, <VAR>G</VAR>, and <VAR>B</VAR>, fields are non-negative exact decimal +integers within the appropriate ranges. +</P> +<P> + +Several additional syntaxes are supported by <CODE>string->color</CODE>: +</P> +<P> + +</P> +<TABLE> +<TR><TD>Color Space</TD> +</TD><TD> External Representation +</TR> +<TR><TD>sRGB</TD> +</TD><TD> sRGB:<I><RRGGBB></I> +</TR> +<TR><TD>sRGB</TD> +</TD><TD> #<I><RRGGBB></I> +</TR> +<TR><TD>sRGB</TD> +</TD><TD> 0x<I><RRGGBB></I> +</TR> +<TR><TD>sRGB</TD> +</TD><TD> #x<I><RRGGBB></I> +</TR></TABLE> +<P> + +Where <VAR>RRGGBB</VAR> is a non-negative six-digit hexadecimal number. +</P> +<P> + +<A NAME="IDX717"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color->string</B> <I>color</I> +<DD>Returns a string representation of <VAR>color</VAR>. +</DL> +<P> + +<A NAME="IDX718"></A> +</P> +<DL> +<DT><U>Function:</U> <B>string->color</B> <I>string</I> +<DD>Returns the color represented by <VAR>string</VAR>. If <VAR>string</VAR> is not a +syntactically valid notation for a color, then <CODE>string->color</CODE> +returns #f. +</DL> +<P> + +<HR SIZE="6"> +<A NAME="SEC121"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC120"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC122"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC118"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 5.9.1.2 White </H4> +<!--docid::SEC121::--> +<P> + +We experience color relative to the illumination around us. +CIEXYZ coordinates, although subject to uniform scaling, are +objective. Thus other color spaces are specified relative to a +<A NAME="IDX719"></A> +<EM>white point</EM> in CIEXYZ coordinates. +<A NAME="IDX720"></A> +</P> +<P> + +The white point for digital color spaces is set to D65. For the other +spaces a <VAR>white-point</VAR> argument can be specified. The default if +none is specified is the white-point with which the color was created +or last converted; and D65 if none has been specified. +</P> +<P> + +<A NAME="IDX721"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>D65</B> +<DD>Is the color of 6500.K (blackbody) illumination. D65 is close +to the average color of daylight. +</DL> +<P> + +<A NAME="IDX722"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>D50</B> +<DD>Is the color of 5000.K (blackbody) illumination. D50 is the color of +indoor lighting by incandescent bulbs, whose filaments have +temperatures around 5000.K. +</DL> +<P> + +<A NAME="Color Spaces"></A> +<HR SIZE="6"> +<A NAME="SEC122"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC121"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC127"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC118"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.9.2 Color Spaces </H3> +<!--docid::SEC122::--> +<P> + +<A NAME="Color_Spaces"></A> +<A NAME="SEC123"></A> +<H4> Measurement-based Color Spaces </H4> +<!--docid::SEC123::--> +<P> + +<A NAME="IDX723"></A> +The <EM>tristimulus</EM> color spaces are those whose component values +<A NAME="IDX724"></A> +are proportional measurements of light intensity. The CIEXYZ(1931) +system provides 3 sets of spectra to convolve with a spectrum of +interest. The result of those convolutions is coordinates in CIEXYZ +space. All tristimuls color spaces are related to CIEXYZ by linear +transforms, namely matrix multiplication. Of the color spaces listed +here, CIEXYZ and RGB709 are tristimulus spaces. +</P> +<P> + +<A NAME="IDX725"></A> +</P> +<DL> +<DT><U>Color Space:</U> <B>CIEXYZ</B> +<DD>The CIEXYZ color space covers the full <EM>gamut</EM>. +<A NAME="IDX726"></A> +It is the basis for color-space conversions. +<P> + +CIEXYZ is a list of three inexact numbers between 0 and 1.1. +'(0. 0. 0.) is black; '(1. 1. 1.) is white. +</P> +</DL> +<P> + +<A NAME="IDX727"></A> +</P> +<DL> +<DT><U>Function:</U> <B>ciexyz->color</B> <I>xyz</I> +<DD><P> + +<VAR>xyz</VAR> must be a list of 3 numbers. If <VAR>xyz</VAR> is valid CIEXYZ coordinates, +then <CODE>ciexyz->color</CODE> returns the color specified by <VAR>xyz</VAR>; otherwise returns #f. +</P> +</DL> +<P> + +<A NAME="IDX728"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color:ciexyz</B> <I>x y z</I> +<DD><P> + +Returns the CIEXYZ color composed of <VAR>x</VAR>, <VAR>y</VAR>, <VAR>z</VAR>. If the +coordinates do not encode a valid CIEXYZ color, then an error is +signaled. +</P> +</DL> +<P> + +<A NAME="IDX729"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color->ciexyz</B> <I>color</I> +<DD>Returns the list of 3 numbers encoding <VAR>color</VAR> in CIEXYZ. +</DL> +<A NAME="IDX730"></A> +<DL> +<DT><U>Color Space:</U> <B>RGB709</B> +<DD>BT.709-4 (03/00) <CITE>Parameter values for the HDTV standards for +production and international programme exchange</CITE> specifies parameter +values for chromaticity, sampling, signal format, frame rates, etc., of +high definition television signals. +<P> + +An RGB709 color is represented by a list of three inexact numbers +between 0 and 1. '(0. 0. 0.) is black '(1. 1. 1.) is white. +</P> +</DL> +<P> + +<A NAME="IDX731"></A> +</P> +<DL> +<DT><U>Function:</U> <B>rgb709->color</B> <I>rgb</I> +<DD><P> + +<VAR>rgb</VAR> must be a list of 3 numbers. If <VAR>rgb</VAR> is valid RGB709 coordinates, +then <CODE>rgb709->color</CODE> returns the color specified by <VAR>rgb</VAR>; otherwise returns #f. +</P> +</DL> +<P> + +<A NAME="IDX732"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color:rgb709</B> <I>r g b</I> +<DD><P> + +Returns the RGB709 color composed of <VAR>r</VAR>, <VAR>g</VAR>, <VAR>b</VAR>. If the +coordinates do not encode a valid RGB709 color, then an error is +signaled. +</P> +</DL> +<P> + +<A NAME="IDX733"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color->rgb709</B> <I>color</I> +<DD>Returns the list of 3 numbers encoding <VAR>color</VAR> in RGB709. +</DL> +<A NAME="SEC124"></A> +<H4> Perceptual Uniformity </H4> +<!--docid::SEC124::--> +<P> + +Although properly encoding the chromaticity, tristimulus spaces do not +match the logarithmic response of human visual systems to intensity. +Minimum detectable differences between colors correspond to a smaller +range of distances (6:1) in the L*a*b* and L*u*v* spaces than in +tristimulus spaces (80:1). For this reason, color distances are +computed in L*a*b* (or L*C*h). +</P> +<P> + +<A NAME="IDX734"></A> +</P> +<DL> +<DT><U>Color Space:</U> <B>L*a*b*</B> +<DD>Is a CIE color space which better matches the human visual system's +perception of color. It is a list of three numbers: +<P> + +<UL> +<LI> +0 <= L* <= 100 (CIE <EM>Lightness</EM>) +<A NAME="IDX735"></A> +<P> + +</P> +<LI> +-500 <= a* <= 500 +<LI> +-200 <= b* <= 200 +</UL> +</DL> +<P> + +<A NAME="IDX736"></A> +</P> +<DL> +<DT><U>Function:</U> <B>l*a*b*->color</B> <I>L*a*b* white-point</I> +<DD><P> + +<VAR>L*a*b*</VAR> must be a list of 3 numbers. If <VAR>L*a*b*</VAR> is valid L*a*b* coordinates, +then <CODE>l*a*b*->color</CODE> returns the color specified by <VAR>L*a*b*</VAR>; otherwise returns #f. +</P> +</DL> +<P> + +<A NAME="IDX737"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color:l*a*b*</B> <I>L* a* b* white-point</I> +<DD><P> + +Returns the L*a*b* color composed of <VAR>L*</VAR>, <VAR>a*</VAR>, <VAR>b*</VAR> with <VAR>white-point</VAR>. +</P> +<P> + +<A NAME="IDX738"></A> +<DT><U>Function:</U> <B>color:l*a*b*</B> <I>L* a* b*</I> +<DD>Returns the L*a*b* color composed of <VAR>L*</VAR>, <VAR>a*</VAR>, <VAR>b*</VAR>. If the coordinates +do not encode a valid L*a*b* color, then an error is signaled. +</P> +</DL> +<P> + +<A NAME="IDX739"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color->l*a*b*</B> <I>color white-point</I> +<DD><P> + +Returns the list of 3 numbers encoding <VAR>color</VAR> in L*a*b* with <VAR>white-point</VAR>. +</P> +<P> + +<A NAME="IDX740"></A> +<DT><U>Function:</U> <B>color->l*a*b*</B> <I>color</I> +<DD>Returns the list of 3 numbers encoding <VAR>color</VAR> in L*a*b*. +</P> +</DL> +<A NAME="IDX741"></A> +<DL> +<DT><U>Color Space:</U> <B>L*u*v*</B> +<DD>Is another CIE encoding designed to better match the human visual +system's perception of color. +</DL> +<P> + +<A NAME="IDX742"></A> +</P> +<DL> +<DT><U>Function:</U> <B>l*u*v*->color</B> <I>L*u*v* white-point</I> +<DD><P> + +<VAR>L*u*v*</VAR> must be a list of 3 numbers. If <VAR>L*u*v*</VAR> is valid L*u*v* coordinates, +then <CODE>l*u*v*->color</CODE> returns the color specified by <VAR>L*u*v*</VAR>; otherwise returns #f. +</P> +</DL> +<P> + +<A NAME="IDX743"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color:l*u*v*</B> <I>L* u* v* white-point</I> +<DD><P> + +Returns the L*u*v* color composed of <VAR>L*</VAR>, <VAR>u*</VAR>, <VAR>v*</VAR> with <VAR>white-point</VAR>. +</P> +<P> + +<A NAME="IDX744"></A> +<DT><U>Function:</U> <B>color:l*u*v*</B> <I>L* u* v*</I> +<DD>Returns the L*u*v* color composed of <VAR>L*</VAR>, <VAR>u*</VAR>, <VAR>v*</VAR>. If the coordinates +do not encode a valid L*u*v* color, then an error is signaled. +</P> +</DL> +<P> + +<A NAME="IDX745"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color->l*u*v*</B> <I>color white-point</I> +<DD><P> + +Returns the list of 3 numbers encoding <VAR>color</VAR> in L*u*v* with <VAR>white-point</VAR>. +</P> +<P> + +<A NAME="IDX746"></A> +<DT><U>Function:</U> <B>color->l*u*v*</B> <I>color</I> +<DD>Returns the list of 3 numbers encoding <VAR>color</VAR> in L*u*v*. +</P> +</DL> +<A NAME="SEC125"></A> +<H4> Cylindrical Coordinates </H4> +<!--docid::SEC125::--> +<P> + +HSL (Hue Saturation Lightness), HSV (Hue Saturation Value), HSI (Hue +Saturation Intensity) and HCI (Hue Chroma Intensity) are cylindrical +color spaces (with angle hue). But these spaces are all defined in +terms device-dependent RGB spaces. +</P> +<P> + +One might wonder if there is some fundamental reason why intuitive +specification of color must be device-dependent. But take heart! A +cylindrical system can be based on L*a*b* and is used for predicting how +close colors seem to observers. +</P> +<P> + +<A NAME="IDX747"></A> +</P> +<DL> +<DT><U>Color Space:</U> <B>L*C*h</B> +<DD>Expresses the *a and b* of L*a*b* in polar coordinates. It is a list of +three numbers: +<P> + +<UL> +<LI> +0 <= L* <= 100 (CIE <EM>Lightness</EM>) +<A NAME="IDX748"></A> +<P> + +</P> +<LI> +C* (CIE <EM>Chroma</EM>) is the distance from the neutral (gray) axis. +<A NAME="IDX749"></A> +<LI> +0 <= h <= 360 (CIE <EM>Hue</EM>) is the angle. +<A NAME="IDX750"></A> +</UL> +<P> + +The colors by quadrant of h are: +</P> +<P> + +</P> +<TABLE> +<TR><TD>0 </TD><TD> red, orange, yellow </TD><TD> 90</TD> +</TR> +<TR><TD>90 </TD><TD> yellow, yellow-green, green </TD><TD> 180</TD> +</TR> +<TR><TD>180 </TD><TD> green, cyan (blue-green), blue </TD><TD> 270</TD> +</TR> +<TR><TD>270 </TD><TD> blue, purple, magenta </TD><TD> 360</TD> +</TR></TABLE> +<P> + +</P> +</DL> +<P> + +<A NAME="IDX751"></A> +</P> +<DL> +<DT><U>Function:</U> <B>l*c*h->color</B> <I>L*C*h white-point</I> +<DD><P> + +<VAR>L*C*h</VAR> must be a list of 3 numbers. If <VAR>L*C*h</VAR> is valid L*C*h coordinates, +then <CODE>l*c*h->color</CODE> returns the color specified by <VAR>L*C*h</VAR>; otherwise returns #f. +</P> +</DL> +<P> + +<A NAME="IDX752"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color:l*c*h</B> <I>L* C* h white-point</I> +<DD><P> + +Returns the L*C*h color composed of <VAR>L*</VAR>, <VAR>C*</VAR>, <VAR>h</VAR> with <VAR>white-point</VAR>. +</P> +<P> + +<A NAME="IDX753"></A> +<DT><U>Function:</U> <B>color:l*c*h</B> <I>L* C* h</I> +<DD>Returns the L*C*h color composed of <VAR>L*</VAR>, <VAR>C*</VAR>, <VAR>h</VAR>. If the coordinates +do not encode a valid L*C*h color, then an error is signaled. +</P> +</DL> +<P> + +<A NAME="IDX754"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color->l*c*h</B> <I>color white-point</I> +<DD><P> + +Returns the list of 3 numbers encoding <VAR>color</VAR> in L*C*h with <VAR>white-point</VAR>. +</P> +<P> + +<A NAME="IDX755"></A> +<DT><U>Function:</U> <B>color->l*c*h</B> <I>color</I> +<DD>Returns the list of 3 numbers encoding <VAR>color</VAR> in L*C*h. +</P> +</DL> +<A NAME="SEC126"></A> +<H4> Digital Color Spaces </H4> +<!--docid::SEC126::--> +<P> + +The color spaces discussed so far are impractical for image data because +of numerical precision and computational requirements. In 1998 the IEC +adopted <CITE>A Standard Default Color Space for the Internet - sRGB</CITE> +(<A HREF="http://www.w3.org/Graphics/Color/sRGB">http://www.w3.org/Graphics/Color/sRGB</A>). sRGB was cleverly +designed to employ the 24-bit (256x256x256) color encoding already in +widespread use; and the 2.2 gamma intrinsic to CRT monitors. +</P> +<P> + +Conversion from CIEXYZ to digital (sRGB) color spaces is accomplished by +conversion first to a RGB709 tristimulus space with D65 white-point; +then each coordinate is individually subjected to the same non-linear +mapping. Inverse operations in the reverse order create the inverse +transform. +</P> +<P> + +<A NAME="IDX756"></A> +</P> +<DL> +<DT><U>Color Space:</U> <B>sRGB</B> +<DD>Is "A Standard Default Color Space for the Internet". Most display +monitors will work fairly well with sRGB directly. Systems using ICC +profiles +<A NAME="IDX757"></A> +<A NAME="DOCF5" HREF="slib_fot.html#FOOT5">(5)</A> +should work very well with sRGB. +<P> + +</P> +</DL> +<P> + +<A NAME="IDX758"></A> +</P> +<DL> +<DT><U>Function:</U> <B>srgb->color</B> <I>rgb</I> +<DD><P> + +<VAR>rgb</VAR> must be a list of 3 numbers. If <VAR>rgb</VAR> is valid sRGB coordinates, +then <CODE>srgb->color</CODE> returns the color specified by <VAR>rgb</VAR>; otherwise returns #f. +</P> +</DL> +<P> + +<A NAME="IDX759"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color:srgb</B> <I>r g b</I> +<DD><P> + +Returns the sRGB color composed of <VAR>r</VAR>, <VAR>g</VAR>, <VAR>b</VAR>. If the +coordinates do not encode a valid sRGB color, then an error is +signaled. +</P> +</DL> +<A NAME="IDX760"></A> +<DL> +<DT><U>Color Space:</U> <B>xRGB</B> +<DD>Represents the equivalent sRGB color with a single 24-bit integer. The +most significant 8 bits encode red, the middle 8 bits blue, and the +least significant 8 bits green. +</DL> +<P> + +<A NAME="IDX761"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color->srgb</B> <I>color</I> +<DD><P> + +Returns the list of 3 integers encoding <VAR>color</VAR> in sRGB. +</P> +</DL> +<P> + +<A NAME="IDX762"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color->xrgb</B> <I>color</I> +<DD>Returns the 24-bit integer encoding <VAR>color</VAR> in sRGB. +</DL> +<P> + +<A NAME="IDX763"></A> +</P> +<DL> +<DT><U>Function:</U> <B>xrgb->color</B> <I>k</I> +<DD><P> + +Returns the sRGB color composed of the 24-bit integer <VAR>k</VAR>. +</P> +</DL> +<A NAME="IDX764"></A> +<DL> +<DT><U>Color Space:</U> <B>e-sRGB</B> +<DD>Is "Photography - Electronic still picture imaging - Extended sRGB color +encoding" (PIMA 7667:2001). It extends the gamut of sRGB; and its +higher precision numbers provide a larger dynamic range. +<P> + +A triplet of integers represent e-sRGB colors. Three precisions are +supported: +</P> +<P> + +</P> +<DL COMPACT> +<DT>e-sRGB10 +<DD>0 to 1023 +<DT>e-sRGB12 +<DD>0 to 4095 +<DT>e-sRGB16 +<DD>0 to 65535 +</DL> +</DL> +<P> + +<A NAME="IDX765"></A> +</P> +<DL> +<DT><U>Function:</U> <B>e-srgb->color</B> <I>precision rgb</I> +<DD><VAR>precision</VAR> must be the integer 10, 12, or 16. <VAR>rgb</VAR> must be a list of 3 +numbers. If <VAR>rgb</VAR> is valid e-sRGB coordinates, then <CODE>e-srgb->color</CODE> returns the color +specified by <VAR>rgb</VAR>; otherwise returns #f. +</DL> +<P> + +<A NAME="IDX766"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color:e-srgb</B> <I>10 r g b</I> +<DD><P> + +Returns the e-sRGB10 color composed of integers <VAR>r</VAR>, <VAR>g</VAR>, <VAR>b</VAR>. +</P> +<P> + +<A NAME="IDX767"></A> +<DT><U>Function:</U> <B>color:e-srgb</B> <I>12 r g b</I> +<DD>Returns the e-sRGB12 color composed of integers <VAR>r</VAR>, <VAR>g</VAR>, <VAR>b</VAR>. +</P> +<P> + +<A NAME="IDX768"></A> +<DT><U>Function:</U> <B>color:e-srgb</B> <I>16 r g b</I> +<DD>Returns the e-sRGB16 color composed of integers <VAR>r</VAR>, <VAR>g</VAR>, <VAR>b</VAR>. +If the coordinates do not encode a valid e-sRGB color, then an error +is signaled. +</P> +</DL> +<P> + +<A NAME="IDX769"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color->e-srgb</B> <I>precision color</I> +<DD><VAR>precision</VAR> must be the integer 10, 12, or 16. <CODE>color->e-srgb</CODE> returns the list of 3 +integers encoding <VAR>color</VAR> in sRGB10, sRGB12, or sRGB16. +</DL> +<P> + +<A NAME="Spectra"></A> +<HR SIZE="6"> +<A NAME="SEC127"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC122"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC128"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC118"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.9.3 Spectra </H3> +<!--docid::SEC127::--> +<P> + +<A NAME="Spectra"></A> +The following functions compute colors from spectra, scale color +luminance, and extract chromaticity. XYZ is used in the names of +procedures for unnormalized colors; the coordinates of CIEXYZ colors are +constrained as described in <A HREF="slib_5.html#SEC122">5.9.2 Color Spaces</A>. +</P> +<P> + +<CODE>(require 'color-space)</CODE> +</P> +<P> + +A spectrum may be represented as: +</P> +<P> + +<UL> +<LI> +A procedure of one argument accepting real numbers from 380e-9 to +780e-9, the wavelength in meters; or +<LI> +A vector of real numbers representing intensity samples evenly spaced +over some range of wavelengths overlapping the range 380e-9 to 780e-9. +</UL> +<P> + +CIEXYZ values are calculated as dot-product with the X, Y (Luminance), +and Z <EM>Spectral Tristimulus Values</EM>. The files `<TT>cie1931.xyz</TT>' +and `<TT>cie1964.xyz</TT>' in the distribution contain these CIE-defined +values. +<A NAME="IDX770"></A> +</P> +<P> + +<A NAME="IDX771"></A> +</P> +<DL> +<DT><U>Feature:</U> <B>cie1964</B> +<DD><A NAME="IDX772"></A> +Loads the Spectral Tristimulus Values defining <CITE>CIE 1964 +Supplementary Standard Colorimetric Observer</CITE>. +<A NAME="IDX773"></A> +<DT><U>Feature:</U> <B>cie1931</B> +<DD><A NAME="IDX774"></A> +Loads the Spectral Tristimulus Values defining <CITE>CIE 1931 +Supplementary Standard Colorimetric Observer</CITE>. +<A NAME="IDX775"></A> +<DT><U>Feature:</U> <B>ciexyz</B> +<DD><A NAME="IDX776"></A> +Requires Spectral Tristimulus Values, defaulting to cie1931. +</DL> +<P> + +<CODE>(require 'cie1964)</CODE> or <CODE>(require 'cie1931)</CODE> will +<A NAME="IDX777"></A> +<CODE>load-ciexyz</CODE> specific values used by the following spectrum +conversion procedures. The spectrum conversion procedures +<CODE>(require 'ciexyz)</CODE> to assure that a set is loaded. +</P> +<P> + +<A NAME="IDX778"></A> +</P> +<DL> +<DT><U>Function:</U> <B>spectrum->XYZ</B> <I>proc</I> +<DD><VAR>proc</VAR> must be a function of one argument. <CODE>spectrum->XYZ</CODE> +computes the CIEXYZ(1931) values for the spectrum returned by <VAR>proc</VAR> +when called with arguments from 380e-9 to 780e-9, the wavelength in +meters. +<P> + +<A NAME="IDX779"></A> +<DT><U>Function:</U> <B>spectrum->XYZ</B> <I>spectrum x1 x2</I> +<DD><VAR>x1</VAR> and <VAR>x2</VAR> must be positive real numbers specifying the +wavelengths (in meters) corresponding to the zeroth and last elements of +vector or list <VAR>spectrum</VAR>. <CODE>spectrum->XYZ</CODE> returns the +CIEXYZ(1931) values for a light source with spectral values proportional +to the elements of <VAR>spectrum</VAR> at evenly spaced wavelengths between +<VAR>x1</VAR> and <VAR>x2</VAR>. +</P> +<P> + +Compute the colors of 6500.K and 5000.K blackbody radiation: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'color-space) +(define xyz (spectrum->XYZ (blackbody-spectrum 6500))) +(define y_n (cadr xyz)) +(map (lambda (x) (/ x y_n)) xyz) + => (0.9687111145512467 1.0 1.1210875945303613) + +(define xyz (spectrum->XYZ (blackbody-spectrum 5000))) +(map (lambda (x) (/ x y_n)) xyz) + => (0.2933441826889158 0.2988931825387761 0.25783646831201573) +</pre></td></tr></table><P> + +<A NAME="IDX780"></A> +<DT><U>Function:</U> <B>spectrum->CIEXYZ</B> <I>proc</I> +<DD><A NAME="IDX781"></A> +<DT><U>Function:</U> <B>spectrum->CIEXYZ</B> <I>spectrum x1 x2</I> +<DD><CODE>spectrum->CIEXYZ</CODE> computes the CIEXYZ(1931) values for the +spectrum, scaled so their sum is 1. +</P> +</DL> +<P> + +<A NAME="IDX782"></A> +</P> +<DL> +<DT><U>Function:</U> <B>spectrum->chromaticity</B> <I>proc</I> +<DD><A NAME="IDX783"></A> +<DT><U>Function:</U> <B>spectrum->chromaticity</B> <I>spectrum x1 x2</I> +<DD>Computes the chromaticity for the given spectrum. +</DL> +<P> + +<A NAME="IDX784"></A> +</P> +<DL> +<DT><U>Function:</U> <B>wavelength->XYZ</B> <I>w</I> +<DD><A NAME="IDX785"></A> +<DT><U>Function:</U> <B>wavelength->chromaticity</B> <I>w</I> +<DD><A NAME="IDX786"></A> +<DT><U>Function:</U> <B>wavelength->CIEXYZ</B> <I>w</I> +<DD><VAR>w</VAR> must be a number between 380e-9 to 780e-9. +<CODE>wavelength->XYZ</CODE> returns (unnormalized) XYZ values for a +monochromatic light source with wavelength <VAR>w</VAR>. +<CODE>wavelength->chromaticity</CODE> returns the chromaticity for a +monochromatic light source with wavelength <VAR>w</VAR>. +<CODE>wavelength->CIEXYZ</CODE> returns XYZ values for the saturated color +having chromaticity of a monochromatic light source with wavelength +<VAR>w</VAR>. +</DL> +<P> + +<A NAME="IDX787"></A> +</P> +<DL> +<DT><U>Function:</U> <B>blackbody-spectrum</B> <I>temp</I> +<DD><A NAME="IDX788"></A> +<DT><U>Function:</U> <B>blackbody-spectrum</B> <I>temp span</I> +<DD>Returns a procedure of one argument (wavelength in meters), which +returns the radiance of a black body at <VAR>temp</VAR>. +<P> + +The optional argument <VAR>span</VAR> is the wavelength analog of bandwidth. +With the default <VAR>span</VAR> of 1.nm (1e-9.m), the values returned by the +procedure correspond to the power of the photons with wavelengths +<VAR>w</VAR> to <VAR>w</VAR>+1e-9. +</P> +</DL> +<P> + +<A NAME="IDX789"></A> +</P> +<DL> +<DT><U>Function:</U> <B>temperature->XYZ</B> <I>x</I> +<DD>The positive number <VAR>x</VAR> is a temperature in degrees kelvin. +<CODE>temperature->XYZ</CODE> computes the CIEXYZ(1931) values for the +spectrum of a black body at temperature <VAR>x</VAR>. +<P> + +Compute the chromaticities of 6500.K and 5000.K blackbody radiation: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'color-space) +(XYZ->chromaticity (temperature->XYZ 6500)) + => (0.3135191660557008 0.3236456786200268) + +(XYZ->chromaticity (temperature->XYZ 5000)) + => (0.34508082841161052 0.3516084965163377) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX790"></A> +</P> +<DL> +<DT><U>Function:</U> <B>temperature->CIEXYZ</B> <I>x</I> +<DD>The positive number <VAR>x</VAR> is a temperature in degrees kelvin. +<CODE>temperature->CIEXYZ</CODE> computes the CIEXYZ(1931) values for the +spectrum of a black body at temperature <VAR>x</VAR>, scaled to be just +inside the RGB709 gamut. +</DL> +<P> + +<A NAME="IDX791"></A> +</P> +<DL> +<DT><U>Function:</U> <B>temperature->chromaticity</B> <I>x</I> +<DD></DL> +<P> + +<A NAME="IDX792"></A> +</P> +<DL> +<DT><U>Function:</U> <B>XYZ:normalize</B> <I>xyz</I> +<DD><VAR>xyz</VAR> is a list of three non-negative real numbers. +<CODE>XYZ:normalize</CODE> returns a list of numbers proportional to +<VAR>xyz</VAR>; scaled so their sum is 1. +</DL> +<P> + +<A NAME="IDX793"></A> +</P> +<DL> +<DT><U>Function:</U> <B>XYZ:normalize-colors</B> <I>colors <small>...</small></I> +<DD><VAR>colors</VAR> is a list of XYZ triples. <CODE>XYZ:normalize-colors</CODE> +scales all the triples by a common factor such that the maximum sum of +numbers in a scaled triple is 1. +</DL> +<P> + +<A NAME="IDX794"></A> +</P> +<DL> +<DT><U>Function:</U> <B>XYZ->chromaticity</B> <I>xyz</I> +<DD>Returns a two element list: the x and y components of <VAR>xyz</VAR> +normalized to 1 (= <VAR>x</VAR> + <VAR>y</VAR> + <VAR>z</VAR>). +</DL> +<P> + +<A NAME="IDX795"></A> +</P> +<DL> +<DT><U>Function:</U> <B>chromaticity->CIEXYZ</B> <I>x y</I> +<DD>Returns the list of <VAR>x</VAR>, and <VAR>y</VAR>, 1 - <VAR>y</VAR> - <VAR>x</VAR>. +</DL> +<P> + +<A NAME="IDX796"></A> +</P> +<DL> +<DT><U>Function:</U> <B>chromaticity->whitepoint</B> <I>x y</I> +<DD>Returns the CIEXYZ(1931) values having luminosity 1 and chromaticity +<VAR>x</VAR> and <VAR>y</VAR>. +</DL> +<P> + +<A NAME="IDX797"></A> +Many color datasets are expressed in <EM>xyY</EM> format; chromaticity with +CIE luminance (Y). But xyY is not a CIE standard like CIEXYZ, CIELAB, +and CIELUV. Although chrominance is well defined, the luminance +component is sometimes scaled to 1, sometimes to 100, but usually has no +obvious range. With no given whitepoint, the only reasonable course is +to ascertain the luminance range of a dataset and normalize the values +to lie from 0 to 1. +</P> +<P> + +<A NAME="IDX798"></A> +</P> +<DL> +<DT><U>Function:</U> <B>XYZ->xyY</B> <I>xyz</I> +<DD>Returns a three element list: the <VAR>x</VAR> and <VAR>y</VAR> components of +<VAR>XYZ</VAR> normalized to 1, and CIE luminance <VAR>Y</VAR>. +</DL> +<P> + +<A NAME="IDX799"></A> +</P> +<DL> +<DT><U>Function:</U> <B>xyY->XYZ</B> <I>xyY</I> +<DD></DL> +<P> + +<A NAME="IDX800"></A> +</P> +<DL> +<DT><U>Function:</U> <B>xyY:normalize-colors</B> <I>colors</I> +<DD><VAR>colors</VAR> is a list of xyY triples. <CODE>xyY:normalize-colors</CODE> +scales each chromaticity so it sums to 1 or less; and divides the +<VAR>Y</VAR> values by the maximum <VAR>Y</VAR> in the dataset, so all lie between +0 and 1. +<P> + +<A NAME="IDX801"></A> +<DT><U>Function:</U> <B>xyY:normalize-colors</B> <I>colors n</I> +<DD>If <VAR>n</VAR> is positive real, then <CODE>xyY:normalize-colors</CODE> divides +the <VAR>Y</VAR> values by <VAR>n</VAR> times the maximum <VAR>Y</VAR> in the dataset. +</P> +<P> + +If <VAR>n</VAR> is an exact non-positive integer, then +<CODE>xyY:normalize-colors</CODE> divides the <VAR>Y</VAR> values by the maximum of +the <VAR>Y</VAR>s in the dataset excepting the -<VAR>n</VAR> largest <VAR>Y</VAR> +values. +</P> +<P> + +In all cases, returned <VAR>Y</VAR> values are limited to lie from 0 to 1. +</P> +</DL> +<P> + +Why would one want to normalize to other than 1? If the sun or its +reflection is the brightest object in a scene, then normalizing to its +luminance will tend to make the rest of the scene very dark. As with +photographs, limiting the specular highlights looks better than +darkening everything else. +</P> +<P> + +The results of measurements being what they are, +<CODE>xyY:normalize-colors</CODE> is extremely tolerant. Negative numbers are +replaced with zero, and chromaticities with sums greater than one are +scaled to sum to one. +</P> +<P> + +<A NAME="Color Difference Metrics"></A> +<HR SIZE="6"> +<A NAME="SEC128"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC127"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC129"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC118"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.9.4 Color Difference Metrics </H3> +<!--docid::SEC128::--> +<P> + +<A NAME="Color_Difference_Metrics"></A> +</P> +<P> + +<CODE>(require 'color-space)</CODE> +</P> +<P> + +The low-level metric functions operate on lists of 3 numbers, lab1, +lab2, lch1, or lch2. +</P> +<P> + +<CODE>(require 'color)</CODE> +</P> +<P> + +The wrapped functions operate on objects of type color, color1 and +color2 in the function entries. +</P> +<P> + +<A NAME="IDX802"></A> +</P> +<DL> +<DT><U>Function:</U> <B>L*a*b*:DE*</B> <I>lab1 lab2</I> +<DD>Returns the Euclidean distance between <VAR>lab1</VAR> and <VAR>lab2</VAR>. +<P> + +<A NAME="IDX803"></A> +<DT><U>Function:</U> <B>CIE:DE*</B> <I>color1 color2 white-point</I> +<DD><A NAME="IDX804"></A> +<DT><U>Function:</U> <B>CIE:DE*</B> <I>color1 color2</I> +<DD>Returns the Euclidean distance in L*a*b* space between <VAR>color1</VAR> and +<VAR>color2</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX805"></A> +</P> +<DL> +<DT><U>Function:</U> <B>L*C*h:DE*94</B> <I>lch1 lch2 parametric-factors</I> +<DD><A NAME="IDX806"></A> +<DT><U>Function:</U> <B>L*C*h:DE*94</B> <I>lch1 lch2</I> +<DD><P> + +<A NAME="IDX807"></A> +<DT><U>Function:</U> <B>CIE:DE*94</B> <I>color1 color2 parametric-factors</I> +<DD><A NAME="IDX808"></A> +<DT><U>Function:</U> <B>CIE:DE*94</B> <I>color1 color2</I> +<DD></P> +<P> + +Measures distance in the L*C*h cylindrical color-space. +The three axes are individually scaled (depending on C*) in their +contributions to the total distance. +</P> +<P> + +The CIE has defined reference conditions under which the metric with +default parameters can be expected to perform well. These are: +</P> +<P> + +<UL> +<LI> +The specimens are homogeneous in colour. +<LI> +The colour difference (CIELAB) is <= 5 units. +<LI> +They are placed in direct edge contact. +<LI> +Each specimen subtends an angle of >4 degrees to the assessor, whose +colour vision is normal. +<LI> +They are illuminated at 1000 lux, and viewed against a background of +uniform grey, with L* of 50, under illumination simulating D65. +</UL> +<P> + +The <VAR>parametric-factors</VAR> argument is a list of 3 quantities kL, kC +and kH. <VAR>parametric-factors</VAR> independently adjust each +colour-difference term to account for any deviations from the reference +viewing conditions. Under the reference conditions explained above, the +default is kL = kC = kH = 1. +</P> +</DL> +<P> + +The Color Measurement Committee of The Society of Dyers and Colorists in +Great Britain created a more sophisticated color-distance function for +use in judging the consistency of dye lots. With CMC:DE* it is possible +to use a single value pass/fail tolerance for all shades. +</P> +<P> + +<A NAME="IDX809"></A> +</P> +<DL> +<DT><U>Function:</U> <B>CMC-DE</B> <I>lch1 lch2 parametric-factors</I> +<DD><A NAME="IDX810"></A> +<DT><U>Function:</U> <B>CMC-DE</B> <I>lch1 lch2 l c</I> +<DD><A NAME="IDX811"></A> +<DT><U>Function:</U> <B>CMC-DE</B> <I>lch1 lch2 l</I> +<DD><A NAME="IDX812"></A> +<DT><U>Function:</U> <B>CMC-DE</B> <I>lch1 lch2</I> +<DD><P> + +<A NAME="IDX813"></A> +<DT><U>Function:</U> <B>CMC:DE*</B> <I>color1 color2 l c</I> +<DD><A NAME="IDX814"></A> +<DT><U>Function:</U> <B>CMC:DE*</B> <I>color1 color2</I> +<DD></P> +<P> + +<CODE>CMC:DE</CODE> is a L*C*h metric. The <VAR>parametric-factors</VAR> +argument is a list of 2 numbers <VAR>l</VAR> and <VAR>c</VAR>. <VAR>l</VAR> and +<VAR>c</VAR> parameterize this metric. 1 and 1 are recommended for +perceptibility; the default, 2 and 1, for acceptability. +</P> +</DL> +<P> + +<A NAME="Color Conversions"></A> +<HR SIZE="6"> +<A NAME="SEC129"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC128"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC130"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC118"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.9.5 Color Conversions </H3> +<!--docid::SEC129::--> +<P> + +<A NAME="Color_Conversions"></A> +</P> +<P> + +This package contains the low-level color conversion and color metric +routines operating on lists of 3 numbers. There is no type or range +checking. +</P> +<P> + +<CODE>(require 'color-space)</CODE> +</P> +<P> + +<A NAME="IDX815"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>CIEXYZ:D65</B> +<DD>Is the color of 6500.K (blackbody) illumination. D65 is close to the +average color of daylight. +</DL> +<P> + +<A NAME="IDX816"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>CIEXYZ:D50</B> +<DD>Is the color of 5000.K (blackbody) illumination. D50 is the color of +indoor lighting by incandescent bulbs. +</DL> +<P> + +<A NAME="IDX817"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>CIEXYZ:A</B> +<DD><A NAME="IDX818"></A> +<DT><U>Constant:</U> <B>CIEXYZ:B</B> +<DD><A NAME="IDX819"></A> +<DT><U>Constant:</U> <B>CIEXYZ:C</B> +<DD><A NAME="IDX820"></A> +<DT><U>Constant:</U> <B>CIEXYZ:E</B> +<DD>CIE 1931 illuminants normalized to 1 = y. +</DL> +<P> + +<A NAME="IDX821"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color:linear-transform</B> <I>matrix row</I> +<DD></DL> +<P> + +<A NAME="IDX822"></A> +</P> +<DL> +<DT><U>Function:</U> <B>CIEXYZ->RGB709</B> <I>xyz</I> +<DD><A NAME="IDX823"></A> +<DT><U>Function:</U> <B>RGB709->CIEXYZ</B> <I>srgb</I> +<DD></DL> +<P> + +<A NAME="IDX824"></A> +</P> +<DL> +<DT><U>Function:</U> <B>CIEXYZ->L*u*v*</B> <I>xyz white-point</I> +<DD><A NAME="IDX825"></A> +<DT><U>Function:</U> <B>CIEXYZ->L*u*v*</B> <I>xyz</I> +<DD><A NAME="IDX826"></A> +<DT><U>Function:</U> <B>L*u*v*->CIEXYZ</B> <I>L*u*v* white-point</I> +<DD><A NAME="IDX827"></A> +<DT><U>Function:</U> <B>L*u*v*->CIEXYZ</B> <I>L*u*v*</I> +<DD>The <VAR>white-point</VAR> defaults to CIEXYZ:D65. +</DL> +<P> + +<A NAME="IDX828"></A> +</P> +<DL> +<DT><U>Function:</U> <B>CIEXYZ->L*a*b*</B> <I>xyz white-point</I> +<DD><A NAME="IDX829"></A> +<DT><U>Function:</U> <B>CIEXYZ->L*a*b*</B> <I>xyz</I> +<DD><A NAME="IDX830"></A> +<DT><U>Function:</U> <B>L*a*b*->CIEXYZ</B> <I>L*a*b* white-point</I> +<DD><A NAME="IDX831"></A> +<DT><U>Function:</U> <B>L*a*b*->CIEXYZ</B> <I>L*a*b*</I> +<DD>The XYZ <VAR>white-point</VAR> defaults to CIEXYZ:D65. +</DL> +<P> + +<A NAME="IDX832"></A> +</P> +<DL> +<DT><U>Function:</U> <B>L*a*b*->L*C*h</B> <I>L*a*b*</I> +<DD><A NAME="IDX833"></A> +<DT><U>Function:</U> <B>L*C*h->L*a*b*</B> <I>L*C*h</I> +<DD></DL> +<P> + +<A NAME="IDX834"></A> +</P> +<DL> +<DT><U>Function:</U> <B>CIEXYZ->sRGB</B> <I>xyz</I> +<DD><A NAME="IDX835"></A> +<DT><U>Function:</U> <B>sRGB->CIEXYZ</B> <I>srgb</I> +<DD></DL> +<P> + +<A NAME="IDX836"></A> +</P> +<DL> +<DT><U>Function:</U> <B>CIEXYZ->xRGB</B> <I>xyz</I> +<DD><A NAME="IDX837"></A> +<DT><U>Function:</U> <B>xRGB->CIEXYZ</B> <I>srgb</I> +<DD></DL> +<P> + +<A NAME="IDX838"></A> +</P> +<DL> +<DT><U>Function:</U> <B>sRGB->xRGB</B> <I>xyz</I> +<DD><A NAME="IDX839"></A> +<DT><U>Function:</U> <B>xRGB->sRGB</B> <I>srgb</I> +<DD></DL> +<P> + +<A NAME="IDX840"></A> +</P> +<DL> +<DT><U>Function:</U> <B>CIEXYZ->e-sRGB</B> <I>n xyz</I> +<DD><A NAME="IDX841"></A> +<DT><U>Function:</U> <B>e-sRGB->CIEXYZ</B> <I>n srgb</I> +<DD></DL> +<P> + +<A NAME="IDX842"></A> +</P> +<DL> +<DT><U>Function:</U> <B>sRGB->e-sRGB</B> <I>n srgb</I> +<DD><A NAME="IDX843"></A> +<DT><U>Function:</U> <B>e-sRGB->sRGB</B> <I>n srgb</I> +<DD>The integer <VAR>n</VAR> must be 10, 12, or 16. Because sRGB and e-sRGB use +the same RGB709 chromaticities, conversion between them is simpler than +conversion through CIEXYZ. +</DL> +<P> + +Do not convert e-sRGB precision through <CODE>e-sRGB->sRGB</CODE> then +<CODE>sRGB->e-sRGB</CODE> -- values would be truncated to 8-bits! +</P> +<P> + +<A NAME="IDX844"></A> +</P> +<DL> +<DT><U>Function:</U> <B>e-sRGB->e-sRGB</B> <I>n1 srgb n2</I> +<DD>The integers <VAR>n1</VAR> and <VAR>n2</VAR> must be 10, 12, or 16. +<CODE>e-sRGB->e-sRGB</CODE> converts <VAR>srgb</VAR> to e-sRGB of precision +<VAR>n2</VAR>. +</DL> +<P> + +<A NAME="Color Names"></A> +<HR SIZE="6"> +<A NAME="SEC130"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC129"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC133"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC118"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.9.6 Color Names </H3> +<!--docid::SEC130::--> +<P> + +<A NAME="Color_Names"></A> +<CODE>(require 'color-names)</CODE> +<A NAME="IDX845"></A> +</P> +<P> + +Rather than ballast the color dictionaries with numbered grays, +<CODE>file->color-dictionary</CODE> discards them. They are provided +through the <CODE>grey</CODE> procedure: +</P> +<P> + +<A NAME="IDX846"></A> +</P> +<DL> +<DT><U>Function:</U> <B>grey</B> <I>k</I> +<DD><P> + +Returns <CODE>(inexact->exact (round (* k 2.55)))</CODE>, the X11 color +grey<I><k></I>. +</P> +</DL> +A color dictionary is a database table relating <EM>canonical</EM> +<A NAME="IDX847"></A> +color-names to color-strings +(see section <A HREF="slib_5.html#SEC119">External Representation</A>). +<P> + +The column names in a color dictionary are unimportant; the first +field is the key, and the second is the color-string. +</P> +<P> + +<A NAME="IDX848"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color-name:canonicalize</B> <I>name</I> +<DD>Returns a downcased copy of the string or symbol <VAR>name</VAR> with +`<SAMP>_</SAMP>', `<SAMP>-</SAMP>', and whitespace removed. +</DL> +<P> + +<A NAME="IDX849"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color-name->color</B> <I>name table1 table2 <small>...</small></I> +<DD><P> + +<VAR>table1</VAR>, <VAR>table2</VAR>, <small>...</small> must be color-dictionary tables. <CODE>color-name->color</CODE> searches for the +canonical form of <VAR>name</VAR> in <VAR>table1</VAR>, <VAR>table2</VAR>, <small>...</small> in order; returning the +color-string of the first matching record; #f otherwise. +</P> +</DL> +<P> + +<A NAME="IDX850"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color-dictionaries->lookup</B> <I>table1 table2 <small>...</small></I> +<DD><P> + +<VAR>table1</VAR>, <VAR>table2</VAR>, <small>...</small> must be color-dictionary tables. <CODE>color-dictionaries->lookup</CODE> returns a +procedure which searches for the canonical form of its string argument +in <VAR>table1</VAR>, <VAR>table2</VAR>, <small>...</small>; returning the color-string of the first matching +record; and #f otherwise. +</P> +</DL> +<P> + +<A NAME="IDX851"></A> +</P> +<DL> +<DT><U>Function:</U> <B>color-dictionary</B> <I>name rdb base-table-type</I> +<DD><P> + +<VAR>rdb</VAR> must be a string naming a relational database file; and the symbol +<VAR>name</VAR> a table therein. The database will be opened as +<VAR>base-table-type</VAR>. <CODE>color-dictionary</CODE> returns the read-only table <VAR>name</VAR> in database +<VAR>name</VAR> if it exists; #f otherwise. +</P> +<P> + +<A NAME="IDX852"></A> +<DT><U>Function:</U> <B>color-dictionary</B> <I>name rdb</I> +<DD></P> +<P> + +<VAR>rdb</VAR> must be an open relational database or a string naming a relational +database file; and the symbol <VAR>name</VAR> a table therein. <CODE>color-dictionary</CODE> returns the +read-only table <VAR>name</VAR> in database <VAR>name</VAR> if it exists; #f otherwise. +</P> +</DL> +<P> + +<A NAME="IDX853"></A> +</P> +<DL> +<DT><U>Function:</U> <B>load-color-dictionary</B> <I>name rdb base-table-type</I> +<DD><P> + +<A NAME="IDX854"></A> +<DT><U>Function:</U> <B>load-color-dictionary</B> <I>name rdb</I> +<DD></P> +<P> + +<VAR>rdb</VAR> must be a string naming a relational database file; and the symbol +<VAR>name</VAR> a table therein. If the symbol <VAR>base-table-type</VAR> is provided, the database will +be opened as <VAR>base-table-type</VAR>. <CODE>load-color-dictionary</CODE> creates a top-level definition of the symbol <VAR>name</VAR> +to a lookup procedure for the color dictionary <VAR>name</VAR> in <VAR>rdb</VAR>. +</P> +<P> + +The value returned by <CODE>load-color-dictionary</CODE> is unspecified. +</P> +</DL> +<P> + +<A NAME="SEC131"></A> +<H4> Dictionary Creation </H4> +<!--docid::SEC131::--> +<P> + +<CODE>(require 'color-database)</CODE> +<A NAME="IDX855"></A> +</P> +<P> + +<A NAME="IDX856"></A> +</P> +<DL> +<DT><U>Function:</U> <B>file->color-dictionary</B> <I>file table-name rdb base-table-type</I> +<DD><P> + +<A NAME="IDX857"></A> +<DT><U>Function:</U> <B>file->color-dictionary</B> <I>file table-name rdb</I> +<DD></P> +<P> + +<VAR>rdb</VAR> must be an open relational database or a string naming a relational +database file, <VAR>table-name</VAR> a symbol, and the string <VAR>file</VAR> must name an existing +file with colornames and their corresponding xRGB (6-digit hex) +values. <CODE>file->color-dictionary</CODE> creates a table <VAR>table-name</VAR> in <VAR>rdb</VAR> and enters the associations found +in <VAR>file</VAR> into it. +</P> +</DL> +<P> + +<A NAME="IDX858"></A> +</P> +<DL> +<DT><U>Function:</U> <B>url->color-dictionary</B> <I>url table-name rdb base-table-type</I> +<DD><P> + +<A NAME="IDX859"></A> +<DT><U>Function:</U> <B>url->color-dictionary</B> <I>url table-name rdb</I> +<DD></P> +<P> + +<VAR>rdb</VAR> must be an open relational database or a string naming a relational +database file and <VAR>table-name</VAR> a symbol. <CODE>url->color-dictionary</CODE> retrieves the resource named by the +string <VAR>url</VAR> using the <EM>wget</EM> program; then calls +<A NAME="IDX860"></A> +<CODE>file->color-dictionary</CODE> to enter its associations in <VAR>table-name</VAR> in <VAR>url</VAR>. +</P> +</DL> +This section has detailed the procedures for creating and loading +color dictionaries. So where are the dictionaries to load? +<P> + +<A HREF="http://swissnet.ai.mit.edu/~jaffer/Color/Dictionaries.html">http://swissnet.ai.mit.edu/~jaffer/Color/Dictionaries.html</A> +</P> +<P> + +Describes and evaluates several color-name dictionaries on the web. +The following procedure creates a database containing two of these +dictionaries. +</P> +<P> + +<A NAME="IDX861"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-slib-color-name-db</B> +<DD><P> + +Creates an alist-table relational database in library-vicinity +containing the <EM>Resene</EM> and <EM>saturate</EM> color-name +<A NAME="IDX862"></A> +<A NAME="IDX863"></A> +dictionaries. +</P> +<P> + +If the files `<TT>resenecolours.txt</TT>' and `<TT>saturate.txt</TT>' exist in +the library-vicinity, then they used as the source of color-name +data. Otherwise, <CODE>make-slib-color-name-db</CODE> calls url->color-dictionary with the URLs of +appropriate source files. +</P> +</DL> +<P> + +<A NAME="SEC132"></A> +<H4> The Short List </H4> +<!--docid::SEC132::--> +<P> + +<CODE>(require 'saturate)</CODE> +<A NAME="IDX864"></A> +</P> +<P> + +<A NAME="IDX865"></A> +</P> +<DL> +<DT><U>Function:</U> <B>saturate</B> <I>name</I> +<DD>Looks for <VAR>name</VAR> among the 19 saturated colors from +<CITE>Approximate Colors on CIE Chromaticity Diagram</CITE>: +<P> + +</P> +<TABLE> +<TR><TD>reddish orange </TD><TD> orange </TD><TD> yellowish orange </TD><TD> yellow</TD> +</TR> +<TR><TD>greenish yellow </TD><TD> yellow green </TD><TD> yellowish green </TD><TD> green</TD> +</TR> +<TR><TD>bluish green </TD><TD> blue green </TD><TD> greenish blue </TD><TD> blue</TD> +</TR> +<TR><TD>purplish blue </TD><TD> bluish purple </TD><TD> purple </TD><TD> reddish purple</TD> +</TR> +<TR><TD>red purple </TD><TD> purplish red </TD><TD> red</TD> +</TR></TABLE> +<P> + +(<A HREF="http://swissnet.ai.mit.edu/~jaffer/Color/saturate.pdf">http://swissnet.ai.mit.edu/~jaffer/Color/saturate.pdf</A>). If +<VAR>name</VAR> is found, the corresponding color is returned. Otherwise #f +is returned. Use saturate only for light source colors. +</P> +</DL> +<P> + +Resene Paints Limited, New Zealand's largest privately-owned and +operated paint manufacturing company, has generously made their +<CITE>Resene RGB Values List</CITE> available. +</P> +<P> + +<CODE>(require 'resene)</CODE> +<A NAME="IDX866"></A> +</P> +<P> + +<A NAME="IDX867"></A> +</P> +<DL> +<DT><U>Function:</U> <B>resene</B> <I>name</I> +<DD>Looks for <VAR>name</VAR> among the 1300 entries in the Resene color-name +dictionary (<A HREF="http://swissnet.ai.mit.edu/~jaffer/Color/resene.pdf">http://swissnet.ai.mit.edu/~jaffer/Color/resene.pdf</A>). +If <VAR>name</VAR> is found, the corresponding color is returned. Otherwise +#f is returned. The <CITE>Resene RGB Values List</CITE> is an excellent +source for surface colors. +</DL> +<P> + +If you include the <EM>Resene RGB Values List</EM> in binary form in a +program, then you must include its license with your program: +</P> +<P> + +<BLOCKQUOTE> +Resene RGB Values List<BR> +For further information refer to http://www.resene.co.nz<BR> +Copyright Resene Paints Ltd 2001 +<P> + +Permission to copy this dictionary, to modify it, to redistribute it, +to distribute modified versions, and to use it for any purpose is +granted, subject to the following restrictions and understandings. +</P> +<P> + +<OL> +<LI> +Any text copy made of this dictionary must include this copyright +notice in full. +<P> + +</P> +<LI> +Any redistribution in binary form must reproduce this copyright +notice in the documentation or other materials provided with the +distribution. +<P> + +</P> +<LI> +Resene Paints Ltd makes no warranty or representation that this +dictionary is error-free, and is under no obligation to provide any +services, by way of maintenance, update, or otherwise. +<P> + +</P> +<LI> +There shall be no use of the name of Resene or Resene Paints Ltd +in any advertising, promotional, or sales literature without prior +written consent in each case. +<P> + +</P> +<LI> +These RGB colour formulations may not be used to the detriment of +Resene Paints Ltd. +</OL> +</BLOCKQUOTE> +<P> + +<A NAME="Daylight"></A> +<HR SIZE="6"> +<A NAME="SEC133"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC130"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC134"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC118"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 5.9.7 Daylight </H3> +<!--docid::SEC133::--> +<P> + +<A NAME="Daylight"></A> +<CODE>(require 'daylight)</CODE> +<A NAME="IDX868"></A> +<A NAME="IDX869"></A> +<A NAME="IDX870"></A> +<A NAME="IDX871"></A> +</P> +<P> + +This package calculates the colors of sky as detailed in:<BR> +<A HREF="http://www.cs.utah.edu/vissim/papers/sunsky/sunsky.pdf">http://www.cs.utah.edu/vissim/papers/sunsky/sunsky.pdf</A><BR> +<CITE>A Practical Analytic Model for Daylight</CITE><BR> +A. J. Preetham, Peter Shirley, Brian Smits +</P> +<P> + +<A NAME="IDX872"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solar-hour</B> <I>julian-day hour</I> +<DD><P> + +Returns the solar-time in hours given the integer <VAR>julian-day</VAR> in the range 1 to +366, and the local time in hours. +</P> +<P> + +To be meticulous, subtract 4 minutes for each degree of longitude west +of the standard meridian of your time zone. +</P> +</DL> +<P> + +<A NAME="IDX873"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solar-declination</B> <I>julian-day</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX874"></A> +</P> +<DL> +<DT><U>Function:</U> <B>solar-polar</B> <I>declination latitude solar-hour</I> +<DD>Returns a list of <VAR>theta_s</VAR>, the solar angle from the +zenith, and <VAR>phi_s</VAR>, the solar azimuth. 0 <= <VAR>theta_s</VAR> +measured in degrees. <VAR>phi_s</VAR> is measured in degrees from due +south; west of south being positive. +</DL> +In the following procedures, the number 0 <= <VAR>theta_s</VAR> <= 90 is +the solar angle from the zenith in degrees. +<P> + +<A NAME="IDX875"></A> +Turbidity is a measure of the fraction of scattering due to haze as +opposed to molecules. This is a convenient quantity because it can be +estimated based on visibility of distant objects. This model fails +for turbidity values less than 1.3. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre> _______________________________________________________________ +512|-: | + | * pure-air | +256|-:** | + | : ** exceptionally-clear | +128|-: * | + | : ** | + 64|-: * | + | : ** very-clear | + 32|-: ** | + | : ** | + 16|-: *** clear | + | : **** | + 8|-: **** | + | : **** light-haze | + 4|-: **** | + | : ****** | + 2|-: ******** haze thin-| + | : *********** fog | + 1|-:----------------------------------------------------*******--| + |_:____.____:____.____:____.____:____.____:____.____:____.____:_| + 1 2 4 8 16 32 64 + Meterorological range (km) versus Turbidity +</pre></td></tr></table><P> + +<A NAME="IDX876"></A> +</P> +<DL> +<DT><U>Function:</U> <B>sunlight-spectrum</B> <I>turbidity theta_s</I> +<DD>Returns a vector of 41 values, the spectrum of sunlight from +380.nm to 790.nm for a given <VAR>turbidity</VAR> and <VAR>theta_s</VAR>. +</DL> +<P> + +<A NAME="IDX877"></A> +</P> +<DL> +<DT><U>Function:</U> <B>sunlight-xyz</B> <I>turbidity theta_s</I> +<DD>Returns (unnormalized) XYZ values for color of sunlight for a +given <VAR>turbidity</VAR> and <VAR>theta_s</VAR>. +</DL> +<P> + +<A NAME="IDX878"></A> +</P> +<DL> +<DT><U>Function:</U> <B>sunlight-ciexyz</B> <I>turbidity theta_s</I> +<DD>Given <VAR>turbidity</VAR> and <VAR>theta_s</VAR>, <CODE>sunlight-ciexyz</CODE> returns the CIEXYZ triple for color of +sunlight scaled to be just inside the RGB709 gamut. +</DL> +<P> + +<A NAME="IDX879"></A> +</P> +<DL> +<DT><U>Function:</U> <B>zenith-xyy</B> <I>turbidity theta_s</I> +<DD>Returns the xyY (chromaticity and luminance) at the zenith. The +Luminance has units kcd/m^2. +</DL> +<P> + +<A NAME="IDX880"></A> +</P> +<DL> +<DT><U>Function:</U> <B>overcast-sky-color-xyy</B> <I>turbidity theta_s</I> +<DD><VAR>turbidity</VAR> is a positive real number expressing the amount of light +scattering. The real number <VAR>theta_s</VAR> is the solar angle from the zenith in +degrees. +<P> + +<CODE>overcast-sky-color-xyy</CODE> returns a function of one angle <VAR>theta</VAR>, the angle from the +zenith of the viewing direction (in degrees); and returning the xyY +value for light coming from that elevation of the sky. +</P> +</DL> +<P> + +<A NAME="IDX881"></A> +</P> +<DL> +<DT><U>Function:</U> <B>clear-sky-color-xyy</B> <I>turbidity theta_s phi_s</I> +<DD><A NAME="IDX882"></A> +<DT><U>Function:</U> <B>sky-color-xyy</B> <I>turbidity theta_s phi_s</I> +<DD><VAR>turbidity</VAR> is a positive real number expressing the amount of light +scattering. The real number <VAR>theta_s</VAR> is the solar angle from the zenith in +degrees. The real number <VAR>phi_s</VAR> is the solar angle from south. +<P> + +<CODE>clear-sky-color-xyy</CODE> returns a function of two angles, <VAR>theta</VAR> and <VAR>phi</VAR> which +specify the angles from the zenith and south meridian of the viewing +direction (in degrees); returning the xyY value for light coming from +that direction of the sky. +</P> +<P> + +<CODE>sky-color-xyY</CODE> calls <CODE>overcast-sky-color-xyY</CODE> for +<VAR>turbidity</VAR> <= 20; otherwise the <CODE>clear-sky-color-xyy</CODE> function. +</P> +</DL> +<P> + +<A NAME="Root Finding"></A> +<HR SIZE="6"> +<A NAME="SEC134"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC133"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC135"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.10 Root Finding </H2> +<!--docid::SEC134::--> +<P> + +<CODE>(require 'root)</CODE> +<A NAME="IDX883"></A> +</P> +<P> + +<A NAME="IDX884"></A> +</P> +<DL> +<DT><U>Function:</U> <B>newton:find-integer-root</B> <I>f df/dx x0</I> +<DD>Given integer valued procedure <VAR>f</VAR>, its derivative (with respect to +its argument) <VAR>df/dx</VAR>, and initial integer value <VAR>x0</VAR> for which +<VAR>df/dx</VAR>(<VAR>x0</VAR>) is non-zero, returns an integer <VAR>x</VAR> for which +<VAR>f</VAR>(<VAR>x</VAR>) is closer to zero than either of the integers adjacent +to <VAR>x</VAR>; or returns <CODE>#f</CODE> if such an integer can't be found. +<P> + +To find the closest integer to a given integers square root: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define (integer-sqrt y) + (newton:find-integer-root + (lambda (x) (- (* x x) y)) + (lambda (x) (* 2 x)) + (ash 1 (quotient (integer-length y) 2)))) + +(integer-sqrt 15) => 4 +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX885"></A> +</P> +<DL> +<DT><U>Function:</U> <B>integer-sqrt</B> <I>y</I> +<DD>Given a non-negative integer <VAR>y</VAR>, returns the rounded square-root of +<VAR>y</VAR>. +</DL> +<P> + +<A NAME="IDX886"></A> +</P> +<DL> +<DT><U>Function:</U> <B>newton:find-root</B> <I>f df/dx x0 prec</I> +<DD>Given real valued procedures <VAR>f</VAR>, <VAR>df/dx</VAR> of one (real) +argument, initial real value <VAR>x0</VAR> for which <VAR>df/dx</VAR>(<VAR>x0</VAR>) is +non-zero, and positive real number <VAR>prec</VAR>, returns a real <VAR>x</VAR> +for which <CODE>abs</CODE>(<VAR>f</VAR>(<VAR>x</VAR>)) is less than <VAR>prec</VAR>; or +returns <CODE>#f</CODE> if such a real can't be found. +<P> + +If <VAR>prec</VAR> is instead a negative integer, <CODE>newton:find-root</CODE> +returns the result of -<VAR>prec</VAR> iterations. +</P> +</DL> +<P> + +H. J. Orchard, <CITE>The Laguerre Method for Finding the Zeros of +Polynomials</CITE>, IEEE Transactions on Circuits and Systems, Vol. 36, +No. 11, November 1989, pp 1377-1381. +</P> +<P> + +<BLOCKQUOTE> +There are 2 errors in Orchard's Table II. Line k=2 for starting +value of 1000+j0 should have Z_k of 1.0475 + j4.1036 and line k=2 +for starting value of 0+j1000 should have Z_k of 1.0988 + j4.0833. +</BLOCKQUOTE> +<P> + +<A NAME="IDX887"></A> +</P> +<DL> +<DT><U>Function:</U> <B>laguerre:find-root</B> <I>f df/dz ddf/dz^2 z0 prec</I> +<DD>Given complex valued procedure <VAR>f</VAR> of one (complex) argument, its +derivative (with respect to its argument) <VAR>df/dx</VAR>, its second +derivative <VAR>ddf/dz^2</VAR>, initial complex value <VAR>z0</VAR>, and positive +real number <VAR>prec</VAR>, returns a complex number <VAR>z</VAR> for which +<CODE>magnitude</CODE>(<VAR>f</VAR>(<VAR>z</VAR>)) is less than <VAR>prec</VAR>; or returns +<CODE>#f</CODE> if such a number can't be found. +<P> + +If <VAR>prec</VAR> is instead a negative integer, <CODE>laguerre:find-root</CODE> +returns the result of -<VAR>prec</VAR> iterations. +</P> +</DL> +<P> + +<A NAME="IDX888"></A> +</P> +<DL> +<DT><U>Function:</U> <B>laguerre:find-polynomial-root</B> <I>deg f df/dz ddf/dz^2 z0 prec</I> +<DD>Given polynomial procedure <VAR>f</VAR> of integer degree <VAR>deg</VAR> of one +argument, its derivative (with respect to its argument) <VAR>df/dx</VAR>, its +second derivative <VAR>ddf/dz^2</VAR>, initial complex value <VAR>z0</VAR>, and +positive real number <VAR>prec</VAR>, returns a complex number <VAR>z</VAR> for +which <CODE>magnitude</CODE>(<VAR>f</VAR>(<VAR>z</VAR>)) is less than <VAR>prec</VAR>; or +returns <CODE>#f</CODE> if such a number can't be found. +<P> + +If <VAR>prec</VAR> is instead a negative integer, +<CODE>laguerre:find-polynomial-root</CODE> returns the result of -<VAR>prec</VAR> +iterations. +</P> +</DL> +<P> + +<A NAME="IDX889"></A> +</P> +<DL> +<DT><U>Function:</U> <B>secant:find-root</B> <I>f x0 x1 prec</I> +<DD><A NAME="IDX890"></A> +<DT><U>Function:</U> <B>secant:find-bracketed-root</B> <I>f x0 x1 prec</I> +<DD>Given a real valued procedure <VAR>f</VAR> and two real valued starting +points <VAR>x0</VAR> and <VAR>x1</VAR>, returns a real <VAR>x</VAR> for which +<CODE>(abs (f x))</CODE> is less than <VAR>prec</VAR>; or returns +<CODE>#f</CODE> if such a real can't be found. +<P> + +If <VAR>x0</VAR> and <VAR>x1</VAR> are chosen such that they bracket a root, that is +<TABLE><tr><td> </td><td class=example><pre>(or (< (f x0) 0 (f x1)) + (< (f x1) 0 (f x0))) +</pre></td></tr></table>then the root returned will be between <VAR>x0</VAR> and <VAR>x1</VAR>, and +<VAR>f</VAR> will not be passed an argument outside of that interval. +<P> + +<CODE>secant:find-bracketed-root</CODE> will return <CODE>#f</CODE> unless <VAR>x0</VAR> +and <VAR>x1</VAR> bracket a root. +</P> +<P> + +The secant method is used until a bracketing interval is found, at which point +a modified <I>regula falsi</I> method is used. +</P> +<P> + +If <VAR>prec</VAR> is instead a negative integer, <CODE>secant:find-root</CODE> +returns the result of -<VAR>prec</VAR> iterations. +</P> +<P> + +If <VAR>prec</VAR> is a procedure it should accept 5 arguments: <VAR>x0</VAR> +<VAR>f0</VAR> <VAR>x1</VAR> <VAR>f1</VAR> and <VAR>count</VAR>, where <VAR>f0</VAR> will be +<CODE>(f x0)</CODE>, <VAR>f1</VAR> <CODE>(f x1)</CODE>, and <VAR>count</VAR> the number of +iterations performed so far. <VAR>prec</VAR> should return non-false +if the iteration should be stopped. +</P> +</DL> +<P> + +<A NAME="Minimizing"></A> +<HR SIZE="6"> +<A NAME="SEC135"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC134"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC136"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.11 Minimizing </H2> +<!--docid::SEC135::--> +<P> + +<CODE>(require 'minimize)</CODE> +<A NAME="IDX891"></A> +<A NAME="IDX892"></A> +</P> +<P> + +</P> +<P> + +The Golden Section Search +<A NAME="DOCF6" HREF="slib_fot.html#FOOT6">(6)</A> +algorithm finds minima of functions which +are expensive to compute or for which derivatives are not available. +Although optimum for the general case, convergence is slow, +requiring nearly 100 iterations for the example (x^3-2x-5). +</P> +<P> + +</P> +<P> + +If the derivative is available, Newton-Raphson is probably a better +choice. If the function is inexpensive to compute, consider +approximating the derivative. +</P> +<P> + +<A NAME="IDX893"></A> +</P> +<DL> +<DT><U>Function:</U> <B>golden-section-search</B> <I>f x0 x1 prec</I> +<DD><P> + +<VAR>x_0</VAR> are <VAR>x_1</VAR> real numbers. The (single argument) +procedure <VAR>f</VAR> is unimodal over the open interval (<VAR>x_0</VAR>, +<VAR>x_1</VAR>). That is, there is exactly one point in the interval for +which the derivative of <VAR>f</VAR> is zero. +</P> +<P> + +<CODE>golden-section-search</CODE> returns a pair (<VAR>x</VAR> . <VAR>f</VAR>(<VAR>x</VAR>)) where <VAR>f</VAR>(<VAR>x</VAR>) +is the minimum. The <VAR>prec</VAR> parameter is the stop criterion. If +<VAR>prec</VAR> is a positive number, then the iteration continues until +<VAR>x</VAR> is within <VAR>prec</VAR> from the true value. If <VAR>prec</VAR> is +a negative integer, then the procedure will iterate <VAR>-prec</VAR> +times or until convergence. If <VAR>prec</VAR> is a procedure of seven +arguments, <VAR>x0</VAR>, <VAR>x1</VAR>, <VAR>a</VAR>, <VAR>b</VAR>, <VAR>fa</VAR>, <VAR>fb</VAR>, +and <VAR>count</VAR>, then the iterations will stop when the procedure +returns <CODE>#t</CODE>. +</P> +<P> + +Analytically, the minimum of x^3-2x-5 is 0.816497. +<TABLE><tr><td> </td><td class=example><pre>(define func (lambda (x) (+ (* x (+ (* x x) -2)) -5))) +(golden-section-search func 0 1 (/ 10000)) + ==> (816.4883855245578e-3 . -6.0886621077391165) +(golden-section-search func 0 1 -5) + ==> (819.6601125010515e-3 . -6.088637561916407) +(golden-section-search func 0 1 + (lambda (a b c d e f g ) (= g 500))) + ==> (816.4965933140557e-3 . -6.088662107903635) +</pre></td></tr></table></DL> +<P> + +<A NAME="Commutative Rings"></A> +<HR SIZE="6"> +<A NAME="SEC136"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC135"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC137"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.12 Commutative Rings </H2> +<!--docid::SEC136::--> +<P> + +Scheme provides a consistent and capable set of numeric functions. +Inexacts implement a field; integers a commutative ring (and Euclidean +domain). This package allows one to use basic Scheme numeric functions +with symbols and non-numeric elements of commutative rings. +</P> +<P> + +<CODE>(require 'commutative-ring)</CODE> +<A NAME="IDX894"></A> +<A NAME="IDX895"></A> +</P> +<P> + +The <EM>commutative-ring</EM> package makes the procedures <CODE>+</CODE>, +<CODE>-</CODE>, <CODE>*</CODE>, <CODE>/</CODE>, and <CODE>^</CODE> <EM>careful</EM> in the sense +<A NAME="IDX896"></A> +that any non-numeric arguments they do not reduce appear in the +expression output. In order to see what working with this package is +like, self-set all the single letter identifiers (to their corresponding +symbols). +<A NAME="IDX897"></A> +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define a 'a) +<small>...</small> +(define z 'z) +</pre></td></tr></table><P> + +Or just <CODE>(require 'self-set)</CODE>. Now try some sample expressions: +<A NAME="IDX898"></A> +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(+ (+ a b) (- a b)) => (* a 2) +(* (+ a b) (+ a b)) => (^ (+ a b) 2) +(* (+ a b) (- a b)) => (* (+ a b) (- a b)) +(* (- a b) (- a b)) => (^ (- a b) 2) +(* (- a b) (+ a b)) => (* (+ a b) (- a b)) +(/ (+ a b) (+ c d)) => (/ (+ a b) (+ c d)) +(^ (+ a b) 3) => (^ (+ a b) 3) +(^ (+ a 2) 3) => (^ (+ 2 a) 3) +</pre></td></tr></table><P> + +Associative rules have been applied and repeated addition and +multiplication converted to multiplication and exponentiation. +</P> +<P> + +We can enable distributive rules, thus expanding to sum of products +form: +<TABLE><tr><td> </td><td class=example><pre>(set! *ruleset* (combined-rulesets distribute* distribute/)) + +(* (+ a b) (+ a b)) => (+ (* 2 a b) (^ a 2) (^ b 2)) +(* (+ a b) (- a b)) => (- (^ a 2) (^ b 2)) +(* (- a b) (- a b)) => (- (+ (^ a 2) (^ b 2)) (* 2 a b)) +(* (- a b) (+ a b)) => (- (^ a 2) (^ b 2)) +(/ (+ a b) (+ c d)) => (+ (/ a (+ c d)) (/ b (+ c d))) +(/ (+ a b) (- c d)) => (+ (/ a (- c d)) (/ b (- c d))) +(/ (- a b) (- c d)) => (- (/ a (- c d)) (/ b (- c d))) +(/ (- a b) (+ c d)) => (- (/ a (+ c d)) (/ b (+ c d))) +(^ (+ a b) 3) => (+ (* 3 a (^ b 2)) (* 3 b (^ a 2)) (^ a 3) (^ b 3)) +(^ (+ a 2) 3) => (+ 8 (* a 12) (* (^ a 2) 6) (^ a 3)) +</pre></td></tr></table><P> + +Use of this package is not restricted to simple arithmetic expressions: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'determinant) + +(determinant '((a b c) (d e f) (g h i))) => +(- (+ (* a e i) (* b f g) (* c d h)) (* a f h) (* b d i) (* c e g)) +</pre></td></tr></table><P> + +Currently, only <CODE>+</CODE>, <CODE>-</CODE>, <CODE>*</CODE>, <CODE>/</CODE>, and <CODE>^</CODE> +support non-numeric elements. Expressions with <CODE>-</CODE> are converted +to equivalent expressions without <CODE>-</CODE>, so behavior for <CODE>-</CODE> is +not defined separately. <CODE>/</CODE> expressions are handled similarly. +</P> +<P> + +This list might be extended to include <CODE>quotient</CODE>, <CODE>modulo</CODE>, +<CODE>remainder</CODE>, <CODE>lcm</CODE>, and <CODE>gcd</CODE>; but these work only for +the more restrictive Euclidean (Unique Factorization) Domain. +<A NAME="IDX899"></A> +<A NAME="IDX900"></A> +</P> +<P> + +<HR SIZE="6"> +<A NAME="SEC137"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC136"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC138"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.13 Rules and Rulesets </H2> +<!--docid::SEC137::--> +<P> + +The <EM>commutative-ring</EM> package allows control of ring properties +through the use of <EM>rulesets</EM>. +</P> +<P> + +<A NAME="IDX901"></A> +</P> +<DL> +<DT><U>Variable:</U> <B>*ruleset*</B> +<DD>Contains the set of rules currently in effect. Rules defined by +<CODE>cring:define-rule</CODE> are stored within the value of *ruleset* at the +time <CODE>cring:define-rule</CODE> is called. If <VAR>*ruleset*</VAR> is +<CODE>#f</CODE>, then no rules apply. +</DL> +<P> + +<A NAME="IDX902"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-ruleset</B> <I>rule1 <small>...</small></I> +<DD><A NAME="IDX903"></A> +<DT><U>Function:</U> <B>make-ruleset</B> <I>name rule1 <small>...</small></I> +<DD>Returns a new ruleset containing the rules formed by applying +<CODE>cring:define-rule</CODE> to each 4-element list argument <VAR>rule</VAR>. If +the first argument to <CODE>make-ruleset</CODE> is a symbol, then the database +table created for the new ruleset will be named <VAR>name</VAR>. Calling +<CODE>make-ruleset</CODE> with no rule arguments creates an empty ruleset. +</DL> +<P> + +<A NAME="IDX904"></A> +</P> +<DL> +<DT><U>Function:</U> <B>combined-rulesets</B> <I>ruleset1 <small>...</small></I> +<DD><A NAME="IDX905"></A> +<DT><U>Function:</U> <B>combined-rulesets</B> <I>name ruleset1 <small>...</small></I> +<DD>Returns a new ruleset containing the rules contained in each ruleset +argument <VAR>ruleset</VAR>. If the first argument to +<CODE>combined-ruleset</CODE> is a symbol, then the database table created for +the new ruleset will be named <VAR>name</VAR>. Calling +<CODE>combined-ruleset</CODE> with no ruleset arguments creates an empty +ruleset. +</DL> +<P> + +Two rulesets are defined by this package. +</P> +<P> + +<A NAME="IDX906"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>distribute*</B> +<DD>Contains the ruleset to distribute multiplication over addition and +subtraction. +</DL> +<P> + +<A NAME="IDX907"></A> +</P> +<DL> +<DT><U>Constant:</U> <B>distribute/</B> +<DD>Contains the ruleset to distribute division over addition and +subtraction. +<P> + +Take care when using both <VAR>distribute*</VAR> and <VAR>distribute/</VAR> +simultaneously. It is possible to put <CODE>/</CODE> into an infinite loop. +</P> +</DL> +<P> + +You can specify how sum and product expressions containing non-numeric +elements simplify by specifying the rules for <CODE>+</CODE> or <CODE>*</CODE> for +cases where expressions involving objects reduce to numbers or to +expressions involving different non-numeric elements. +</P> +<P> + +<A NAME="IDX908"></A> +</P> +<DL> +<DT><U>Function:</U> <B>cring:define-rule</B> <I>op sub-op1 sub-op2 reduction</I> +<DD>Defines a rule for the case when the operation represented by symbol +<VAR>op</VAR> is applied to lists whose <CODE>car</CODE>s are <VAR>sub-op1</VAR> and +<VAR>sub-op2</VAR>, respectively. The argument <VAR>reduction</VAR> is a +procedure accepting 2 arguments which will be lists whose <CODE>car</CODE>s +are <VAR>sub-op1</VAR> and <VAR>sub-op2</VAR>. +<P> + +<A NAME="IDX909"></A> +<DT><U>Function:</U> <B>cring:define-rule</B> <I>op sub-op1 'identity reduction</I> +<DD>Defines a rule for the case when the operation represented by symbol +<VAR>op</VAR> is applied to a list whose <CODE>car</CODE> is <VAR>sub-op1</VAR>, and +some other argument. <VAR>Reduction</VAR> will be called with the list whose +<CODE>car</CODE> is <VAR>sub-op1</VAR> and some other argument. +</P> +<P> + +If <VAR>reduction</VAR> returns <CODE>#f</CODE>, the reduction has failed and other +reductions will be tried. If <VAR>reduction</VAR> returns a non-false value, +that value will replace the two arguments in arithmetic (<CODE>+</CODE>, +<CODE>-</CODE>, and <CODE>*</CODE>) calculations involving non-numeric elements. +</P> +<P> + +The operations <CODE>+</CODE> and <CODE>*</CODE> are assumed commutative; hence both +orders of arguments to <VAR>reduction</VAR> will be tried if necessary. +</P> +<P> + +The following rule is the definition for distributing <CODE>*</CODE> over +<CODE>+</CODE>. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(cring:define-rule + '* '+ 'identity + (lambda (exp1 exp2) + (apply + (map (lambda (trm) (* trm exp2)) (cdr exp1)))))) +</pre></td></tr></table></DL> +<P> + +<HR SIZE="6"> +<A NAME="SEC138"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC137"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC139"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.14 How to Create a Commutative Ring </H2> +<!--docid::SEC138::--> +<P> + +The first step in creating your commutative ring is to write procedures +to create elements of the ring. A non-numeric element of the ring must +be represented as a list whose first element is a symbol or string. +This first element identifies the type of the object. A convenient and +clear convention is to make the type-identifying element be the same +symbol whose top-level value is the procedure to create it. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define (n . list1) + (cond ((and (= 2 (length list1)) + (eq? (car list1) (cadr list1))) + 0) + ((not (term< (first list1) (last1 list1))) + (apply n (reverse list1))) + (else (cons 'n list1)))) + +(define (s x y) (n x y)) + +(define (m . list1) + (cond ((neq? (first list1) (term_min list1)) + (apply m (cyclicrotate list1))) + ((term< (last1 list1) (cadr list1)) + (apply m (reverse (cyclicrotate list1)))) + (else (cons 'm list1)))) +</pre></td></tr></table><P> + +Define a procedure to multiply 2 non-numeric elements of the ring. +Other multiplicatons are handled automatically. Objects for which rules +have <EM>not</EM> been defined are not changed. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define (n*n ni nj) + (let ((list1 (cdr ni)) (list2 (cdr nj))) + (cond ((null? (intersection list1 list2)) #f) + ((and (eq? (last1 list1) (first list2)) + (neq? (first list1) (last1 list2))) + (apply n (splice list1 list2))) + ((and (eq? (first list1) (first list2)) + (neq? (last1 list1) (last1 list2))) + (apply n (splice (reverse list1) list2))) + ((and (eq? (last1 list1) (last1 list2)) + (neq? (first list1) (first list2))) + (apply n (splice list1 (reverse list2)))) + ((and (eq? (last1 list1) (first list2)) + (eq? (first list1) (last1 list2))) + (apply m (cyclicsplice list1 list2))) + ((and (eq? (first list1) (first list2)) + (eq? (last1 list1) (last1 list2))) + (apply m (cyclicsplice (reverse list1) list2))) + (else #f)))) +</pre></td></tr></table><P> + +Test the procedures to see if they work. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>;;; where cyclicrotate(list) is cyclic rotation of the list one step +;;; by putting the first element at the end +(define (cyclicrotate list1) + (append (rest list1) (list (first list1)))) +;;; and where term_min(list) is the element of the list which is +;;; first in the term ordering. +(define (term_min list1) + (car (sort list1 term<))) +(define (term< sym1 sym2) + (string<? (symbol->string sym1) (symbol->string sym2))) +(define first car) +(define rest cdr) +(define (last1 list1) (car (last-pair list1))) +(define (neq? obj1 obj2) (not (eq? obj1 obj2))) +;;; where splice is the concatenation of list1 and list2 except that their +;;; common element is not repeated. +(define (splice list1 list2) + (cond ((eq? (last1 list1) (first list2)) + (append list1 (cdr list2))) + (else (slib:error 'splice list1 list2)))) +;;; where cyclicsplice is the result of leaving off the last element of +;;; splice(list1,list2). +(define (cyclicsplice list1 list2) + (cond ((and (eq? (last1 list1) (first list2)) + (eq? (first list1) (last1 list2))) + (butlast (splice list1 list2) 1)) + (else (slib:error 'cyclicsplice list1 list2)))) + +(N*N (S a b) (S a b)) => (m a b) +</pre></td></tr></table><P> + +Then register the rule for multiplying type N objects by type N objects. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(cring:define-rule '* 'N 'N N*N)) +</pre></td></tr></table><P> + +Now we are ready to compute! +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define (t) + (define detM + (+ (* (S g b) + (+ (* (S f d) + (- (* (S a f) (S d g)) (* (S a g) (S d f)))) + (* (S f f) + (- (* (S a g) (S d d)) (* (S a d) (S d g)))) + (* (S f g) + (- (* (S a d) (S d f)) (* (S a f) (S d d)))))) + (* (S g d) + (+ (* (S f b) + (- (* (S a g) (S d f)) (* (S a f) (S d g)))) + (* (S f f) + (- (* (S a b) (S d g)) (* (S a g) (S d b)))) + (* (S f g) + (- (* (S a f) (S d b)) (* (S a b) (S d f)))))) + (* (S g f) + (+ (* (S f b) + (- (* (S a d) (S d g)) (* (S a g) (S d d)))) + (* (S f d) + (- (* (S a g) (S d b)) (* (S a b) (S d g)))) + (* (S f g) + (- (* (S a b) (S d d)) (* (S a d) (S d b)))))) + (* (S g g) + (+ (* (S f b) + (- (* (S a f) (S d d)) (* (S a d) (S d f)))) + (* (S f d) + (- (* (S a b) (S d f)) (* (S a f) (S d b)))) + (* (S f f) + (- (* (S a d) (S d b)) (* (S a b) (S d d)))))))) + (* (S b e) (S c a) (S e c) + detM + )) +(pretty-print (t)) +-| +(- (+ (m a c e b d f g) + (m a c e b d g f) + (m a c e b f d g) + (m a c e b f g d) + (m a c e b g d f) + (m a c e b g f d)) + (* 2 (m a b e c) (m d f g)) + (* (m a c e b d) (m f g)) + (* (m a c e b f) (m d g)) + (* (m a c e b g) (m d f))) +</pre></td></tr></table><P> + +<A NAME="Matrix Algebra"></A> +<HR SIZE="6"> +<A NAME="SEC139"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC138"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 5.15 Matrix Algebra </H2> +<!--docid::SEC139::--> +<P> + +<CODE>(require 'determinant)</CODE> +<A NAME="IDX910"></A> +</P> +<P> + +A Matrix can be either a list of lists (rows) or an array. +As with linear-algebra texts, this package uses 1-based coordinates. +</P> +<P> + +<A NAME="IDX911"></A> +</P> +<DL> +<DT><U>Function:</U> <B>matrix->lists</B> <I>matrix</I> +<DD><P> + +Returns the list-of-lists form of <VAR>matrix</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX912"></A> +</P> +<DL> +<DT><U>Function:</U> <B>matrix->array</B> <I>matrix</I> +<DD><P> + +Returns the (ones-based) array form of <VAR>matrix</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX913"></A> +</P> +<DL> +<DT><U>Function:</U> <B>determinant</B> <I>matrix</I> +<DD><P> + +<VAR>matrix</VAR> must be a square matrix. +<CODE>determinant</CODE> returns the determinant of <VAR>matrix</VAR>. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'determinant) +(determinant '((1 2) (3 4))) => -2 +(determinant '((1 2 3) (4 5 6) (7 8 9))) => 0 +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX914"></A> +</P> +<DL> +<DT><U>Function:</U> <B>transpose</B> <I>matrix</I> +<DD><P> + +Returns a copy of <VAR>matrix</VAR> flipped over the diagonal containing the 1,1 +element. +</P> +</DL> +<P> + +<A NAME="IDX915"></A> +</P> +<DL> +<DT><U>Function:</U> <B>matrix:product</B> <I>m1 m2</I> +<DD><P> + +Returns the product of matrices <VAR>m1</VAR> and <VAR>m2</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX916"></A> +</P> +<DL> +<DT><U>Function:</U> <B>matrix:inverse</B> <I>matrix</I> +<DD><P> + +<VAR>matrix</VAR> must be a square matrix. +If <VAR>matrix</VAR> is singlar, then <CODE>matrix:inverse</CODE> returns #f; otherwise <CODE>matrix:inverse</CODE> returns the +<CODE>matrix:product</CODE> inverse of <VAR>matrix</VAR>. +</P> +</DL> +<P> + +<A NAME="Database Packages"></A> +<HR SIZE="6"> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_5.html#SEC88"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<BR> +<FONT SIZE="-1"> +This document was generated +by <I>Steve Langasek</I> on <I>January, 10 2005</I> +using <A HREF="http://texi2html.cvshome.org"><I>texi2html</I></A> +</FONT> + +</BODY> +</HTML> |