(Arne Babenhauserheide)
2016-06-08: merge merge
diff --git a/examples/d20world.w b/examples/d20world.w --- a/examples/d20world.w +++ b/examples/d20world.w @@ -1,4 +1,6 @@ -#!/home/arne/wisp/wisp-multiline.sh +#!/usr/bin/env sh +# -*- wisp -*- +exec guile -L $(dirname $(dirname $(realpath "$0"))) --language=wisp -e '(@@ (examples d20world) main)' -s "$0" "$@" ; !# ; A world projected on a d20 (20-sided die, ikosaeder) @@ -17,6 +19,7 @@ define-module : examples d20world . #:export : world neighbors d20-as-text d20-diffuse use-modules : ice-9 format +use-modules : srfi srfi-1 use-modules : ice-9 popen . #:select : open-output-pipe close-pipe @@ -188,150 +191,236 @@ define : d20-advect world advection-dire loop : cdr neighbors-to-advect -define φ : * (/ 1 2) : 1+ : sqrt 5 +define d20numbers '(1 14 10 6 + 19 18 4 8 9 16 + 2 3 17 13 12 5 + 11 15 7 20) + +define : cellidx->dienumber idx + list-ref d20numbers idx + +define : dienumber->cellidx number + list-index (λ(x)(= x number)) d20numbers + + +define : latlonsixthslabidx latfromtop lonfrac + . "calculate the index in a sixth longitude slab of the icosaeder" + let* + : triangleheight : / (sqrt 3) 2 + length-top-to-bottom-at-lon0 : + 1 (* 2 triangleheight) + height-deg : * 180 : / triangleheight length-top-to-bottom-at-lon0 + side-deg : * 180 : / 1 length-top-to-bottom-at-lon0 + ; in one sixth of the icosaeder, there are 6 reachable + ; fields. I am indexing them from top to bottom. + ; format #t "latfromtop: ~a, lonfrac: ~a, height-deg/3: ~a, side-deg: ~a\n" latfromtop lonfrac (/ height-deg 3) side-deg + cond + : < latfromtop : / height-deg 3 + . 0 + : < latfromtop : - (* 2 (/ height-deg 3)) (* lonfrac (/ height-deg 3)) + . 0 + : < latfromtop : * 2 : / height-deg 3 + . 1 + : < latfromtop : + (* 2 (/ height-deg 3)) (* lonfrac (* 2 (/ height-deg 3))) + . 1 + : < latfromtop : * 4 : / height-deg 3 + . 2 + : < latfromtop : - (+ side-deg (* 2 (/ height-deg 3))) (* lonfrac (- (+ side-deg (* 2 (/ height-deg 3))) (* 4 (/ height-deg 3)))) + . 2 + : < latfromtop : + side-deg : * 2 : / height-deg 3 + . 3 + : < latfromtop : + (+ side-deg (* 2 (/ height-deg 3))) (* lonfrac (- (+ side-deg (* 4 (/ height-deg 3))) (+ side-deg (* 2 (/ height-deg 3))))) + . 3 + : < latfromtop : - (+ side-deg (* 5 (/ height-deg 3))) (* lonfrac (- (+ side-deg (* 5 (/ height-deg 3))) (+ side-deg (* 4 (/ height-deg 3))))) + . 4 + else + . 5 + define : latlon2cellidx lat lon - . "Convert a position given as latitude and longitude into the correct cell index." - ; cell 1 (index 0) is on top, cell 20 at the bottom. The right - ; border of cell 2 is situated at longitude 0. With that, the - ; left corner of cell 19 is at longitude 180. Top and bottom - ; are point-symmetric. We can cleanly divide the upper part of - ; the icosaeder into 3 regions by longitude. Let's do that. - let* - : upper : > lat 0 - ; we start by switching to a symmetric longitude - slon : if upper lon : + lon 180 - ; the sector number is defined by the uppermost triangle - ; in it. - sector : if (< slon 120) 4 (if (< slon 270) 3 2) + . "Convert a position given as latitude (-90 .. 90) and +longitude (0 .. 360) into the correct cell index. + +This uses heavy linear approximation." + ; cell 1 (index 0) is on top, cell 20 at the bottom. The left + ; border of cell 2 is situated at longitude 0. We can cleanly + ; divide the upper part of the icosaeder into 3 regions by + ; longitude. Let's do that. + let* ; the sector number is defined by the uppermost triangle + : sector : if (< lon 120) 2 (if (< lon 270) 4 3) ; we start by calculating the fraction inside the sector - lonsectorfraction : modulo slon 120 + lonsectorfraction : modulo lon 120 ; we can further subdivide the sector by longitude into two subsectors - subseclon : if (< lon 60) lon (-120 lon) - ; TODO find some more symmetry or start nontrivial geometry. - . #t + subsector : if (< lonsectorfraction 60) 0 1 + subseclon : if (= subsector 0) lonsectorfraction (- 120 lonsectorfraction) + lonfrac : / subseclon 60 + latfromtop : - 90 lat + sixthslab : latlonsixthslabidx latfromtop lonfrac + ; for each sector and subsector, set the dienumber + slabsec->index '((2 . ((1 14 19 13 15 20) (1 14 16 17 11 20))) + (4 . ((1 6 9 3 11 20) (1 6 8 2 7 20))) + (3 . ((1 10 4 5 7 20) (1 10 18 12 15 20)))) + dienumber->cellidx + list-ref + list-ref + assoc-ref slabsec->index sector + . subsector + . sixthslab -display : d20-as-text world -newline - -format #t "Diffuse ~A\n" 0.01 -d20-diffuse world neighbors 0.01 -display : d20-as-text world -newline -format #t "Advect ~A\n" 0.1 -d20-advect world advection-directions 0.1 -display : d20-as-text world -newline -format #t "Diffuse ~A\n" 0.1 -d20-diffuse world neighbors 0.1 -display : d20-as-text world -newline -format #t "Diffuse: ~A*(~A)\n" 100 0.1 -let loop : : steps 100 - cond - : = 0 steps - . world - else - d20-diffuse world neighbors 0.1 - loop : 1- steps -display : d20-as-text world -newline -let - : number 20 - val 1 - format #t "disturb: ~A to ~A\n" number val - vector-set! world (1- number) val - display : d20-as-text world - newline -format #t "Diffuse ~A\n" 0.1 -d20-diffuse world neighbors 0.1 -display : d20-as-text world -newline - -format #t "Advect: ~A*(~A)\n" 1000 0.001 -let loop : : steps 1000 - cond - : = 0 steps - . world - else - d20-advect world advection-directions 0.001 - display : d20-as-text world - d20-cursor-up-text world - loop : 1- steps -display : d20-as-text world -newline -format #t "Diffuse: ~A*(~A)\n" 1000 0.004 -let loop : : steps 1000 - cond - : = 0 steps - . world - else - d20-diffuse world neighbors 0.004 - display : d20-as-text world - d20-cursor-up-text world - loop : 1- steps -display : d20-as-text world -newline -format #t "Diffuse+Advect: ~A*(~A+~A)\n" 1000 0.002 0.001 -let loop : : steps 1000 - cond - : = 0 steps - . world - else - d20-diffuse world neighbors 0.002 - d20-advect world advection-directions 0.001 - display : d20-as-text world - d20-cursor-up-text world - loop : 1- steps -display : d20-as-text world -newline - -; now plot the result -let : : port : open-output-pipe "python" - format port "from mpl_toolkits.mplot3d import Axes3D, art3d -import numpy as np -import scipy as sp -from matplotlib import cm -import matplotlib.pyplot as plt -from scipy.spatial import Delaunay - -def Icosahedron(): - h = 0.5*(1+np.sqrt(5)) - p1 = np.array([[0,1,h],[0,1,-h],[0,-1,h],[0,-1,-h]]) - p2 = p1[:,[1,2,0]] - p3 = p1[:,[2,0,1]] - return np.vstack((p1,p2,p3)) - -Ico = Icosahedron() -tri = Delaunay(Ico) -CH = tri.convex_hull -points = tri.points - -fig = plt.figure(figsize=(4.0,4.0)) -ax = fig.add_subplot(111, projection='3d') - -print points -for i in range(points.shape[0]): - neighbors = tri.neighbors[i,:] - for n in range(points.shape[0]): - pts = [] - for u in range(points.shape[0]): - pt = np.zeros((3,3)) - pt[0,:] = points[(i),:] - pt[1,:] = points[(n),:] - pt[2,:] = points[(u),:] - # print pt - pt *= 0.5 - pt += 0.5 - pts.append(pt) - tr = art3d.Poly3DCollection(pts) - tr.set_color([(0.9*i)/points.shape[0]] + [(0.9*n)/points.shape[0]]*3) - ax.add_collection3d(tr) -# ax.plot_surface(x, y, z, color='g') - -plt.show() - -exit()\n" - close-pipe port - +define : main args + . "Test the code" + if : > 2 (length args) + set! args : append args '("88") ; lat + if : > 3 (length args) + set! args : append args '("45") ; lon + display : latlon2cellidx (string->number (first (take-right args 2))) (string->number (last args)) + newline + display : d20-as-text world + newline + + format #t "Diffuse ~A\n" 0.01 + d20-diffuse world neighbors 0.01 + display : d20-as-text world + newline + format #t "Advect ~A\n" 0.1 + d20-advect world advection-directions 0.1 + display : d20-as-text world + newline + format #t "Diffuse ~A\n" 0.1 + d20-diffuse world neighbors 0.1 + display : d20-as-text world + newline + format #t "Diffuse: ~A*(~A)\n" 100 0.1 + let loop : : steps 100 + cond + : = 0 steps + . world + else + d20-diffuse world neighbors 0.1 + loop : 1- steps + display : d20-as-text world + newline + let + : number 20 + val 1 + format #t "disturb: ~A to ~A\n" number val + vector-set! world (1- number) val + display : d20-as-text world + newline + format #t "Diffuse ~A\n" 0.1 + d20-diffuse world neighbors 0.1 + display : d20-as-text world + newline + + format #t "Advect: ~A*(~A)\n" 1000 0.001 + let loop : : steps 1000 + cond + : = 0 steps + . world + else + d20-advect world advection-directions 0.001 + display : d20-as-text world + d20-cursor-up-text world + loop : 1- steps + display : d20-as-text world + newline + format #t "Diffuse: ~A*(~A)\n" 1000 0.004 + let loop : : steps 1000 + cond + : = 0 steps + . world + else + d20-diffuse world neighbors 0.004 + display : d20-as-text world + d20-cursor-up-text world + loop : 1- steps + display : d20-as-text world + newline + format #t "Diffuse+Advect: ~A*(~A+~A)\n" 1000 0.002 0.001 + let loop : : steps 1000 + cond + : = 0 steps + . world + else + d20-diffuse world neighbors 0.002 + d20-advect world advection-directions 0.001 + display : d20-as-text world + d20-cursor-up-text world + loop : 1- steps + display : d20-as-text world + newline + + display + let loop + : lon 360 + lat 90 + map '() + zone '() + cond + : and (= lat -90) (= lon 0) + cons : cons (vector-ref world (latlon2cellidx lat lon)) zone + . map + : = lon 0 + loop + . 360 + - lat 1 + cons : cons (vector-ref world (latlon2cellidx lat lon)) zone + . map + . '() + else + loop + - lon 1 + . lat + . map + cons : vector-ref world : latlon2cellidx lat lon + . zone + newline + + +; ; now plot the result +; let : : port : open-output-pipe "python" +; format port "from mpl_toolkits.mplot3d import Axes3D, art3d +; import numpy as np +; import scipy as sp +; from matplotlib import cm +; import matplotlib.pyplot as plt +; from scipy.spatial import Delaunay +; +; def Icosahedron(): +; h = 0.5*(1+np.sqrt(5)) +; p1 = np.array([[0,1,h],[0,1,-h],[0,-1,h],[0,-1,-h]]) +; p2 = p1[:,[1,2,0]] +; p3 = p1[:,[2,0,1]] +; return np.vstack((p1,p2,p3)) +; +; Ico = Icosahedron() +; tri = Delaunay(Ico) +; CH = tri.convex_hull +; points = tri.points +; +; fig = plt.figure(figsize=(4.0,4.0)) +; ax = fig.add_subplot(111, projection='3d') +; +; print points +; for i in range(points.shape[0]): +; neighbors = tri.neighbors[i,:] +; for n in range(points.shape[0]): +; pts = [] +; for u in range(points.shape[0]): +; pt = np.zeros((3,3)) +; pt[0,:] = points[(i),:] +; pt[1,:] = points[(n),:] +; pt[2,:] = points[(u),:] +; # print pt +; pt *= 0.5 +; pt += 0.5 +; pts.append(pt) +; tr = art3d.Poly3DCollection(pts) +; tr.set_color([(0.9*i)/points.shape[0]] + [(0.9*n)/points.shape[0]]*3) +; ax.add_collection3d(tr) +; # ax.plot_surface(x, y, z, color='g') +; +; plt.show() +; +; exit()\n" +; close-pipe port diff --git a/examples/ensemble-estimation.w b/examples/ensemble-estimation.w --- a/examples/ensemble-estimation.w +++ b/examples/ensemble-estimation.w @@ -209,7 +209,7 @@ Limitations: y is a single value. R and define : main args let* - : optimized : EnSRT H x^b P y⁰ R y⁰-pos 100 + : optimized : EnSRT H x^b P y⁰ R y⁰-pos 40 x-opt : list-ref optimized 0 x-deviations : list-ref optimized 1 ; std : sqrt : * {1 / {(length x-deviations) - 1}} : sum-ec (: i x-deviations) : expt i 2