midas-edge 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 26505328048e0f4f78f7bba8bf8a9362fa2937623c199770b252ccead21e1cef
4
- data.tar.gz: 52b93dd03d32c353533b10efa459a149f67242d1430e786d0487a29974231807
3
+ metadata.gz: 21c556323034482b687c06ff507a7af020c5bdacf48bf9bd9ebc5c691ea79b1c
4
+ data.tar.gz: c9686a23cf785e7cea85d2eb4bb41243a49eac3420697d0e7eaa1be39272e26d
5
5
  SHA512:
6
- metadata.gz: 1075c67b8cbe336ac737d694464877a461251984ed3e22704cd87a3e9d04f29be262c38d030960243a28d9b6e327d7ea1615987c757976534526f7cedb265a84
7
- data.tar.gz: efba3c9e2def1feae8ced454c46a3a68d1285fd8fca53f230d967f57da61c47176e6319ed21b0925ff85750f12bd1e215382e87fe3eb592902e61ba481700414
6
+ metadata.gz: d895acee325aa21bdedcf295eaeb8a2993f62f383a2979eb1de14328f7dc8002dd06df068b2753068b43ee0d0adbf104925edc2eeafdbf5dbd1bccf6d7ede50b
7
+ data.tar.gz: b2bc93ca791413e1eccab0a08d99d01a1bfeea05966b31a9ff05a003cf61d1c0b6a3eb28e197d3be33fe93d2af96c8e2fc3f42afb9517f2979b6422eb1b9c117
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 0.6.0 (2026-04-07)
2
+
3
+ - Added `update` and `batch_update` methods
4
+ - Moved `directed` option to `fit_predict` and `partial_fit_predict` methods
5
+ - Removed dependency on `numo-narray`
6
+ - Dropped support for Ruby < 3.3
7
+
8
+ ## 0.5.1 (2026-02-07)
9
+
10
+ - Added `partial_fit_predict` method
11
+ - Reduced memory usage
12
+
1
13
  ## 0.5.0 (2025-04-03)
2
14
 
3
15
  - Dropped support for Ruby < 3.2
data/NOTICE.txt CHANGED
@@ -1,5 +1,5 @@
1
1
  Copyright 2020 Rui Liu (liurui39660) and Siddharth Bhatia (bhatiasiddharth)
2
- Copyright 2020-2023 Andrew Kane
2
+ Copyright 2020-2026 Andrew Kane
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIDAS Ruby
2
2
 
3
- [MIDAS](https://github.com/bhatiasiddharth/MIDAS) - edge stream anomaly detection - for Ruby
3
+ [MIDAS](https://github.com/Stream-AD/MIDAS) - edge stream anomaly detection - for Ruby
4
4
 
5
5
  [![Build Status](https://github.com/ankane/midas-ruby/actions/workflows/build.yml/badge.svg)](https://github.com/ankane/midas-ruby/actions)
6
6
 
@@ -14,67 +14,46 @@ gem "midas-edge"
14
14
 
15
15
  ## Getting Started
16
16
 
17
- Prep your data in the format `[source, destination, time]` (all integers) and sorted by time (ascending)
17
+ Create a detector
18
18
 
19
19
  ```ruby
20
- data = [
21
- [2, 3, 1],
22
- [3, 4, 2],
23
- [5, 9, 2],
24
- [2, 3, 3]
25
- ]
20
+ midas = Midas::Detector.new
26
21
  ```
27
22
 
28
- Get anomaly scores
23
+ Update with an event
29
24
 
30
25
  ```ruby
31
- midas = Midas.new
32
- scores = midas.fit_predict(data)
26
+ score = midas.update(source_id, destination_id, time)
33
27
  ```
34
28
 
35
- Higher scores are more anomalous. There is [not currently](https://github.com/bhatiasiddharth/MIDAS/issues/4) a defined threshold for anomalies.
29
+ IDs should be integers and events should be ordered by time (ascending). Higher scores are more anomalous. There is [not currently](https://github.com/Stream-AD/MIDAS/issues/4) a defined threshold for anomalies.
36
30
 
37
31
  ## Parameters
38
32
 
39
33
  Pass parameters - default values below
40
34
 
41
35
  ```ruby
42
- Midas.new(
36
+ Midas::Detector.new(
43
37
  rows: 2, # number of hash functions
44
38
  buckets: 769, # number of buckets
45
39
  alpha: 0.5, # temporal decay factor
46
40
  threshold: nil, # todo
47
41
  relations: true, # whether to use MIDAS-R or MIDAS
48
- directed: true, # treat the graph as directed or undirected
49
42
  seed: 0 # random seed
50
43
  )
51
44
  ```
52
45
 
53
- ## Data
54
-
55
- Data can be an array of arrays
56
-
57
- ```ruby
58
- [[1, 2, 3], [4, 5, 6]]
59
- ```
60
-
61
- Or a Numo array
62
-
63
- ```ruby
64
- Numo::NArray.cast([[1, 2, 3], [4, 5, 6]])
65
- ```
66
-
67
46
  ## Performance
68
47
 
69
48
  For large datasets, read data directly from files
70
49
 
71
50
  ```ruby
72
- midas.fit_predict("data.csv")
51
+ midas.batch_update("data.csv")
73
52
  ```
74
53
 
75
54
  ## Resources
76
55
 
77
- - [MIDAS: Microcluster-Based Detector of Anomalies in Edge Streams](https://www.comp.nus.edu.sg/~sbhatia/assets/pdf/midas.pdf)
56
+ - [MIDAS: Microcluster-Based Detector of Anomalies in Edge Streams](https://arxiv.org/pdf/1911.04464)
78
57
 
79
58
  ## History
80
59
 
data/ext/midas/ext.cpp CHANGED
@@ -1,6 +1,8 @@
1
1
  // stdlib
2
- #include <iostream>
3
- #include <vector>
2
+ #include <cstddef>
3
+ #include <cstdlib>
4
+ #include <fstream>
5
+ #include <string>
4
6
 
5
7
  // midas
6
8
  #include <FilteringCore.hpp>
@@ -9,121 +11,92 @@
9
11
 
10
12
  // rice
11
13
  #include <rice/rice.hpp>
12
- #include <rice/stl.hpp>
13
-
14
- // numo
15
- #include "numo.hpp"
16
-
17
- void load_array(std::vector<int>& src, std::vector<int>& dst, std::vector<int>& times, numo::Int32 input, bool directed) {
18
- auto shape = input.shape();
19
- if (input.ndim() != 2 || shape[1] != 3) {
20
- throw Rice::Exception(rb_eArgError, "Bad shape");
21
- }
22
-
23
- auto input_ptr = input.read_ptr();
24
- auto n = shape[0];
25
- auto sz = input.size();
26
-
27
- if (directed) {
28
- src.reserve(n);
29
- dst.reserve(n);
30
- times.reserve(n);
31
-
32
- for (size_t i = 0; i < sz; i += 3) {
33
- src.push_back(input_ptr[i]);
34
- dst.push_back(input_ptr[i + 1]);
35
- times.push_back(input_ptr[i + 2]);
36
- }
37
- } else {
38
- src.reserve(n * 2);
39
- dst.reserve(n * 2);
40
- times.reserve(n * 2);
41
-
42
- for (size_t i = 0; i < sz; i += 3) {
43
- src.push_back(input_ptr[i]);
44
- dst.push_back(input_ptr[i + 1]);
45
- times.push_back(input_ptr[i + 2]);
46
-
47
- src.push_back(input_ptr[i + 1]);
48
- dst.push_back(input_ptr[i]);
49
- times.push_back(input_ptr[i + 2]);
50
- }
51
- }
52
- }
53
14
 
54
15
  // load_data from main.cpp
55
16
  // modified to throw std::runtime_error when cannot find file
56
17
  // instead of exiting
57
- void load_file(std::vector<int>& src, std::vector<int>& dst, std::vector<int>& times, Rice::String input_file, bool directed) {
58
- FILE* infile = fopen(input_file.c_str(), "r");
59
- if (infile == NULL) {
60
- throw std::runtime_error("Could not read file: " + input_file.str());
18
+ template<typename T>
19
+ Rice::Array update_file(T& midas, Rice::String input_file, bool directed) {
20
+ std::ifstream infile(input_file.str());
21
+ if (!infile.is_open()) {
22
+ throw std::runtime_error{"Could not read file: " + input_file.str()};
61
23
  }
62
24
 
63
- int s, d, t;
25
+ Rice::Array result;
26
+ std::string line;
64
27
 
65
- if (directed) {
66
- while (fscanf(infile, "%d,%d,%d", &s, &d, &t) == 3) {
67
- src.push_back(s);
68
- dst.push_back(d);
69
- times.push_back(t);
28
+ while (std::getline(infile, line)) {
29
+ size_t n = line.find(',');
30
+ if (n == std::string::npos) {
31
+ throw std::runtime_error{"Invalid line"};
70
32
  }
71
- } else {
72
- while (fscanf(infile, "%d,%d,%d", &s, &d, &t) == 3) {
73
- src.push_back(s);
74
- dst.push_back(d);
75
- times.push_back(t);
76
33
 
77
- src.push_back(d);
78
- dst.push_back(s);
79
- times.push_back(t);
34
+ size_t n2 = line.find(',', n + 1);
35
+ if (n2 == std::string::npos) {
36
+ throw std::runtime_error{"Invalid line"};
80
37
  }
81
- }
82
-
83
- fclose(infile);
84
- }
85
38
 
86
- Rice::Object fit_predict(std::vector<int>& src, std::vector<int>& dst, std::vector<int>& times, int num_rows, int num_buckets, float factor, float threshold, bool relations, int seed) {
87
- srand(seed);
88
- size_t n = src.size();
39
+ int s = std::stoi(line.substr(0, n));
40
+ int d = std::stoi(line.substr(n + 1, n2 - n - 1));
41
+ int t = std::stoi(line.substr(n2 + 1));
89
42
 
90
- auto ary = numo::SFloat({n});
91
- auto result = ary.write_ptr();
92
-
93
- if (!std::isnan(threshold)) {
94
- MIDAS::FilteringCore midas(num_rows, num_buckets, threshold, factor);
95
- for (size_t i = 0; i < n; i++) {
96
- result[i] = midas(src[i], dst[i], times[i]);
97
- }
98
- } else if (relations) {
99
- MIDAS::RelationalCore midas(num_rows, num_buckets, factor);
100
- for (size_t i = 0; i < n; i++) {
101
- result[i] = midas(src[i], dst[i], times[i]);
102
- }
103
- } else {
104
- MIDAS::NormalCore midas(num_rows, num_buckets);
105
- for (size_t i = 0; i < n; i++) {
106
- result[i] = midas(src[i], dst[i], times[i]);
43
+ result.push(midas(s, d, t), false);
44
+ if (!directed) {
45
+ result.push(midas(d, s, t), false);
107
46
  }
108
47
  }
109
48
 
110
- return ary;
49
+ return result;
111
50
  }
112
51
 
113
52
  extern "C"
114
53
  void Init_ext() {
115
54
  auto rb_mMidas = Rice::define_module("Midas");
116
55
 
56
+ // TODO make seed part of Core classes
117
57
  Rice::define_class_under(rb_mMidas, "Detector")
118
58
  .define_function(
119
- "_fit_predict",
120
- [](Rice::Object input, int num_rows, int num_buckets, float factor, float threshold, bool relations, bool directed, int seed) {
121
- std::vector<int> src, dst, times;
122
- if (input.is_a(rb_cString)) {
123
- load_file(src, dst, times, input, directed);
124
- } else {
125
- load_array(src, dst, times, input, directed);
126
- }
127
- return fit_predict(src, dst, times, num_rows, num_buckets, factor, threshold, relations, seed);
59
+ "_set_seed",
60
+ [](int seed) {
61
+ std::srand(seed);
62
+ });
63
+
64
+ Rice::define_class_under<MIDAS::NormalCore>(rb_mMidas, "NormalCore")
65
+ .define_constructor(Rice::Constructor<MIDAS::NormalCore, int, int>())
66
+ .define_method(
67
+ "update",
68
+ [](MIDAS::NormalCore& self, int source, int destination, int time) {
69
+ return self(source, destination, time);
70
+ })
71
+ .define_method(
72
+ "update_file",
73
+ [](MIDAS::NormalCore& self, Rice::String input, bool directed) {
74
+ return update_file(self, input, directed);
75
+ });
76
+
77
+ Rice::define_class_under<MIDAS::RelationalCore>(rb_mMidas, "RelationalCore")
78
+ .define_constructor(Rice::Constructor<MIDAS::RelationalCore, int, int, float>())
79
+ .define_method(
80
+ "update",
81
+ [](MIDAS::RelationalCore& self, int source, int destination, int time) {
82
+ return self(source, destination, time);
83
+ })
84
+ .define_method(
85
+ "update_file",
86
+ [](MIDAS::RelationalCore& self, Rice::String input, bool directed) {
87
+ return update_file(self, input, directed);
88
+ });
89
+
90
+ Rice::define_class_under<MIDAS::FilteringCore>(rb_mMidas, "FilteringCore")
91
+ .define_constructor(Rice::Constructor<MIDAS::FilteringCore, int, int, float, float>())
92
+ .define_method(
93
+ "update",
94
+ [](MIDAS::FilteringCore& self, int source, int destination, int time) {
95
+ return self(source, destination, time);
96
+ })
97
+ .define_method(
98
+ "update_file",
99
+ [](MIDAS::FilteringCore& self, Rice::String input, bool directed) {
100
+ return update_file(self, input, directed);
128
101
  });
129
102
  }
data/ext/midas/extconf.rb CHANGED
@@ -1,15 +1,7 @@
1
1
  require "mkmf-rice"
2
- require "numo/narray"
3
2
 
4
3
  $CXXFLAGS << " -std=c++17 $(optflags)"
5
4
 
6
- numo = File.join(Gem.loaded_specs["numo-narray"].require_path, "numo")
7
- abort "Numo header not found" unless find_header("numo/narray.h", numo)
8
- abort "Numo library not found" if Gem.win_platform? && !find_library("narray", nil, numo)
9
-
10
- # for https://bugs.ruby-lang.org/issues/19005
11
- $LDFLAGS += " -Wl,-undefined,dynamic_lookup" if RbConfig::CONFIG["host_os"] =~ /darwin/i
12
-
13
5
  midas = File.expand_path("../../vendor/MIDAS/src", __dir__)
14
6
  abort "Midas not found" unless find_header("NormalCore.hpp", midas)
15
7
 
@@ -1,17 +1,64 @@
1
1
  module Midas
2
2
  class Detector
3
- def initialize(rows: 2, buckets: 769, alpha: 0.5, threshold: nil, relations: true, directed: true, seed: 0)
3
+ def initialize(
4
+ rows: 2,
5
+ buckets: 769,
6
+ alpha: 0.5,
7
+ threshold: nil,
8
+ relations: true,
9
+ seed: 0
10
+ )
4
11
  @rows = rows
5
12
  @buckets = buckets
6
13
  @alpha = alpha
7
14
  @threshold = threshold
8
15
  @relations = relations
9
- @directed = directed
10
16
  @seed = seed
11
17
  end
12
18
 
13
- def fit_predict(x)
14
- _fit_predict(x, @rows, @buckets, @alpha, @threshold || Float::NAN, @relations, @directed, @seed)
19
+ def update(source, destination, time)
20
+ @core ||= core
21
+ @core.update(source, destination, time.to_i)
22
+ end
23
+
24
+ def batch_update(x, directed: true)
25
+ if x.is_a?(String)
26
+ @core ||= core
27
+ @core.update_file(x, directed)
28
+ else
29
+ x = x.to_a
30
+ result = []
31
+ x.each do |v|
32
+ if !v.is_a?(Array) || v.size != 3
33
+ raise ArgumentError, "Bad shape"
34
+ end
35
+ result << update(v[0], v[1], v[2])
36
+ result << update(v[1], v[0], v[2]) if !directed
37
+ end
38
+ result
39
+ end
40
+ end
41
+
42
+ # legacy
43
+ alias_method :partial_fit_predict, :batch_update
44
+
45
+ # legacy
46
+ def fit_predict(x, directed: true)
47
+ @core = nil # reset core
48
+ batch_update(x, directed:)
49
+ end
50
+
51
+ private
52
+
53
+ def core
54
+ _set_seed(@seed)
55
+ if @threshold && !@threshold.to_f.nan?
56
+ FilteringCore.new(@rows, @buckets, @threshold, @alpha)
57
+ elsif @relations
58
+ RelationalCore.new(@rows, @buckets, @alpha)
59
+ else
60
+ NormalCore.new(@rows, @buckets)
61
+ end
15
62
  end
16
63
  end
17
64
  end
data/lib/midas/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Midas
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
data/lib/midas-edge.rb CHANGED
@@ -1,6 +1,3 @@
1
- # dependencies
2
- require "numo/narray"
3
-
4
1
  # ext
5
2
  require "midas/ext"
6
3
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: midas-edge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-03 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rice
@@ -15,28 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 4.3.3
18
+ version: '4.8'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 4.3.3
26
- - !ruby/object:Gem::Dependency
27
- name: numo-narray
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: '0'
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: '0'
25
+ version: '4.8'
40
26
  email: andrew@ankane.org
41
27
  executables: []
42
28
  extensions:
@@ -49,7 +35,6 @@ files:
49
35
  - README.md
50
36
  - ext/midas/ext.cpp
51
37
  - ext/midas/extconf.rb
52
- - ext/midas/numo.hpp
53
38
  - lib/midas-edge.rb
54
39
  - lib/midas/detector.rb
55
40
  - lib/midas/version.rb
@@ -70,14 +55,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
70
55
  requirements:
71
56
  - - ">="
72
57
  - !ruby/object:Gem::Version
73
- version: '3.2'
58
+ version: '3.3'
74
59
  required_rubygems_version: !ruby/object:Gem::Requirement
75
60
  requirements:
76
61
  - - ">="
77
62
  - !ruby/object:Gem::Version
78
63
  version: '0'
79
64
  requirements: []
80
- rubygems_version: 3.6.2
65
+ rubygems_version: 4.0.6
81
66
  specification_version: 4
82
67
  summary: Edge stream anomaly detection for Ruby
83
68
  test_files: []
data/ext/midas/numo.hpp DELETED
@@ -1,867 +0,0 @@
1
- /*!
2
- * Numo.hpp v0.1.0
3
- * https://github.com/ankane/numo.hpp
4
- * BSD-2-Clause License
5
- */
6
-
7
- #pragma once
8
-
9
- #include <rice/rice.hpp>
10
- #include <numo/narray.h>
11
-
12
- namespace numo {
13
- class NArray {
14
- public:
15
- NArray(VALUE v) {
16
- construct_value(this->dtype(), v);
17
- }
18
-
19
- NArray(Rice::Object o) {
20
- construct_value(this->dtype(), o.value());
21
- }
22
-
23
- VALUE value() const {
24
- return this->_value;
25
- }
26
-
27
- size_t ndim() {
28
- return RNARRAY_NDIM(this->_value);
29
- }
30
-
31
- size_t* shape() {
32
- return RNARRAY_SHAPE(this->_value);
33
- }
34
-
35
- size_t size() {
36
- return RNARRAY_SIZE(this->_value);
37
- }
38
-
39
- bool is_contiguous() {
40
- return nary_check_contiguous(this->_value) == Qtrue;
41
- }
42
-
43
- operator Rice::Object() const {
44
- return Rice::Object(this->_value);
45
- }
46
-
47
- const void* read_ptr() {
48
- if (!is_contiguous()) {
49
- this->_value = nary_dup(this->_value);
50
- }
51
- return nary_get_pointer_for_read(this->_value) + nary_get_offset(this->_value);
52
- }
53
-
54
- void* write_ptr() {
55
- return nary_get_pointer_for_write(this->_value);
56
- }
57
-
58
- protected:
59
- NArray() { }
60
-
61
- void construct_value(VALUE dtype, VALUE v) {
62
- this->_value = rb_funcall(dtype, rb_intern("cast"), 1, v);
63
- }
64
-
65
- void construct_shape(VALUE dtype, std::initializer_list<size_t> shape) {
66
- // rb_narray_new doesn't modify shape, but not marked as const
67
- this->_value = rb_narray_new(dtype, shape.size(), const_cast<size_t*>(shape.begin()));
68
- }
69
-
70
- VALUE _value;
71
-
72
- private:
73
- VALUE dtype() {
74
- return numo_cNArray;
75
- }
76
- };
77
-
78
- class SFloat: public NArray {
79
- public:
80
- SFloat(VALUE v) {
81
- construct_value(this->dtype(), v);
82
- }
83
-
84
- SFloat(Rice::Object o) {
85
- construct_value(this->dtype(), o.value());
86
- }
87
-
88
- SFloat(std::initializer_list<size_t> shape) {
89
- construct_shape(this->dtype(), shape);
90
- }
91
-
92
- const float* read_ptr() {
93
- return reinterpret_cast<const float*>(NArray::read_ptr());
94
- }
95
-
96
- float* write_ptr() {
97
- return reinterpret_cast<float*>(NArray::write_ptr());
98
- }
99
-
100
- private:
101
- VALUE dtype() {
102
- return numo_cSFloat;
103
- }
104
- };
105
-
106
- class DFloat: public NArray {
107
- public:
108
- DFloat(VALUE v) {
109
- construct_value(this->dtype(), v);
110
- }
111
-
112
- DFloat(Rice::Object o) {
113
- construct_value(this->dtype(), o.value());
114
- }
115
-
116
- DFloat(std::initializer_list<size_t> shape) {
117
- construct_shape(this->dtype(), shape);
118
- }
119
-
120
- const double* read_ptr() {
121
- return reinterpret_cast<const double*>(NArray::read_ptr());
122
- }
123
-
124
- double* write_ptr() {
125
- return reinterpret_cast<double*>(NArray::write_ptr());
126
- }
127
-
128
- private:
129
- VALUE dtype() {
130
- return numo_cDFloat;
131
- }
132
- };
133
-
134
- class Int8: public NArray {
135
- public:
136
- Int8(VALUE v) {
137
- construct_value(this->dtype(), v);
138
- }
139
-
140
- Int8(Rice::Object o) {
141
- construct_value(this->dtype(), o.value());
142
- }
143
-
144
- Int8(std::initializer_list<size_t> shape) {
145
- construct_shape(this->dtype(), shape);
146
- }
147
-
148
- const int8_t* read_ptr() {
149
- return reinterpret_cast<const int8_t*>(NArray::read_ptr());
150
- }
151
-
152
- int8_t* write_ptr() {
153
- return reinterpret_cast<int8_t*>(NArray::write_ptr());
154
- }
155
-
156
- private:
157
- VALUE dtype() {
158
- return numo_cInt8;
159
- }
160
- };
161
-
162
- class Int16: public NArray {
163
- public:
164
- Int16(VALUE v) {
165
- construct_value(this->dtype(), v);
166
- }
167
-
168
- Int16(Rice::Object o) {
169
- construct_value(this->dtype(), o.value());
170
- }
171
-
172
- Int16(std::initializer_list<size_t> shape) {
173
- construct_shape(this->dtype(), shape);
174
- }
175
-
176
- const int16_t* read_ptr() {
177
- return reinterpret_cast<const int16_t*>(NArray::read_ptr());
178
- }
179
-
180
- int16_t* write_ptr() {
181
- return reinterpret_cast<int16_t*>(NArray::write_ptr());
182
- }
183
-
184
- private:
185
- VALUE dtype() {
186
- return numo_cInt16;
187
- }
188
- };
189
-
190
- class Int32: public NArray {
191
- public:
192
- Int32(VALUE v) {
193
- construct_value(this->dtype(), v);
194
- }
195
-
196
- Int32(Rice::Object o) {
197
- construct_value(this->dtype(), o.value());
198
- }
199
-
200
- Int32(std::initializer_list<size_t> shape) {
201
- construct_shape(this->dtype(), shape);
202
- }
203
-
204
- const int32_t* read_ptr() {
205
- return reinterpret_cast<const int32_t*>(NArray::read_ptr());
206
- }
207
-
208
- int32_t* write_ptr() {
209
- return reinterpret_cast<int32_t*>(NArray::write_ptr());
210
- }
211
-
212
- private:
213
- VALUE dtype() {
214
- return numo_cInt32;
215
- }
216
- };
217
-
218
- class Int64: public NArray {
219
- public:
220
- Int64(VALUE v) {
221
- construct_value(this->dtype(), v);
222
- }
223
-
224
- Int64(Rice::Object o) {
225
- construct_value(this->dtype(), o.value());
226
- }
227
-
228
- Int64(std::initializer_list<size_t> shape) {
229
- construct_shape(this->dtype(), shape);
230
- }
231
-
232
- const int64_t* read_ptr() {
233
- return reinterpret_cast<const int64_t*>(NArray::read_ptr());
234
- }
235
-
236
- int64_t* write_ptr() {
237
- return reinterpret_cast<int64_t*>(NArray::write_ptr());
238
- }
239
-
240
- private:
241
- VALUE dtype() {
242
- return numo_cInt64;
243
- }
244
- };
245
-
246
- class UInt8: public NArray {
247
- public:
248
- UInt8(VALUE v) {
249
- construct_value(this->dtype(), v);
250
- }
251
-
252
- UInt8(Rice::Object o) {
253
- construct_value(this->dtype(), o.value());
254
- }
255
-
256
- UInt8(std::initializer_list<size_t> shape) {
257
- construct_shape(this->dtype(), shape);
258
- }
259
-
260
- const uint8_t* read_ptr() {
261
- return reinterpret_cast<const uint8_t*>(NArray::read_ptr());
262
- }
263
-
264
- uint8_t* write_ptr() {
265
- return reinterpret_cast<uint8_t*>(NArray::write_ptr());
266
- }
267
-
268
- private:
269
- VALUE dtype() {
270
- return numo_cUInt8;
271
- }
272
- };
273
-
274
- class UInt16: public NArray {
275
- public:
276
- UInt16(VALUE v) {
277
- construct_value(this->dtype(), v);
278
- }
279
-
280
- UInt16(Rice::Object o) {
281
- construct_value(this->dtype(), o.value());
282
- }
283
-
284
- UInt16(std::initializer_list<size_t> shape) {
285
- construct_shape(this->dtype(), shape);
286
- }
287
-
288
- const uint16_t* read_ptr() {
289
- return reinterpret_cast<const uint16_t*>(NArray::read_ptr());
290
- }
291
-
292
- uint16_t* write_ptr() {
293
- return reinterpret_cast<uint16_t*>(NArray::write_ptr());
294
- }
295
-
296
- private:
297
- VALUE dtype() {
298
- return numo_cUInt16;
299
- }
300
- };
301
-
302
- class UInt32: public NArray {
303
- public:
304
- UInt32(VALUE v) {
305
- construct_value(this->dtype(), v);
306
- }
307
-
308
- UInt32(Rice::Object o) {
309
- construct_value(this->dtype(), o.value());
310
- }
311
-
312
- UInt32(std::initializer_list<size_t> shape) {
313
- construct_shape(this->dtype(), shape);
314
- }
315
-
316
- const uint32_t* read_ptr() {
317
- return reinterpret_cast<const uint32_t*>(NArray::read_ptr());
318
- }
319
-
320
- uint32_t* write_ptr() {
321
- return reinterpret_cast<uint32_t*>(NArray::write_ptr());
322
- }
323
-
324
- private:
325
- VALUE dtype() {
326
- return numo_cUInt32;
327
- }
328
- };
329
-
330
- class UInt64: public NArray {
331
- public:
332
- UInt64(VALUE v) {
333
- construct_value(this->dtype(), v);
334
- }
335
-
336
- UInt64(Rice::Object o) {
337
- construct_value(this->dtype(), o.value());
338
- }
339
-
340
- UInt64(std::initializer_list<size_t> shape) {
341
- construct_shape(this->dtype(), shape);
342
- }
343
-
344
- const uint64_t* read_ptr() {
345
- return reinterpret_cast<const uint64_t*>(NArray::read_ptr());
346
- }
347
-
348
- uint64_t* write_ptr() {
349
- return reinterpret_cast<uint64_t*>(NArray::write_ptr());
350
- }
351
-
352
- private:
353
- VALUE dtype() {
354
- return numo_cUInt64;
355
- }
356
- };
357
-
358
- class SComplex: public NArray {
359
- public:
360
- SComplex(VALUE v) {
361
- construct_value(this->dtype(), v);
362
- }
363
-
364
- SComplex(Rice::Object o) {
365
- construct_value(this->dtype(), o.value());
366
- }
367
-
368
- SComplex(std::initializer_list<size_t> shape) {
369
- construct_shape(this->dtype(), shape);
370
- }
371
-
372
- private:
373
- VALUE dtype() {
374
- return numo_cSComplex;
375
- }
376
- };
377
-
378
- class DComplex: public NArray {
379
- public:
380
- DComplex(VALUE v) {
381
- construct_value(this->dtype(), v);
382
- }
383
-
384
- DComplex(Rice::Object o) {
385
- construct_value(this->dtype(), o.value());
386
- }
387
-
388
- DComplex(std::initializer_list<size_t> shape) {
389
- construct_shape(this->dtype(), shape);
390
- }
391
-
392
- private:
393
- VALUE dtype() {
394
- return numo_cDComplex;
395
- }
396
- };
397
-
398
- class Bit: public NArray {
399
- public:
400
- Bit(VALUE v) {
401
- construct_value(this->dtype(), v);
402
- }
403
-
404
- Bit(Rice::Object o) {
405
- construct_value(this->dtype(), o.value());
406
- }
407
-
408
- Bit(std::initializer_list<size_t> shape) {
409
- construct_shape(this->dtype(), shape);
410
- }
411
-
412
- private:
413
- VALUE dtype() {
414
- return numo_cBit;
415
- }
416
- };
417
-
418
- class RObject: public NArray {
419
- public:
420
- RObject(VALUE v) {
421
- construct_value(this->dtype(), v);
422
- }
423
-
424
- RObject(Rice::Object o) {
425
- construct_value(this->dtype(), o.value());
426
- }
427
-
428
- RObject(std::initializer_list<size_t> shape) {
429
- construct_shape(this->dtype(), shape);
430
- }
431
-
432
- const VALUE* read_ptr() {
433
- return reinterpret_cast<const VALUE*>(NArray::read_ptr());
434
- }
435
-
436
- VALUE* write_ptr() {
437
- return reinterpret_cast<VALUE*>(NArray::write_ptr());
438
- }
439
-
440
- private:
441
- VALUE dtype() {
442
- return numo_cRObject;
443
- }
444
- };
445
- }
446
-
447
- namespace Rice::detail {
448
- template<>
449
- struct Type<numo::NArray>
450
- {
451
- static bool verify()
452
- {
453
- return true;
454
- }
455
- };
456
-
457
- template<>
458
- class From_Ruby<numo::NArray>
459
- {
460
- public:
461
- numo::NArray convert(VALUE x)
462
- {
463
- return numo::NArray(x);
464
- }
465
- };
466
-
467
- template<>
468
- class To_Ruby<numo::NArray>
469
- {
470
- public:
471
- VALUE convert(const numo::NArray& x) {
472
- return x.value();
473
- }
474
- };
475
-
476
- template<>
477
- struct Type<numo::SFloat>
478
- {
479
- static bool verify()
480
- {
481
- return true;
482
- }
483
- };
484
-
485
- template<>
486
- class From_Ruby<numo::SFloat>
487
- {
488
- public:
489
- numo::SFloat convert(VALUE x)
490
- {
491
- return numo::SFloat(x);
492
- }
493
- };
494
-
495
- template<>
496
- class To_Ruby<numo::SFloat>
497
- {
498
- public:
499
- VALUE convert(const numo::SFloat& x) {
500
- return x.value();
501
- }
502
- };
503
-
504
- template<>
505
- struct Type<numo::DFloat>
506
- {
507
- static bool verify()
508
- {
509
- return true;
510
- }
511
- };
512
-
513
- template<>
514
- class From_Ruby<numo::DFloat>
515
- {
516
- public:
517
- numo::DFloat convert(VALUE x)
518
- {
519
- return numo::DFloat(x);
520
- }
521
- };
522
-
523
- template<>
524
- class To_Ruby<numo::DFloat>
525
- {
526
- public:
527
- VALUE convert(const numo::DFloat& x) {
528
- return x.value();
529
- }
530
- };
531
-
532
- template<>
533
- struct Type<numo::Int8>
534
- {
535
- static bool verify()
536
- {
537
- return true;
538
- }
539
- };
540
-
541
- template<>
542
- class From_Ruby<numo::Int8>
543
- {
544
- public:
545
- numo::Int8 convert(VALUE x)
546
- {
547
- return numo::Int8(x);
548
- }
549
- };
550
-
551
- template<>
552
- class To_Ruby<numo::Int8>
553
- {
554
- public:
555
- VALUE convert(const numo::Int8& x) {
556
- return x.value();
557
- }
558
- };
559
-
560
- template<>
561
- struct Type<numo::Int16>
562
- {
563
- static bool verify()
564
- {
565
- return true;
566
- }
567
- };
568
-
569
- template<>
570
- class From_Ruby<numo::Int16>
571
- {
572
- public:
573
- numo::Int16 convert(VALUE x)
574
- {
575
- return numo::Int16(x);
576
- }
577
- };
578
-
579
- template<>
580
- class To_Ruby<numo::Int16>
581
- {
582
- public:
583
- VALUE convert(const numo::Int16& x) {
584
- return x.value();
585
- }
586
- };
587
-
588
- template<>
589
- struct Type<numo::Int32>
590
- {
591
- static bool verify()
592
- {
593
- return true;
594
- }
595
- };
596
-
597
- template<>
598
- class From_Ruby<numo::Int32>
599
- {
600
- public:
601
- numo::Int32 convert(VALUE x)
602
- {
603
- return numo::Int32(x);
604
- }
605
- };
606
-
607
- template<>
608
- class To_Ruby<numo::Int32>
609
- {
610
- public:
611
- VALUE convert(const numo::Int32& x) {
612
- return x.value();
613
- }
614
- };
615
-
616
- template<>
617
- struct Type<numo::Int64>
618
- {
619
- static bool verify()
620
- {
621
- return true;
622
- }
623
- };
624
-
625
- template<>
626
- class From_Ruby<numo::Int64>
627
- {
628
- public:
629
- numo::Int64 convert(VALUE x)
630
- {
631
- return numo::Int64(x);
632
- }
633
- };
634
-
635
- template<>
636
- class To_Ruby<numo::Int64>
637
- {
638
- public:
639
- VALUE convert(const numo::Int64& x) {
640
- return x.value();
641
- }
642
- };
643
-
644
- template<>
645
- struct Type<numo::UInt8>
646
- {
647
- static bool verify()
648
- {
649
- return true;
650
- }
651
- };
652
-
653
- template<>
654
- class From_Ruby<numo::UInt8>
655
- {
656
- public:
657
- numo::UInt8 convert(VALUE x)
658
- {
659
- return numo::UInt8(x);
660
- }
661
- };
662
-
663
- template<>
664
- class To_Ruby<numo::UInt8>
665
- {
666
- public:
667
- VALUE convert(const numo::UInt8& x) {
668
- return x.value();
669
- }
670
- };
671
-
672
- template<>
673
- struct Type<numo::UInt16>
674
- {
675
- static bool verify()
676
- {
677
- return true;
678
- }
679
- };
680
-
681
- template<>
682
- class From_Ruby<numo::UInt16>
683
- {
684
- public:
685
- numo::UInt16 convert(VALUE x)
686
- {
687
- return numo::UInt16(x);
688
- }
689
- };
690
-
691
- template<>
692
- class To_Ruby<numo::UInt16>
693
- {
694
- public:
695
- VALUE convert(const numo::UInt16& x) {
696
- return x.value();
697
- }
698
- };
699
-
700
- template<>
701
- struct Type<numo::UInt32>
702
- {
703
- static bool verify()
704
- {
705
- return true;
706
- }
707
- };
708
-
709
- template<>
710
- class From_Ruby<numo::UInt32>
711
- {
712
- public:
713
- numo::UInt32 convert(VALUE x)
714
- {
715
- return numo::UInt32(x);
716
- }
717
- };
718
-
719
- template<>
720
- class To_Ruby<numo::UInt32>
721
- {
722
- public:
723
- VALUE convert(const numo::UInt32& x) {
724
- return x.value();
725
- }
726
- };
727
-
728
- template<>
729
- struct Type<numo::UInt64>
730
- {
731
- static bool verify()
732
- {
733
- return true;
734
- }
735
- };
736
-
737
- template<>
738
- class From_Ruby<numo::UInt64>
739
- {
740
- public:
741
- numo::UInt64 convert(VALUE x)
742
- {
743
- return numo::UInt64(x);
744
- }
745
- };
746
-
747
- template<>
748
- class To_Ruby<numo::UInt64>
749
- {
750
- public:
751
- VALUE convert(const numo::UInt64& x) {
752
- return x.value();
753
- }
754
- };
755
-
756
- template<>
757
- struct Type<numo::SComplex>
758
- {
759
- static bool verify()
760
- {
761
- return true;
762
- }
763
- };
764
-
765
- template<>
766
- class From_Ruby<numo::SComplex>
767
- {
768
- public:
769
- numo::SComplex convert(VALUE x)
770
- {
771
- return numo::SComplex(x);
772
- }
773
- };
774
-
775
- template<>
776
- class To_Ruby<numo::SComplex>
777
- {
778
- public:
779
- VALUE convert(const numo::SComplex& x) {
780
- return x.value();
781
- }
782
- };
783
-
784
- template<>
785
- struct Type<numo::DComplex>
786
- {
787
- static bool verify()
788
- {
789
- return true;
790
- }
791
- };
792
-
793
- template<>
794
- class From_Ruby<numo::DComplex>
795
- {
796
- public:
797
- numo::DComplex convert(VALUE x)
798
- {
799
- return numo::DComplex(x);
800
- }
801
- };
802
-
803
- template<>
804
- class To_Ruby<numo::DComplex>
805
- {
806
- public:
807
- VALUE convert(const numo::DComplex& x) {
808
- return x.value();
809
- }
810
- };
811
-
812
- template<>
813
- struct Type<numo::Bit>
814
- {
815
- static bool verify()
816
- {
817
- return true;
818
- }
819
- };
820
-
821
- template<>
822
- class From_Ruby<numo::Bit>
823
- {
824
- public:
825
- numo::Bit convert(VALUE x)
826
- {
827
- return numo::Bit(x);
828
- }
829
- };
830
-
831
- template<>
832
- class To_Ruby<numo::Bit>
833
- {
834
- public:
835
- VALUE convert(const numo::Bit& x) {
836
- return x.value();
837
- }
838
- };
839
-
840
- template<>
841
- struct Type<numo::RObject>
842
- {
843
- static bool verify()
844
- {
845
- return true;
846
- }
847
- };
848
-
849
- template<>
850
- class From_Ruby<numo::RObject>
851
- {
852
- public:
853
- numo::RObject convert(VALUE x)
854
- {
855
- return numo::RObject(x);
856
- }
857
- };
858
-
859
- template<>
860
- class To_Ruby<numo::RObject>
861
- {
862
- public:
863
- VALUE convert(const numo::RObject& x) {
864
- return x.value();
865
- }
866
- };
867
- }