1 /** This file is part of Shapes.
3 ** Shapes is free software: you can redistribute it and/or modify
4 ** it under the terms of the GNU General Public License as published by
5 ** the Free Software Foundation, either version 3 of the License, or
8 ** Shapes is distributed in the hope that it will be useful,
9 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 ** GNU General Public License for more details.
13 ** You should have received a copy of the GNU General Public License
14 ** along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 ** Copyright 2014 Henrik Tidefelt
19 ##needs ..Shapes..Data / seq-support
22 ##lookin ..Shapes..Geometry
23 ##lookin ..Shapes..Layout
24 ##lookin ..Shapes..Traits
25 ##lookin ..Shapes..Control
26 ##lookin ..Shapes..Data
27 ##lookin ..Shapes..Numeric..Random
28 ##lookin ..Shapes..Numeric..Math
30 /** Merge sort implemented in Shapes
35 helper1: \ p q res → [if [nil? q] [fcons [seq_reverse res] p] [helper2 p q.cdr res]]
36 helper2: \ p q res → [if [nil? q] [fcons [seq_reverse res] p] [helper1 p.cdr q.cdr ( p.car ; res )]]
37 \ seq → [helper1 seq seq nil]
42 append_reverse: \ elems res → [if [nil? elems] [seq_reverse res] [append_reverse elems.cdr ( elems.car ; res )]]
44 helper: \ left right res precedes →
46 [append_reverse right res]
48 [append_reverse left res]
49 [if [precedes right.car left.car]
50 [helper left right.cdr ( right.car ; res) precedes]
51 [helper left.cdr right ( left.car ; res) precedes]
56 \ left right precedes → [helper left right nil precedes]
61 mergeSort1: \ seq precedes →
65 /** At least two elements in seq. **/
67 leftSorted: [mergeSort1 lr.car precedes]
68 rightSorted: [mergeSort1 lr.cdr precedes]
69 [seq_merge leftSorted rightSorted precedes]
73 \ seq precedes → [if [nil? seq] nil [mergeSort1 seq precedes]]
76 /** Measure computation times.
81 helper: \ n res •rnd → [if (n = '0) res [helper (n - '1) (![ball1D •rnd] ; res) •rnd]]
82 \ n •rnd → [helper n nil •rnd]
85 seed: [newRandom (•time)]
87 clockRandomData: \ sortfun n seed →
90 data: [randomList n •rnd]
93 dataSorted: ![sortfun data]
98 timeData_lexiographicSort_random:
100 \ p → [clockRandomData (\ data → [lexiographicSort [fmap array data] data]) [pow '2 p] seed]
103 timeData_sort_random:
105 \ p → [clockRandomData (\ data → [sort data (<)]) [pow '2 p] seed]
108 timeData_mergeSort_random:
110 \ p → [clockRandomData (\ data → [mergeSort data (<)]) [pow '2 p] seed]
122 xMap: \ x → ( xSize / [log xMax / xMin] ) * [log x / xMin]
123 yMap: \ y → ( ySize / [log yMax / yMin] ) * [log y / yMin]
125 dataLine: \ timeData → [timeData.foldl (\ s e → s--([xMap e.x], [yMap e.y])) emptypath]
126 mark: @width:0.1bp | [Graphics..stroke [circle 1bp]]
127 dataMarks: \ timeData → [timeData.foldl (\ s e → s & [[shift ([xMap e.x], [yMap e.y])] mark]) Graphics..null]
131 IO..•page << @width:0.3bp | [Graphics..stroke (0m,0m)--(xSize, 0m) head:Graphics..ShapesArrow]
132 IO..•page << @width:0.3bp | [Graphics..stroke (0m,0m)--(0m, ySize) head:Graphics..ShapesArrow]
136 |**IO..•page << @width:0.3bp | [[range 0 0.95*xRange step:2000].cdr.foldl (\ s e → s & [[shift ([xMap e],0)] [Graphics..stroke (0m,0m)--(0m,~1.5mm)] & [[shift (0,~5mm)] [center_x (Text..newText << [String..sprintf `%g´ e])]]]) Graphics..null]
137 |**IO..•page << @width:0.3bp | [[range 0 0.95*yRange step:5].cdr.foldl (\ s e → s & [[shift (0,[yMap e])] [Graphics..stroke (0m,0m)--(~1.5mm,0m)] & [[shift (~2mm,~0.4*Text..@size)] [center_x (Text..newText << [String..sprintf `%g´ e]) 1]]]) Graphics..null]
141 IO..•page << @width:0.3bp & Text..@size:8bp |
143 [[range [floor [log10 xMin]] [ceil [log10 xMax]]].cdr.foldl
148 val: [pow 10 e] * eSub
150 [if xMin < val and val < xMax
151 s & [[shift (c,0)] [Graphics..stroke (0m,0m)--(0m,~1.5mm)] & [[shift (0,~5mm)] [center_x (Text..newText << [String..sprintf `%g´ val])]]]
160 IO..•page << @width:0.3bp & Text..@size:8bp |
162 [[range [floor [log10 yMin]] [ceil [log10 yMax]]].cdr.foldl
167 val: [pow 10 e] * eSub
169 [if yMin < val and val < yMax
170 s & [[shift (0,c)] [Graphics..stroke (0m,0m)--(~1.5mm,0m)] & [[shift (~2mm,~0.4*Text..@size)] [center_x (Text..newText << [String..sprintf `%g´ val]) 1]]]
180 •dataView: Graphics..newGroup
185 line: [dataLine timeData_lexiographicSort_random]
186 •dataView << @width:0.5bp | [Graphics..stroke line]
187 << [dataMarks timeData_lexiographicSort_random]
188 << [[shift [intersection line (0.6*xSize,0)--((+0cm),ySize)].p] [center_wlm (Text..newText << `lexiographicSort´) (~1, 1)]]
191 line: [dataLine timeData_sort_random]
192 •dataView << @width:0.5bp | [Graphics..stroke line]
193 << [dataMarks timeData_sort_random]
194 << [[shift [intersection line (0.55*xSize,0)--((+0cm),ySize)].p] [center_wlm (Text..newText << `sort´) (1, ~1)]]
197 line: [dataLine timeData_mergeSort_random]
198 •dataView << @width:0.5bp | [Graphics..stroke line]
199 << [dataMarks timeData_mergeSort_random]
200 << [[shift [intersection line (0.3*xSize,0)--((+0cm),ySize)].p] [center_wlm (Text..newText << `mergeSort´) (1, ~1)]]
203 /** Draw an n * log( n ) helper line.
207 line: [[range [log10 xMin] [log10 xMax] count:'100].foldl
211 s--(1%C^)<([xMap x], [yMap c * x * [log x]])>(1%C^)
215 •dataView << @width:0.5bp & @stroking:[gray 0.5] | [Graphics..stroke line]
216 << [[shift [intersection line (0.65*xSize,0)--((+0cm),ySize)].p] [center_wlm [Graphics..TeX [String..sprintf `$%g\, n\, \log(\, n \,)$´ c]] (1, ~1)]]
219 dataView: freeze •dataView
220 IO..•page << [Graphics..clip dataView [rectangle (0m,0m) (xSize, ySize)]]