From 8466d8cfa486fb30d1755c4261b781135083787b Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Mon, 20 Feb 2017 00:05:29 -0800 Subject: Import Upstream version 3a1 --- phil-spc.scm | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 phil-spc.scm (limited to 'phil-spc.scm') diff --git a/phil-spc.scm b/phil-spc.scm new file mode 100644 index 0000000..3372ce6 --- /dev/null +++ b/phil-spc.scm @@ -0,0 +1,94 @@ +; "phil-spc.scm": Peano-Hilbert space filling mapping +; Copyright (c) 2003 Aubrey Jaffer +; +;Permission to copy this software, 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. +; +;1. Any copy made of this software must include this copyright notice +;in full. +; +;2. I have made no warranty or representation that the operation of +;this software will be error-free, and I am under no obligation to +;provide any services, by way of maintenance, update, or otherwise. +; +;3. In conjunction with products arising from the use of this +;material, there shall be no use of my name in any advertising, +;promotional, or sales literature without prior written consent in +;each case. + +(require 'logical) + +;;@code{(require 'hilbert-fill)} +;;@ftindex hilbert-fill +;; +;;@noindent +;;@cindex Peano +;;@cindex Hilbert +;;@cindex Space-Filling +;;The @dfn{Peano-Hilbert Space-Filling Curve} is a one-to-one mapping +;;between a unit line segment and an @var{n}-dimensional unit cube. +;; +;;@noindent +;;The integer procedures map the non-negative integers to an +;;arbitrarily large @var{n}-dimensional cube with its corner at the +;;origin and all coordinates are non-negative. +;; +;;@noindent +;;For any exact nonnegative integers @var{scalar} and @var{rank}, +;; +;;@example +;;(= @var{scalar} (hilbert-coordinates->integer +;; (integer->hilbert-coordinates @var{scalar} @var{rank}))) +;; @result{} #t +;;@end example + +;;@body +;;Returns a list of @2 integer coordinates corresponding to exact +;;non-negative integer @1. The lists returned by @0 for @1 arguments +;;0 and 1 will differ in the first element. +(define (integer->hilbert-coordinates scalar rank) + (define ndones (logical:ones rank)) + (define rank*nbits + (let ((rank^2 (* rank rank))) + (* (quotient (+ -1 rank^2 (integer-length scalar)) rank^2) + rank^2))) + (let ((nthbits (quotient (logical:ones rank*nbits) ndones))) + (define igry (logxor (integer->gray-code scalar) (ash nthbits -1))) + (do ((bdxn (- rank rank*nbits) (+ rank bdxn)) + (chnk (logand (ash igry (- rank rank*nbits)) ndones) + (logand (ash igry (+ rank bdxn)) ndones)) + (rotation 0 (modulo (+ (integer-length (logand (- chnk) chnk)) + 1 rotation) + rank)) + (flipbit 0 (ash 1 rotation)) + (bignum 0 (+ (logxor flipbit (logical:rotate chnk rotation rank)) + (ash bignum rank)))) + ((positive? bdxn) + (map gray-code->integer (bitwise:delaminate rank bignum)))))) + +;;@body +;;Returns an exact non-negative integer corresponding to @1, a list +;;of non-negative integer coordinates. +(define (hilbert-coordinates->integer coords) + (define rank (length coords)) + (define bignum (apply bitwise:laminate (map integer->gray-code coords))) + (let ((rank*nbits + (* (quotient (+ -1 rank (integer-length (apply max coords))) rank) + rank rank)) + (ndones (logical:ones rank))) + (define nthbits (quotient (logical:ones rank*nbits) ndones)) + (define (loop bdxn rotation flipbit scalar) + (if (positive? bdxn) + (gray-code->integer (logxor scalar (ash nthbits -1))) + (let ((chnk (logical:rotate + (logxor flipbit (logand ndones (ash bignum bdxn))) + (- rotation) + rank))) + (loop (+ rank bdxn) + (modulo (+ (integer-length (logand (- chnk) chnk)) + 1 rotation) + rank) + (ash 1 rotation) + (+ chnk (ash scalar rank)))))) + (loop (- rank rank*nbits) 0 0 0))) -- cgit v1.2.3