Skip to content

Commit

Permalink
Merge b8a324d into 27e2cff
Browse files Browse the repository at this point in the history
  • Loading branch information
gyrdym committed May 21, 2020
2 parents 27e2cff + b8a324d commit 494c9fa
Show file tree
Hide file tree
Showing 15 changed files with 137 additions and 2 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog

## 12.9.0
- `Vector`:
- `fromJson` constructor added
- `toJson` method added
- `vectorToJson` helper function added to public API
- `fromVectorJson` helper function added to public API

## 12.8.2
- `fromMatrixJson`: dynamic type support added to parsing

Expand Down
1 change: 1 addition & 0 deletions lib/from_vector_json.dart
@@ -0,0 +1 @@
export 'package:ml_linalg/src/vector/serialization/from_vector_json.dart';
4 changes: 4 additions & 0 deletions lib/src/vector/float32x4_vector.dart
Expand Up @@ -7,6 +7,7 @@ import 'package:ml_linalg/dtype.dart';
import 'package:ml_linalg/matrix.dart';
import 'package:ml_linalg/norm.dart';
import 'package:ml_linalg/src/common/cache_manager/cache_manager.dart';
import 'package:ml_linalg/src/vector/serialization/vector_to_json.dart';
import 'package:ml_linalg/src/vector/simd_helper/simd_helper.dart';
import 'package:ml_linalg/src/vector/vector_cache_keys.dart';
import 'package:ml_linalg/vector.dart';
Expand Down Expand Up @@ -412,6 +413,9 @@ class Float32x4Vector with IterableMixin<double> implements Vector {
return (this - minValue) / (maxValue - minValue);
}, skipCaching: skipCaching);

@override
Map<String, dynamic> toJson() => vectorToJson(this);

/// Returns exponent depending on vector norm type (for Euclidean norm - 2,
/// Manhattan - 1)
int _getPowerByNormType(Norm norm) {
Expand Down
4 changes: 4 additions & 0 deletions lib/src/vector/float64x2_vector.dart
Expand Up @@ -9,6 +9,7 @@ import 'package:ml_linalg/dtype.dart';
import 'package:ml_linalg/matrix.dart';
import 'package:ml_linalg/norm.dart';
import 'package:ml_linalg/src/common/cache_manager/cache_manager.dart';
import 'package:ml_linalg/src/vector/serialization/vector_to_json.dart';
import 'package:ml_linalg/src/vector/simd_helper/simd_helper.dart';
import 'package:ml_linalg/src/vector/vector_cache_keys.dart';
import 'package:ml_linalg/vector.dart';
Expand Down Expand Up @@ -414,6 +415,9 @@ class Float64x2Vector with IterableMixin<double> implements Vector {
return (this - minValue) / (maxValue - minValue);
}, skipCaching: skipCaching);

@override
Map<String, dynamic> toJson() => vectorToJson(this);

/// Returns exponent depending on vector norm type (for Euclidean norm - 2,
/// Manhattan - 1)
int _getPowerByNormType(Norm norm) {
Expand Down
21 changes: 21 additions & 0 deletions lib/src/vector/serialization/from_vector_json.dart
@@ -0,0 +1,21 @@
import 'package:ml_linalg/linalg.dart';
import 'package:ml_linalg/src/common/dtype_serializer/dtype_encoded_values.dart';
import 'package:ml_linalg/src/vector/vector_json_keys.dart';

Vector fromVectorJson(Map<String, dynamic> json) {
final source = (json[vectorDataJsonKey] as List)
.map((dynamic value) => double.parse(value.toString()))
.toList(growable: false);

switch(json[vectorDTypeJsonKey] as String) {
case dTypeFloat32EncodedValue:
return Vector.fromList(source, dtype: DType.float32);

case dTypeFloat64EncodedValue:
return Vector.fromList(source, dtype: DType.float64);

default:
throw UnsupportedError('Unknown dtype encoded value - '
'${json[vectorDTypeJsonKey]}');
}
}
13 changes: 13 additions & 0 deletions lib/src/vector/serialization/vector_to_json.dart
@@ -0,0 +1,13 @@
import 'package:ml_linalg/dtype_to_json.dart';
import 'package:ml_linalg/src/vector/vector_json_keys.dart';
import 'package:ml_linalg/vector.dart';

Map<String, dynamic> vectorToJson(Vector vector) {
final encodedDType = dTypeToJson(vector.dtype);
final encodedData = vector.toList(growable: false);

return <String, dynamic>{
vectorDTypeJsonKey: encodedDType,
vectorDataJsonKey: encodedData,
};
}
2 changes: 2 additions & 0 deletions lib/src/vector/vector_json_keys.dart
@@ -0,0 +1,2 @@
const vectorDTypeJsonKey = 'DT';
const vectorDataJsonKey = 'D';
6 changes: 6 additions & 0 deletions lib/vector.dart
Expand Up @@ -7,6 +7,7 @@ import 'package:ml_linalg/src/common/cache_manager/cache_manager_factory.dart';
import 'package:ml_linalg/src/di/dependencies.dart';
import 'package:ml_linalg/src/vector/float32x4_vector.dart';
import 'package:ml_linalg/src/vector/float64x2_vector.dart';
import 'package:ml_linalg/src/vector/serialization/from_vector_json.dart';
import 'package:ml_linalg/src/vector/simd_helper/simd_helper_factory.dart';
import 'package:ml_linalg/src/vector/vector_cache_keys.dart';

Expand Down Expand Up @@ -283,6 +284,8 @@ abstract class Vector implements Iterable<double> {
}
}

factory Vector.fromJson(Map<String, dynamic> json) => fromVectorJson(json);

/// Denotes a data type, used for representation of the vector's elements
DType get dtype;

Expand Down Expand Up @@ -386,4 +389,7 @@ abstract class Vector implements Iterable<double> {
/// Returns a new vector composed of values which indices are within the range
/// [start] (inclusive) - [end] (exclusive)
Vector subvector(int start, [int end]);

/// Returns a json-serializable map
Map<String, dynamic> toJson();
}
1 change: 1 addition & 0 deletions lib/vector_to_json.dart
@@ -0,0 +1 @@
export 'package:ml_linalg/src/vector/serialization/vector_to_json.dart';
2 changes: 1 addition & 1 deletion pubspec.yaml
@@ -1,6 +1,6 @@
name: ml_linalg
description: SIMD-based linear algebra and statistics for data science
version: 12.8.2
version: 12.9.0
homepage: https://github.com/gyrdym/ml_linalg

environment:
Expand Down
Expand Up @@ -8,7 +8,7 @@ import '../../../../dtype_to_title.dart';

void toJsonTestGroupFactory(DType dtype) =>
group(dtypeToMatrixTestTitle[dtype], () {
group('toJson', () {
group('toJson method', () {
test('should return a serializable map', () {
final source = [
[1.0, 2.0, 3.0, 4.0],
Expand Down
@@ -0,0 +1,8 @@
import 'package:ml_linalg/dtype.dart';

import 'from_json_constructor_test_group_factory.dart';

void main() {
fromJsonConstructorTestGroupFactory(DType.float32);
fromJsonConstructorTestGroupFactory(DType.float64);
}
@@ -0,0 +1,36 @@
import 'package:ml_linalg/dtype.dart';
import 'package:ml_linalg/dtype_to_json.dart';
import 'package:ml_linalg/src/vector/vector_json_keys.dart';
import 'package:ml_linalg/vector.dart';
import 'package:ml_tech/unit_testing/matchers/iterable_almost_equal_to.dart';
import 'package:test/test.dart';

import '../../../../dtype_to_title.dart';

void fromJsonConstructorTestGroupFactory(DType dtype) =>
group(dtypeToVectorTestTitle[dtype], () {
group('fromJson constructor', () {
final data = <double>[12, 23, 44.0, -1e10, 10007.888, -10, 0, 7];
final json = {
vectorDTypeJsonKey: dTypeToJson(dtype),
vectorDataJsonKey: data,
};
final unknownJson = {
vectorDTypeJsonKey: 'some_unknown_dtype',
vectorDataJsonKey: data,
};

test('should decode serialized vector', () {
final vector = Vector.fromJson(json);

expect(vector, iterableAlmostEqualTo(data, 1e-3));
expect(vector.dtype, dtype);
});

test('should throw an error if unknown decoded value is passed', () {
final actual = () => Vector.fromJson(unknownJson);

expect(actual, throwsUnsupportedError);
});
});
});
@@ -0,0 +1,8 @@
import 'package:ml_linalg/dtype.dart';

import 'to_json_test_group_factory.dart';

void main() {
vectorToJsonTestGroupFactory(DType.float32);
vectorToJsonTestGroupFactory(DType.float64);
}
@@ -0,0 +1,24 @@
import 'package:ml_linalg/dtype.dart';
import 'package:ml_linalg/dtype_to_json.dart';
import 'package:ml_linalg/src/vector/vector_json_keys.dart';
import 'package:ml_linalg/vector.dart';
import 'package:ml_tech/unit_testing/matchers/iterable_almost_equal_to.dart';
import 'package:test/test.dart';

import '../../../../dtype_to_title.dart';

void vectorToJsonTestGroupFactory(DType dtype) =>
group(dtypeToVectorTestTitle[dtype], () {
group('toJson method', () {
final data = <double>[100, 129, 3.555, 5.07, -600, 17, 84];
final vector = Vector.fromList(data, dtype: dtype);

test('should return a json-serializable map', () {
final encoded = vector.toJson();

expect(encoded[vectorDTypeJsonKey], dTypeToJson(dtype));
expect(encoded[vectorDataJsonKey], iterableAlmostEqualTo(data));
expect(encoded.keys, hasLength(2));
});
});
});

0 comments on commit 494c9fa

Please sign in to comment.