ml_linalg 12.3.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 77

Build Status Coverage Status pub package Gitter Chat

SIMD-based Linear algebra with Dart

Table of contents

Linear algebra #

    In a few words, linear algebra is a branch of mathematics that is working with vectors and matrices.

    Let's give a simple definition of Vector and Matrix. Vector is an ordered set of numbers, representing a point in the space where the vector is directed from the origin. Matrix is a collection of vectors, used to map vectors from one space to another.

    Vectors and matrices are extremely powerful tools, which can be used in real-life applications, such as machine learning algorithms. There are many implementations of these great mathematical entities in a plenty of programming languages, and as Dart offers developers good instrumentarium, e.g. highly optimized virtual machine and rich out-of-the-box library, Dart-based implementation of vectors and matrices has to be quite performant.

    Among myriad of standard Dart tools there are SIMD data types. Namely support of SIMD computational architecture served as a source of inspiration for creating this library.

What is SIMD? #

    SIMD stands for Single instruction, multiple data - it is a computer architecture, that allows to perform uniform operations in parallel on huge amount of data. For instance, one has two arrays:

  • a = [10, 20, 30, 40]
  • b = [50, 60, 70, 80]

and one needs to add these arrays element-wise. Using the regular architecture this operation could be done in this manner:

    We need to do 4 operations one by one in a row. Using SIMD architecture we may perform one mathematical operations on several operands in parallel, thus element-wise sum of two arrays will be done for just one step:

Vectors #

A couple of words about the underlying architecture #

    The library contains a high performance SIMD vector class, based on Float32x4 - Float32Vector. Most of operations in the vector class are performed in four "threads". This kind of parallelism is reached by special 128-bit processor registers, which are used directly by program code.

    Float32Vector is hidden from the library's users. You can create a Float32Vector instance via Vector factory (see examples below).

    The vector is absolutely immutable - there is no way to change once created instance. All vector operations lead to creation of a new vector instance (of course, if the operation is supposed to return Vector).

    The class implements Iterable<double> interface - so it's possible to use it as a regular iterable collection.

    It's possible to use vector instances as keys for HashMap and similar data structures and to look up a value by the vector-key, since the hash code is the same for equal vectors:

import 'package:ml_linalg/vector.dart';

final map = HashMap<Vector, bool>();

map[Vector.fromList([1, 2, 3, 4, 5])] = true;

print(map[Vector.fromList([1, 2, 3, 4, 5])]); // true
print(Vector.fromList([1, 2, 3, 4, 5]).hashCode == Vector.fromList([1, 2, 3, 4, 5]).hashCode); // true

Vector operations examples #

Vectors sum #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1 + vector2;
  print(result.toList()); // [3.0, 5.0, 7.0, 9.0, 11.0]
Vectors subtraction #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([4.0, 5.0, 6.0, 7.0, 8.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 2.0, 3.0, 2.0]);
  final result = vector1 - vector2;
  print(result.toList()); // [2.0, 2.0, 4.0, 4.0, 6.0]
Element wise vector by vector multiplication #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1 * vector2;
  print(result.toList()); // [2.0, 6.0, 12.0, 20.0, 30.0]
Element wise vector by vector division #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([6.0, 12.0, 24.0, 48.0, 96.0]);
  final vector2 = Vector.fromList([3.0, 4.0, 6.0, 8.0, 12.0]);
  final result = vector1 / vector2;
  print(result.toList()); // [2.0, 3.0, 4.0, 6.0, 8.0]
Euclidean norm #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.norm();
  print(result); // sqrt(2^2 + 3^2 + 4^2 + 5^2 + 6^2) = sqrt(90) ~~ 9.48
Manhattan norm #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.norm(Norm.manhattan);
  print(result); // 2 + 3 + 4 + 5 + 6 = 20.0
Mean value #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.mean();
  print(result); // (2 + 3 + 4 + 5 + 6) / 5 = 4.0
Sum of all vector elements #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.sum();
  print(result); // 2 + 3 + 4 + 5 + 6 = 20.0 (equivalent to Manhattan norm)
Dot product of two vectors #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.dot(vector2);
  print(result); // 1.0 * 2.0 + 2.0 * 3.0 + 3.0 * 4.0 + 4.0 * 5.0 + 5.0 * 6.0 = 70.0
Sum of a vector and a scalar #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final scalar = 5.0;
  final result = vector1 + scalar;
  print(result.toList()); // [6.0, 7.0, 8.0, 9.0, 10.0]
Subtraction of a scalar from a vector #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final scalar = 5.0;
  final result = vector1 - scalar;
  print(result.toList()); // [-4.0, -3.0, -2.0, -1.0, 0.0]
Multiplication (scaling) of a vector by a scalar #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final scalar = 5.0;
  final result = vector1 * scalar;
  print(result.toList()); // [5.0, 10.0, 15.0, 20.0, 25.0]
Division (scaling) of a vector by a scalar value #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([25.0, 50.0, 75.0, 100.0, 125.0]);
  final scalar = 5.0;
  final result = vector1.scalarDiv(scalar);
  print(result.toList()); // [5.0, 10.0, 15.0, 20.0, 25.0]
Euclidean distance between two vectors #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.distanceTo(vector2, distance: Distance.euclidean);
  print(result); // ~~2.23
Manhattan distance between two vectors #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.distanceTo(vector2, distance: Distance.manhattan);
  print(result); // 5.0
Cosine distance between two vectors #
  import 'package:ml_linalg/linalg.dart';

  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.distanceTo(vector2, distance: Distance.cosine);
  print(result); // 0.00506
Vector normalization using Euclidean norm #
  import 'package:ml_linalg/linalg.dart';

  final vector = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final result = vector.normalize(Norm.euclidean);
  print(result); // [0.134, 0.269, 0.404, 0.539, 0.674]
Vector normalization using Manhattan norm #
  import 'package:ml_linalg/linalg.dart';

  final vector = Vector.fromList([1.0, -2.0, 3.0, -4.0, 5.0]);
  final result = vector.normalize(Norm.manhattan);
  print(result); // [0.066, -0.133, 0.200, -0.266, 0.333]
Vector rescaling (min-max normalization) #
  import 'package:ml_linalg/linalg.dart';

  final vector = Vector.fromList([1.0, -2.0, 3.0, -4.0, 5.0, 0.0]);
  final result = vector.rescale();
  print(result); // [0.555, 0.222, 0.777, 0.0, 1.0, 0.444]

Matrices #

    Along with SIMD vectors, the library presents SIMD-based Matrices. One can use the matrices via Matrix factory. The matrices are immutable as well as vectors and also they implement Iterable, to be precise - Iterable<Iterable<double>> interface, thus it's possible to use them as a regular iterable collection.

Matrix operations examples #

Sum of a matrix and another matrix #
import 'package:ml_linalg/linalg.dart';

final matrix1 = Matrix.fromList([
  [1.0, 2.0, 3.0, 4.0],
  [5.0, 6.0, 7.0, 8.0],
  [9.0, .0, -2.0, -3.0],
]);
final matrix2 = Matrix.fromList([
  [10.0, 20.0, 30.0, 40.0],
  [-5.0, 16.0, 2.0, 18.0],
  [2.0, -1.0, -2.0, -7.0],
]);
print(matrix1 + matrix2);
// [
//  [11.0, 22.0, 33.0, 44.0],
//  [0.0, 22.0, 9.0, 26.0],
//  [11.0, -1.0, -4.0, -10.0],
// ];
Sum of a matrix and a scalar #
import 'package:ml_linalg/linalg.dart';

final matrix = Matrix.fromList([
  [1.0, 2.0, 3.0, 4.0],
  [5.0, 6.0, 7.0, 8.0],
  [9.0, .0, -2.0, -3.0],
]);
print(matrix + 7);
//  [
//    [8.0, 9.0, 10.0, 11.0],
//    [12.0, 13.0, 14.0, 15.0],
//    [16.0, 7.0, 5.0, 4.0],
//  ];
Multiplication of a matrix and a vector #
  import 'package:ml_linalg/linalg.dart';

  final matrix = Matrix.fromList([
    [1.0, 2.0, 3.0, 4.0],
    [5.0, 6.0, 7.0, 8.0],
    [9.0, .0, -2.0, -3.0],
  ]);
  final vector = Vector.fromList([2.0, 3.0, 4.0, 5.0]);
  final result = matrix * vector;
  print(result); 
  // a vector-column [
  //  [40],
  //  [96],
  //  [-5],
  //]
Multiplication of a matrix and another matrix #
  import 'package:ml_linalg/linalg.dart';

  final matrix1 = Matrix.fromList([
    [1.0, 2.0, 3.0, 4.0],
    [5.0, 6.0, 7.0, 8.0],
    [9.0, .0, -2.0, -3.0],
  ]);
  final matrix2 = Matrix.fromList([
    [1.0, 2.0],
    [5.0, 6.0],
    [9.0, .0],
    [-9.0, 1.0],
  ]);
  final result = matrix1 * matrix2;
  print(result);
  //[
  // [2.0, 18.0],
  // [26.0, 54.0],
  // [18.0, 15.0],
  //]
Multiplication of a matrix and a scalar #
import 'package:ml_linalg/linalg.dart';

final matrix = Matrix.fromList([
  [1.0, 2.0, 3.0, 4.0],
  [5.0, 6.0, 7.0, 8.0],
  [9.0, .0, -2.0, -3.0],
]);
print(matrix * 3);
// [
//   [3.0, 6.0, 9.0, 12.0],
//   [15.0, 18.0, 21.0, 24.0],
//   [27.0, .0, -6.0, -9.0],
// ];
Element wise matrices subtraction #
import 'package:ml_linalg/linalg.dart';

final matrix1 = Matrix.fromList([
  [1.0, 2.0, 3.0, 4.0],
  [5.0, 6.0, 7.0, 8.0],
  [9.0, .0, -2.0, -3.0],
]);
final matrix2 = Matrix.fromList([
  [10.0, 20.0, 30.0, 40.0],
  [-5.0, 16.0, 2.0, 18.0],
  [2.0, -1.0, -2.0, -7.0],
]);
print(matrix1 - matrix2);
// [
//   [-9.0, -18.0, -27.0, -36.0],
//   [10.0, -10.0, 5.0, -10.0],
//   [7.0, 1.0, .0, 4.0],
// ];
Matrix transposition #
  import 'package:ml_linalg/linalg.dart';
  
  final matrix = Matrix.fromList([
    [1.0, 2.0, 3.0, 4.0],
    [5.0, 6.0, 7.0, 8.0],
    [9.0, .0, -2.0, -3.0],
  ]);
  final result = matrix.transpose();
  print(result);
  //[
  // [1.0, 5.0, 9.0],
  // [2.0, 6.0, .0],
  // [3.0, 7.0, -2.0],
  // [4.0, 8.0, -3.0],
  //]
Matrix row wise reduce #
  import 'package:ml_linalg/linalg.dart';

  final matrix = Matrix.fromList([
    [1.0, 2.0, 3.0, 4.0],
    [5.0, 6.0, 7.0, 8.0],
  ]); 
  final reduced = matrix.reduceRows((combine, row) => combine + row);
  print(reduced); // [6.0, 8.0, 10.0, 12.0]
Matrix column wise reduce #
  import 'package:ml_linalg/linalg.dart';

  final matrix = Matrix.fromList([
    [11.0, 12.0, 13.0, 14.0],
    [15.0, 16.0, 17.0, 18.0],
    [21.0, 22.0, 23.0, 24.0],
  ]);
  final result = matrix.reduceColumns((combine, vector) => combine + vector);
  print(result); // [50, 66, 90]
Matrix row wise map #
  import 'package:ml_linalg/linalg.dart';

  final matrix = Matrix.fromList([
    [1.0, 2.0, 3.0, 4.0],
    [5.0, 6.0, 7.0, 8.0],
  ]); 
  final modifier = Vector.filled(4, 2.0);
  final newMatrix = matrix.rowsMap((row) => row + modifier);
  print(newMatrix); 
  // [
  //  [3.0, 4.0, 5.0, 6.0],
  //  [7.0, 8.0, 9.0, 10.0],
  // ]
Matrix column wise map #
  import 'package:ml_linalg/linalg.dart';

  final matrix = Matrix.fromList([
    [1.0, 2.0, 3.0, 4.0],
    [5.0, 6.0, 7.0, 8.0],
  ]); 
  final modifier = Vector.filled(2, 2.0);
  final newMatrix = matrix.columnsMap((column) => column + modifier);
  print(newMatrix); 
  // [
  //  [3.0, 4.0, 5.0, 6.0],
  //  [7.0, 8.0, 9.0, 10.0],
  // ]
Getting max value of the matrix #
  import 'package:ml_linalg/linalg.dart';

  final matrix = Matrix.fromList([
    [11.0, 12.0, 13.0, 14.0],
    [15.0, 16.0, 17.0, 18.0],
    [21.0, 22.0, 23.0, 24.0],
    [24.0, 32.0, 53.0, 74.0],
  ]);
  final maxValue = matrix.max();
  print(maxValue);
  // 74.0
Getting min value of the matrix #
  import 'package:ml_linalg/linalg.dart';

  final matrix = Matrix.fromList([
    [11.0, 12.0, 13.0, 14.0],
    [15.0, 16.0, 0.0, 18.0],
    [21.0, 22.0, -23.0, 24.0],
    [24.0, 32.0, 53.0, 74.0],
  ]);
  final minValue = matrix.min();
  print(minValue);
  // -23.0

Matrix indexing and sampling #

    To access a certain row vector of the matrix one may use [] operator:

import 'package:ml_linalg/linalg.dart';

final matrix = Matrix.fromList([
    [11.0, 12.0, 13.0, 14.0],
    [15.0, 16.0, 0.0, 18.0],
    [21.0, 22.0, -23.0, 24.0],
    [24.0, 32.0, 53.0, 74.0],
  ]);

final row = matrix[2];

print(row); // [21.0, 22.0, -23.0, 24.0]

    The library's matrix interface offers sample method, that is supposed to return a new matrix, consisting of different segments of a source matrix. It's possible to build a new matrix from certain columns and vectors and they should not be necessarily subsequent.

    For example, one needs to create a matrix from rows 1, 3, 5 and columns 1 and 3. To do so, it's needed to perform the following:

import 'package:ml_linalg/linalg.dart';

final matrix = Matrix.fromList([
//| 1 |         | 3 |                
  [4.0,   8.0,   12.0,   16.0,  34.0], // 1 Range(0, 1)
  [20.0,  24.0,  28.0,   32.0,  23.0],
  [36.0,  .0,   -8.0,   -12.0,  12.0], // 3 Range(2, 3)
  [16.0,  1.0,  -18.0,   3.0,   11.0],
  [112.0, 10.0,  34.0,   2.0,   10.0], // 5 Range(4, 5)
]);
final result = matrix.sample(
  rowIndices: [0, 2, 4],
  columnIndices: [0, 2],
);
print(result);
/*
  [4.0,   12.0],
  [36.0,  -8.0],
  [112.0, 34.0]
*/

Add new columns to a matrix #

import 'package:ml_linalg/linalg.dart';

final matrix = Matrix.fromList([
  [11.0, 12.0, 13.0, 14.0],
  [15.0, 16.0, 0.0, 18.0],
  [21.0, 22.0, -23.0, 24.0],
  [24.0, 32.0, 53.0, 74.0],
], dtype: DType.float32);

final updatedMatrix = matrix.insertColumns(0, [
  Vector.fromList([1.0, 2.0, 3.0, 4.0]),
  Vector.fromList([-1.0, -2.0, -3.0, -4.0]),
]);

print(updatedMatrix);
// [
//  [1.0, -1.0, 11.0, 12.0, 13.0, 14.0],
//  [2.0, -2.0, 15.0, 16.0, 0.0, 18.0],
//  [3.0, -3.0, 21.0, 22.0, -23.0, 24.0],
//  [4.0, -4.0, 24.0, 32.0, 53.0, 74.0],
// ]

print(updatedMatrix == matrix); // false

Contacts #

If you have questions, feel free to write me on

Changelog #

12.3.0 #

  • Matrix:
    • mean method added
    • deviation method added
    • hasData getter added
    • empty constructor added
  • Vector:
    • empty constructor added

12.2.0 #

  • Vector:
    • sqrt method added

12.1.0 #

  • Matrix:
    • rowIndices field added to the interface
    • columnIndices field added to the interface

12.0.2 #

  • xrange 0.0.8 version supported (integers function used instead of ZRange)

12.0.1 #

  • xrange package version locked

12.0.0 #

  • Matrix:
    • pick method removed
    • submatrix method replaced with sample method
    • [] operator returns Vector from now
  • Vector:
    • randomFilled constructor api changed, min and max args are of num type now
    • fromList constructor api changed, from now as a source expected List<num> instead of List<doublet>
    • filled constructor api changed, from now sampling value is a num instead of double
  • Dart sdk constraint returned to 2.2.0

11.0.0 #

  • Dart sdk constraint changed: from 2.2.0 to 2.4.0
  • Matrix: pick method refactored
  • Grinder tasks for unit testing, code analysis and coverage added

10.3.7 #

  • Matrix: Iterable<Iterable<double>> implemented

10.3.6 #

  • Vector: randomFilled default parameters fixed
  • Tests for Vector's constructors added

10.3.5 #

  • readme updated: explanation images added

10.3.4 #

  • Images for readme.md updated (simd architecture explanation)

10.3.3 #

  • Images for readme.md added (simd architecture explanation)

10.3.2 #

  • Vector:
    • hashCode speed up
    • randomFilled constructor extended: min and max parameters added

10.3.1 #

  • Vector: hashCode improvements

10.3.0 #

  • Vector: hashCode re-implemented: now it's possible to use the vector as a map key

10.2.0 #

  • Matrix: sort method added and implemented

10.1.0 #

  • Vector: subvectorByRange method added and implemented (for float32 vector)

10.0.4 #

  • pubspec.yaml: sdk version constraint changed from >=2.3.0 to >=2.2.0

10.0.3 #

  • Float32Matrix.columns: empty list supported as a source
  • Float32Matrix.rows: empty list supported as a source

10.0.2 #

  • Float32Matrix.fromList: empty list supported as a source

10.0.1 #

  • Links in README corrected

10.0.0 #

  • Vector:
    • removed possibility to mutate an instance of the Vector:
      • isMutable flag removed
      • []= operator removed
  • Matrix:
    • removed possibility to mutate an instance of the Matrix:
      • setColumn method removed
    • insertColumns method added
    • Matrix.from renamed to Matrix.fromList
    • Matrix.fromFlattened renamed to Matrix.fromFlattenedList
    • benchmarks added for checking matrix initialization performance
  • Performance enhancements
  • Dart 2.3.0 supported

9.0.0 #

  • Vector:
    • Distance enum added
    • distanceTo method refactored
    • cosine distance calculation added

8.0.0 #

  • Matrix:
    • rows constructor renamed to fromRows
    • columns constructor renamed to fromColumns
    • flattened constructor renamed to fromFlattened
    • rows getter added
    • columns getter added

7.0.0 #

  • Matrix: ZRange support (instead of the library built-in Range)

6.1.1 #

  • Vector: unique method refactored

6.1.0 #

  • Vector:
    • normalize method added to interface and supported in Float32x4Vector
    • rescale method added to interface and supported in Float32x4Vector
  • VectorBase: cache for popular operations implemented

6.0.2 #

  • Matrix: MatrixMixin corrected

6.0.1 #

  • Vector class refactored (get rid of redundant mixins)

6.0.0 #

  • prefix ML removed from entities' names
  • Float32x4Vector: equality operator override added
  • Matrix: uniqueRows method added

5.5.1 #

  • MLMatrix: fixed bug in setColumn method when rows cache was not cleared

5.5.0 #

  • MLMatrix: setColumn method implemented

5.4.0 #

  • MLMatrix: dummy for setColumn method added

5.3.0 #

  • MLMatrix: frobenius norm calculation added

5.2.0 #

  • MLMatrix: / operator added
  • MLMatrix: rowsMap method added
  • MLMatrix: columnsMap method added

5.1.0 #

  • max and min methods added for matrix

5.0.1 #

  • Travis integration added
  • dartfmt task added

5.0.0 #

  • MLVector and MLMatrix now don't have generic type parameters

4.2.0 #

  • Static factories converted into abstract factories

4.1.0 #

  • toString method specified for matrix mixin
  • examples for vector operations fixed

4.0.0 #

  • Vector type removed (there are no longer column and row vectors)
  • Matrix's method getColumnVector renamed to getColumn
  • Matrix method getRowVector renamed to getRow
  • Public api documentation for MLMatrix<E> added

3.5.0 #

  • Mutable vectors supported in matrix

3.4.0 #

  • Add possibility to create mutable vectors
  • Add support for value assignment via []= operator

3.0.3 #

  • readme contacts section updated
  • build_runner dependency updated

3.0.2 #

  • readme badge corrected

3.0.1 #

  • readme updated

3.0.0 #

  • vectorizedMap vector's method improved: batch boundary indexes may be passed into a mapper function
  • columnsMap and rowsMap matrix's method combined into one method - vectorizedMap
  • Public factories Float32x4VectorFactory and Float32x4MatrixFactory renamed into Float32x4Vector and Float32x4Matrix
  • copy vector's method removed

2.3.0 #

  • pick method added to matrix api: it's possible now to combine a new matrix from different segments of a source matrix

2.2.2 #

  • README.md updated (table of content)

2.2.1 #

  • Travis integration added

2.2.0 #

  • Support matrices in vector operations

2.1.0 #

  • Column and row vectors added

2.0.0 #

  • Unnecessary generic type argument removed from MLMatrix class
  • Matrix logic split into separate mixins

1.3.0 #

  • MLVectorMixin added, benchmark directory reorganized

1.2.0 #

  • Map functions added to matrix

1.1.0 #

  • Float32x4MatrixFactory extended

1.0.1 #

  • Readme updated

1.0.0 #

  • Library public release

example/main.dart

import 'package:ml_linalg/distance.dart';
import 'package:ml_linalg/linalg.dart';

void main() {
  addition();
  subtraction();
  multiplication();
  division();
  euclideanNorm();
  manhattanNorm();
  mean();
  sum();
  dot();
  scalarAddition();
  scalarSubtraction();
  scalarMultiplication();
  scalarDivision();
  euclideanDistanceBetweenVectors();
  manhattanDistanceBetweenVectors();
  cosineDistanceBetweenVectors();
}

void addition() {
  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1 + vector2;
  print(result); // [3.0, 5.0, 7.0, 9.0, 11.0]
}

void subtraction() {
  final vector1 = Vector.fromList([4.0, 5.0, 6.0, 7.0, 8.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 2.0, 3.0, 2.0]);
  final result = vector1 - vector2;
  print(result); // [2.0, 2.0, 4.0, 4.0, 6.0]
}

void multiplication() {
  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1 * vector2;
  print(result); // [2.0, 6.0, 12.0, 20.0, 30.0]
}

void division() {
  final vector1 = Vector.fromList([6.0, 12.0, 24.0, 48.0, 96.0]);
  final vector2 = Vector.fromList([3.0, 4.0, 6.0, 8.0, 12.0]);
  final result = vector1 / vector2;
  print(result); // [2.0, 3.0, 4.0, 6.0, 8.0]
}

void euclideanNorm() {
  final vector1 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.norm();
  print(result); // sqrt(2^2 + 3^2 + 4^2 + 5^2 + 6^2) = sqrt(90) ~~ 9.48
}

void manhattanNorm() {
  final vector1 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.norm(Norm.manhattan);
  print(result); // 2 + 3 + 4 + 5 + 6 = 20.0
}

void mean() {
  final vector1 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.mean();
  print(result); // (2 + 3 + 4 + 5 + 6) / 5 = 4.0
}

void sum() {
  final vector1 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.sum();
  print(result); // 2 + 3 + 4 + 5 + 6 = 20.0 (equivalent to Manhattan norm)
}

void dot() {
  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.dot(vector2);
  print(
      result); // 1.0 * 2.0 + 2.0 * 3.0 + 3.0 * 4.0 + 4.0 * 5.0 + 5.0 * 6.0 = 70.0
}

void scalarAddition() {
  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final scalar = 5.0;
  final result = vector1 + scalar;
  print(result); // [6.0, 7.0, 8.0, 9.0, 10.0]
}

void scalarSubtraction() {
  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final scalar = 5.0;
  final result = vector1 / scalar;
  print(result); // [-4.0, -3.0, -2.0, -1.0, 0.0]
}

void scalarMultiplication() {
  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final scalar = 5.0;
  final result = vector1 * scalar;
  print(result); // [5.0, 10.0, 15.0, 20.0, 25.0]
}

void scalarDivision() {
  final vector1 = Vector.fromList([25.0, 50.0, 75.0, 100.0, 125.0]);
  final scalar = 5.0;
  final result = vector1 / scalar;
  print(result); // [5.0, 10.0, 15.0, 20.0, 25.0]
}

void euclideanDistanceBetweenVectors() {
  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.distanceTo(vector2);
  print(result); // ~~2.23
}

void manhattanDistanceBetweenVectors() {
  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.distanceTo(vector2, distance: Distance.manhattan);
  print(result); // 5.0
}

void cosineDistanceBetweenVectors() {
  final vector1 = Vector.fromList([1.0, 2.0, 3.0, 4.0, 5.0]);
  final vector2 = Vector.fromList([2.0, 3.0, 4.0, 5.0, 6.0]);
  final result = vector1.distanceTo(vector2, distance: Distance.cosine);
  print(result); // 0.00506
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  ml_linalg: ^12.3.0

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:ml_linalg/axis.dart';
import 'package:ml_linalg/distance.dart';
import 'package:ml_linalg/dtype.dart';
import 'package:ml_linalg/linalg.dart';
import 'package:ml_linalg/matrix.dart';
import 'package:ml_linalg/matrix_norm.dart';
import 'package:ml_linalg/norm.dart';
import 'package:ml_linalg/sort_direction.dart';
import 'package:ml_linalg/vector.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
54
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
77
Learn more about scoring.

We analyzed this package on Oct 16, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.5.1
  • pana: 0.12.21

Platforms

Detected platforms: Flutter, web, other

No platform restriction found in libraries.

Health suggestions

Fix lib/src/matrix/base_matrix.dart. (-0.50 points)

Analysis of lib/src/matrix/base_matrix.dart reported 1 hint:

line 320 col 29: DO use curly braces for all flow control structures.

Format lib/axis.dart.

Run dartfmt to format lib/axis.dart.

Format lib/distance.dart.

Run dartfmt to format lib/distance.dart.

Fix additional 16 files with analysis or formatting issues.

Additional issues in the following files:

  • lib/dtype.dart (Run dartfmt to format lib/dtype.dart.)
  • lib/matrix.dart (Run dartfmt to format lib/matrix.dart.)
  • lib/sort_direction.dart (Run dartfmt to format lib/sort_direction.dart.)
  • lib/src/common/float32_list_helper/float32_list_helper.dart (Run dartfmt to format lib/src/common/float32_list_helper/float32_list_helper.dart.)
  • lib/src/common/helper/get_2d_iterable_length.dart (Run dartfmt to format lib/src/common/helper/get_2d_iterable_length.dart.)
  • lib/src/common/helper/get_length_of_first_or_zero.dart (Run dartfmt to format lib/src/common/helper/get_length_of_first_or_zero.dart.)
  • lib/src/common/helper/get_zero_based_indices.dart (Run dartfmt to format lib/src/common/helper/get_zero_based_indices.dart.)
  • lib/src/matrix/common/data_manager/matrix_data_manager_impl.dart (Run dartfmt to format lib/src/matrix/common/data_manager/matrix_data_manager_impl.dart.)
  • lib/src/matrix/common/matrix_iterator.dart (Run dartfmt to format lib/src/matrix/common/matrix_iterator.dart.)
  • lib/src/matrix/common/matrix_validator_mixin.dart (Run dartfmt to format lib/src/matrix/common/matrix_validator_mixin.dart.)
  • lib/src/matrix/float32/float32_matrix.dart (Run dartfmt to format lib/src/matrix/float32/float32_matrix.dart.)
  • lib/src/vector/base_vector.dart (Run dartfmt to format lib/src/vector/base_vector.dart.)
  • lib/src/vector/float32/float32_vector.dart (Run dartfmt to format lib/src/vector/float32/float32_vector.dart.)
  • lib/src/vector/float32/simd_helper/float32x4_helper.dart (Run dartfmt to format lib/src/vector/float32/simd_helper/float32x4_helper.dart.)
  • lib/src/vector/float32/simd_helper/float32x4_helper_factory.dart (Run dartfmt to format lib/src/vector/float32/simd_helper/float32x4_helper_factory.dart.)
  • lib/vector.dart (Run dartfmt to format lib/vector.dart.)

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.2.0 <3.0.0
quiver >=2.0.0 <3.0.0 2.0.5
xrange 0.0.8 0.0.8
Transitive dependencies
injector 1.0.8
matcher 0.12.5
meta 1.1.7
path 1.6.4
stack_trace 1.9.3
Dev dependencies
benchmark_harness >=1.0.0 <2.0.0
build_runner ^1.1.2
build_test ^0.10.2
dartdoc any
grinder ^0.8.3
ml_tech ^0.0.5
mockito ^3.0.0
test ^1.2.0