4 个版本 (2 个重大更改)
0.3.0 | 2024年3月23日 |
---|---|
0.2.0 | 2024年3月22日 |
0.1.1 | 2024年3月22日 |
0.1.0 | 2024年3月14日 |
#425 在 数据结构
每月116次下载
125KB
2K SLoC
SignVec
SignVec
通过提供基于 Signable
特性的功能,扩展了传统 Vec
的功能,以便高效地跟踪和操作基于元素符号(正或负)的操作。
特性
- 跟踪元素的符号以优化符号特定操作。
- 提供基于符号的元素计数、访问和操作方法。
- 通过
Signable
特性与用户定义的类型集成。
使用:基本操作
use nanorand::{Rng, WyRand};
use signvec::{svec, Sign, SignVec};
fn main() {
let mut vector = svec![1, -2, 3, -4];
assert_eq!(vector.len(), 4);
assert_eq!(vector[0], 1);
assert_eq!(vector[1], -2);
// Count positive and negative elements
assert_eq!(vector.count(Sign::Plus), 2);
assert_eq!(vector.count(Sign::Minus), 2);
// Get indices of positive and negative elements
assert_eq!(
vector.indices(Sign::Plus).iter().collect::<Vec<_>>(),
vec![&0, &2]
);
assert_eq!(
vector.indices(Sign::Minus).iter().collect::<Vec<_>>(),
vec![&1, &3]
);
// Retrieve values based on their sign
assert_eq!(vector.values(Sign::Plus).collect::<Vec<_>>(), vec![&1, &3]);
assert_eq!(
vector.values(Sign::Minus).collect::<Vec<_>>(),
vec![&-2, &-4]
);
// Modify individual elements
vector.set(1, 5);
assert_eq!(vector[1], 5);
// Randomly select an element based on its sign
let mut rng = WyRand::new();
if let Some(random_positive) = vector.random(Sign::Plus, &mut rng) {
println!("Random positive value: {}", random_positive);
}
}
使用:蒙特卡洛模拟
这演示了一个简单的蒙特卡洛模拟,其中 SignVec
中的站点能量根据模拟动力学和系统能量分布进行更新。
use signvec::{SignVec, svec, Sign, Signable};
use nanorand::{WyRand, Rng};
fn main() {
let mut energies = svec![1.0, -1.0, 1.5, -1.5, 0.5, -0.5];
let mut rng = WyRand::new();
// Simulation loop for multiple Monte Carlo steps
for _step in 0..100 {
let site = rng.generate_range(0..energies.len());
let dE = rng.generate::<f64>() - 0.5; // Change in energy
let new_energy = energies[site] + dE; // Update site energy
// Make decisions based on system's energy distribution
if energies.count(Sign::Minus) > energies.count(Sign::Plus) {
if energies[site].sign() == Sign::Minus && rng.generate::<f64>() < 0.5 {
energies.set(site, -new_energy); // Flip energy sign
} else {
energies.set(site, new_energy);
}
} else {
energies.set(site, new_energy); // Balanced distribution
}
}
println!("Final energy distribution: {:?}", energies);
}
使用:投资组合管理
演示了如何使用 SignVec
进行金融投资组合管理,模拟市场条件,并根据资产和负债的符号特性做出决策。
use signvec::{SignVec, Sign, svec};
use nanorand::WyRand;
fn main() {
let mut portfolio = svec![150.0, -200.0, 300.0, -50.0, 400.0];
let market_conditions = vec![1.05, 0.95, 1.10, 1.00, 1.03];
// Apply market conditions to adjust portfolio balances
for (index, &factor) in market_conditions.iter().enumerate() {
portfolio.set(index, portfolio[index] * factor);
}
// Decision making based on portfolio's sign-aware characteristics
if portfolio.count(Sign::Minus) > 2 {
println!("Consider rebalancing your portfolio to manage risk.");
} else {
println!("Your portfolio is well-balanced and diversified.");
}
// Calculate 10% of total liabilities for debt reduction
let debt_reduction = portfolio.values(Sign::Minus).sum::<f64>() * 0.1;
println!("Plan for a debt reduction of ${:.2} to strengthen your financial position.", debt_reduction.abs());
// Identify a high-performing asset for potential investment
let mut rng = WyRand::new();
if let Some(lucky_asset) = portfolio.random(Sign::Plus, &mut rng) {
println!("Consider investing more in an asset valued at ${:.2}.", lucky_asset);
} else {
println!("No standout assets for additional investment at the moment.");
}
}
基准测试
下表是 SignVec
专用功能基准结果的摘要。
操作 | SignVec |
Vec |
加速 |
---|---|---|---|
set |
1.3922 ns | - | - |
set_unchecked |
1.3873 ns | - | - |
random (Plus) |
822.90 ps | - | - |
random (Minus) |
829.92 ps | - | - |
random_pos |
652.96 ps | - | - |
random_neg |
687.77 ps | - | - |
count (Plus) |
453.21 ps | - | - |
count (Minus) |
458.70 ps | - | - |
count_pos |
229.73 ps | - | - |
count_neg |
228.44 ps | - | - |
indices (Plus) |
465.04 ps | - | - |
indices (Minus) |
461.85 ps | - | - |
indices_pos |
226.99 ps | - | - |
indices_neg |
225.83 ps | - | - |
sync |
61.208 µs | - | - |
count [^1] |
225.74 ps | 153.38 ns | ~679x 更快 |
indices [^2] |
86.42 ns | 1.11 µs | ~12.8x 更快 |
values [^3] |
579.37 ns | 1.13 µs | ~1.95x 更快 |
random [^4] |
857.86 ps | 950.84 ns | ~1106x 更快 |
[^1]:此处使用 count_pos
和 count_neg
基准测试进行比较,因为它们代表了按符号计数元素的优化路径。[^2]:将 indices_pos
和 indices_neg
基准测试呈现为按符号检索索引的优化方法。[^3]:values
操作在提供的基准测试中没有直接的对应项,但包含在上下文中。[^4]:random_pos
和 random_neg
基准测试提供了在符号预定的条件下 random
操作性能的上下文。
基准测试是在以下规格的机器上进行的
- 处理器:AMD Ryzen™ 5 5600G 配备 Radeon™ 图形 x 12
- 内存:58.8 GiB
- 操作系统:Guix 系统
- 操作系统类型:64位
依赖项
~0.6–1.2MB
~26K SLoC