Библиотека nalgebra в Rust

от автора

Привет, Хабр!

Линейная алгебра сейчас применяется практические везде. В связс с этим сегодня рассмотрим одну из библиотек для Rust — nalgebra.

Основная цель nalgebra — предоставить инструмент для работы с линейной алгеброй.

Основные возможности

Векторы

Векторы в nalgebra могут быть как статически, так и динамически выделяемыми. Векторы со статическими размерами известны на этапе компиляции и хранятся в стеке, тогда как динамические векторы выделяются в куче.

Пример статического вектора:

use nalgebra::Vector3;  fn main() {     let v = Vector3::new(1.0, 2.0, 3.0);     println!("Vector: {:?}", v); }

Пример динамического вектора:

use nalgebra::DVector;  fn main() {     let v = DVector::from_vec(vec![1.0, 2.0, 3.0, 4.0]);     println!("Dynamic Vector: {:?}", v); }

Матрицы

Матрицы также могут быть статическими и динамическими. Статические матрицы имеют размеры, известные на этапе компиляции, тогда как размеры динамических матриц могут изменяться во время выполнения.

Пример статической матрицы:

use nalgebra::Matrix3;  fn main() {     let m = Matrix3::new(1.0, 2.0, 3.0,                          4.0, 5.0, 6.0,                          7.0, 8.0, 9.0);     println!("Matrix:\n{}", m); }

Пример динамической матрицы:

use nalgebra::DMatrix;  fn main() {     let m = DMatrix::from_row_slice(3, 3, &[         1.0, 2.0, 3.0,         4.0, 5.0, 6.0,         7.0, 8.0, 9.0     ]);     println!("Dynamic Matrix:\n{}", m); }

Операции с векторами и матрицами включают сложение, умножение, транспонирование, инверсию и другие стандартные линейные операции.

Точки и трансформации

Точки

Точки в nalgebra представляют собой координаты в пространстве. Их используют для обозначения положений объектов, в отличие от векторов, которые обозначают направления и расстояния.

Пример:

use nalgebra::{Point2, Point3};  fn main() {     let p2 = Point2::new(1.0, 2.0);     let p3 = Point3::new(1.0, 2.0, 3.0);          println!("Point2: {:?}", p2);     println!("Point3: {:?}", p3); }

Трансформации

Трансформации включают в себя различные операции, такие как переводы, вращения и масштабирования.

Пример:

use nalgebra::{Translation3, Rotation3, Isometry3, Vector3};  fn main() {     let translation = Translation3::new(1.0, 2.0, 3.0);     let rotation = Rotation3::from_axis_angle(&Vector3::z_axis(), 0.785398163); // 45 degrees in radians      let isometry = Isometry3::new(translation.vector, rotation.scaled_axis());          println!("Isometry:\n{}", isometry); }

Специфические структуры данных

Кватернионы

Кватернионы используются для представления и вычисления 3D вращений. Иногда это некий мастхев для анимаций и графических приложений из-за своей компактности и отсутствия эффекта «гимбаллок«.

Пример:

use nalgebra::{Quaternion, UnitQuaternion};  fn main() {     let axis = Vector3::y_axis();     let angle = 1.57; // 90 degrees in radians      let quaternion = UnitQuaternion::from_axis_angle(&axis, angle);          println!("Quaternion: {:?}", quaternion); }

Изометрии

Изометрия сочетает в себе перевод и вращение. Эта структура нужна для представления позиций и ориентаций объектов в пространстве.

Пример:

use nalgebra::{Isometry3, Vector3};  fn main() {     let translation = Vector3::new(1.0, 2.0, 3.0);     let rotation = Vector3::new(0.0, 1.0, 0.0); // Rotate around Y axis      let iso = Isometry3::new(translation, rotation);          println!("Isometry:\n{}", iso); }

Гомогенные матрицы

Гомогенные матрицы используются для представления общих линейных преобразований: переводы, вращения, масштабирования и сдвиги.

Пример:

use nalgebra::Matrix4;  fn main() {     let mut m = Matrix4::identity();     m[(0, 3)] = 1.0; // Translation along X axis     m[(1, 1)] = 0.5; // Scaling along Y axis          println!("Homogeneous Matrix:\n{}", m); }

Прочие возможности

Факторизации матриц

Факторизация матриц — это процесс разложения матрицы на произведение нескольких матриц, что очень часто используют для решения систем линейных уравнений, вычисления обратных матриц и определителей.

LU-разложение

LU-разложение разделяет матрицу на нижнюю треугольную матрицу L и верхнюю треугольную матрицу U.

Пример кода:

use nalgebra::DMatrix;  fn main() {     let matrix = DMatrix::from_row_slice(3, 3, &[2.0, 1.0, 1.0,                                                  4.0, -6.0, 0.0,                                                  -2.0, 7.0, 2.0]);     let lu = matrix.lu();     let l = lu.l();     let u = lu.u();     println!("L:\n{}", l);     println!("U:\n{}", u); } 

QR-разложение

QR-разложение разлагает матрицу на ортогональную матрицу Q и верхнюю треугольную матрицу R.

Пример кода:

use nalgebra::DMatrix;  fn main() {     let matrix = DMatrix::from_row_slice(3, 3, &[12.0, -51.0, 4.0,                                                  6.0, 167.0, -68.0,                                                 -4.0, 24.0, -41.0]);     let qr = matrix.qr();     let q = qr.q();     let r = qr.r();     println!("Q:\n{}", q);     println!("R:\n{}", r); }

SVD-разложение

SVD-разложение представляет матрицу в виде произведения трех матриц: U, Σ диагональная матрица с сингулярными значениями и V^*.

Пример разложения:

use nalgebra::DMatrix;  fn main() {     let matrix = DMatrix::from_row_slice(3, 2, &[1.0, 0.0,                                                  0.0, 1.0,                                                  1.0, 1.0]);     let svd = matrix.svd(true, true);     let u = svd.u.unwrap();     let s = svd.singular_values;     let v_t = svd.v_t.unwrap();     println!("U:\n{}", u);     println!("Σ:\n{}", s);     println!("V^T:\n{}", v_t); }

Специальные виды матриц

Разреженные матрицы

Разреженные матрицы содержат преимущественно нулевые элементы, что частенько позволяет сэкономить память. В nalgebra поддерживаются различные форматы разреженных матриц, такие как compressed sparse column и compressed sparse row.

Пример создания разреженной матрицы:

use nalgebra_sparse::csr::CsrMatrix;  fn main() {     let num_rows = 4;     let num_cols = 4;     let row_offsets = vec![0, 2, 4, 7, 8];     let col_indices = vec![0, 1, 1, 2, 0, 2, 3, 3];     let values = vec![10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0];     let csr = CsrMatrix::try_from_csr_data(num_rows, num_cols, row_offsets, col_indices, values).unwrap();     println!("CSR Matrix:\n{}", csr); }

Ортографические и перспективные проекции

Ортографические и перспективные проекции используют в компьютерной графике для отображения трехмерных сцен на двумерный экран.

Пример ортографической проекции:

use nalgebra::Orthographic3;  fn main() {     let orthographic = Orthographic3::new(-1.0, 1.0, -1.0, 1.0, 0.1, 100.0);     println!("Orthographic Projection:\n{}", orthographic.as_matrix()); }

Пример перспективной проекции:

use nalgebra::Perspective3;  fn main() {     let perspective = Perspective3::new(16.0 / 9.0, 3.14 / 4.0, 0.1, 100.0);     println!("Perspective Projection:\n{}", perspective.as_matrix()); }

Вычисления на GPU и встраиваемые системы

Nalgebra поддерживает компиляцию для WebAssembly и различные встраиваемые системы.

Пример компиляции для WebAssembly:

# В Cargo.toml добавьте поддержку wasm [dependencies] nalgebra = "0.27" wasm-bindgen = "0.2"  # В main.rs use nalgebra::Vector3; use wasm_bindgen::prelude::*;  #[wasm_bindgen] pub fn add_vectors(a: &Vector3<f32>, b: &Vector3<f32>) -> Vector3<f32> {     a + b }

Для компиляции есть команда:

wasm-pack build --target web

Nalgebra также может использоваться с библиотеками для GPU вычислений, такими как wgpu и ash.

Библиотека nalgebra — мощный и гибкий инструмент для работы с линейной алгеброй в Rust.

•‎ nalgebra на GitHub


Что делать, если у вас неопытная команда, а надо делать сложную задачу? Можно написать заявление об увольнении, а потом с ужасом рассказывать в интернете про прошлые места работы. А можно попробовать выстроить процессы так, чтобы получить требуемый результат. На открытом уроке мы не будем обсуждать, какая из этих двух стратегий правильная, но поговорим о том, как математика может помочь выстроить архитектуру приложения, которая позволит решить эту трудную задачу.

Урок пройдёт в рамках курса «Математика для программистов» 26 июля. Записаться можно по ссылке.


ссылка на оригинал статьи https://habr.com/ru/articles/828316/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *