hilbert.scm 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees
  3. ; Hilbert vectors are like vectors that grow as large as they need to.
  4. ; That is, they can be indexed by arbitrarily large nonnegative integers.
  5. ; The implementation allows for arbitrarily large gaps by arranging
  6. ; the entries in a tree.
  7. ; So-called because they live in an infinite-dimensional vector
  8. ; space...
  9. (define hilbert-log 8)
  10. (define hilbert-node-size (arithmetic-shift 1 hilbert-log))
  11. (define hilbert-mask (- hilbert-node-size 1))
  12. (define minus-hilbert-log (- 0 hilbert-log))
  13. (define-record-type hilbert :hilbert
  14. (make-hilbert height root)
  15. (height hilbert-height set-hilbert-height!)
  16. (root hilbert-root set-hilbert-root!))
  17. (define-record-discloser :hilbert
  18. (lambda (h)
  19. '(sparse-vector)))
  20. (define (make-sparse-vector)
  21. (make-hilbert 1 (make-vector hilbert-node-size #f)))
  22. (define (sparse-vector-ref hilbert index)
  23. (let recur ((height (hilbert-height hilbert))
  24. (index index))
  25. (if (= height 1)
  26. (let ((root (hilbert-root hilbert)))
  27. (if (< index (vector-length root))
  28. (vector-ref root index)
  29. #f))
  30. (let ((node (recur (- height 1)
  31. (arithmetic-shift index minus-hilbert-log))))
  32. (if node
  33. (vector-ref node (bitwise-and index hilbert-mask))
  34. #f)))))
  35. (define (sparse-vector-set! hilbert index value)
  36. (vector-set!
  37. (let recur ((height (hilbert-height hilbert))
  38. (index index))
  39. (if (= height 1)
  40. (make-higher-if-necessary hilbert index)
  41. (let ((index (arithmetic-shift index minus-hilbert-log)))
  42. (make-node-if-necessary
  43. (recur (- height 1) index)
  44. (bitwise-and index hilbert-mask)))))
  45. (bitwise-and index hilbert-mask)
  46. value))
  47. (define (make-higher-if-necessary hilbert index)
  48. (if (< index hilbert-node-size)
  49. (hilbert-root hilbert)
  50. (let ((new-root (make-vector hilbert-node-size #f)))
  51. (vector-set! new-root 0 (hilbert-root hilbert))
  52. (set-hilbert-root! hilbert new-root)
  53. (set-hilbert-height! hilbert (+ (hilbert-height hilbert) 1))
  54. (let ((index (arithmetic-shift index minus-hilbert-log)))
  55. (make-node-if-necessary (make-higher-if-necessary hilbert index)
  56. (bitwise-and index hilbert-mask))))))
  57. (define (make-node-if-necessary node index)
  58. (or (vector-ref node index)
  59. (let ((new (make-vector hilbert-node-size #f)))
  60. (vector-set! node index new)
  61. new)))
  62. ; For debugging
  63. (define (sparse-vector->list h)
  64. (let recur ((node (hilbert-root h))
  65. (height (hilbert-height h))
  66. (more '()))
  67. (if (= height 0)
  68. (if (or node (pair? more))
  69. (cons node more)
  70. '())
  71. (do ((i (- hilbert-node-size 1) (- i 1))
  72. (more more (recur (if node
  73. (vector-ref node i)
  74. #f)
  75. (- height 1) more)))
  76. ((< i 0) more)))))