diff --git a/CHANGELOG.md b/CHANGELOG.md index c8aea60..7581ebb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# 0.1.0 +- **Breaking change** svd returns a dart3 record (E, U, D) instead of a map {'E': E, 'U': U, 'D': D} +- Fix null safety issues. # 0.0.29+1 - Fix percentile index error in `Percentile.value` getter ([zeshuaro](https://github.com/zeshuaro)). diff --git a/example/extended_math_example.dart b/example/extended_math_example.dart index c33caab..e805710 100644 --- a/example/extended_math_example.dart +++ b/example/extended_math_example.dart @@ -4,7 +4,7 @@ void main() { final v1 = Vector([1, 2, 3]); final v2 = Vector([4, 5, 6]); // Multiply vectors - final double res = v1.dot(v2); + final num res = v1.dot(v2); // Add vectors final Vector res1 = v1 + v2; @@ -14,12 +14,12 @@ void main() { print(v5.angleBetween(v6)); final v3 = SquareMatrix(>[ - [9, 3, 5], - [-6, -9, 7], + [9, 3, 5], + [-6, -9, 7], [-1, -8, 1] ]); // Gets determinant of matrix - final double det = v3.determinant(); + final num det = v3.determinant(); // Computes eigenvalues and eigenvectors of square matrix final Map result = v3.eigen(); diff --git a/lib/src/applied_mathematics/numerical_analysis/newtons_method.dart b/lib/src/applied_mathematics/numerical_analysis/newtons_method.dart index 967784b..c4475b7 100644 --- a/lib/src/applied_mathematics/numerical_analysis/newtons_method.dart +++ b/lib/src/applied_mathematics/numerical_analysis/newtons_method.dart @@ -85,7 +85,7 @@ class NewtonsMethod { /// Counting Lowest limit for negative roots num lowerLimit() { - final helpArray = List(_equationCoef.length); + final helpArray = List.filled(_equationCoef.length, 0); for (var i = 0; i < _equationCoef.length; i++) { if (_equationPower[i] % 2 == 0) { helpArray[i] = _equationCoef[i]; @@ -113,8 +113,8 @@ class NewtonsMethod { var point1 = lowLim; var point2 = lowLim + delta; - var value1 = 0.0; - var value2 = 0.0; + num value1 = 0.0; + num value2 = 0.0; while (point2 < upLim) { value1 = _calcValue(point1); diff --git a/lib/src/applied_mathematics/probability_theory/numbers_generator.dart b/lib/src/applied_mathematics/probability_theory/numbers_generator.dart index 0d672c2..bd4ac5f 100644 --- a/lib/src/applied_mathematics/probability_theory/numbers_generator.dart +++ b/lib/src/applied_mathematics/probability_theory/numbers_generator.dart @@ -1,7 +1,5 @@ import 'dart:math'; -import 'package:meta/meta.dart'; - /// Generator of random numbers /// /// It isn't extend `Random` of `dart:math`, but provide functionality @@ -25,7 +23,7 @@ class NumbersGenerator { /// /// Generates `integer` number in range [from] - [to] inclusively. /// [from] should be less than [to]. - Iterable intIterableSync({@required int to, int from = 0}) sync* { + Iterable intIterableSync({required int to, int from = 0}) sync* { while (true) { yield nextInt(to, from: from); } diff --git a/lib/src/applied_mathematics/statistic/central_tendency.dart b/lib/src/applied_mathematics/statistic/central_tendency.dart index 73ddc0f..a80d9c1 100644 --- a/lib/src/applied_mathematics/statistic/central_tendency.dart +++ b/lib/src/applied_mathematics/statistic/central_tendency.dart @@ -21,7 +21,7 @@ class CentralTendency { /// /// If [weights] isn't `null` then the weighted arithmetic mean are computed. /// If provided, [weights] must have the same shape as the number's set. - num arithmetic({TensorBase weights}) { + num arithmetic({TensorBase? weights}) { if (_set.any((e) => e <= 0)) { throw MeanException('All numbers in set must be greatest than zero!'); } @@ -29,7 +29,7 @@ class CentralTendency { var set = _set.copy(); final w = weights ?? TensorBase.generate(set.shape, (_) => 1); - if (!mapsEqual(set.shape, w.shape)) { + if (!listsEqual(set.shape, w.shape)) { throw ArgumentError.value(weights, 'weights', 'Items count of weights don\'t match set of numbers!'); } @@ -43,7 +43,7 @@ class CentralTendency { /// /// If [weights] isn't `null` then the weighted geometric mean are computed. /// If provided, [weights] must have the same shape as the number's set. - num geometric({TensorBase weights}) { + num geometric({TensorBase? weights}) { if (_set.any((e) => e <= 0)) { throw MeanException('All numbers in set must be greatest than zero!'); } @@ -51,7 +51,7 @@ class CentralTendency { final set = _set.copy(); final w = weights ?? TensorBase.generate(set.shape, (_) => 1); - if (!mapsEqual(set.shape, w.shape)) { + if (!listsEqual(set.shape, w.shape)) { throw ArgumentError.value(weights, 'weights', 'Items count of weights don\'t match set of numbers!'); } @@ -71,7 +71,7 @@ class CentralTendency { /// /// If [weights] isn't `null` then the weighted harmonic mean are computed. /// If provided, [weights] must have the same shape as the number's set. - num harmonic({TensorBase weights}) { + num harmonic({TensorBase? weights}) { if (_set.any((e) => e <= 0)) { throw MeanException('All numbers in set must be greatest than zero!'); } @@ -79,7 +79,7 @@ class CentralTendency { final set = _set.copy(); final w = weights ?? TensorBase.generate(set.shape, (_) => 1); - if (!mapsEqual(set.shape, w.shape)) { + if (!listsEqual(set.shape, w.shape)) { throw ArgumentError.value(weights, 'weights', 'Items count of weights don\'t match set of numbers!'); } diff --git a/lib/src/applied_mathematics/statistic/dispersion.dart b/lib/src/applied_mathematics/statistic/dispersion.dart index 6d598b8..3eeb37e 100644 --- a/lib/src/applied_mathematics/statistic/dispersion.dart +++ b/lib/src/applied_mathematics/statistic/dispersion.dart @@ -10,7 +10,7 @@ class Dispersion { /// /// By default means that all values have an equal propabilities if /// it isn't so, you can provide your own. - Dispersion(this._values, {TensorBase probabilities}) + Dispersion(this._values, {TensorBase? probabilities}) : _probabilities = probabilities ?? TensorBase.generate(_values.shape, (_) => 1 / _values.itemsCount); @@ -28,7 +28,8 @@ class Dispersion { /// Computes expected value for all possible [values] of a random number /// for finite case with its probabilities - double expectedValue() => (values * probabilities).reduce((f, s) => f + s); + double expectedValue() => + (values * probabilities).reduce((f, s) => f + s).toDouble(); /// Computes `population` or `sample` [type]s of standard deviation of /// [values] @@ -47,7 +48,7 @@ class Dispersion { default: final summ = (values.map((v) => pow(v, 2)) * probabilities) .reduce((f, s) => f + s); - return summ - pow(mu, 2); + return (summ - pow(mu, 2)).toDouble(); } } diff --git a/lib/src/complex_analysis/complex.dart b/lib/src/complex_analysis/complex.dart index 1fdd194..07960ed 100644 --- a/lib/src/complex_analysis/complex.dart +++ b/lib/src/complex_analysis/complex.dart @@ -35,7 +35,7 @@ class Complex with CopyableMixin { /// /// [other] can be either number or complex number. Complex operator +(Object other) { - Complex c; + var c = Complex(); if (other is num) { c = Complex(re: re + other, im: im); } else if (other is Complex) { @@ -50,7 +50,7 @@ class Complex with CopyableMixin { /// /// [other] can be either number or complex number. Complex operator -(Object other) { - Complex c; + var c = Complex(); if (other is Complex) { c = this + -other; } else if (other is num) { @@ -68,7 +68,7 @@ class Complex with CopyableMixin { /// /// [other] can be either number or complex number. Complex operator *(Object other) { - Complex c; + var c = Complex(); if (other is num) { final newRe = re * other; final newIm = im * other; @@ -89,7 +89,7 @@ class Complex with CopyableMixin { /// /// [other] can be either number or complex number. Complex operator /(Object other) { - Complex c; + var c = Complex(); if (other is num) { final down = m.pow(other, 2); final newRe = (re * other) / down; @@ -137,7 +137,7 @@ class Complex with CopyableMixin { } // final rootModule = m.pow(module, 1 / root); - final rootModule = Double(module).rootOf(root).toDouble(); + final rootModule = Double(module.toDouble()).rootOf(root).toDouble(); for (var i = 0; i < root; i++) { final newRe = m.cos((argument + 2 * argument * i) / root) * rootModule; diff --git a/lib/src/discrete_mathematics/general_algebraic_systems/number/base/number.dart b/lib/src/discrete_mathematics/general_algebraic_systems/number/base/number.dart index a416789..ad46b8c 100644 --- a/lib/src/discrete_mathematics/general_algebraic_systems/number/base/number.dart +++ b/lib/src/discrete_mathematics/general_algebraic_systems/number/base/number.dart @@ -23,8 +23,7 @@ class Number extends TensorBase { num get data => _value; @override - Map get shape => - {}; // Empty because numbers haven't shape + List get shape => []; // Empty because numbers haven't shape /// Gets nth root of this number /// @@ -62,7 +61,7 @@ class Number extends TensorBase { /// [other] can be either `num` or [Number]. @override Number operator +(Object other) { - Number n; + var n = Number(0); if (other is num) { n = Number(_value + other); } else if (other is Number) { @@ -79,7 +78,7 @@ class Number extends TensorBase { /// [other] can be either `num` or [Number]. @override Number operator -(Object other) { - Number n; + var n = Number(0); if (other is num) { n = Number(_value - other); } else if (other is Number) { @@ -93,7 +92,7 @@ class Number extends TensorBase { /// [other] can be either `num` or [Number]. @override Number operator *(Object other) { - Number n; + var n = Number(0); if (other is num) { n = Number(_value * other); } else if (other is Number) { @@ -107,7 +106,7 @@ class Number extends TensorBase { /// [other] can be either `num` or [Number]. @override Double operator /(Object other) { - Double n; + var n = Double(0); if (other is num) { if (other == 0) { throw DivisionByZeroException(); @@ -124,7 +123,7 @@ class Number extends TensorBase { @override bool operator ==(Object other) { - bool result; + var result = false; if (other is num) { result = _value == other; } else if (other is Number) { diff --git a/lib/src/discrete_mathematics/linear_algebra/tensor/base/tensor_base.dart b/lib/src/discrete_mathematics/linear_algebra/tensor/base/tensor_base.dart index 5bc0d82..7b503d7 100644 --- a/lib/src/discrete_mathematics/linear_algebra/tensor/base/tensor_base.dart +++ b/lib/src/discrete_mathematics/linear_algebra/tensor/base/tensor_base.dart @@ -24,25 +24,25 @@ abstract class TensorBase with CopyableMixin { /// - [2, 3] -> `Matrix` with 2 rows and 3 columns /// - [4, 2, 5] -> `Tensor3` with 4 width, 2 length and 5 depth factory TensorBase.generate( - Map shape, num Function(num number) generator) { + List shape, num Function(num number) generator) { switch (shape.length) { case 1: - return Vector(List.generate(shape['width'], generator)); + return Vector(List.generate(shape[0], generator)); case 2: - final row = List.generate(shape['width'], generator); - return Matrix(List>.generate(shape['length'], (_) => row)); + final row = List.generate(shape[1], generator); + return Matrix(List>.generate(shape[0], (_) => row)); case 3: - final depth = List.generate(shape['depth'], generator); - final width = List>.generate(shape['width'], (_) => depth); + final depth = List.generate(shape[2], generator); + final width = List>.generate(shape[1], (_) => depth); return Tensor3( - List>>.generate(shape['length'], (_) => width)); + List>>.generate(shape[0], (_) => width)); case 4: - final depth2 = List.generate(shape['depth2'], generator); - final depth = List>.generate(shape['depth'], (_) => depth2); + final depth2 = List.generate(shape[3], generator); + final depth = List>.generate(shape[2], (_) => depth2); final width = - List>>.generate(shape['width'], (_) => depth); + List>>.generate(shape[1], (_) => depth); return Tensor4(List>>>.generate( - shape['length'], (_) => width)); + shape[0], (_) => width)); default: return Number(generator(1)); } @@ -59,9 +59,10 @@ abstract class TensorBase with CopyableMixin { /// Gets shape of this tensor /// - /// [shape] may contain numbers that denote count of `width`(columns), - /// `length`(rows), `depth` and `depth2` in this order. - Map get shape; + /// [shape] may contain numbers that denote count of entries in each + /// dimension of the tensor, with shape[0] being the count for the first + /// dimension shape[1] in the second and so on. + List get shape; /// Reduces data to number with provided [f] reduce function num reduce(num Function(num prev, num next) f); @@ -79,7 +80,7 @@ abstract class TensorBase with CopyableMixin { /// otherwise throws [TensorException] Number toScalar() { if (dimension == 0) { - return Number(data); + return Number(data as num); } else { throw TensorException('Tensor cannot be converted to Number, because ' 'dimension of this tensor isn\'t equal to 0!'); @@ -90,7 +91,7 @@ abstract class TensorBase with CopyableMixin { /// otherwise throws [TensorException] Vector toVector() { if (dimension == 1) { - return Vector(data); + return Vector(data as List); } else { throw TensorException('Tensor cannot be converted to Vector, because ' 'dimension of this tensor isn\'t equal to 1!'); @@ -101,7 +102,7 @@ abstract class TensorBase with CopyableMixin { /// otherwise throws [TensorException] Matrix toMatrix() { if (dimension == 2) { - return Matrix(data); + return Matrix(data as List>); } else { throw TensorException('Tensor cannot be converted to Matrix, because ' 'dimension of this tensor isn\'t equal to 2!'); @@ -112,7 +113,7 @@ abstract class TensorBase with CopyableMixin { /// otherwise throws [TensorException] Tensor3 toTensor3() { if (dimension == 3) { - return Tensor3(data); + return Tensor3(data as List>>); } else { throw TensorException('Tensor cannot be converted to Tensor3, because ' 'dimension of this tensor isn\'t equal to 3!'); @@ -123,7 +124,7 @@ abstract class TensorBase with CopyableMixin { /// otherwise throws [TensorException] Tensor4 toTensor4() { if (dimension == 4) { - return Tensor4(data); + return Tensor4(data as List>>>); } else { throw TensorException('Tensor cannot be converted to Tensor4, because ' 'dimension of this tensor isn\'t equal to 4!'); @@ -137,7 +138,7 @@ abstract class TensorBase with CopyableMixin { /// of known data points [a] (alpha) may be in range from 0 to 1 /// inclusively. Otherwise throws [TensorException]. TensorBase lerp(TensorBase other, double a) { - if (dimension != other.dimension && !mapsEqual(shape, other.shape)) { + if (dimension != other.dimension && !listsEqual(shape, other.shape)) { throw ArgumentError('Tensors aren\'t equals!'); } diff --git a/lib/src/discrete_mathematics/linear_algebra/tensor/tensor1/vector.dart b/lib/src/discrete_mathematics/linear_algebra/tensor/tensor1/vector.dart index 5184dc8..6af96e3 100644 --- a/lib/src/discrete_mathematics/linear_algebra/tensor/tensor1/vector.dart +++ b/lib/src/discrete_mathematics/linear_algebra/tensor/tensor1/vector.dart @@ -16,7 +16,7 @@ class Vector extends TensorBase { /// Generates vector with [length] and values generated by [generator] factory Vector.generate(int length, num Function(num number) generator) => - TensorBase.generate({'width': length}, generator).toVector(); + TensorBase.generate([length], generator).toVector(); /// Data for vector final List _data; @@ -25,7 +25,7 @@ class Vector extends TensorBase { List get data => _data.toList(); @override - Map get shape => {'width': itemsCount}; + List get shape => [itemsCount]; @override int get itemsCount => data.length; @@ -148,7 +148,7 @@ class Vector extends TensorBase { /// Gets subvector from this [Vector] /// /// [start] and [end] may be in range from 1 to end inclusively. - Vector subvector(int start, [int end]) => + Vector subvector(int start, [int? end]) => Vector(data.sublist(start - 1, end != null ? end : null)); /// Gets Hadamard product of vectors @@ -172,7 +172,7 @@ class Vector extends TensorBase { @override Vector operator *(Object other) { - Vector v; + var v = Vector([]); if (other is num) { v = map((v) => v * other); } else if (other is Vector) { @@ -185,7 +185,7 @@ class Vector extends TensorBase { @override Vector operator /(Object other) { - Vector v; + var v = Vector([]); if (other is num) { if (other == 0) { throw DivisionByZeroException(); diff --git a/lib/src/discrete_mathematics/linear_algebra/tensor/tensor2/matrix.dart b/lib/src/discrete_mathematics/linear_algebra/tensor/tensor2/matrix.dart index 6239ab8..146a161 100644 --- a/lib/src/discrete_mathematics/linear_algebra/tensor/tensor2/matrix.dart +++ b/lib/src/discrete_mathematics/linear_algebra/tensor/tensor2/matrix.dart @@ -58,7 +58,7 @@ class Matrix extends TensorBase { List> get data => _data.map((r) => r.toList()).toList(); @override - Map get shape => {'width': columns, 'length': rows}; + List get shape => [columns, rows]; /// Rows count of matrix int get rows => data.length; @@ -432,11 +432,11 @@ class Matrix extends TensorBase { /// matrix with positive eigenvalues) to any m×n matrix via an extension /// of the polar decomposition. /// - /// Returns `Map` that contains `E` (singular values), `U` (left-singular + /// Returns the matrices `E` (singular values), `U` (left-singular /// vectors) and `V` (right-singular vectors) with corresponding values. /// /// Created from [Jama's implemetation](https://github.com/fiji/Jama/blob/master/src/main/java/Jama/SingularValueDecomposition.java). - Map svd() { + (Matrix, Matrix, Matrix) svd() { // Row and column dimensions final m = rows; final n = columns; @@ -449,9 +449,9 @@ class Matrix extends TensorBase { final v = SquareMatrix.generate(n).data; // array for internal storage of singular values - final s = List(min(m + 1, n)); - final e = List(n); - final work = List(m); + final s = List.filled(min(m + 1, n), 0); + final e = List.filled(n, 0); + final work = List.filled(m, 0); bool wantu = true; bool wantv = true; @@ -632,8 +632,8 @@ class Matrix extends TensorBase { int pp = p - 1; int iter = 0; - double eps = pow(2.0, -52.0); - double tiny = pow(2.0, -966.0); + double eps = pow(2.0, -52.0).toDouble(); + double tiny = pow(2.0, -966.0).toDouble(); while (p > 0) { int k, kase; @@ -666,7 +666,7 @@ class Matrix extends TensorBase { if (ks == k) { break; } - double t = (ks != p ? e[ks].abs() : 0.0) + + num t = (ks != p ? e[ks].abs() : 0.0) + (ks != k + 1 ? e[ks - 1].abs() : 0.0); if (s[ks].abs() <= tiny + eps * t) { s[ks] = 0.0; @@ -692,10 +692,10 @@ class Matrix extends TensorBase { case 1: { - double f = e[p - 2]; + num f = e[p - 2]; e[p - 2] = 0.0; for (int j = p - 2; j >= k; j--) { - double t = hypot(s[j], f); + num t = hypot(s[j], f); double cs = s[j] / t; double sn = f / t; s[j] = t; @@ -718,10 +718,10 @@ class Matrix extends TensorBase { case 2: { - double f = e[k - 1]; + num f = e[k - 1]; e[k - 1] = 0.0; for (int j = k; j < p; j++) { - double t = hypot(s[j], f); + num t = hypot(s[j], f); double cs = s[j] / t; double sn = f / t; s[j] = t; @@ -744,7 +744,7 @@ class Matrix extends TensorBase { { // Calculate the shift. - double scale = max( + num scale = max( max(max(max(s[p - 1].abs(), s[p - 2].abs()), e[p - 2].abs()), s[k].abs()), e[k].abs()); @@ -769,7 +769,7 @@ class Matrix extends TensorBase { // Chase zeros. for (int j = k; j < p - 1; j++) { - double t = hypot(f, g); + num t = hypot(f, g); double cs = f / t; double sn = g / t; if (j != k) { @@ -828,7 +828,7 @@ class Matrix extends TensorBase { if (s[k] >= s[k + 1]) { break; } - double t = s[k]; + num t = s[k]; s[k] = s[k + 1]; s[k + 1] = t; if (wantv && (k < n - 1)) { @@ -861,12 +861,11 @@ class Matrix extends TensorBase { } sAsMatrix[i][i] = s[i]; } - - return { - 'E': Matrix(sAsMatrix), - 'U': SquareMatrix(u), - 'V': Matrix(v) - }; + return ( + Matrix(sAsMatrix), // E + SquareMatrix(u), // U + Matrix(v), // V + ); } /// Calculates QR decomposition of this matrix @@ -912,7 +911,7 @@ class Matrix extends TensorBase { /// (vectors) are matrices (of given dimensions). /// /// If [q] is provided method computes `Lp,q norm`. - double norm(int p, [int q]) { + double norm(int p, [int? q]) { final matrix = map((v) => pow(v.abs(), p)); if (q == null) { return Number(matrix.reduce((f, s) => f + s)).rootOf(p).data; @@ -947,14 +946,15 @@ class Matrix extends TensorBase { /// Computes spectral norm of this matrix num spectralNorm() { - final singularValues = svd()['E']; + final (singularValues, _, _) = svd(); return CentralTendency(singularValues).maximum(); } /// Calculates the ratio `C` of the largest to smallest singular value in /// the singular value decomposition of a matrix double condition() { - final c = CentralTendency(svd()['E']); + final (singularValues, _, _) = svd(); + final c = CentralTendency(singularValues); return c.maximum() / c.minimum(); } @@ -991,7 +991,7 @@ class Matrix extends TensorBase { /// Otherwise returns `null`. @override Matrix operator *(Object other) { - Matrix m; + var m = Matrix([]); if (other is num) { m = copy().map((v) => v * other); } else if (other is Matrix) { @@ -1006,7 +1006,7 @@ class Matrix extends TensorBase { /// if `this` matrix and [other] are square matrix. @override Matrix operator /(Object other) { - Matrix m; + var m = Matrix([]); if (other is num) { if (other == 0) { throw DivisionByZeroException(); diff --git a/lib/src/discrete_mathematics/linear_algebra/tensor/tensor2/square_matrix.dart b/lib/src/discrete_mathematics/linear_algebra/tensor/tensor2/square_matrix.dart index a5262a3..051cb75 100644 --- a/lib/src/discrete_mathematics/linear_algebra/tensor/tensor2/square_matrix.dart +++ b/lib/src/discrete_mathematics/linear_algebra/tensor/tensor2/square_matrix.dart @@ -168,7 +168,7 @@ class SquareMatrix extends Matrix { /** Row and column dimension (square matrix). @serial matrix dimension. */ - int n; + int n = columns; /** Symmetry flag. @serial internal symmetry flag. @@ -178,22 +178,27 @@ class SquareMatrix extends Matrix { /** Arrays for internal storage of eigenvalues. @serial internal storage of eigenvalues. */ - List d, e; + List d = List.filled(n, 0), e = List.filled(n, 0); /** Array for internal storage of eigenvectors. @serial internal storage of eigenvectors. */ - List> V; + List> V = []; /** Array for internal storage of nonsymmetric Hessenberg form. @serial internal storage of nonsymmetric Hessenberg form. */ - List> H; + List> H = []; /** Working storage for nonsymmetric algorithm. @serial working storage for nonsymmetric algorithm. */ - List ort; + List ort = List.filled(n, 0.0); + + for (var i = 0; i < n; i++) { + V.add(List.filled(n, 0.0)); + H.add(List.filled(n, 0.0)); + } /* ------------------------ Private Methods @@ -328,7 +333,7 @@ class SquareMatrix extends Matrix { double f = 0.0; double tst1 = 0.0; - double eps = pow(2.0, -52.0); + double eps = pow(2.0, -52.0).toDouble(); for (int l = 0; l < n; l++) { // Find small subdiagonal element @@ -353,7 +358,7 @@ class SquareMatrix extends Matrix { double g = d[l]; double p = (d[l + 1] - g) / (2.0 * e[l]); - double r = hypot(p, 1.0); + double r = hypot(p, 1.0).toDouble(); if (p < 0) { r = -r; } @@ -381,7 +386,7 @@ class SquareMatrix extends Matrix { s2 = s; g = c * e[i]; h = c * p; - r = hypot(p, e[i]); + r = hypot(p, e[i]).toDouble(); e[i + 1] = s * r; s = e[i] / r; c = p / r; @@ -523,7 +528,7 @@ class SquareMatrix extends Matrix { // Complex scalar division. - double cdivr, cdivi; + double cdivr = 0, cdivi = 0; void cdiv(double xr, double xi, double yr, double yi) { double r, d; if (yr.abs() > yi.abs()) { @@ -553,9 +558,9 @@ class SquareMatrix extends Matrix { int inn = nn - 1; int low = 0; int high = nn - 1; - double eps = pow(2.0, -52.0); + double eps = pow(2.0, -52.0).toDouble(); double exshift = 0.0; - num p = 0, q = 0, r = 0, s = 0, z = 0, t, w, x, y; + double p = 0, q = 0, r = 0, s = 0, z = 0, t, w, x, y; // Store roots isolated by balanc and compute matrix norm @@ -992,10 +997,6 @@ class SquareMatrix extends Matrix { */ final A = data; - n = columns; - V = SquareMatrix.generate(n).data; - d = List(n); - e = List(n); issymmetric = true; for (int j = 0; (j < n) & issymmetric; j++) { @@ -1007,7 +1008,7 @@ class SquareMatrix extends Matrix { if (issymmetric) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { - V[i][j] = A[i][j]; + V[i][j] = A[i][j].toDouble(); } } @@ -1017,12 +1018,9 @@ class SquareMatrix extends Matrix { // Diagonalize. tql2(); } else { - H = SquareMatrix.generate(n).data; - ort = List(n); - for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { - H[i][j] = A[i][j]; + H[i][j] = A[i][j].toDouble(); } } @@ -1064,7 +1062,7 @@ class SquareMatrix extends Matrix { /// /// Created from [Jama's implemetation](https://github.com/fiji/Jama/blob/master/src/main/java/Jama/CholeskyDecomposition.java). SquareMatrix cholesky() { - SquareMatrix m; + var m = SquareMatrix([]); if (isPositiveDefinite()) { /* ------------------------ Class variables diff --git a/lib/src/discrete_mathematics/linear_algebra/tensor/tensor3.dart b/lib/src/discrete_mathematics/linear_algebra/tensor/tensor3.dart index 654f7bb..83f7009 100644 --- a/lib/src/discrete_mathematics/linear_algebra/tensor/tensor3.dart +++ b/lib/src/discrete_mathematics/linear_algebra/tensor/tensor3.dart @@ -15,7 +15,7 @@ class Tensor3 extends TensorBase { factory Tensor3.generate(int width, int length, int depth, num Function(num number) generator) => TensorBase.generate( - {'width': width, 'length': length, 'depth': depth}, + [width, length, depth], generator) .toTensor3(); @@ -38,8 +38,7 @@ class Tensor3 extends TensorBase { _data.map((r) => r.map((c) => c.toList()).toList()).toList(); @override - Map get shape => - {'width': width, 'length': length, 'depth': depth}; + List get shape => [width, length, depth]; /// Gets two dimensional matrix in specified depth position /// @@ -144,7 +143,7 @@ class Tensor3 extends TensorBase { /// Otherwise returns `null`. @override Tensor3 operator *(Object other) { - Tensor3 m; + var m = Tensor3([]); if (other is num) { m = copy().map((v) => v * other); } else if (other is Tensor3) { @@ -166,7 +165,7 @@ class Tensor3 extends TensorBase { /// Divide this tensor by number of by [other] @override Tensor3 operator /(Object other) { - Tensor3 m; + var m = Tensor3([]); if (other is num) { if (other == 0) { throw DivisionByZeroException(); diff --git a/lib/src/discrete_mathematics/linear_algebra/tensor/tensor4.dart b/lib/src/discrete_mathematics/linear_algebra/tensor/tensor4.dart index 5b914f2..2b6e271 100644 --- a/lib/src/discrete_mathematics/linear_algebra/tensor/tensor4.dart +++ b/lib/src/discrete_mathematics/linear_algebra/tensor/tensor4.dart @@ -13,12 +13,7 @@ class Tensor4 extends TensorBase { /// and values generated by [generator] factory Tensor4.generate(int width, int length, int depth, int depth2, num Function(num number) generator) => - TensorBase.generate({ - 'width': width, - 'length': length, - 'depth': depth, - 'depth2': depth2 - }, generator) + TensorBase.generate([width, length, depth, depth2], generator) .toTensor4(); final List>>> _data; @@ -39,12 +34,7 @@ class Tensor4 extends TensorBase { int get itemsCount => width * length * depth * depth2; @override - Map get shape => { - 'width': width, - 'length': length, - 'depth': depth, - 'depth2': depth2 - }; + List get shape => [width, length, depth, depth2]; @override List>>> get data => _data @@ -156,7 +146,7 @@ class Tensor4 extends TensorBase { /// Otherwise returns `null`. @override Tensor4 operator *(Object other) { - Tensor4 m; + var m = Tensor4([]); if (other is num) { m = copy().map((v) => v * other); } else if (other is Tensor4) { @@ -181,7 +171,7 @@ class Tensor4 extends TensorBase { /// Divide this tensor by number of by [other] @override Tensor4 operator /(Object other) { - Tensor4 m; + var m = Tensor4([]); if (other is num) { if (other == 0) { throw DivisionByZeroException(); diff --git a/lib/src/general/elementary_algebra/equations/base/equation_base.dart b/lib/src/general/elementary_algebra/equations/base/equation_base.dart index fb42ffa..d7257ef 100644 --- a/lib/src/general/elementary_algebra/equations/base/equation_base.dart +++ b/lib/src/general/elementary_algebra/equations/base/equation_base.dart @@ -6,7 +6,7 @@ abstract class EquationBase { /// /// Any real roots are converted to [Complex] numbers and can /// be resolved with [Complex.toReal] method. - Map calculate(); + List calculate(); /// Gets discriminant of equation num discriminant(); diff --git a/lib/src/general/elementary_algebra/equations/cubic_equation.dart b/lib/src/general/elementary_algebra/equations/cubic_equation.dart index ea7f375..6edace2 100644 --- a/lib/src/general/elementary_algebra/equations/cubic_equation.dart +++ b/lib/src/general/elementary_algebra/equations/cubic_equation.dart @@ -43,44 +43,45 @@ class CubicEquation extends EquationBase { } @override - Map calculate() { - final result = {}; + List calculate() { + final result = []; + Complex? x1; final dis = discriminant(); if (d != 0) { - final possibleX = Integer(d).factorizate(); + final possibleX = Integer(d.round()).factorizate(); possibleX.add(1); for (var item in possibleX) { for (var i = 1; i <= 2; i++) { if (evaluate(pow(-1, i) * item, 0)) { - result['x1'] = Complex(re: pow(-1, i) * item); + x1 = Complex(re: pow(-1, i) * item); } } } } else { - result['x1'] = Complex(); + x1 = Complex(); } - if (result.isEmpty) { + if (x1 == null) { final alpha = Double(-(q / 2) + sqrt(dis)).preciseTo(2).rootOf(3).toDouble(); final beta = Double(-(q / 2) - sqrt(dis)).preciseTo(2).rootOf(3).toDouble(); final z = alpha + beta; final x = z - b / (3 * a); - result['x1'] = Complex(re: x); + x1 = Complex(re: x); } - final tmpB = result['x1'] * a + b; - final tmpC = result['x1'] * tmpB + c; + result.add(x1); + + final tmpB = x1 * a + b; + final tmpC = x1 * tmpB + c; final quadratic = QuadraticEquation(a: a, b: tmpB.toReal(), c: tmpC.toReal()); final quadResult = quadratic.calculate(); - for (var i = 1; i <= quadResult.length; i++) { - result['x${i + 1}'] = quadResult['x$i']; - } + result.addAll(quadResult); return result; } diff --git a/lib/src/general/elementary_algebra/equations/quadratic_equation.dart b/lib/src/general/elementary_algebra/equations/quadratic_equation.dart index 788b89f..ed3a9d4 100644 --- a/lib/src/general/elementary_algebra/equations/quadratic_equation.dart +++ b/lib/src/general/elementary_algebra/equations/quadratic_equation.dart @@ -26,21 +26,21 @@ class QuadraticEquation extends EquationBase { num c; @override - Map calculate() { - final result = {}; + List calculate() { + final result = []; final dis = discriminant(); if (dis > 0) { for (var i = 1; i <= 2; i++) { - result['x$i'] = Complex(re: (-b + pow(-1, i) * sqrt(dis)) / (2 * a)); + result.add(Complex(re: (-b + pow(-1, i) * sqrt(dis)) / (2 * a))); } } else if (dis == 0) { - result['x'] = Complex(re: -b / (2 * a)); + result.add(Complex(re: -b / (2 * a))); } else { for (var i = 1; i <= 2; i++) { final re = -b / (2 * a); final im = pow(-1, i) * sqrt(-dis) / (2 * a); - result['x$i'] = Complex(re: re, im: im); + result.add(Complex(re: re, im: im)); } } return result; diff --git a/pubspec.yaml b/pubspec.yaml index 823c674..f1d381a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,16 +1,15 @@ name: extended_math description: Library that add functionality of all maths sections that don't exist in dart:math. -version: 0.0.29+1 +version: 0.1.0 homepage: https://github.com/YevhenKap/extended_math license: MIT environment: - sdk: '>=2.2.0 <3.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: - meta: ^1.1.8 - quiver: ^2.1.2 + quiver: ^3.0.0 dev_dependencies: - test: ^1.5.3 - pedantic: ^1.9.0 + test: ^1.20.0 + lints: ^2.0.0