9 个不稳定版本 (3 个破坏性更新)
使用旧的 Rust 2015
0.4.7 | 2017年12月21日 |
---|---|
0.4.6 |
|
0.4.3 | 2017年11月16日 |
0.3.0 | 2017年10月31日 |
0.1.0 | 2017年10月29日 |
#1078 in 数据结构
在 3 个crate中使用(通过 kmerutils)
70KB
1K SLoC
Rust 语言的小波矩阵
它在常数时间内提供了对非常大的无符号整数序列的各种分析。
使用方法
在Cargo.toml中添加后,将此行添加到lib.rs或main.rs中。
extern crate wavelet_matrix;
查看crate文档顶部以获取更多示例。
基准测试
-
总体性能
- https://github.com/sekineh/wavelet-matrix-rs/blob/master/BENCH.md
- 在 Intel Xeon 2800 MHz 上执行基准测试
-
O(1) SUM 的错误评估
功能
给定一个无符号整数序列 T,它提供以下查询。
基本操作
.len()
:- 返回
T
的长度。 - 几乎没有开销,只是返回存储的值。
- 返回
.lookup(pos)
:- 返回 T 位置处的值,
T[pos]
。 - 比数组查找慢,但仍然是 O(1)。您可能想保存原始 Vector 以加快查找速度。
- 返回 T 位置处的值,
计数
计数在 O(1) 内完成。
.count(start..end,value)
:- 返回满足
e == value
且包含在T[start..end]
的元素e
的数量
- 返回满足
.count_prefix(start..end,value,ignore_bit)
:- 返回满足
e >> ignore_bit == value >> ignore_bit
且包含在T[start..end]
的元素e
的数量 - 这可以用来统计满足诸如
192.168.10.0/24
这样的 IPv4 前缀的 IPv4 地址的数量。在这种情况下,ignore_bit 将是 8。
- 返回满足
.count_lt(start..end,value)
:- 返回满足条件
e < value
的元素e
的数量,该条件包含在T[start..end]
中。
- 返回满足条件
.count_gt(start..end,value)
:- 返回满足条件
e > value
的元素e
的数量,该条件包含在T[start..end]
中。
- 返回满足条件
.count_range(start..end,val_start..val_end)
:- 返回满足条件
val_start <= e < val_end
的元素e
的数量,该条件包含在T[start..end]
中。
- 返回满足条件
搜索
每次搜索的索引的时间复杂度为 O(1)。
.search(start..end,value)
:- 返回一个迭代器,该迭代器找到满足条件
e == value
的元素e
的索引,该条件包含在T[start..end]
中。
- 返回一个迭代器,该迭代器找到满足条件
.search_prefix(start..end,value,ignore_bit)
:- 返回一个迭代器,该迭代器找到满足条件
e >> ignore_bit == value >> ignore_bit
的元素e
的索引,该条件包含在T[start..end]
中。
- 返回一个迭代器,该迭代器找到满足条件
- [待办] 实现除等于之外的各种条件。
排名
与元素数量 n
相关的排名操作大致为 O(1)。
.max_k(start..end,val_start..val_end,k)
:- 按降序列出
(value, count)
对。 - 值被限制在范围
val_start..val_end
内。
- 按降序列出
.min_k(start..end,val_start..val_end,k)
:- 按升序列出
(value, count)
对。 - 值被限制在范围
val_start..val_end
内。
- 按升序列出
.top_k()
在最佳情况下也以 O(1) 的速度执行,但在最坏情况下(每个值只出现一次)可能需要 O(n)!
.top_k(start..end,val_start..val_end,k)
:- 按最频繁出现顺序列出
(value, count)
对。 - 值被限制在范围
val_start..val_end
内。 - [待办] 明确相同计数的顺序。
- 按最频繁出现顺序列出
为了在不考虑唯一值数量的情况下实现 O(1) 性能,请使用 .top_k_ranges()
- [实验性]
.top_k_ranges(start..end, val_start..val_end, k)
- 按最频繁出现顺序列出
(v_start..v_end, count)
对。 - 与
.top_k()
不同,.top_k_ranges()
返回包含所有值的完整范围集。 - 值被限制在范围
val_start..val_end
内。 - [待办] 明确相同计数的顺序。
- 按最频繁出现顺序列出
统计
O(1) 中位数 / O(1) 分位数
.median(start..end)
:- 从
T[start..end]
返回中位数。 - 与
.quantile(start..end, start + (end - start) / 2)
相同。
- 从
.quantile(start..end,k)
:- 从
T[start..end]
返回第 (k+1) 个最小值。
- 从
O(1) 求和 / O(1) 平均值 / O(1) 方差
实验 1
这些方法使用 .top_k_ranges()
来枚举最相关的值范围。
它们不如实验 2 中的方法准确。
- [实验性]
.sum_experiment1(start..end, val_start..val_end, k)
- 使用最多
k
个小波树节点来近似计算T[start..end]
的总和。 - 仅处理包含在范围
val_start..val_end
内的值。 - 要得到精确结果,指定
k = m + 1
,其中m
是唯一值的数量。
- 使用最多
- [实验性]
.mean_experiment1(start..end, val_start..val_end, k)
- 使用最多
k
个小波树节点来近似计算T[start..end]
的平均值。 - 仅处理包含在范围
val_start..val_end
内的值。 - 要得到精确结果,指定
k = m + 1
,其中m
是唯一值的数量。
- 使用最多
- [实验性]
.variance_experiment1(start..end, val_start..val_end, k)
- 使用最多
k
个小波树节点来近似计算T[start..end]
的方差。 - 仅处理包含在范围
val_start..val_end
内的值。 - 要得到精确结果,指定
k = m + 1
,其中m
是唯一值的数量。
- 使用最多
实验 2
比实验 1 有所改进。它们使用自定义节点枚举器来最小化误差。
- [实验性]
.sum_experiment2(start..end, val_start..val_end, k)
实验 3
比实验 2 有所改进。它们使用 Range<u64>
来表示计算值的精确度。
- [实验性]
.sum_experiment3(start..end, val_start..val_end, k)
经典小波矩阵操作
.rank(pos, value)
:计算包含在T[0..pos]
中的值数量。- 注意:pos是排他的。当pos为0时,
.rank()
总是返回0。
- 注意:pos是排他的。当pos为0时,
.select(rank, value)
:返回第(rank+1)个值的索引- 注意:如果没有找到,则返回
.len()
而不是None。
- 注意:如果没有找到,则返回
版本发布
v0.4.7
- 修复测试错误#4
- 修复测试错误#3
v0.4.6
- 添加对
.median()
和.quantile()
的测试。 - 添加索引范围检查。
v0.4.5
- 修复依赖项错误。
v0.4.4
- 添加
.median()
和.quantile()
。它们非常快,在16位值上只需3-5微秒。 - 添加
.top_k_ranges()
,它在最坏情况下比.top_k()
更快。 - 添加
.sum_experiment1()
、.mean_experiment1()
和.variance_experiment1()
。 - 添加
.sum_experiment2()
。 - 添加
.sum_experiment3()
。 - 添加
BENCH.md
基准测试报告。 - 添加
BENCH_SUM.md
基准测试报告。
v0.4.3
- 添加
.bit_len()
。 - 添加
.dim()
。 - 将示例移动到crate文档顶部。
- 添加对
.top_k()
、.max_k()
和min_k()
的测试。 - 抑制警告。
v0.4.2
- 添加
.top_k()
、.max_k()
和min_k()
。
v0.4.1
- 添加
.search()
和.search_prefix()
。
v0.4.0
- 添加
.count()
、.count_prefix()
、.count_lt()
、.count_gt()
和.count_range()
。 - [不兼容] WaveletMatrix::new() 现在接受
&Vec<u64>
,而不是Vec<u64>
v0.3.0
- [不兼容] .select() 现在返回 .len() 而不是 None。
待办事项
-
添加基准测试。
- 使用简单算法实现相同的查询。
- 比较 wm 的查询与简单算法的查询。
- 制作一个漂亮的图表。
-
性能分析
-
优化底层的 rsdic 结构。
-
添加 travis CI。
-
添加 u128 支持或任意长度整数支持
-
地球上最快的实现
致谢
-
一个使用波尔差树的 Go 包,用于执行多种数组操作
- https://github.com/hillbig/waveletTree
- 基本上,该算法深深来源于上述 Go 实现。
-
日文出色的幻灯片
-
原始发明者的 pdf
依赖项
~445KB