{"id":16647420,"url":"https://github.com/gyrdym/ml_linalg","last_synced_at":"2025-06-10T22:33:42.578Z","repository":{"id":22328932,"uuid":"95952257","full_name":"gyrdym/ml_linalg","owner":"gyrdym","description":"SIMD-based linear algebra and statistics for data science with dart","archived":false,"fork":false,"pushed_at":"2024-08-18T18:37:33.000Z","size":1157,"stargazers_count":83,"open_issues_count":6,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-11T00:13:04.607Z","etag":null,"topics":["dart","linalg","linear-algebra","machine-learning","math","mathematical-methods","mathematics","matrix","scalar","simd","simd-library","simd-parallelism","simd-programming","simd-vector","vector","vector-elements","vector-multiplication"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gyrdym.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["gyrdym"]}},"created_at":"2017-07-01T08:34:17.000Z","updated_at":"2025-03-23T16:37:58.000Z","dependencies_parsed_at":"2024-06-06T22:50:50.321Z","dependency_job_id":"ca3f0eb6-4882-408e-ab64-10850b2eed29","html_url":"https://github.com/gyrdym/ml_linalg","commit_stats":null,"previous_names":[],"tags_count":85,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyrdym%2Fml_linalg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyrdym%2Fml_linalg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyrdym%2Fml_linalg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyrdym%2Fml_linalg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gyrdym","download_url":"https://codeload.github.com/gyrdym/ml_linalg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gyrdym%2Fml_linalg/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259164056,"owners_count":22815266,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","linalg","linear-algebra","machine-learning","math","mathematical-methods","mathematics","matrix","scalar","simd","simd-library","simd-parallelism","simd-programming","simd-vector","vector","vector-elements","vector-multiplication"],"created_at":"2024-10-12T08:44:42.452Z","updated_at":"2025-06-10T22:33:42.558Z","avatar_url":"https://github.com/gyrdym.png","language":"Dart","funding_links":["https://github.com/sponsors/gyrdym"],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://github.com/gyrdym/ml_linalg/workflows/CI%20pipeline/badge.svg)](https://github.com/gyrdym/ml_linalg/actions?query=branch%3Amaster+)\n[![Coverage Status](https://coveralls.io/repos/github/gyrdym/ml_linalg/badge.svg)](https://coveralls.io/github/gyrdym/ml_linalg)\n[![pub package](https://img.shields.io/pub/v/ml_linalg.svg)](https://pub.dartlang.org/packages/ml_linalg)\n[![Gitter Chat](https://badges.gitter.im/gyrdym/gyrdym.svg)](https://gitter.im/gyrdym/)\n\n**SIMD-based linear algebra and statistics for data science with Dart**\n\n\u003cdetails\u003e\n\u003csummary\u003eTABLE OF CONTENTS\u003c/summary\u003e\n\n- [What is linear algebra](#linear-algebra)\n- [What is SIMD](#what-is-simd)\n- [Vectors](#vectors)\n\t- [A couple of words about the underlying architecture](#a-couple-of-words-about-the-underlying-architecture)\n\t- [Vector benchmarks](#vector-benchmarks)\n\t- [Vector operations](#vector-operations-examples)\n        - [Vector summation](#vector-summation)\n        - [Vector and List summation](#vector-and-list-summation)\n        - [Summation of Vectors of different dtype](#summation-of-vectors-of-different-dtype)\n        - [Vector subtraction](#vector-subtraction)\n        - [Vector and List subtraction](#vector-and-list-subtraction)\n        - [Subtraction of Vectors of different dtype](#subtraction-of-vectors-of-different-dtype)\n        - [Element-wise Vector by Vector multiplication](#element-wise-vector-by-vector-multiplication)\n        - [Element-wise Vector and List multiplication](#element-wise-vector-and-list-multiplication)\n        - [Element-wise multiplication of Vectors of different dtype](#element-wise-multiplication-of-vectors-of-different-dtype)\n        - [Element-wise Vector by Vector division](#element-wise-vector-by-vector-division)\n        - [Element-wise Vector and List division](#element-wise-vector-and-list-division)\n        - [Element-wise division of Vectors of different dtype](#element-wise-division-of-vectors-of-different-dtype)\n        - [Euclidean norm](#euclidean-norm)\n        - [Manhattan norm](#manhattan-norm)\n        - [Mean value](#mean-value)\n        - [Median value](#median-value)\n        - [Sum of all vector elements](#sum-of-all-vector-elements)\n        - [Product of all vector elements](#product-of-all-vector-elements)\n        - [Element-wise power](#element-wise-power)\n        - [Element-wise exp](#element-wise-exp)\n        - [Dot product](#dot-product-of-two-vectors)\n        - [Sum of a vector and a scalar](#sum-of-a-vector-and-a-scalar)\n        - [Subtraction of a scalar from a vector](#subtraction-of-a-scalar-from-a-vector)\n        - [Multiplication of a vector by a scalar](#multiplication-of-a-vector-by-a-scalar)\n        - [Division of a vector by a scalar](#division-of-a-vector-by-a-scalar)\n        - [Euclidean distance between two vectors](#euclidean-distance-between-two-vectors)\n        - [Manhattan distance between two vectors](#manhattan-distance-between-two-vectors)\n        - [Cosine distance between two vectors](#cosine-distance-between-two-vectors)\n        - [Vector normalization (using Euclidean norm)](#vector-normalization-using-euclidean-norm)\n        - [Vector normalization (using Manhattan norm)](#vector-normalization-using-manhattan-norm)\n        - [Vector rescaling (min-max normalization)](#vector-rescaling-min-max-normalization)\n        - [Vector serialization](#vector-serialization)\n        - [Vector mapping](#vector-mapping)\n- [Matrices](#matrices)\n    - [Matrix operations](#matrix-operations-examples)\n        - [Creation of diagonal matrix](#creation-of-diagonal-matrix)\n        - [Creation of scalar matrix](#creation-of-scalar-matrix)\n        - [Creation of identity matrix](#creation-of-identity-matrix)\n        - [Creation of column matrix](#creation-of-column-matrix)\n        - [Creation of row matrix](#creation-of-row-matrix)\n        - [Sum of a matrix and another matrix](#sum-of-a-matrix-and-another-matrix)\n        - [Sum of a matrix and a scalar](#sum-of-a-matrix-and-a-scalar)\n        - [Multiplication of a matrix and a vector](#multiplication-of-a-matrix-and-a-vector)\n        - [Multiplication of a matrix and another matrix](#multiplication-of-a-matrix-and-another-matrix)\n        - [Multiplication of a matrix and a scalar](#multiplication-of-a-matrix-and-a-scalar)\n        - [Hadamard product (element-wise matrices multiplication)](#hadamard-product-element-wise-matrices-multiplication)\n        - [Element-wise matrices subtraction](#element-wise-matrices-subtraction)\n        - [Matrix transposition](#matrix-transposition)\n        - [Matrix LU decomposition](#matrix-lu-decomposition)\n        - [Matrix Cholesky decomposition](#matrix-cholesky-decomposition)\n        - [Matrix LU inversion](#matrix-lu-inversion)\n        - [Matrix Cholesky inversion](#matrix-cholesky-inversion)\n        - [Lower triangular matrix inversion](#lower-triangular-matrix-inversion)\n        - [Upper triangular matrix inversion](#upper-triangular-matrix-inversion)\n        - [Solving a system of linear equations](#solving-a-system-of-linear-equations)\n        - [Obtaining Matrix eigenvectors and eigenvalues, Power Iteration method](#obtaining-matrix-eigenvectors-and-eigenvalues-power-iteration-method)\n        - [Matrix row-wise reduce](#matrix-row-wise-reduce)\n        - [Matrix column-wise reduce](#matrix-column-wise-reduce)\n        - [Matrix row-wise mapping](#matrix-row-wise-mapping)\n        - [Matrix column-wise mapping](#matrix-column-wise-mapping)\n        - [Matrix element-wise mapping](#matrix-element-wise-mapping)\n        - [Matrix' columns filtering (by column index)](#matrix-columns-filtering-by-column-index)\n        - [Matrix' columns filtering (by column)](#matrix-columns-filtering-by-column)\n        - [Getting max value of the matrix](#getting-max-value-of-the-matrix)\n        - [Getting min value of the matrix](#getting-min-value-of-the-matrix)\n        - [Matrix element-wise power](#matrix-element-wise-power)\n        - [Matrix element-wise exp](#matrix-element-wise-exp)\n        - [Sum of all matrix elements](#sum-of-all-matrix-elements)\n        - [Product of all matrix elements](#product-of-all-matrix-elements)\n        - [Matrix indexing and sampling](#matrix-indexing-and-sampling)\n        - [Add new columns to a matrix](#add-new-columns-to-a-matrix)\n        - [Matrix serialization/deserialization](#matrix-serializationdeserialization)\n- [vector_math and ml_linalg differences](#differences-between-vector-math-and-ml-linalg)\n- [Contacts](#contacts)\n\u003c/details\u003e\n\n## Linear algebra\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;In a few words, linear algebra is a branch of mathematics that works with vectors and matrices.\nVectors and matrices are practical tools in real-life applications, such as machine learning algorithms. These significant \nmathematical entities are implemented in plenty of programming languages.\n \n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;As Dart offers developers good instrumentation, e.g. highly optimized virtual machine, specific data types and rich out-of-the-box library, Dart-based implementation of vectors and matrices has to be quite performant.\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Among numerous standard Dart tools, there are SIMD data types, and support of SIMD computational \narchitecture served as inspiration for creating this library.\n\n\n## What is SIMD?\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;SIMD stands for `Single instruction, multiple data` - it's a computer architecture that allows \nto perform uniform mathematical operations in parallel on a list-like data structure. For instance, one has two arrays: \n\n```Dart\nfinal a = [10, 20, 30, 40];\nfinal b = [50, 60, 70, 80];\n```\n\nand one needs to add these arrays element-wise. Using the regular architecture this operation could be done in the following \nmanner:\n\n```Dart\nfinal c = List(4);\n\nc[0] = a[0] + b[0]; // operation 1\nc[1] = a[1] + b[1]; // operation 2\nc[2] = a[2] + b[2]; // operation 3\nc[3] = a[3] + b[3]; // operation 4\n```\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;As you may have noticed, we need to do 4 operations one by one in a row using regular \ncomputational approach. But with help of SIMD architecture we may do one arithmetic operation on several operands in \nparallel, thus element-wise sum of two arrays can be done for just one step:\n\n\u003cp align=\"center\"\u003e\n    \u003cimg height=\"350\" src=\"https://raw.github.com/gyrdym/ml_linalg/master/readme_resources/img/simd_array_sum.svg?sanitize=true\"\u003e \n\u003c/p\u003e\n\n## Vectors\n\n### A couple of words about the underlying architecture\n    \n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;The library contains two high performant vector classes based on [Float32x4](https://api.dartlang.org/stable/2.5.0/dart-typed_data/Float32x4-class.html) \nand [Float64x2](https://api.dartlang.org/stable/2.5.0/dart-typed_data/Float64x2-class.html) data types - \n[Float32x4Vector](https://github.com/gyrdym/linalg/blob/master/lib/src/vector/float32x4_vector.dart) and [Float64x2Vector](https://github.com/gyrdym/linalg/blob/master/lib/src/vector/float64x2_vector.gen.dart) (the second one is generated from the source code of the first vector's implementation)\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Most of element-wise operations in the first one are performed in four \"threads\" and in the second one - in two \"threads\".\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Implementation of both classes is hidden from the library's users. You can create a \n`Float32x4Vector` or a `Float64x2Vector` instance via [Vector](https://github.com/gyrdym/ml_linalg/blob/master/lib/vector.dart) factory (see examples below).\n\nOne can create `Float32x4`-based vectors the following way:\n\n```dart\nimport 'package:ml_linalg/linalg.dart';\n\nvoid main() {\n  final vector = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0], dtype: DType.float32);\n}\n```\n\nor simply\n\n```dart\nimport 'package:ml_linalg/linalg.dart';\n\nvoid main() {\n  final vector = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n}\n```\n\nsince `dtype` is set to `DType.float32` by default.\n\nOne can create `Float64x2`-based vectors the following way: \n\n```dart\nimport 'package:ml_linalg/linalg.dart';\n\nvoid main() {\n  final vector = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0], dtype: DType.float64);\n}\n```\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Float32x4-based vectors are much faster than Float64x2-based ones, but Float64x2-based vectors are more precise since \nthey use 64 bits to represent numbers in the memory versus 32 bits for Float32x4-based vectors.\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Nevertheless, Float32x4 representation uses by default since usually 32 bits is enough for number precision, and along \nwith that, this representation is more performant.\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;The vectors are immutable: once created, the vector cannot be changed. All the vector operations \nlead to creation of a new vector instance (of course, if the operation is supposed to return a `Vector`).\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Both classes implement `Iterable\u003cdouble\u003e` interface, so it's possible to use them as regular \niterable collections.\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;It's possible to use vector instances as keys for `HashMap` and similar data structures \nand to look up a value by the vector-key, since the hash code for equal vectors is the same:\n\n```dart\nimport 'package:ml_linalg/vector.dart';\n\nfinal map = HashMap\u003cVector, bool\u003e();\n\nmap[Vector.fromList([1, 2, 3, 4, 5])] = true;\n\nprint(map[Vector.fromList([1, 2, 3, 4, 5])]); // true\nprint(Vector.fromList([1, 2, 3, 4, 5]).hashCode == Vector.fromList([1, 2, 3, 4, 5]).hashCode); // true\n``` \n\n### Vector benchmarks\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;To see the performance benefits provided by the library's vector classes, one may visit `benchmark` directory: one may find \nthere a baseline [benchmark](https://github.com/gyrdym/ml_linalg/blob/master/benchmark/vector/baseline/regular_lists_addition.dart) - \nelement-wise summation of two regular List instances and a [benchmark](https://github.com/gyrdym/ml_linalg/blob/master/benchmark/vector/float32/vector_operations/float32x4_vector_vector_addition.dart)\nof a similar operation, but performed on two `Float32x4Vector` instances on the same amount of elements and compare \nthe timings:\n\n- Baseline benchmark (executed on Macbook Air mid 2017), 2 regular lists each with 10,000,000 elements:\n\u003cp align=\"center\"\u003e\n    \u003cimg height=\"250\" src=\"https://raw.github.com/gyrdym/ml_linalg/master/readme_resources/img/vector_baseline_benchmark_timing.png\"\u003e \n\u003c/p\u003e\n\n- Actual benchmark (executed on Macbook Air mid 2017), 2 vectors each with 10,000,000 elements:\n\u003cp align=\"center\"\u003e\n    \u003cimg height=\"250\" src=\"https://raw.github.com/gyrdym/ml_linalg/master/readme_resources/img/vector_actual_benchmark_timing.png\"\u003e \n\u003c/p\u003e\n\nIt took 15 seconds to create a new regular list by summing the elements of two lists, and 0.7 second to sum two vectors - \nthe difference is significant.\n\n### Vector operations examples\n\n#### Vector summation\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector1 + vector2;\n\n  print(result.toList()); // [3.0, 5.0, 7.0, 9.0, 11.0]\n````\n\n#### Vector and List summation\n\n*This operation doesn't benefit from SIMD*\n\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final result = vector + [2.0, 3.0, 4.0, 5.0, 6.0];\n\n  print(result.toList()); // [3.0, 5.0, 7.0, 9.0, 11.0]\n````\n\n#### Summation of Vectors of different dtype\n\n*This operation doesn't benefit from SIMD*\n\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0], dtype: DType.float32);\n  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0], dtype: DType.float64);\n  final result = vector1 + vector2;\n\n  print(result.toList()); // [3.0, 5.0, 7.0, 9.0, 11.0]\n````\n\n#### Vector subtraction\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([4.0, 5.0, 6.0, 7.0, 8.0]);\n  final vector2 = Vector.fromList([2.0, 3.0, 2.0, 3.0, 2.0]);\n  final result = vector1 - vector2;\n\n  print(result.toList()); // [2.0, 2.0, 4.0, 4.0, 6.0]\n````\n\n#### Vector and List subtraction\n\n*This operation doesn't benefit from SIMD*\n\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([4.0, 5.0, 6.0, 7.0, 8.0]);\n  final result = vector - [2.0, 3.0, 2.0, 3.0, 2.0];\n\n  print(result.toList()); // [2.0, 2.0, 4.0, 4.0, 6.0]\n````\n\n#### Subtraction of vectors of different dtype\n\n*This operation doesn't benefit from SIMD*\n\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([4.0, 5.0, 6.0, 7.0, 8.0], dtype: DType.float32);\n  final vector2 = Vector.fromList([2.0, 3.0, 2.0, 3.0, 2.0], dtype: DType.float64);\n  final result = vector1 - vector2;\n\n  print(result.toList()); // [2.0, 2.0, 4.0, 4.0, 6.0]\n````\n\n#### Element wise Vector by Vector multiplication\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector1 * vector2;\n\n  print(result.toList()); // [2.0, 6.0, 12.0, 20.0, 30.0]\n````\n\n#### Element wise Vector and List multiplication\n\n*This operation doesn't benefit from SIMD*\n\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final result = vector * [2.0, 3.0, 4.0, 5.0, 6.0];\n\n  print(result.toList()); // [2.0, 6.0, 12.0, 20.0, 30.0]\n````\n\n#### Element wise multiplication of Vectors of different dtype\n\n*This operation doesn't benefit from SIMD*\n\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0], dtype: DType.float32);\n  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0], dtype: DType.float64);\n  final result = vector1 * vector2;\n\n  print(result.toList()); // [2.0, 6.0, 12.0, 20.0, 30.0]\n````\n\n#### Element wise Vector by Vector division\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([6.0, 12.0, 24.0, 48.0, 96.0]);\n  final vector2 = Vector.fromList([3.0, 4.0, 6.0, 8.0, 12.0]);\n  final result = vector1 / vector2;\n\n  print(result.toList()); // [2.0, 3.0, 4.0, 6.0, 8.0]\n````\n\n#### Element-wise Vector and List division\n\n*This operation doesn't benefit from SIMD*\n\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([6.0, 12.0, 24.0, 48.0, 96.0]);\n  final result = vector / [3.0, 4.0, 6.0, 8.0, 12.0];\n\n  print(result.toList()); // [2.0, 3.0, 4.0, 6.0, 8.0]\n````\n\n#### Element wise division of vectors of different dtype\n\n*This operation doesn't benefit from SIMD*\n\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([6.0, 12.0, 24.0, 48.0, 96.0], dtype: DType.float32);\n  final vector2 = Vector.fromList([3.0, 4.0, 6.0, 8.0, 12.0], dtype: DType.float64);\n  final result = vector1 / vector2;\n\n  print(result.toList()); // [2.0, 3.0, 4.0, 6.0, 8.0]\n````\n\n#### Euclidean norm\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector.norm();\n\n  print(result); // sqrt(2^2 + 3^2 + 4^2 + 5^2 + 6^2) = sqrt(90) ~~ 9.48\n````\n\n#### Manhattan norm\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector.norm(Norm.manhattan);\n\n  print(result); // 2 + 3 + 4 + 5 + 6 = 20.0\n````\n\n#### Mean value\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector.mean();\n\n  print(result); // (2 + 3 + 4 + 5 + 6) / 5 = 4.0\n````\n\n#### Median value\n\n##### Even length\n```dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([10, 12, 4, 7, 9, 12]);\n  final result = vector.median();\n\n  print(result); // 9.5\n```\n\n##### Odd length\n```dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([10, 12, 4, 7, 9, 12, 34]);\n  final result = vector.median();\n\n  print(result); // 10\n```\n\n#### Sum of all vector elements\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector.sum();\n\n  print(result); // 2 + 3 + 4 + 5 + 6 = 20.0\n````\n\n#### Product of all vector elements\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector.prod();\n\n  print(result); // 2 * 3 * 4 * 5 * 6 = 720\n````\n\n#### Element-wise power\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector.pow(3);\n  \n  print(result); // [2 ^ 3 = 8.0, 3 ^ 3 = 27.0, 4 ^ 3 = 64.0, 5 ^3 = 125.0, 6 ^ 3 = 216.0]\n````\n\n#### Element-wise exp\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector.exp();\n  \n  print(result); // [e ^ 2, e ^ 3, e ^ 4, e ^ 5, e ^ 6]\n````\n\n#### Dot product of two vectors\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector1.dot(vector2);\n\n  print(result); // 1.0 * 2.0 + 2.0 * 3.0 + 3.0 * 4.0 + 4.0 * 5.0 + 5.0 * 6.0 = 70.0\n````\n\n#### Sum of a vector and a scalar\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final scalar = 5.0;\n  final result = vector + scalar;\n\n  print(result.toList()); // [6.0, 7.0, 8.0, 9.0, 10.0]\n````\n\n#### Subtraction of a scalar from a vector\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final scalar = 5.0;\n  final result = vector - scalar;\n\n  print(result.toList()); // [-4.0, -3.0, -2.0, -1.0, 0.0]\n````\n\n#### Multiplication of a vector by a scalar\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final scalar = 5.0;\n  final result = vector * scalar;\n\n  print(result.toList()); // [5.0, 10.0, 15.0, 20.0, 25.0]\n````\n\n#### Division of a vector by a scalar\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([25.0, 50.0, 75.0, 100.0, 125.0]);\n  final scalar = 5.0;\n  final result = vector.scalarDiv(scalar);\n\n  print(result.toList()); // [5.0, 10.0, 15.0, 20.0, 25.0]\n````\n\n#### Euclidean distance between two vectors\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector1.distanceTo(vector2, distance: Distance.euclidean);\n\n  print(result); // ~~2.23\n````\n\n#### Manhattan distance between two vectors\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector1.distanceTo(vector2, distance: Distance.manhattan);\n\n  print(result); // 5.0\n````\n\n#### Cosine distance between two vectors\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);\n  final result = vector1.distanceTo(vector2, distance: Distance.cosine);\n\n  print(result); // 0.00506\n````\n\n#### Vector normalization using Euclidean norm\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);\n  final result = vector.normalize(Norm.euclidean);\n\n  print(result); // [0.134, 0.269, 0.404, 0.539, 0.674]\n````\n\n#### Vector normalization using Manhattan norm\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([1.0, -2.0, 3.0, -4.0, 5.0]);\n  final result = vector.normalize(Norm.manhattan);\n\n  print(result); // [0.066, -0.133, 0.200, -0.266, 0.333]\n````\n\n#### Vector rescaling (min-max normalization)\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([1.0, -2.0, 3.0, -4.0, 5.0, 0.0]);\n  final result = vector.rescale();\n\n  print(result); // [0.555, 0.222, 0.777, 0.0, 1.0, 0.444]\n````\n\n#### Vector serialization\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([1.0, -2.0, 3.0, -4.0, 5.0, 0.0]);\n  final serialized = vector.toJson();\n  print(serialized); // it yields a serializable representation of the vector\n\n  final restoredVector = Vector.fromJson(serialized);\n  print(restoredVector); // [1.0, -2.0, 3.0, -4.0, 5.0, 0.0]\n````\n\n#### Vector mapping\n\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final vector = Vector.fromList([1.0, -2.0, 3.0, -4.0, 5.0, 0.0]);\n  final mapped = vector.mapToVector((el) =\u003e el * 2);\n  \n  print(mapped); // [2.0, -4.0, 6.0, -8.0, 10.0, 0.0]\n  print(mapped is Vector); // true\n  print(identical(vector, mapped)); // false\n````\n\n## Matrices\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;Along with SIMD vectors, the library contains SIMD-based Matrices. One can use the matrices via \n[Matrix factory](https://github.com/gyrdym/ml_linalg/blob/master/lib/matrix.dart). The matrices are immutable as well \nas vectors and also they implement `Iterable` interface (to be more precise, `Iterable\u003cIterable\u003cdouble\u003e\u003e`), thus it's \npossible to use them as a regular iterable collection.\n\nMatrices are serializable, and that means that one can easily convert a Matrix instance to a json-serializable map \nvia `toJson` method, see the examples below.\n\n### Matrix operations examples\n\n#### Creation of diagonal matrix\n````dart\nimport 'package:ml_linalg/matrix.dart';\n\nfinal matrix = Matrix.diagonal([1, 2, 3, 4, 5]);\n\nprint(matrix);\n````\n  \nThe output:\n\n```\nMatrix 5 x 5:\n(1.0, 0.0, 0.0, 0.0, 0.0)\n(0.0, 2.0, 0.0, 0.0, 0.0)\n(0.0, 0.0, 3.0, 0.0, 0.0)\n(0.0, 0.0, 0.0, 4.0, 0.0)\n(0.0, 0.0, 0.0, 0.0, 5.0)\n```\n\n#### Creation of scalar matrix\n````dart\nimport 'package:ml_linalg/matrix.dart';\n\nfinal matrix = Matrix.scalar(3, 5);\n\nprint(matrix);\n````\n  \nThe output:\n\n```\nMatrix 5 x 5:\n(3.0, 0.0, 0.0, 0.0, 0.0)\n(0.0, 3.0, 0.0, 0.0, 0.0)\n(0.0, 0.0, 3.0, 0.0, 0.0)\n(0.0, 0.0, 0.0, 3.0, 0.0)\n(0.0, 0.0, 0.0, 0.0, 3.0)\n```\n\n#### Creation of identity matrix\n````dart\nimport 'package:ml_linalg/matrix.dart';\n\nfinal matrix = Matrix.identity(5);\n\nprint(matrix);\n````\n  \nThe output:\n\n```\nMatrix 5 x 5:\n(1.0, 0.0, 0.0, 0.0, 0.0)\n(0.0, 1.0, 0.0, 0.0, 0.0)\n(0.0, 0.0, 1.0, 0.0, 0.0)\n(0.0, 0.0, 0.0, 1.0, 0.0)\n(0.0, 0.0, 0.0, 0.0, 1.0)\n```\n\n#### Creation of column matrix\n````dart\nfinal matrix = Matrix.column([1, 2, 3, 4, 5]);\n\nprint(matrix);\n````\n\nThe output:\n\n```\nMatrix 5 x 1:\n(1.0)\n(2.0)\n(3.0)\n(4.0)\n(5.0)\n```\n\n#### Creation of row matrix\n\n````dart\nfinal matrix = Matrix.row([1, 2, 3, 4, 5]);\n\nprint(matrix);\n````\n\nThe output:\n\n```\nMatrix 1 x 5:\n(1.0, 2.0, 3.0, 4.0, 5.0)\n```\n\n#### Sum of a matrix and another matrix\n````Dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix1 = Matrix.fromList([\n  [1.0, 2.0, 3.0, 4.0],\n  [5.0, 6.0, 7.0, 8.0],\n  [9.0, .0, -2.0, -3.0],\n]);\nfinal matrix2 = Matrix.fromList([\n  [10.0, 20.0, 30.0, 40.0],\n  [-5.0, 16.0, 2.0, 18.0],\n  [2.0, -1.0, -2.0, -7.0],\n]);\nprint(matrix1 + matrix2);\n// [\n//  [11.0, 22.0, 33.0, 44.0],\n//  [0.0, 22.0, 9.0, 26.0],\n//  [11.0, -1.0, -4.0, -10.0],\n// ];\n````\n\n#### Sum of a matrix and a scalar\n````Dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix = Matrix.fromList([\n  [1.0, 2.0, 3.0, 4.0],\n  [5.0, 6.0, 7.0, 8.0],\n  [9.0, .0, -2.0, -3.0],\n]);\nprint(matrix + 7);\n//  [\n//    [8.0, 9.0, 10.0, 11.0],\n//    [12.0, 13.0, 14.0, 15.0],\n//    [16.0, 7.0, 5.0, 4.0],\n//  ];\n````\n\n#### Multiplication of a matrix and a vector\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix = Matrix.fromList([\n    [1.0, 2.0, 3.0, 4.0],\n    [5.0, 6.0, 7.0, 8.0],\n    [9.0, .0, -2.0, -3.0],\n  ]);\n  final vector = Vector.fromList([2.0, 3.0, 4.0, 5.0]);\n  final result = matrix * vector;\n  print(result); \n  // a vector-column [\n  //  [40],\n  //  [96],\n  //  [-5],\n  //]\n````\n\n#### Multiplication of a matrix and another matrix\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix1 = Matrix.fromList([\n    [1.0, 2.0, 3.0, 4.0],\n    [5.0, 6.0, 7.0, 8.0],\n    [9.0, .0, -2.0, -3.0],\n  ]);\n  final matrix2 = Matrix.fromList([\n    [1.0, 2.0],\n    [5.0, 6.0],\n    [9.0, .0],\n    [-9.0, 1.0],\n  ]);\n  final result = matrix1 * matrix2;\n  print(result);\n  //[\n  // [2.0, 18.0],\n  // [26.0, 54.0],\n  // [18.0, 15.0],\n  //]\n````\n\n#### Multiplication of a matrix and a scalar\n````Dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix = Matrix.fromList([\n  [1.0, 2.0, 3.0, 4.0],\n  [5.0, 6.0, 7.0, 8.0],\n  [9.0, .0, -2.0, -3.0],\n]);\nprint(matrix * 3);\n// [\n//   [3.0, 6.0, 9.0, 12.0],\n//   [15.0, 18.0, 21.0, 24.0],\n//   [27.0, .0, -6.0, -9.0],\n// ];\n````\n\n#### Hadamard product (element-wise matrices multiplication)\n````Dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix1 = Matrix.fromList([\n  [1.0, 2.0,  3.0,  4.0],\n  [5.0, 6.0,  7.0,  8.0],\n  [9.0, 0.0, -2.0, -3.0],\n]);\nfinal matrix2 = Matrix.fromList([\n  [7.0,   1.0,  9.0,  2.0],\n  [2.0,   4.0,  3.0, -8.0],\n  [0.0, -10.0, -2.0, -3.0],\n]);\nprint(matrix1.multiply(matrix2));\n// [\n//   [ 7.0,  2.0, 27.0,   8.0],\n//   [10.0, 24.0, 21.0, -64.0],\n//   [ 0.0,  0.0,  4.0,   9.0],\n// ];\n````\n\n#### Element wise matrices subtraction\n````Dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix1 = Matrix.fromList([\n  [1.0, 2.0, 3.0, 4.0],\n  [5.0, 6.0, 7.0, 8.0],\n  [9.0, .0, -2.0, -3.0],\n]);\nfinal matrix2 = Matrix.fromList([\n  [10.0, 20.0, 30.0, 40.0],\n  [-5.0, 16.0, 2.0, 18.0],\n  [2.0, -1.0, -2.0, -7.0],\n]);\nprint(matrix1 - matrix2);\n// [\n//   [-9.0, -18.0, -27.0, -36.0],\n//   [10.0, -10.0, 5.0, -10.0],\n//   [7.0, 1.0, .0, 4.0],\n// ];\n````\n\n#### Matrix transposition\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n  \n  final matrix = Matrix.fromList([\n    [1.0, 2.0, 3.0, 4.0],\n    [5.0, 6.0, 7.0, 8.0],\n    [9.0, .0, -2.0, -3.0],\n  ]);\n  final result = matrix.transpose();\n  print(result);\n  //[\n  // [1.0, 5.0, 9.0],\n  // [2.0, 6.0, .0],\n  // [3.0, 7.0, -2.0],\n  // [4.0, 8.0, -3.0],\n  //]\n````\n\n#### Matrix LU decomposition\n```dart\n  final matrix = Matrix.fromList([\n    [4, 12, -16],\n    [12, 37, -43],\n    [-16, -43, 98],\n  ], dtype: dtype);\n  final decomposed = matrix.decompose(Decomposition.LU);\n  \n  // yields approximately the same matrix as the original one:\n  print(decomposed.first * decomposed.last);\n```\n\n#### Matrix Cholesky decomposition\n```dart\n  final matrix = Matrix.fromList([\n    [4, 12, -16],\n    [12, 37, -43],\n    [-16, -43, 98],\n  ], dtype: dtype);\n  final decomposed = matrix.decompose(Decomposition.cholesky);\n  \n  // yields approximately the same matrix as the original one:\n  print(decomposed.first * decomposed.last);\n```\n\n*Keep in mind that Cholesky decomposition is applicable only for positive definite and symmetric matrices*\n\n#### Matrix LU inversion\n\n```dart\n  final matrix = Matrix.fromList([\n    [-16, -43, 98],\n    [33, 12.4, 37],\n    [12, -88.3, 4],\n  ], dtype: dtype);\n  final inverted = matrix.inverse(Inverse.LU);\n\n  print(inverted * matrix);\n  // The output (there can be some round-off errors):\n  // [1, 0, 0],\n  // [0, 1, 0],\n  // [0, 0, 1],\n```\n\n#### Matrix Cholesky inversion\n\n```dart\n  final matrix = Matrix.fromList([\n    [4, 12, -16],\n    [12, 37, -43],\n    [-16, -43, 98],\n  ], dtype: dtype);\n  final inverted = matrix.inverse(Inverse.cholesky);\n\n  print(inverted * matrix);\n  // The output (there can be some round-off errors):\n  // [1, 0, 0],\n  // [0, 1, 0],\n  // [0, 0, 1],\n```\n\n*Keep in mind that since this kind of inversion is based on Cholesky decomposition, the inversion is applicable only for positive definite and symmetric matrices*\n\n#### Lower triangular matrix inversion\n\n```dart\n  final matrix = Matrix.fromList([\n    [  4,   0,  0],\n    [ 12,  37,  0],\n    [-16, -43, 98],\n  ], dtype: dtype);\n  final inverted = matrix.inverse(Inverse.forwardSubstitution);\n\n  print(inverted * matrix);\n  // The output (there can be some round-off errors):\n  // [1, 0, 0],\n  // [0, 1, 0],\n  // [0, 0, 1],\n```\n\n#### Upper triangular matrix inversion\n\n```dart\n  final matrix = Matrix.fromList([\n    [4, 12, -16],\n    [0, 37, -43],\n    [0,  0, -98],\n  ], dtype: dtype);\n  final inverted = matrix.inverse(Inverse.backwardSubstitution);\n\n  print(inverted * matrix);\n  // The output (there can be some round-off errors):\n  // [1, 0, 0],\n  // [0, 1, 0],\n  // [0, 0, 1],\n```\n\n\n#### Solving a system of linear equations\n\nA matrix notation for [a system of linear equations](https://en.wikipedia.org/wiki/System_of_linear_equations):\n\n```\nAX=B\n```\n\nTo solve the system and find `X`, one may use the [`solve`](https://pub.dev/documentation/ml_linalg/latest/matrix/Matrix/solve.html) method:\n\n````Dart\nimport 'package:ml_linalg/linalg.dart';\n\nvoid main() {\n  final A = Matrix.fromList([\n    [1, 1, 1],\n    [0, 2, 5],\n    [2, 5, -1],\n  ], dtype: dtype);\n  final B = Matrix.fromList([\n    [6],\n    [-4],\n    [27],\n  ], dtype: dtype);\n  final result = A.solve(B);\n  \n  print(result); // the output is close to [[5], [3], [-2]]\n}\n````\n\n#### Obtaining Matrix eigenvectors and eigenvalues, Power Iteration method\n\nThe method returns a collection of pairs of an eigenvector and its corresponding eigenvalue. \nBy default `Power iteration` method is used.\n\n```dart\n  final matrix = Matrix.fromList([\n    [1, 0],\n    [0, 2],\n  ]);\n  final eigen = matrix.eigen();\n  \n  print(eigen); // It prints the following: [Value: 1.999, Vector: (0.001, 0.999);]\n```\n \n#### Matrix row-wise reduce\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix = Matrix.fromList([\n    [1.0, 2.0, 3.0, 4.0],\n    [5.0, 6.0, 7.0, 8.0],\n  ]); \n  final reduced = matrix.reduceRows((combine, row) =\u003e combine + row);\n  print(reduced); // [6.0, 8.0, 10.0, 12.0]\n````\n\n#### Matrix column-wise reduce\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix = Matrix.fromList([\n    [11.0, 12.0, 13.0, 14.0],\n    [15.0, 16.0, 17.0, 18.0],\n    [21.0, 22.0, 23.0, 24.0],\n  ]);\n  final result = matrix.reduceColumns((combine, vector) =\u003e combine + vector);\n  print(result); // [50, 66, 90]\n````\n\n#### Matrix row-wise mapping\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix = Matrix.fromList([\n    [1.0, 2.0, 3.0, 4.0],\n    [5.0, 6.0, 7.0, 8.0],\n  ]); \n  final modifier = Vector.filled(4, 2.0);\n  final newMatrix = matrix.rowsMap((row) =\u003e row + modifier);\n  print(newMatrix); \n  // [\n  //  [3.0, 4.0, 5.0, 6.0],\n  //  [7.0, 8.0, 9.0, 10.0],\n  // ]\n````\n\n#### Matrix column-wise mapping\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix = Matrix.fromList([\n    [1.0, 2.0, 3.0, 4.0],\n    [5.0, 6.0, 7.0, 8.0],\n  ]); \n  final modifier = Vector.filled(2, 2.0);\n  final newMatrix = matrix.columnsMap((column) =\u003e column + modifier);\n  print(newMatrix); \n  // [\n  //  [3.0, 4.0, 5.0, 6.0],\n  //  [7.0, 8.0, 9.0, 10.0],\n  // ]\n````\n\n#### Matrix element-wise mapping\n````dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix = Matrix.fromList([\n  [11.0, 12.0, 13.0, 14.0],\n  [15.0, 16.0, 0.0, 18.0],\n  [21.0, 22.0, -23.0, 24.0],\n], dtype: DType.float32);\nfinal result = matrix.mapElements((element) =\u003e element * 2);\n\nprint(result);\n// [\n//  [22.0, 24.0,  26.0, 28.0],\n//  [30.0, 32.0,   0.0, 36.0],\n//  [42.0, 44.0, -46.0, 48.0],\n// ]\n````\n\n#### Matrix' columns filtering (by column index) \n````dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix = Matrix.fromList([\n  [11.0, 12.0, 13.0, 14.0],\n  [15.0, 16.0, 17.0, 18.0],\n  [21.0, 22.0, 23.0, 24.0],\n], dtype: dtype);\n\nfinal indicesToExclude = [0, 3];\nfinal result = matrix.filterColumns((column, idx) =\u003e !indicesToExclude.contains(idx));\n\nprint(result);\n// [\n//   [12.0, 13.0],\n//   [16.0, 17.0],\n//   [22.0, 23.0],\n// ]\n````\n\n#### Matrix' columns filtering (by column)\n````dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix = Matrix.fromList([\n  [11.0, 33.0, 13.0, 14.0],\n  [15.0, 92.0, 17.0, 18.0],\n  [21.0, 22.0, 23.0, 24.0],\n], dtype: dtype);\n\nfinal result = matrix.filterColumns((column, _) =\u003e column.sum() \u003e 100);\n\nprint(result);\n// [\n//   [33.0],\n//   [92.0],\n//   [22.0],\n// ];\n````\n\n#### Getting max value of the matrix\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix = Matrix.fromList([\n    [11.0, 12.0, 13.0, 14.0],\n    [15.0, 16.0, 17.0, 18.0],\n    [21.0, 22.0, 23.0, 24.0],\n    [24.0, 32.0, 53.0, 74.0],\n  ]);\n  final maxValue = matrix.max();\n  print(maxValue);\n  // 74.0\n````\n\n#### Getting min value of the matrix\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix = Matrix.fromList([\n    [11.0, 12.0, 13.0, 14.0],\n    [15.0, 16.0, 0.0, 18.0],\n    [21.0, 22.0, -23.0, 24.0],\n    [24.0, 32.0, 53.0, 74.0],\n  ]);\n  final minValue = matrix.min();\n  print(minValue);\n  // -23.0\n````\n\n#### Matrix element-wise power\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix = Matrix.fromList([\n    [1.0, 2.0, 3.0],\n    [4.0, 5.0, 6.0],\n    [7.0, 8.0, 9.0],\n  ]);\n  final result = matrix.pow(3.0);\n  \n  print(result);\n  // [1 ^ 3 = 1,   2 ^ 3 = 8,   3 ^ 3 = 27 ]\n  // [4 ^ 3 = 64,  5 ^ 3 = 125, 6 ^ 3 = 216]\n  // [7 ^ 3 = 343, 8 ^ 3 = 512, 9 ^ 3 = 729]\n````\n\n#### Matrix element-wise exp\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix = Matrix.fromList([\n    [1.0, 2.0, 3.0],\n    [4.0, 5.0, 6.0],\n    [7.0, 8.0, 9.0],\n  ]);\n  final result = matrix.exp();\n  \n  print(result);\n  // [e ^ 1, e ^ 2, e ^ 3]\n  // [e ^ 4, e ^ 5, e ^ 6]\n  // [e ^ 7, e ^ 8, e ^ 9]\n````\n\n#### Sum of all matrix elements\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix = Matrix.fromList([\n    [1.0, 2.0, 3.0],\n    [4.0, 5.0, 6.0],\n    [7.0, 8.0, 9.0],\n  ]);\n  final result = matrix.sum();\n  \n  print(result); // 1.0 + 2.0 + 3.0 + 4.0 + 5.0 + 6.0 + 7.0 + 8.0 + 9.0\n````\n\n#### Product of all matrix elements\n````Dart\n  import 'package:ml_linalg/linalg.dart';\n\n  final matrix = Matrix.fromList([\n    [1.0, 2.0, 3.0],\n    [4.0, 5.0, 6.0],\n    [7.0, 8.0, 9.0],\n  ]);\n  final result = matrix.product();\n  \n  print(result); // 1.0 * 2.0 * 3.0 * 4.0 * 5.0 * 6.0 * 7.0 * 8.0 * 9.0\n````\n\n#### Matrix indexing and sampling\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;To access a certain row vector of the matrix one may use `[]` operator:\n\n````Dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix = Matrix.fromList([\n    [11.0, 12.0, 13.0, 14.0],\n    [15.0, 16.0, 0.0, 18.0],\n    [21.0, 22.0, -23.0, 24.0],\n    [24.0, 32.0, 53.0, 74.0],\n  ]);\n\nfinal row = matrix[2];\n\nprint(row); // [21.0, 22.0, -23.0, 24.0]\n```` \n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;The library's matrix interface offers `sample` method that is supposed to return a new matrix, \nconsisting of different segments of a source matrix. It's possible to build a new matrix from certain columns and \nvectors and they should not be necessarily subsequent.\n \n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;For example, one needs to create a matrix from rows 1, 3, 5 and columns 1 and 3. To do so, \nit's needed to perform the following:\n\n````Dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix = Matrix.fromList([\n//| 1 |         | 3 |                \n  [4.0,   8.0,   12.0,   16.0,  34.0], // 1 Range(0, 1)\n  [20.0,  24.0,  28.0,   32.0,  23.0],\n  [36.0,  .0,   -8.0,   -12.0,  12.0], // 3 Range(2, 3)\n  [16.0,  1.0,  -18.0,   3.0,   11.0],\n  [112.0, 10.0,  34.0,   2.0,   10.0], // 5 Range(4, 5)\n]);\nfinal result = matrix.sample(\n  rowIndices: [0, 2, 4],\n  columnIndices: [0, 2],\n);\nprint(result);\n/*\n  [4.0,   12.0],\n  [36.0,  -8.0],\n  [112.0, 34.0]\n*/\n````\n\n#### Add new columns to a matrix\n````dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix = Matrix.fromList([\n  [11.0, 12.0, 13.0, 14.0],\n  [15.0, 16.0, 0.0, 18.0],\n  [21.0, 22.0, -23.0, 24.0],\n  [24.0, 32.0, 53.0, 74.0],\n], dtype: DType.float32);\n\nfinal updatedMatrix = matrix.insertColumns(0, [\n  Vector.fromList([1.0, 2.0, 3.0, 4.0]),\n  Vector.fromList([-1.0, -2.0, -3.0, -4.0]),\n]);\n\nprint(updatedMatrix);\n// [\n//  [1.0, -1.0, 11.0, 12.0, 13.0, 14.0],\n//  [2.0, -2.0, 15.0, 16.0, 0.0, 18.0],\n//  [3.0, -3.0, 21.0, 22.0, -23.0, 24.0],\n//  [4.0, -4.0, 24.0, 32.0, 53.0, 74.0],\n// ]\n\nprint(updatedMatrix == matrix); // false\n````\n\n#### Matrix serialization/deserialization\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;To convert a matrix to a json-serializable map one may use `toJson` method:\n\n````Dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix = Matrix.fromList([\n    [11.0, 12.0, 13.0, 14.0],\n    [15.0, 16.0, 0.0, 18.0],\n    [21.0, 22.0, -23.0, 24.0],\n    [24.0, 32.0, 53.0, 74.0],\n  ]);\n\nfinal serialized = matrix.toJson();\n````\n\nTo restore a serialized matrix one may use `Matrix.fromJson` constructor:\n\n````Dart\nimport 'package:ml_linalg/linalg.dart';\n\nfinal matrix = Matrix.fromJson(serialized);\n````\n\n## Differences between vector math and ml linalg\n\nThere are similar solutions on the internet, the most famous of which is [vector_math](https://pub.dev/packages/vector_math) by the Google team. At first \nglance, `vector_math` and `ml_linalg` look similar - both of them are based on SIMD, but in fact, these are two completely \ndifferent libraries:\n\n`vector_math` supports only four dimensions for vectors and matrices at max; `ml_linalg` can handle vectors and matrices\nof potentially infinite length, keeping SIMD nature.\n\n### Contacts\nIf you have questions, feel free to write me on \n - [Twitter](https://twitter.com/ilgyrd)\n - [Facebook](https://www.facebook.com/ilya.gyrdymov)\n - [Linkedin](https://www.linkedin.com/in/gyrdym/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyrdym%2Fml_linalg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgyrdym%2Fml_linalg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgyrdym%2Fml_linalg/lists"}