numo-pocketfft 0.2.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4bd70edeb6b4247e01c8cc7cf439830a158518550f3c95c4ca5b502ae6ef7c2d
4
- data.tar.gz: 2ff73865a15805b7e8e69d55ac87f892d3d0e4aea9b0e2af7cd129b3fa489d63
3
+ metadata.gz: 9869e7964f7c3ace43a835f43318400b01051a2087f5392445ba22371ca16ef5
4
+ data.tar.gz: 4b2703db3b805fd135514b651a4d1d09f85dc0cede5333ae0f82faee74a72873
5
5
  SHA512:
6
- metadata.gz: ef1cfc56b929763495695a28855217292a65126cdbf7134aaa208334722b75456724e0196719932c7fedbcad2dc010e8d34d937c65554429992b623ed6bfdf9f
7
- data.tar.gz: '08917a93b37b1c81519a5ad11fde74585077eee3d80761b17a2cbac24b8a67b01ae48f1afdedf8aee8a872af28eaf3df48a6c06006a6b53f2ab0381941bd5573'
6
+ metadata.gz: dadb8c33ea4eab319eea76546116735be99558dee9c70777c76a77099e45b1689d7293903b875032782942f8e1ec427aa25a655a2a39e2fec2aabcd6ca9ae4f3
7
+ data.tar.gz: 8d8c2d1b153d84ca3dd03233d612ce28393f76b164ad42b968cbb705083eb0861fcfeb3ab56e09b2fab55ff137dd764745bbb91de0005fc42ce4a9a30b1dde3e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ # 0.4.0
2
+ - Refactor native extension codes with C99 style.
3
+ - Change not ot use git submodule for pocketfft codes bundle.
4
+ - Introduce conventional commits.
5
+
6
+ # 0.3.2
7
+ - Update type declaration file.
8
+ - Remove dependent gem's type declaration file from installation files.
9
+
10
+ # 0.3.1
11
+ - Fix version specifier of runtime dependencies.
12
+
13
+ # 0.3.0
14
+ - Add type declaration file: sig/numo/pocketfft.rbs
15
+ - Refactor to avoid generating unnecessary arrays.
16
+
1
17
  # 0.2.2
2
18
  - Fix bug that caused segmentation fault due to garbage collection ([#4](https://github.com/yoshoku/numo-pocketfft/pull/4)).
3
19
  - Fix some configuration files.
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2019-2021 Atsushi Tatsuma
1
+ Copyright (c) 2019-2022 Atsushi Tatsuma
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Numo::Pocketfft
2
2
 
3
3
  [![Build Status](https://github.com/yoshoku/numo-pocketfft/workflows/build/badge.svg)](https://github.com/yoshoku/numo-pocketfft/actions?query=workflow%3Abuild)
4
- [![Coverage Status](https://coveralls.io/repos/github/yoshoku/numo-pocketfft/badge.svg?branch=master)](https://coveralls.io/github/yoshoku/numo-pocketfft?branch=master)
4
+ [![Coverage Status](https://coveralls.io/repos/github/yoshoku/numo-pocketfft/badge.svg?branch=main)](https://coveralls.io/github/yoshoku/numo-pocketfft?branch=main)
5
5
  [![Gem Version](https://badge.fury.io/rb/numo-pocketfft.svg)](https://badge.fury.io/rb/numo-pocketfft)
6
6
  [![BSD 3-Clause License](https://img.shields.io/badge/License-BSD%203--Clause-orange.svg)](https://github.com/yoshoku/numo-pocketfft/blob/main/LICENSE.txt)
7
7
  [![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](https://yoshoku.github.io/numo-pocketfft/doc/)
@@ -59,12 +59,6 @@ Numo::Pocketfft.ifft2(Numo::Pocketfft.fft2(c))
59
59
  # [0.794815+0.539948i, 0.201042+0.737815i]]
60
60
  ```
61
61
 
62
- ## Development
63
-
64
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
65
-
66
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
67
-
68
62
  ## Contributing
69
63
 
70
64
  Bug reports and pull requests are welcome on GitHub at https://github.com/yoshoku/numo-pocketfft. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
@@ -72,7 +66,3 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/yoshok
72
66
  ## License
73
67
 
74
68
  The gem is available as open source under the terms of the [BSD-3-Clause License](https://opensource.org/licenses/BSD-3-Clause).
75
-
76
- ## Code of Conduct
77
-
78
- Everyone interacting in the Numo::Pocketfft project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/yoshoku/numo-pocketfft/blob/main/CODE_OF_CONDUCT.md).
@@ -28,12 +28,7 @@ end
28
28
 
29
29
  $CFLAGS = "#{$CFLAGS} -std=c99"
30
30
 
31
- $srcs = Dir.glob("#{$srcdir}/*.c").map { |path| File.basename(path) }
32
- $srcs << 'pocketfft.c'
33
- Dir.glob("#{$srcdir}/*/") do |path|
34
- dir = File.basename(path)
35
- $INCFLAGS << " -I$(srcdir)/#{dir}"
36
- $VPATH << "$(srcdir)/#{dir}"
37
- end
31
+ $srcs = Dir.glob("#{$srcdir}/**/*.c").map { |path| File.basename(path) }
32
+ $VPATH << "$(srcdir)/src"
38
33
 
39
34
  create_makefile('numo/pocketfft/pocketfftext')
@@ -3,22 +3,7 @@
3
3
  VALUE mNumo;
4
4
  VALUE mPocketfft;
5
5
 
6
- VALUE numo_pocketfft_fft(VALUE x_val, int is_forward)
7
- {
8
- narray_t* x_nary;
9
- double* x_pt;
10
- size_t length;
11
- int n_dims;
12
- int n_repeats;
13
- int i;
14
- int res;
15
- int fail;
16
- double fct;
17
- VALUE z_val;
18
- double* z_pt;
19
- narray_t* z_nary;
20
- cfft_plan plan = NULL;
21
-
6
+ VALUE numo_pocketfft_fft(VALUE x_val, int is_forward) {
22
7
  if (CLASS_OF(x_val) != numo_cDComplex) {
23
8
  x_val = rb_funcall(numo_cDComplex, rb_intern("cast"), 1, x_val);
24
9
  }
@@ -26,29 +11,30 @@ VALUE numo_pocketfft_fft(VALUE x_val, int is_forward)
26
11
  x_val = nary_dup(x_val);
27
12
  }
28
13
 
14
+ narray_t* x_nary;
29
15
  GetNArray(x_val, x_nary);
30
- n_dims = NA_NDIM(x_nary);
31
- length = NA_SHAPE(x_nary)[n_dims - 1];
32
- x_pt = (double*)na_get_pointer_for_read(x_val);
16
+ int n_dims = NA_NDIM(x_nary);
17
+ size_t length = NA_SHAPE(x_nary)[n_dims - 1];
18
+ double* x_pt = (double*)na_get_pointer_for_read(x_val);
33
19
 
34
- plan = make_cfft_plan(length);
20
+ cfft_plan plan = make_cfft_plan(length);
35
21
  if (!plan) {
36
22
  rb_raise(rb_eNoMemError, "Failed to allocate memory for plan of pocketfft.");
37
23
  return Qnil;
38
24
  }
39
25
 
40
- z_val = nary_s_new_like(numo_cDComplex, x_val);
41
- z_pt = (double*)na_get_pointer_for_write(z_val);
26
+ VALUE z_val = nary_s_new_like(numo_cDComplex, x_val);
27
+ double* z_pt = (double*)na_get_pointer_for_write(z_val);
28
+ narray_t* z_nary;
42
29
  GetNArray(z_val, z_nary);
43
- for (i = 0; i < (int)(NA_SIZE(z_nary) * 2); z_pt[i++] = 0.0);
30
+ memset(z_pt, 0, (NA_SIZE(z_nary) * 2) * sizeof(double));
44
31
 
45
- fail = 0;
46
- fct = is_forward == 1 ? 1.0 : 1.0 / length;
47
- n_repeats = (int)(NA_SIZE(x_nary)) / length;
48
- for (i = 0; i < n_repeats; i++) {
32
+ int fail = 0;
33
+ double fct = is_forward == 1 ? 1.0 : 1.0 / length;
34
+ int n_repeats = (int)(NA_SIZE(x_nary)) / length;
35
+ for (int i = 0; i < n_repeats; i++) {
49
36
  memcpy(z_pt, x_pt, 2 * length * sizeof(double));
50
- res = is_forward == 1 ? cfft_forward(plan, z_pt, fct) : cfft_backward(plan, z_pt, fct);
51
- if (res != 0) {
37
+ if ((is_forward == 1 ? cfft_forward(plan, z_pt, fct) : cfft_backward(plan, z_pt, fct)) != 0) {
52
38
  fail = 1;
53
39
  break;
54
40
  }
@@ -63,8 +49,8 @@ VALUE numo_pocketfft_fft(VALUE x_val, int is_forward)
63
49
  RB_GC_GUARD(x_val);
64
50
 
65
51
  if (fail) {
66
- rb_raise(rb_eNoMemError, "Failed to allocate memory in function of pocketfft.");
67
52
  rb_funcall(z_val, rb_intern("free"), 0);
53
+ rb_raise(rb_eNoMemError, "Failed to allocate memory in function of pocketfft.");
68
54
  return Qnil;
69
55
  }
70
56
 
@@ -74,38 +60,17 @@ VALUE numo_pocketfft_fft(VALUE x_val, int is_forward)
74
60
  /**
75
61
  * @!visibility private
76
62
  */
77
- static VALUE numo_pocketfft_cfft(VALUE self, VALUE x_val)
78
- {
79
- return numo_pocketfft_fft(x_val, 1);
80
- }
63
+ static VALUE numo_pocketfft_cfft(VALUE self, VALUE x_val) { return numo_pocketfft_fft(x_val, 1); }
81
64
 
82
65
  /**
83
66
  * @!visibility private
84
67
  */
85
- static VALUE numo_pocketfft_icfft(VALUE self, VALUE x_val)
86
- {
87
- return numo_pocketfft_fft(x_val, 0);
88
- }
68
+ static VALUE numo_pocketfft_icfft(VALUE self, VALUE x_val) { return numo_pocketfft_fft(x_val, 0); }
89
69
 
90
70
  /**
91
71
  * @!visibility private
92
72
  */
93
- static VALUE numo_pocketfft_rfft(VALUE self, VALUE x_val)
94
- {
95
- narray_t* x_nary;
96
- double* x_pt;
97
- int n_dims;
98
- size_t length;
99
- int n_repeats;
100
- int i;
101
- int fail;
102
- size_t* z_shape;
103
- VALUE z_val;
104
- narray_t* z_nary;
105
- double* z_pt;
106
- int z_step;
107
- rfft_plan plan = NULL;
108
-
73
+ static VALUE numo_pocketfft_rfft(VALUE self, VALUE x_val) {
109
74
  if (CLASS_OF(x_val) != numo_cDFloat) {
110
75
  x_val = rb_funcall(numo_cDFloat, rb_intern("cast"), 1, x_val);
111
76
  }
@@ -113,31 +78,32 @@ static VALUE numo_pocketfft_rfft(VALUE self, VALUE x_val)
113
78
  x_val = nary_dup(x_val);
114
79
  }
115
80
 
81
+ narray_t* x_nary;
116
82
  GetNArray(x_val, x_nary);
117
- n_dims = NA_NDIM(x_nary);
118
- length = NA_SHAPE(x_nary)[n_dims - 1];
119
- x_pt = (double*)na_get_pointer_for_read(x_val);
83
+ int n_dims = NA_NDIM(x_nary);
84
+ size_t length = NA_SHAPE(x_nary)[n_dims - 1];
85
+ double* x_pt = (double*)na_get_pointer_for_read(x_val);
120
86
 
121
- plan = make_rfft_plan(length);
87
+ rfft_plan plan = make_rfft_plan(length);
122
88
  if (!plan) {
123
89
  rb_raise(rb_eNoMemError, "Failed to allocate memory for plan of pocketfft.");
124
90
  return Qnil;
125
91
  }
126
92
 
127
- z_shape = ALLOCA_N(size_t, n_dims);
128
- for (i = 0; i < n_dims - 1; i++) {
93
+ size_t* z_shape = ALLOCA_N(size_t, n_dims);
94
+ for (int i = 0; i < n_dims - 1; i++)
129
95
  z_shape[i] = NA_SHAPE(x_nary)[i];
130
- }
131
96
  z_shape[n_dims - 1] = length / 2 + 1;
132
- z_val = rb_narray_new(numo_cDComplex, n_dims, z_shape);
133
- z_pt = (double*)na_get_pointer_for_write(z_val);
97
+ VALUE z_val = rb_narray_new(numo_cDComplex, n_dims, z_shape);
98
+ double* z_pt = (double*)na_get_pointer_for_write(z_val);
99
+ narray_t* z_nary;
134
100
  GetNArray(z_val, z_nary);
135
- for (i = 0; i < (int)(NA_SIZE(z_nary) * 2); z_pt[i++] = 0.0);
101
+ memset(z_pt, 0, (NA_SIZE(z_nary) * 2) * sizeof(double));
136
102
 
137
- fail = 0;
138
- z_step = (int)(NA_SHAPE(z_nary)[n_dims - 1]) * 2;
139
- n_repeats = (int)(NA_SIZE(x_nary)) / length;
140
- for (i = 0; i < n_repeats; i++) {
103
+ int fail = 0;
104
+ int z_step = (int)(NA_SHAPE(z_nary)[n_dims - 1]) * 2;
105
+ int n_repeats = (int)(NA_SIZE(x_nary)) / length;
106
+ for (int i = 0; i < n_repeats; i++) {
141
107
  z_pt[z_step - 1] = 0.0;
142
108
  memcpy(z_pt + 1, x_pt, length * sizeof(double));
143
109
  if (rfft_forward(plan, z_pt + 1, 1.0) != 0) {
@@ -157,8 +123,8 @@ static VALUE numo_pocketfft_rfft(VALUE self, VALUE x_val)
157
123
  RB_GC_GUARD(x_val);
158
124
 
159
125
  if (fail) {
160
- rb_raise(rb_eNoMemError, "Failed to allocate memory in function of pocketfft.");
161
126
  rb_funcall(z_val, rb_intern("free"), 0);
127
+ rb_raise(rb_eNoMemError, "Failed to allocate memory in function of pocketfft.");
162
128
  return Qnil;
163
129
  }
164
130
 
@@ -168,22 +134,7 @@ static VALUE numo_pocketfft_rfft(VALUE self, VALUE x_val)
168
134
  /**
169
135
  * @!visibility private
170
136
  */
171
- static VALUE numo_pocketfft_irfft(VALUE self, VALUE x_val)
172
- {
173
- narray_t* x_nary;
174
- double* x_pt;
175
- size_t length;
176
- int n_dims;
177
- int n_repeats;
178
- int i;
179
- int fail;
180
- double fct;
181
- size_t* z_shape;
182
- VALUE z_val;
183
- double* z_pt;
184
- narray_t* z_nary;
185
- rfft_plan plan = NULL;
186
-
137
+ static VALUE numo_pocketfft_irfft(VALUE self, VALUE x_val) {
187
138
  if (CLASS_OF(x_val) != numo_cDComplex) {
188
139
  x_val = rb_funcall(numo_cDComplex, rb_intern("cast"), 1, x_val);
189
140
  }
@@ -191,31 +142,33 @@ static VALUE numo_pocketfft_irfft(VALUE self, VALUE x_val)
191
142
  x_val = nary_dup(x_val);
192
143
  }
193
144
 
145
+ narray_t* x_nary;
194
146
  GetNArray(x_val, x_nary);
195
- n_dims = NA_NDIM(x_nary);
196
- length = NA_SHAPE(x_nary)[n_dims - 1];
197
- x_pt = (double*)na_get_pointer_for_read(x_val);
147
+ int n_dims = NA_NDIM(x_nary);
148
+ size_t length = NA_SHAPE(x_nary)[n_dims - 1];
149
+ double* x_pt = (double*)na_get_pointer_for_read(x_val);
198
150
 
199
- plan = make_rfft_plan(length);
151
+ rfft_plan plan = make_rfft_plan(length);
200
152
  if (!plan) {
201
153
  rb_raise(rb_eNoMemError, "Failed to allocate memory for plan of pocketfft.");
202
154
  return Qnil;
203
155
  }
204
156
 
205
- z_shape = ALLOCA_N(size_t, n_dims);
206
- for (i = 0; i < n_dims - 1; i++) {
157
+ size_t* z_shape = ALLOCA_N(size_t, n_dims);
158
+ for (int i = 0; i < n_dims - 1; i++) {
207
159
  z_shape[i] = NA_SHAPE(x_nary)[i];
208
160
  }
209
161
  z_shape[n_dims - 1] = length;
210
- z_val = rb_narray_new(numo_cDFloat, n_dims, z_shape);
211
- z_pt = (double*)na_get_pointer_for_write(z_val);
162
+ VALUE z_val = rb_narray_new(numo_cDFloat, n_dims, z_shape);
163
+ double* z_pt = (double*)na_get_pointer_for_write(z_val);
164
+ narray_t* z_nary;
212
165
  GetNArray(z_val, z_nary);
213
- for (i = 0; i < (int)NA_SIZE(z_nary); z_pt[i++] = 0.0);
166
+ memset(z_pt, 0, NA_SIZE(z_nary) * sizeof(double));
214
167
 
215
- fail = 0;
216
- fct = 1.0 / length;
217
- n_repeats = (int)(NA_SIZE(z_nary)) / length;
218
- for (i = 0; i < n_repeats; i++) {
168
+ int fail = 0;
169
+ double fct = 1.0 / length;
170
+ int n_repeats = (int)(NA_SIZE(z_nary)) / length;
171
+ for (int i = 0; i < n_repeats; i++) {
219
172
  memcpy(z_pt + 1, x_pt + 2, (length - 1) * sizeof(double));
220
173
  z_pt[0] = x_pt[0];
221
174
  if (rfft_backward(plan, z_pt, fct) != 0) {
@@ -233,16 +186,15 @@ static VALUE numo_pocketfft_irfft(VALUE self, VALUE x_val)
233
186
  RB_GC_GUARD(x_val);
234
187
 
235
188
  if (fail) {
236
- rb_raise(rb_eNoMemError, "Failed to allocate memory in function of pocketfft.");
237
189
  rb_funcall(z_val, rb_intern("free"), 0);
190
+ rb_raise(rb_eNoMemError, "Failed to allocate memory in function of pocketfft.");
238
191
  return Qnil;
239
192
  }
240
193
 
241
194
  return z_val;
242
195
  }
243
196
 
244
- void Init_pocketfftext()
245
- {
197
+ void Init_pocketfftext() {
246
198
  rb_require("numo/narray");
247
199
 
248
200
  mNumo = rb_define_module("Numo");
@@ -5,9 +5,10 @@
5
5
  #include <string.h>
6
6
 
7
7
  #include <ruby.h>
8
+
8
9
  #include <numo/narray.h>
9
10
  #include <numo/template.h>
10
11
 
11
- #include "pocketfft/pocketfft.h"
12
+ #include "src/pocketfft.h"
12
13
 
13
14
  #endif /* NUMO_POCKETFFT_H */
File without changes
File without changes
File without changes
@@ -5,6 +5,6 @@ module Numo
5
5
  # Numo::Pocketfft is the module that has functions for Fourier transform.
6
6
  module Pocketfft
7
7
  # The version of Numo::Pocketfft you are using.
8
- VERSION = '0.2.2'
8
+ VERSION = '0.4.0'
9
9
  end
10
10
  end
@@ -64,8 +64,11 @@ module Numo
64
64
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
65
65
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
66
66
 
67
- b = a.dup
68
- (0...b.ndim).to_a.reverse.each { |ax_id| b = raw_fft(b, ax_id, inverse: false, real: false) }
67
+ return raw_fft(a, 0, inverse: false, real: false) if a.ndim == 1
68
+
69
+ last_axis_id = a.ndim - 1
70
+ b = raw_fft(a, last_axis_id, inverse: false, real: false)
71
+ (last_axis_id - 1).downto(0) { |ax_id| b = raw_fft(b, ax_id, inverse: false, real: false) }
69
72
  b
70
73
  end
71
74
 
@@ -77,8 +80,11 @@ module Numo
77
80
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
78
81
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
79
82
 
80
- b = a.dup
81
- (0...b.ndim).to_a.each { |ax_id| b = raw_fft(b, ax_id, inverse: true, real: false) }
83
+ return raw_fft(a, 0, inverse: true, real: false) if a.ndim == 1
84
+
85
+ last_axis_id = a.ndim - 1
86
+ b = raw_fft(a, 0, inverse: true, real: false)
87
+ 1.upto(last_axis_id) { |ax_id| b = raw_fft(b, ax_id, inverse: true, real: false) }
82
88
  b
83
89
  end
84
90
 
@@ -138,9 +144,11 @@ module Numo
138
144
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
139
145
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
140
146
 
147
+ return raw_fft(a, 0, inverse: false, real: true) if a.ndim == 1
148
+
141
149
  last_axis_id = a.ndim - 1
142
150
  b = raw_fft(a, last_axis_id, inverse: false, real: true)
143
- (0...last_axis_id).to_a.reverse.each { |ax_id| b = raw_fft(b, ax_id, inverse: false, real: false) }
151
+ (last_axis_id - 1).downto(0) { |ax_id| b = raw_fft(b, ax_id, inverse: false, real: false) }
144
152
  b
145
153
  end
146
154
 
@@ -152,9 +160,11 @@ module Numo
152
160
  raise ArgumentError, 'Expect class of input array to be Numo::NArray.' unless a.is_a?(Numo::NArray)
153
161
  raise ArgumentError, 'Expect input array to be non-empty.' if a.empty?
154
162
 
163
+ return raw_fft(a, 0, inverse: true, real: true) if a.ndim == 1
164
+
155
165
  last_axis_id = a.ndim - 1
156
- b = a.dup
157
- (0...last_axis_id).to_a.each { |ax_id| b = raw_fft(b, ax_id, inverse: true, real: false) }
166
+ b = raw_fft(a, 0, inverse: true, real: false)
167
+ 1.upto(last_axis_id - 1) { |ax_id| b = raw_fft(b, ax_id, inverse: true, real: false) }
158
168
  raw_fft(b, last_axis_id, inverse: true, real: true)
159
169
  end
160
170
 
@@ -209,8 +219,7 @@ module Numo
209
219
  b_shape = a.shape
210
220
  b_shape[-1] = n
211
221
  b = Numo::DComplex.zeros(*b_shape)
212
- b_range = [true] * b.ndim
213
- b_range[-1] = 0...a.shape[-1]
222
+ b_range = Array.new(b.ndim) { |idx| idx < b.ndim - 1 ? true : 0...a.shape[-1] }
214
223
  b[*b_range] = a
215
224
  # inverse of dft for real data
216
225
  ext_irfft(b)
@@ -0,0 +1,28 @@
1
+ module Numo
2
+ module Pocketfft
3
+ VERSION: String
4
+
5
+ def self?.fft: (Numo::DFloat | Numo::DComplex a) -> Numo::DComplex
6
+ def self?.fft2: (Numo::DFloat | Numo::DComplex a) -> Numo::DComplex
7
+ def self?.fftn: (Numo::DFloat | Numo::DComplex a) -> Numo::DComplex
8
+ def self?.ifft: (Numo::DComplex a) -> Numo::DComplex
9
+ def self?.ifft2: (Numo::DComplex a) -> Numo::DComplex
10
+ def self?.ifftn: (Numo::DComplex a) -> Numo::DComplex
11
+ def self?.rfft: (Numo::DFloat a) -> Numo::DComplex
12
+ def self?.rfft2: (Numo::DFloat a) -> Numo::DComplex
13
+ def self?.rfftn: (Numo::DFloat a) -> Numo::DComplex
14
+ def self?.irfft: (Numo::DComplex a) -> Numo::DFloat
15
+ def self?.irfft2: (Numo::DComplex a) -> Numo::DFloat
16
+ def self?.irfftn: (Numo::DComplex a) -> Numo::DFloat
17
+ def self?.fftconvolve: (Numo::DFloat | Numo::DComplex a, Numo::DFloat | Numo::DComplex b) -> Numo::DComplex
18
+ | (Numo::DFloat a, Numo::DFloat b) -> Numo::DFloat
19
+
20
+ private
21
+
22
+ def self?.ext_cfft: (Numo::DComplex a) -> Numo::DComplex
23
+ def self?.ext_icfft: (Numo::DComplex a) -> Numo::DComplex
24
+ def self?.ext_rfft: (Numo::DFloat a) -> Numo::DComplex
25
+ def self?.ext_irfft: (Numo::DComplex a) -> Numo::DFloat
26
+ def self?.raw_fft: (untyped a, Integer axis_id, inverse: bool inverse, real: bool real) -> untyped
27
+ end
28
+ end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: numo-pocketfft
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yoshoku
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-16 00:00:00.000000000 Z
11
+ date: 2022-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: numo-narray
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.9.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.9.1
27
27
  description: 'Numo::Pocketfft provides functions for descrete Fourier Transform based
@@ -35,31 +35,18 @@ extensions:
35
35
  - ext/numo/pocketfft/extconf.rb
36
36
  extra_rdoc_files: []
37
37
  files:
38
- - ".coveralls.yml"
39
- - ".github/workflows/build.yml"
40
- - ".github/workflows/coverage.yml"
41
- - ".gitignore"
42
- - ".gitmodules"
43
- - ".rspec"
44
38
  - CHANGELOG.md
45
- - CODE_OF_CONDUCT.md
46
- - Gemfile
47
39
  - LICENSE.txt
48
40
  - README.md
49
- - Rakefile
50
41
  - ext/numo/pocketfft/extconf.rb
51
- - ext/numo/pocketfft/pocketfft/.gitlab-ci.yml
52
- - ext/numo/pocketfft/pocketfft/LICENSE.md
53
- - ext/numo/pocketfft/pocketfft/README.md
54
- - ext/numo/pocketfft/pocketfft/TESTING
55
- - ext/numo/pocketfft/pocketfft/ffttest.c
56
- - ext/numo/pocketfft/pocketfft/pocketfft.c
57
- - ext/numo/pocketfft/pocketfft/pocketfft.h
58
42
  - ext/numo/pocketfft/pocketfftext.c
59
43
  - ext/numo/pocketfft/pocketfftext.h
44
+ - ext/numo/pocketfft/src/LICENSE.md
45
+ - ext/numo/pocketfft/src/pocketfft.c
46
+ - ext/numo/pocketfft/src/pocketfft.h
60
47
  - lib/numo/pocketfft.rb
61
48
  - lib/numo/pocketfft/version.rb
62
- - numo-pocketfft.gemspec
49
+ - sig/numo/pocketfft.rbs
63
50
  homepage: https://github.com/yoshoku/numo-pocketfft
64
51
  licenses:
65
52
  - BSD-3-Clause
@@ -84,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
71
  - !ruby/object:Gem::Version
85
72
  version: '0'
86
73
  requirements: []
87
- rubygems_version: 3.1.4
74
+ rubygems_version: 3.2.32
88
75
  signing_key:
89
76
  specification_version: 4
90
77
  summary: Numo::Pocketfft provides functions for descrete Fourier Transform based on
data/.coveralls.yml DELETED
@@ -1 +0,0 @@
1
- service_name: github-ci
@@ -1,27 +0,0 @@
1
- name: build
2
-
3
- on: [push, pull_request]
4
-
5
- jobs:
6
- build:
7
- runs-on: ubuntu-20.04
8
- strategy:
9
- matrix:
10
- ruby: [ '2.5', '2.6', '2.7' ]
11
- steps:
12
- - uses: actions/checkout@v2
13
- - name: Checkout submodule
14
- shell: bash
15
- run: |
16
- auth_header="$(git config --local --get http.https://github.com/.extraheader)"
17
- git submodule sync --recursive
18
- git submodule update --init --force --recursive
19
- - name: Set up Ruby ${{ matrix.ruby }}
20
- uses: actions/setup-ruby@v1
21
- with:
22
- ruby-version: ${{ matrix.ruby }}
23
- - name: Build and test with Rake
24
- run: |
25
- gem install bundler
26
- bundle install --jobs 4 --retry 3
27
- bundle exec rake
@@ -1,32 +0,0 @@
1
- name: coverage
2
-
3
- on:
4
- push:
5
- branches: [ main ]
6
- pull_request:
7
- branches: [ main ]
8
-
9
- jobs:
10
- coverage:
11
- runs-on: ubuntu-20.04
12
- steps:
13
- - uses: actions/checkout@v2
14
- - name: Checkout submodule
15
- shell: bash
16
- run: |
17
- auth_header="$(git config --local --get http.https://github.com/.extraheader)"
18
- git submodule sync --recursive
19
- git submodule update --init --force --recursive
20
- - name: Set up Ruby 2.7
21
- uses: actions/setup-ruby@v1
22
- with:
23
- ruby-version: '2.7'
24
- - name: Build and test with Rake
25
- run: |
26
- gem install bundler
27
- bundle install
28
- bundle exec rake
29
- - name: Coveralls GitHub Action
30
- uses: coverallsapp/github-action@v1.1.2
31
- with:
32
- github-token: ${{ secrets.GITHUB_TOKEN }}
data/.gitignore DELETED
@@ -1,20 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- /bin/
11
-
12
- # rspec failure tracking
13
- .rspec_status
14
-
15
- *.swp
16
- *.bundle
17
- mkmf.log
18
- tags
19
- .DS_Store
20
- .ruby-version
data/.gitmodules DELETED
@@ -1,4 +0,0 @@
1
- [submodule "ext/numo/pocketfft/pocketfft"]
2
- path = ext/numo/pocketfft/pocketfft
3
- url = https://gitlab.mpcdf.mpg.de/mtr/pocketfft.git
4
- ignore = dirty
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/CODE_OF_CONDUCT.md DELETED
@@ -1,74 +0,0 @@
1
- # Contributor Covenant Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- In the interest of fostering an open and welcoming environment, we as
6
- contributors and maintainers pledge to making participation in our project and
7
- our community a harassment-free experience for everyone, regardless of age, body
8
- size, disability, ethnicity, gender identity and expression, level of experience,
9
- nationality, personal appearance, race, religion, or sexual identity and
10
- orientation.
11
-
12
- ## Our Standards
13
-
14
- Examples of behavior that contributes to creating a positive environment
15
- include:
16
-
17
- * Using welcoming and inclusive language
18
- * Being respectful of differing viewpoints and experiences
19
- * Gracefully accepting constructive criticism
20
- * Focusing on what is best for the community
21
- * Showing empathy towards other community members
22
-
23
- Examples of unacceptable behavior by participants include:
24
-
25
- * The use of sexualized language or imagery and unwelcome sexual attention or
26
- advances
27
- * Trolling, insulting/derogatory comments, and personal or political attacks
28
- * Public or private harassment
29
- * Publishing others' private information, such as a physical or electronic
30
- address, without explicit permission
31
- * Other conduct which could reasonably be considered inappropriate in a
32
- professional setting
33
-
34
- ## Our Responsibilities
35
-
36
- Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
39
-
40
- Project maintainers have the right and responsibility to remove, edit, or
41
- reject comments, commits, code, wiki edits, issues, and other contributions
42
- that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
44
- threatening, offensive, or harmful.
45
-
46
- ## Scope
47
-
48
- This Code of Conduct applies both within project spaces and in public spaces
49
- when an individual is representing the project or its community. Examples of
50
- representing a project or community include using an official project e-mail
51
- address, posting via an official social media account, or acting as an appointed
52
- representative at an online or offline event. Representation of a project may be
53
- further defined and clarified by project maintainers.
54
-
55
- ## Enforcement
56
-
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at yoshoku@outlook.com. All
59
- complaints will be reviewed and investigated and will result in a response that
60
- is deemed necessary and appropriate to the circumstances. The project team is
61
- obligated to maintain confidentiality with regard to the reporter of an incident.
62
- Further details of specific enforcement policies may be posted separately.
63
-
64
- Project maintainers who do not follow or enforce the Code of Conduct in good
65
- faith may face temporary or permanent repercussions as determined by other
66
- members of the project's leadership.
67
-
68
- ## Attribution
69
-
70
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at [http://contributor-covenant.org/version/1/4][version]
72
-
73
- [homepage]: http://contributor-covenant.org
74
- [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile DELETED
@@ -1,10 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in numo-pocketfft.gemspec
4
- gemspec
5
-
6
- gem 'rake', '~> 12.0'
7
- gem 'rake-compiler', '~> 1.0'
8
- gem 'rspec', '~> 3.0'
9
- gem 'simplecov', '~> 0.19'
10
- gem 'simplecov-lcov', '~> 0.8'
data/Rakefile DELETED
@@ -1,16 +0,0 @@
1
- require 'bundler/gem_tasks'
2
- require 'rspec/core/rake_task'
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- require 'rake/extensiontask'
7
-
8
- task :build => :compile
9
-
10
- Rake::ExtensionTask.new('pocketfftext') do |ext|
11
- ext.ext_dir = 'ext/numo/pocketfft'
12
- ext.lib_dir = 'lib/numo/pocketfft'
13
- end
14
-
15
- task :default => [:clobber, :compile, :spec]
16
-
@@ -1,12 +0,0 @@
1
- image: debian:testing-slim
2
-
3
- stages:
4
- - testing
5
-
6
- test:
7
- stage: testing
8
- script:
9
- - apt-get update
10
- - apt-get install -y gcc
11
- - gcc -O3 -W -Wall -std=c99 -march=native *.c -lm
12
- - ./a.out
@@ -1,55 +0,0 @@
1
- PocketFFT
2
- ---------
3
-
4
- This is a heavily modified implementation of FFTPack [1,2], with the following
5
- advantages:
6
-
7
- - strictly C99 compliant
8
- - more accurate twiddle factor computation
9
- - very fast plan generation
10
- - worst case complexity for transform sizes with large prime factors is
11
- `N*log(N)`, because Bluestein's algorithm [3] is used for these cases.
12
-
13
- License
14
- -------
15
-
16
- 3-clause BSD (see LICENSE.md)
17
-
18
-
19
- Some code details
20
- -----------------
21
-
22
- Twiddle factor computation:
23
-
24
- - making use of symmetries to reduce number of sin/cos evaluations
25
- - all angles are reduced to the range `[0; pi/4]` for higher accuracy
26
- - an adapted implementation of `sincospi()` is used, which actually computes
27
- `sin(x)` and `(cos(x)-1)`.
28
- - if `n` sin/cos pairs are required, the adjusted `sincospi()` is only called
29
- `2*sqrt(n)` times; the remaining values are obtained by evaluating the
30
- angle addition theorems in a numerically accurate way.
31
-
32
- Parallel invocation:
33
-
34
- - Plans only contain read-only data; all temporary arrays are allocated and
35
- deallocated during an individual FFT execution. This means that a single plan
36
- can be used in several threads at the same time.
37
-
38
- Efficient codelets are available for the factors:
39
-
40
- - 2, 3, 4, 5, 7, 11 for complex-valued FFTs
41
- - 2, 3, 4, 5 for real-valued FFTs
42
-
43
- Larger prime factors are handled by somewhat less efficient, generic routines.
44
-
45
- For lengths with very large prime factors, Bluestein's algorithm is used, and
46
- instead of an FFT of length `n`, a convolution of length `n2 >= 2*n-1`
47
- is performed, where `n2` is chosen to be highly composite.
48
-
49
-
50
- [1] Swarztrauber, P. 1982, Vectorizing the Fast Fourier Transforms
51
- (New York: Academic Press), 51
52
-
53
- [2] https://www.netlib.org/fftpack/
54
-
55
- [3] https://en.wikipedia.org/wiki/Chirp_Z-transform
@@ -1,6 +0,0 @@
1
- To run a quick test for all FFT sizes up to 8192, do
2
-
3
- gcc -std=c99 -O2 -W -Wall *.c -lm
4
- ./a.out
5
-
6
- If there is no output, the tests have succeeded.
@@ -1,96 +0,0 @@
1
- /*
2
- * This file is part of pocketfft.
3
- * Licensed under a 3-clause BSD style license - see LICENSE.md
4
- */
5
-
6
- /*
7
- * Test codes for pocketfft.
8
- *
9
- * Copyright (C) 2004-2018 Max-Planck-Society
10
- * \author Martin Reinecke
11
- */
12
-
13
- #include <stdio.h>
14
- #include <stdlib.h>
15
- #include <math.h>
16
- #include <string.h>
17
- #include "pocketfft.h"
18
-
19
- #define maxlen 8192
20
-
21
- static void fill_random (double *data, size_t length)
22
- {
23
- for (size_t m=0; m<length; ++m)
24
- data[m] = rand()/(RAND_MAX+1.0)-0.5;
25
- }
26
-
27
- static double errcalc (double *data, double *odata, size_t length)
28
- {
29
- double sum = 0, errsum = 0;
30
- for (size_t m=0; m<length; ++m)
31
- {
32
- errsum += (data[m]-odata[m])*(data[m]-odata[m]);
33
- sum += odata[m]*odata[m];
34
- }
35
- return sqrt(errsum/sum);
36
- }
37
-
38
- static int test_real(void)
39
- {
40
- double data[maxlen], odata[maxlen];
41
- const double epsilon=2e-15;
42
- int ret = 0;
43
- fill_random (odata, maxlen);
44
- double errsum=0;
45
- for (int length=1; length<=maxlen; ++length)
46
- {
47
- memcpy (data,odata,length*sizeof(double));
48
- rfft_plan plan = make_rfft_plan (length);
49
- rfft_forward (plan, data, 1.);
50
- rfft_backward (plan, data, 1./length);
51
- destroy_rfft_plan (plan);
52
- double err = errcalc (data, odata, length);
53
- if (err>epsilon)
54
- {
55
- printf("problem at real length %i: %e\n",length,err);
56
- ret = 1;
57
- }
58
- errsum+=err;
59
- }
60
- printf("errsum: %e\n",errsum);
61
- return ret;
62
- }
63
-
64
- static int test_complex(void)
65
- {
66
- double data[2*maxlen], odata[2*maxlen];
67
- fill_random (odata, 2*maxlen);
68
- const double epsilon=2e-15;
69
- int ret = 0;
70
- double errsum=0;
71
- for (int length=1; length<=maxlen; ++length)
72
- {
73
- memcpy (data,odata,2*length*sizeof(double));
74
- cfft_plan plan = make_cfft_plan (length);
75
- cfft_forward(plan, data, 1.);
76
- cfft_backward(plan, data, 1./length);
77
- destroy_cfft_plan (plan);
78
- double err = errcalc (data, odata, 2*length);
79
- if (err>epsilon)
80
- {
81
- printf("problem at complex length %i: %e\n",length,err);
82
- ret = 1;
83
- }
84
- errsum+=err;
85
- }
86
- printf("errsum: %e\n",errsum);
87
- return ret;
88
- }
89
-
90
- int main(void)
91
- {
92
- int ret = 0;
93
- ret = test_real();
94
- ret += test_complex();
95
- return ret;
96
- }
@@ -1,49 +0,0 @@
1
- lib = File.expand_path('lib', __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require 'numo/pocketfft/version'
4
-
5
- Gem::Specification.new do |spec|
6
- spec.name = 'numo-pocketfft'
7
- spec.version = Numo::Pocketfft::VERSION
8
- spec.authors = ['yoshoku']
9
- spec.email = ['yoshoku@outlook.com']
10
-
11
- spec.summary = <<~MSG
12
- Numo::Pocketfft provides functions for descrete Fourier Transform based on pocketfft.
13
- MSG
14
- spec.description = <<~MSG
15
- Numo::Pocketfft provides functions for descrete Fourier Transform based on pocketfft.
16
- MSG
17
- spec.homepage = 'https://github.com/yoshoku/numo-pocketfft'
18
- spec.license = 'BSD-3-Clause'
19
-
20
- # Specify which files should be added to the gem when it is released.
21
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
- end
25
-
26
- # Add files in submodule: https://gist.github.com/mattconnolly/5875987
27
- gem_dir = __dir__ + '/'
28
- `git submodule --quiet foreach pwd`.split($OUTPUT_RECORD_SEPARATOR).each do |submodule_path|
29
- Dir.chdir(submodule_path) do
30
- submodule_relative_path = submodule_path.sub gem_dir, ''
31
- `git ls-files`.split($OUTPUT_RECORD_SEPARATOR).each do |filename|
32
- spec.files << "#{submodule_relative_path}/#{filename}"
33
- end
34
- end
35
- end
36
-
37
- spec.require_paths = ['lib']
38
- spec.extensions = ['ext/numo/pocketfft/extconf.rb']
39
-
40
- spec.metadata = {
41
- 'homepage_uri' => 'https://github.com/yoshoku/numo-pocketfft',
42
- 'changelog_uri' => 'https://github.com/yoshoku/numo-pocketfft/blob/main/CHANGELOG.md',
43
- 'source_code_uri' => 'https://github.com/yoshoku/numo-pocketfft',
44
- 'documentation_uri' => 'https://yoshoku.github.io/numo-pocketfft/doc/',
45
- 'bug_tracker_uri' => 'https://github.com/yoshoku/numo-pocketfft/issues'
46
- }
47
-
48
- spec.add_runtime_dependency 'numo-narray', '~> 0.9.1'
49
- end