VapourSynth-llvmexpr
Loading...
Searching...
No Matches
algorithms.expr
Go to the documentation of this file.
1# Copyright (C) 2025 yuygfgg
2#
3# This file is part of Vapoursynth-llvmexpr.
4#
5# Vapoursynth-llvmexpr is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# Vapoursynth-llvmexpr is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with Vapoursynth-llvmexpr. If not, see <https://www.gnu.org/licenses/>.
17
18@ifdef __EXPR__
19 @define ___STDLIB_ALGORITHMS_RANGE_PARAM_TYPE Literal
20@else
21 @define ___STDLIB_ALGORITHMS_RANGE_PARAM_TYPE Value
22@endif
23
24function ___stdlib_algorithms_swap(Array a, Value i, Value j) {
25 tmp = a[i];
26 a[i] = a[j];
27 a[j] = tmp;
28}
29
30function ___stdlib_algorithms_heapify(Array a, Value n, Value i, Value offset) {
31 current_i = i;
32 while (1) {
33 largest = current_i;
34 left = 2 * current_i + 1;
35 right = 2 * current_i + 2;
36
37 if (left < n && a[offset + largest] < a[offset + left]) {
38 largest = left;
39 }
40 if (right < n && a[offset + largest] < a[offset + right]) {
41 largest = right;
42 }
43
44 if (largest == current_i) {
45 goto heapify_loop_end;
46 }
47
48 ___stdlib_algorithms_swap(a, offset + current_i, offset + largest);
49 current_i = largest;
50 }
51 heapify_loop_end:
52}
53
54function ___stdlib_algorithms_insertion_sort(Array a, Value begin, Value end) {
55 i = begin + 1;
56 while (i < end) {
57 key = a[i];
58 j = i - 1;
59 while (j >= begin && a[j] > key) {
60 a[j + 1] = a[j];
61 j = j - 1;
62 }
63 a[j + 1] = key;
64 i = i + 1;
65 }
66}
67
68function ___stdlib_algorithms_heapsort(Array a, Value begin, Value end) {
69 n = end - begin;
70
71 i = n / 2 - 1;
72 while (i >= 0) {
73 ___stdlib_algorithms_heapify(a, n, i, begin);
74 i = i - 1;
75 }
76
77 i = n - 1;
78 while (i > 0) {
79 ___stdlib_algorithms_swap(a, begin, begin + i);
80 ___stdlib_algorithms_heapify(a, i, 0, begin);
81 i = i - 1;
82 }
83}
84
85function ___stdlib_algorithms_median_of_three(Array a, Value low, Value high) {
86 mid = floor(low + (high - low) / 2);
87 if (a[low] > a[mid]) {
88 ___stdlib_algorithms_swap(a, low, mid);
89 }
90 if (a[low] > a[high]) {
91 ___stdlib_algorithms_swap(a, low, high);
92 }
93 if (a[mid] > a[high]) {
94 ___stdlib_algorithms_swap(a, mid, high);
95 }
96 ___stdlib_algorithms_swap(a, mid, high);
97}
98
99function ___stdlib_algorithms_partition(Array a, Value low, Value high) {
100 pivot = a[high];
101 i = low - 1;
102 j = low;
103 while (j < high) {
104 if (a[j] <= pivot) {
105 i = i + 1;
106 ___stdlib_algorithms_swap(a, i, j);
107 }
108 j = j + 1;
109 }
110 ___stdlib_algorithms_swap(a, i + 1, high);
111 return i + 1;
112}
113
114function ___stdlib_algorithms_copy_range(Array dest, Value dest_start, Array src, Value src_start, Value len) {
115 i = 0;
116 while (i < len) {
117 dest[dest_start + i] = src[src_start + i];
118 i = i + 1;
119 }
120}
121
122function ___stdlib_algorithms_find_kth_smallest_fast(Array a, ___STDLIB_ALGORITHMS_RANGE_PARAM_TYPE begin, ___STDLIB_ALGORITHMS_RANGE_PARAM_TYPE end, ___STDLIB_ALGORITHMS_RANGE_PARAM_TYPE len, Value k) {
123 temp_arr = new(len);
124 ___stdlib_algorithms_copy_range(temp_arr, 0, a, begin, len);
125
126 low = 0;
127 high = len - 1;
128 result = -1.0; # Default error value
129
130 while (low <= high) {
131 pivot_idx = ___stdlib_algorithms_partition(temp_arr, low, high);
132 if (pivot_idx == k) {
133 result = temp_arr[k];
134 goto find_kth_fast_end;
135 }
136 if (pivot_idx < k) {
137 low = pivot_idx + 1;
138 } else {
139 high = pivot_idx - 1;
140 }
141 }
142
143 find_kth_fast_end:
144 return result;
145}
146
147function ___stdlib_algorithms_find_kth_smallest_slow(Array arr, Value begin, Value end, Value k) {
148 i = begin;
149 while (i < end) {
150 candidate_val = arr[i];
151 less_count = 0;
152 equal_count = 0;
153 j = begin;
154 while (j < end) {
155 elem = arr[j];
156 if (elem < candidate_val) {
157 less_count = less_count + 1;
158 } else if (elem == candidate_val) {
159 equal_count = equal_count + 1;
160 }
161 j = j + 1;
162 }
163 if (k >= less_count && k < (less_count + equal_count)) {
164 return candidate_val;
165 }
166 i = i + 1;
167 }
168 return -1.0;
169}
170
171function ___stdlib_algorithms_sort(Array a, Value begin, Value end) {
172 n = end - begin;
173 if (n <= 1) {
174 return;
175 }
176
177 INSERTION_SORT_THRESHOLD = 16;
178 if (n < INSERTION_SORT_THRESHOLD) {
179 ___stdlib_algorithms_insertion_sort(a, begin, end);
180 return;
181 }
182
183 stack = new(192);
184 stack_ptr = 0;
185
186 stack[stack_ptr] = begin;
187 stack[stack_ptr + 1] = end;
188 stack[stack_ptr + 2] = 2 * floor(log2(n));
189 stack_ptr = stack_ptr + 3;
190
191 while (stack_ptr > 0) {
192 stack_ptr = stack_ptr - 3;
193 current_begin = stack[stack_ptr];
194 current_end = stack[stack_ptr + 1];
195 depth_limit = stack[stack_ptr + 2];
196
197 current_n = current_end - current_begin;
198 if (current_n > 1) {
199 if (current_n < INSERTION_SORT_THRESHOLD) {
200 ___stdlib_algorithms_insertion_sort(a, current_begin, current_end);
201 } else if (depth_limit == 0) {
202 ___stdlib_algorithms_heapsort(a, current_begin, current_end);
203 } else {
204 p_high = current_end - 1;
205 ___stdlib_algorithms_median_of_three(a, current_begin, p_high);
206 pivot_idx = ___stdlib_algorithms_partition(a, current_begin, p_high);
207
208 stack[stack_ptr] = pivot_idx + 1;
209 stack[stack_ptr + 1] = current_end;
210 stack[stack_ptr + 2] = depth_limit - 1;
211 stack_ptr = stack_ptr + 3;
212
213 stack[stack_ptr] = current_begin;
214 stack[stack_ptr + 1] = pivot_idx;
215 stack[stack_ptr + 2] = depth_limit - 1;
216 stack_ptr = stack_ptr + 3;
217 }
218 }
219 }
220}
221
222function ___stdlib_algorithms_reverse(Array a, Value begin, Value end) {
223 left = begin;
224 right = end - 1;
225 while (left < right) {
226 ___stdlib_algorithms_swap(a, left, right);
227 left = left + 1;
228 right = right - 1;
229 }
230}
231
232@define ___STDLIB_ALGORITHMS_CALC_LEN(b, e) ((e) - (b))
233@define ___STDLIB_ALGORITHMS_USE_SLOW_IMPL(begin, end) (!is_consteval(___STDLIB_ALGORITHMS_CALC_LEN(begin, end)) && defined(__EXPR__))
234@define ___stdlib_algorithms_find_kth_smallest(a, begin, end, k) (___STDLIB_ALGORITHMS_USE_SLOW_IMPL(begin, end) ? ___stdlib_algorithms_find_kth_smallest_slow(a, begin, end, k) : ___stdlib_algorithms_find_kth_smallest_fast(a, begin, end, ___STDLIB_ALGORITHMS_CALC_LEN(begin, end), k))