Комментарии 13
www.jmargolin.com/sense/refs/ref26_fang.pdf
Конечно есть, уйма их:
- Bucher, R., Misra, D., A Synthesizable VHDL Model of the Exact Solution for Three-dimensional Hyperbolic Positioning System, VLSI Design, Volume 15/2, 2002, pp. 507-520.
- Упомянутый вами Fang: B. T. Fang, «Simple solutions for hyperbolic and related position fixes,» in IEEE Transactions on Aerospace and Electronic Systems, vol. 26, no. 5, pp. 748-753, Sept. 1990.
- «An Algebraic Solution of the GPS Equations», Stephen Bancroft, IEEE Transactions on Aerospace and Electronic Systems, Volume: AES-21, Issue: 7 (Jan. 1985), pp 56–59.
- “A direct solution to GPS-type navigation equations”, L.O. Krause, IEEE Transactions on Aerospace and Electronic Systems, AES-23, 2 (1987), pp 225–232.
В реальной жизни только это особо не применимо, как я уже упомянул в статье, из-за зашумленных измерений.
2. Можно использовать рекомбинацию троек и найти тройку с минимальной невязкой за меньшую стоимость вычислений по сравнению численно-итеративным способом.
pub fn eps_tdoa3d(base_lines: &Vec<(f64, f64, f64, f64, f64, f64, f64)>, x: f64, y: f64, z: f64) -> f64
Я не эксперт в Расте, но это выглядит очень странно.
Во-первых, зачем ссылка на вектор, если есть слайс &[T]?
Во-вторых, зачем внутри вектора такой некрасивый кортеж, если это по сути просто двумерный массив (как в примере на других языках)?
На самом деле массив только в матлабе передается, и я сказал об этом в статье. В C# передается массив структур. Кортеж в этом смысле гарантирует что в функцию не передадут массив 100х100 или что-то несуразное. Т.к. функция невязки вызывается часто, то не хочется внутри ничего проверять.
В любом случае, можете сделать форк и улучшить реализацию.
В расте есть массивы с фиксированным количеством элементов, т.е. более идиоматично было бы написать это, например, так:
pub fn eps_tdoa3d(base_lines: &[[f64; 4]], point: [f64; 3]) -> f64
Либо используя nalgebra
вообще переписать как:
pub type Point = nalgebra::geometry::Point3<f64>;
pub struct BasePoint {
point: Point,
dist: f64,
}
pub fn eps_toa3d(base_points: &[BasePoint], point: Point) -> f64 {
base_points.iter()
.map(|bp| (bp.point - point).norm() - bp.dist)
.sum()
}
Как с C# не знаю, но вот сравнение с Матлабом без использования специализированных матричных библиотек, вероятно, будет нечестным. Кроме того, в Расте умышленно используется достаточно маленькая стандартная библиотека, поэтому без использования внешних зависимостей вы далеко с ним не уйдёте. Благо подключение зависимостей и их использование в Расте это сущее удовольствие. Т.к. nalgebra
(либо аналоги попроще) позволяет значительно сократить кол-во бойлерплейта, то называть данную зависимость лишней я бы не стал.
Про объявление структур советую внимательно подумать, их использование не только позволяет сокращать количество бойлерплейта как в моём примере, и тем самым сокращать вероятность ошибок (явные имена полей этому тоже способствуют), но и позволяет лучше и быстрее понимать код не только другим людям, но и вам после того как вы к нему вернётесь через какое-то время. Разумеется, тут нужно соблюдать меру, но лично мне разбираться в вашем коде было достаточно сложно.
Через всю географию: навигационные и геодезические задачи на разных языках