SpectraRust/src/synspec/math/locate.rs
fmq 0f97c0b05b feat: 添加 TLUSTY 新模块 + 修复编译错误
新增 TLUSTY 模块:
- crossd: 光电离截面评估 (bound-free cross section)
- sgmer0: 合并能级光电离截面初始化
- sgmerd: 合并能级光电离截面计算
- dwnfr0: 频率网格下载 (continuum)
- convc1: 对流收敛控制 (radiative)
- chckse: 统计平衡检查 (rates)

扩展 RESOLV 编排器:
- 添加 Feautrier 形式解
- 添加 Lucy 温度修正
- 添加 ROSSTD/PZEVAL/CONOUT 调用
- 添加 IFPOPR=2 占据数更新
- 添加 HESOL6 流体静力平衡修正

修复:
- sgmer0.rs: 修复 config 未声明为 mut 的编译错误
- crossd.rs: 修复测试中使用错误字段路径的问题
  (frqall.ijbf/phoexp.aijbf/phoexp.bfcs 而非 obfpar)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 12:35:09 +08:00

78 lines
1.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! 二分查找子程序。
//!
//! 重构自 SYNSPEC `locate.f`
//!
//! 在有序数组 `xx` 中查找值 `x` 的位置,使得 `xx[j] <= x < xx[j+1]`。
/// 在有序数组中二分查找。
///
/// 查找 `x` 在有序数组 `xx[0..n]` 中的插入位置。
/// 返回索引 `j`,使得 `xx[j-1] <= x < xx[j]`1-indexed
///
/// # 参数
///
/// * `xx` - 有序数组(升序或降序)
/// * `n` - 数组有效长度
/// * `x` - 待查找的值
///
/// # 返回值
///
/// 索引 `j`1-indexed使得 `xx[j-1] <= x < xx[j]`
pub fn locate(xx: &[f64], n: usize, x: f64) -> usize {
let mut jl: isize = 0;
let mut ju = (n + 1) as isize;
while ju - jl > 1 {
let jm = (ju + jl) / 2;
if (xx[n - 1] >= xx[0]) == (x >= xx[jm as usize - 1]) {
jl = jm;
} else {
ju = jm;
}
}
if x == xx[0] {
1
} else if x == xx[n - 1] {
n - 1
} else {
jl as usize
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_locate_basic() {
let xx = [1.0, 2.0, 3.0, 4.0, 5.0];
// x=2.5 应该在 xx[1] 和 xx[2] 之间,返回 j=2
let j = locate(&xx, 5, 2.5);
assert!(j >= 1 && j <= 4);
assert!(xx[j - 1] <= 2.5 && xx[j] >= 2.5);
}
#[test]
fn test_locate_exact_first() {
let xx = [1.0, 2.0, 3.0, 4.0, 5.0];
let j = locate(&xx, 5, 1.0);
assert_eq!(j, 1);
}
#[test]
fn test_locate_exact_last() {
let xx = [1.0, 2.0, 3.0, 4.0, 5.0];
let j = locate(&xx, 5, 5.0);
assert_eq!(j, 4);
}
#[test]
fn test_locate_between() {
let xx = [0.0, 10.0, 20.0, 30.0];
let j = locate(&xx, 4, 15.0);
assert!(j >= 1 && j <= 3);
assert!(xx[j - 1] <= 15.0 && xx[j] >= 15.0);
}
}