nmatrix-fftw 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nmatrix/data/complex.h +388 -0
  3. data/ext/nmatrix/data/data.h +652 -0
  4. data/ext/nmatrix/data/meta.h +64 -0
  5. data/ext/nmatrix/data/ruby_object.h +389 -0
  6. data/ext/nmatrix/math/asum.h +120 -0
  7. data/ext/nmatrix/math/cblas_enums.h +36 -0
  8. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  9. data/ext/nmatrix/math/gemm.h +241 -0
  10. data/ext/nmatrix/math/gemv.h +178 -0
  11. data/ext/nmatrix/math/getrf.h +255 -0
  12. data/ext/nmatrix/math/getrs.h +121 -0
  13. data/ext/nmatrix/math/imax.h +79 -0
  14. data/ext/nmatrix/math/laswp.h +165 -0
  15. data/ext/nmatrix/math/long_dtype.h +49 -0
  16. data/ext/nmatrix/math/math.h +745 -0
  17. data/ext/nmatrix/math/nrm2.h +160 -0
  18. data/ext/nmatrix/math/rot.h +117 -0
  19. data/ext/nmatrix/math/rotg.h +106 -0
  20. data/ext/nmatrix/math/scal.h +71 -0
  21. data/ext/nmatrix/math/trsm.h +332 -0
  22. data/ext/nmatrix/math/util.h +148 -0
  23. data/ext/nmatrix/nm_memory.h +60 -0
  24. data/ext/nmatrix/nmatrix.h +438 -0
  25. data/ext/nmatrix/ruby_constants.h +106 -0
  26. data/ext/nmatrix/storage/common.h +177 -0
  27. data/ext/nmatrix/storage/dense/dense.h +129 -0
  28. data/ext/nmatrix/storage/list/list.h +138 -0
  29. data/ext/nmatrix/storage/storage.h +99 -0
  30. data/ext/nmatrix/storage/yale/class.h +1139 -0
  31. data/ext/nmatrix/storage/yale/iterators/base.h +143 -0
  32. data/ext/nmatrix/storage/yale/iterators/iterator.h +131 -0
  33. data/ext/nmatrix/storage/yale/iterators/row.h +450 -0
  34. data/ext/nmatrix/storage/yale/iterators/row_stored.h +140 -0
  35. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +169 -0
  36. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +124 -0
  37. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  38. data/ext/nmatrix/storage/yale/yale.h +203 -0
  39. data/ext/nmatrix/types.h +55 -0
  40. data/ext/nmatrix/util/io.h +115 -0
  41. data/ext/nmatrix/util/sl_list.h +144 -0
  42. data/ext/nmatrix/util/util.h +78 -0
  43. data/ext/nmatrix_fftw/extconf.rb +122 -0
  44. data/ext/nmatrix_fftw/nmatrix_fftw.cpp +274 -0
  45. data/lib/nmatrix/fftw.rb +343 -0
  46. data/spec/00_nmatrix_spec.rb +736 -0
  47. data/spec/01_enum_spec.rb +190 -0
  48. data/spec/02_slice_spec.rb +389 -0
  49. data/spec/03_nmatrix_monkeys_spec.rb +78 -0
  50. data/spec/2x2_dense_double.mat +0 -0
  51. data/spec/4x4_sparse.mat +0 -0
  52. data/spec/4x5_dense.mat +0 -0
  53. data/spec/blas_spec.rb +193 -0
  54. data/spec/elementwise_spec.rb +303 -0
  55. data/spec/homogeneous_spec.rb +99 -0
  56. data/spec/io/fortran_format_spec.rb +88 -0
  57. data/spec/io/harwell_boeing_spec.rb +98 -0
  58. data/spec/io/test.rua +9 -0
  59. data/spec/io_spec.rb +149 -0
  60. data/spec/lapack_core_spec.rb +482 -0
  61. data/spec/leakcheck.rb +16 -0
  62. data/spec/math_spec.rb +807 -0
  63. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  64. data/spec/nmatrix_yale_spec.rb +286 -0
  65. data/spec/plugins/fftw/fftw_spec.rb +348 -0
  66. data/spec/rspec_monkeys.rb +56 -0
  67. data/spec/rspec_spec.rb +34 -0
  68. data/spec/shortcuts_spec.rb +310 -0
  69. data/spec/slice_set_spec.rb +157 -0
  70. data/spec/spec_helper.rb +149 -0
  71. data/spec/stat_spec.rb +203 -0
  72. data/spec/test.pcd +20 -0
  73. data/spec/utm5940.mtx +83844 -0
  74. metadata +151 -0
@@ -0,0 +1,78 @@
1
+ /////////////////////////////////////////////////////////////////////
2
+ // = NMatrix
3
+ //
4
+ // A linear algebra library for scientific computation in Ruby.
5
+ // NMatrix is part of SciRuby.
6
+ //
7
+ // NMatrix was originally inspired by and derived from NArray, by
8
+ // Masahiro Tanaka: http://narray.rubyforge.org
9
+ //
10
+ // == Copyright Information
11
+ //
12
+ // SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
+ // NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
14
+ //
15
+ // Please see LICENSE.txt for additional copyright notices.
16
+ //
17
+ // == Contributing
18
+ //
19
+ // By contributing source code to SciRuby, you agree to be bound by
20
+ // our Contributor Agreement:
21
+ //
22
+ // * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
23
+ //
24
+ // == util.h
25
+ //
26
+ // Header file for utility functions and data.
27
+
28
+ #ifndef UTIL_H
29
+ #define UTIL_H
30
+
31
+ /*
32
+ * Standard Includes
33
+ */
34
+
35
+ /*
36
+ * Project Includes
37
+ */
38
+
39
+ #include "types.h"
40
+
41
+ /*
42
+ * Macros
43
+ */
44
+
45
+ /*
46
+ * Types
47
+ */
48
+
49
+ /*
50
+ * Data
51
+ */
52
+
53
+ /*
54
+ * Functions
55
+ */
56
+ namespace nm {
57
+ template <typename Type>
58
+ inline Type gcf(Type x, Type y) {
59
+ Type t;
60
+
61
+ if (x < 0) x = -x;
62
+ if (y < 0) y = -y;
63
+
64
+ if (x == 0) return y;
65
+ if (y == 0) return x;
66
+
67
+ while (x > 0) {
68
+ t = x;
69
+ x = y % x;
70
+ y = t;
71
+ }
72
+
73
+ return y;
74
+ }
75
+ } // end of namespace nm
76
+
77
+
78
+ #endif // UTIL_H
@@ -0,0 +1,122 @@
1
+ # = NMatrix
2
+ #
3
+ # A linear algebra library for scientific computation in Ruby.
4
+ # NMatrix is part of SciRuby.
5
+ #
6
+ # NMatrix was originally inspired by and derived from NArray, by
7
+ # Masahiro Tanaka: http://narray.rubyforge.org
8
+ #
9
+ # == Copyright Information
10
+ #
11
+ # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
12
+ # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
13
+ #
14
+ # Please see LICENSE.txt for additional copyright notices.
15
+ #
16
+ # == Contributing
17
+ #
18
+ # By contributing source code to SciRuby, you agree to be bound by
19
+ # our Contributor Agreement:
20
+ #
21
+ # * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
22
+ #
23
+ # == nmatrix_fftw/extconf.rb
24
+ #
25
+ # This file checks FFTW3 and other necessary headers/shared objects.
26
+
27
+ require 'mkmf'
28
+
29
+ # Function derived from NArray's extconf.rb.
30
+ def create_conf_h(file) #:nodoc:
31
+ print "creating #{file}\n"
32
+ File.open(file, 'w') do |hfile|
33
+ header_guard = file.upcase.sub(/\s|\./, '_')
34
+
35
+ hfile.puts "#ifndef #{header_guard}"
36
+ hfile.puts "#define #{header_guard}"
37
+ hfile.puts
38
+
39
+ # FIXME: Find a better way to do this:
40
+ hfile.puts "#define RUBY_2 1" if RUBY_VERSION >= '2.0'
41
+
42
+ for line in $defs
43
+ line =~ /^-D(.*)/
44
+ hfile.printf "#define %s 1\n", $1
45
+ end
46
+
47
+ hfile.puts
48
+ hfile.puts "#endif"
49
+ end
50
+ end
51
+
52
+ def find_newer_gplusplus #:nodoc:
53
+ print "checking for apparent GNU g++ binary with C++0x/C++11 support... "
54
+ [9,8,7,6,5,4,3].each do |minor|
55
+ ver = "4.#{minor}"
56
+ gpp = "g++-#{ver}"
57
+ result = `which #{gpp}`
58
+ next if result.empty?
59
+ CONFIG['CXX'] = gpp
60
+ puts ver
61
+ return CONFIG['CXX']
62
+ end
63
+ false
64
+ end
65
+
66
+ def gplusplus_version
67
+ cxxvar = proc { |n| `#{CONFIG['CXX']} -E -dM - </dev/null | grep #{n}`.chomp.split(' ')[2] }
68
+ major = cxxvar.call('__GNUC__')
69
+ minor = cxxvar.call('__GNUC_MINOR__')
70
+ patch = cxxvar.call('__GNUC_PATCHLEVEL__')
71
+
72
+ raise("unable to determine g++ version (match to get version was nil)") if major.nil? || minor.nil? || patch.nil?
73
+
74
+ "#{major}.#{minor}.#{patch}"
75
+ end
76
+
77
+ fftw_libdir = RbConfig::CONFIG['libdir']
78
+ fftw_incdir = RbConfig::CONFIG['includedir']
79
+ fftw_srcdir = RbConfig::CONFIG['srcdir']
80
+
81
+ $CFLAGS = ["-Wall -Werror=return-type -I$(srcdir)/../nmatrix -I$(srcdir)/lapacke/include",$CFLAGS].join(" ")
82
+ $CXXFLAGS = ["-Wall -Werror=return-type -I$(srcdir)/../nmatrix -I$(srcdir)/lapacke/include -std=c++11",$CXXFLAGS].join(" ")
83
+ $CPPFLAGS = ["-Wall -Werror=return-type -I$(srcdir)/../nmatrix -I$(srcdir)/lapacke/include -std=c++11",$CPPFLAGS].join(" ")
84
+
85
+ CONFIG['CXX'] = 'g++'
86
+
87
+ if CONFIG['CXX'] == 'clang++'
88
+ $CPP_STANDARD = 'c++11'
89
+ else
90
+ version = gplusplus_version
91
+ if version < '4.3.0' && CONFIG['CXX'] == 'g++' # see if we can find a newer G++, unless it's been overridden by user
92
+ if !find_newer_gplusplus
93
+ raise("You need a version of g++ which supports -std=c++0x or -std=c++11. If you're on a Mac and using Homebrew, we recommend using mac-brew-gcc.sh to install a more recent g++.")
94
+ end
95
+ version = gplusplus_version
96
+ end
97
+
98
+ if version < '4.7.0'
99
+ $CPP_STANDARD = 'c++0x'
100
+ else
101
+ $CPP_STANDARD = 'c++11'
102
+ end
103
+ puts "using C++ standard... #{$CPP_STANDARD}"
104
+ puts "g++ reports version... " + `#{CONFIG['CXX']} --version|head -n 1|cut -f 3 -d " "`
105
+ end
106
+
107
+ flags = " --include=#{fftw_incdir} --libdir=#{fftw_libdir}"
108
+
109
+ if have_library("fftw3")
110
+ $CFLAGS += [" -lfftw3 -lm #{$CFLAGS} #{$flags}"].join(" ")
111
+ dir_config('nmatrix_fftw', fftw_incdir, fftw_libdir)
112
+ dir_config('nmatrix_fftw')
113
+ end
114
+
115
+ create_conf_h("nmatrix_fftw_config.h")
116
+ create_makefile("nmatrix_fftw")
117
+
118
+ # to clean up object files in subdirectories:
119
+ open('Makefile', 'a') do |f|
120
+ clean_objs_paths = %w{ }.map { |d| "#{d}/*.#{CONFIG["OBJEXT"]}" }
121
+ f.write("CLEANOBJS := $(CLEANOBJS) #{clean_objs_paths.join(' ')}")
122
+ end
@@ -0,0 +1,274 @@
1
+ /////////////////////////////////////////////////////////////////////
2
+ // = NMatrix
3
+ //
4
+ // A linear algebra library for scientific computation in Ruby.
5
+ // NMatrix is part of SciRuby.
6
+ //
7
+ // NMatrix was originally inspired by and derived from NArray, by
8
+ // Masahiro Tanaka: http://narray.rubyforge.org
9
+ //
10
+ // == Copyright Information
11
+ //
12
+ // SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
+ // NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
14
+ //
15
+ // Please see LICENSE.txt for additional copyright notices.
16
+ //
17
+ // == Contributing
18
+ //
19
+ // By contributing source code to SciRuby, you agree to be bound by
20
+ // our Contributor Agreement:
21
+ //
22
+ // * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
23
+ //
24
+ // == nmatrix_fftw.cpp
25
+ //
26
+ // Main file for nmatrix_fftw extension
27
+ //
28
+
29
+ #include <ruby.h>
30
+ #include <complex.h>
31
+ #include <fftw3.h>
32
+ #include "storage/common.h"
33
+ #include "nmatrix.h"
34
+ #include <iostream>
35
+
36
+ #define TYPE_COMPLEX_COMPLEX 0
37
+ #define TYPE_REAL_COMPLEX 1
38
+ #define TYPE_COMPLEX_REAL 2
39
+ #define TYPE_REAL_REAL 3
40
+
41
+ // @private Used internally by the C API.
42
+ static VALUE cNMatrix_FFTW_Plan_Data;
43
+
44
+ // @private Used internally by the C API.
45
+ //
46
+ // ADT for encapsulating various data structures required for sucessfully planning
47
+ // and executing a fourier transform with FFTW. Uses void* pointers because
48
+ // input/output can be either double or fftw_complex depending on the type of
49
+ // FFT being planned.
50
+ struct fftw_data {
51
+ void* input;
52
+ void* output;
53
+ fftw_plan plan;
54
+ };
55
+
56
+ // @private Used internally by the C API.
57
+ // Method used by Ruby GC for freeing memory allocated by FFTW.
58
+ static void nm_fftw_cleanup(fftw_data* d)
59
+ {
60
+ xfree(d->input);
61
+ xfree(d->output);
62
+ fftw_destroy_plan(d->plan);
63
+ xfree(d);
64
+ }
65
+
66
+ // @private Used internally by the C API.
67
+ // Used for converting a Ruby Array containing the shape to a C++ array of ints.
68
+ static int* nm_fftw_interpret_shape(VALUE rb_shape, const int dimensions)
69
+ {
70
+ Check_Type(rb_shape, T_ARRAY);
71
+
72
+ int *shape = new int[dimensions];
73
+ const VALUE *arr = RARRAY_CONST_PTR(rb_shape);
74
+
75
+ for (int i = 0; i < dimensions; ++i) {
76
+ shape[i] = FIX2INT(arr[i]);
77
+ }
78
+
79
+ return shape;
80
+ }
81
+
82
+ // @private Used internally by the C API.
83
+ // Convert values passed in Ruby Array containing kinds of real-real transforms
84
+ // to a C array of ints.
85
+ static void
86
+ nm_fftw_interpret_real_real_kind(VALUE real_real_kind, int *r2r_kinds)
87
+ {
88
+ int size = RARRAY_LEN(real_real_kind);
89
+ const VALUE *a = RARRAY_CONST_PTR(real_real_kind);
90
+ for (int i = 0; i < size; ++i) {
91
+ r2r_kinds[i] = FIX2INT(a[i]);
92
+ }
93
+ }
94
+
95
+ // @private Used internally by the C API.
96
+ // Actually calls the FFTW planner routines based on the input/output and the
97
+ // type of routine selected. Also allocates memory for input and output pointers.
98
+ static void nm_fftw_actually_create_plan(fftw_data* data,
99
+ size_t size, const int dimensions, const int* shape, int sign, unsigned flags,
100
+ VALUE rb_type, VALUE real_real_kind)
101
+ {
102
+ switch (FIX2INT(rb_type))
103
+ {
104
+ case TYPE_COMPLEX_COMPLEX:
105
+ data->input = ALLOC_N(fftw_complex, size);
106
+ data->output = ALLOC_N(fftw_complex, size);
107
+ data->plan = fftw_plan_dft(dimensions, shape, (fftw_complex*)data->input,
108
+ (fftw_complex*)data->output, sign, flags);
109
+ break;
110
+ case TYPE_REAL_COMPLEX:
111
+ data->input = ALLOC_N(double , size);
112
+ data->output = ALLOC_N(fftw_complex, size);
113
+ data->plan = fftw_plan_dft_r2c(dimensions, shape, (double*)data->input,
114
+ (fftw_complex*)data->output, flags);
115
+ break;
116
+ case TYPE_COMPLEX_REAL:
117
+ data->input = ALLOC_N(fftw_complex, size);
118
+ data->output = ALLOC_N(double , size);
119
+ data->plan = fftw_plan_dft_c2r(dimensions, shape, (fftw_complex*)data->input,
120
+ (double*)data->output, flags);
121
+ break;
122
+ case TYPE_REAL_REAL:
123
+ int* r2r_kinds = ALLOC_N(int, FIX2INT(real_real_kind));
124
+ nm_fftw_interpret_real_real_kind(real_real_kind, r2r_kinds);
125
+ data->input = ALLOC_N(double, size);
126
+ data->output = ALLOC_N(double, size);
127
+ data->plan = fftw_plan_r2r(dimensions, shape, (double*)data->input,
128
+ (double*)data->output, (fftw_r2r_kind*)r2r_kinds, flags);
129
+ xfree(r2r_kinds);
130
+ break;
131
+ }
132
+ }
133
+
134
+ /** \brief Create a plan for performing the fourier transform based on input,
135
+ * output pointers and the underlying hardware.
136
+ *
137
+ * @param[in] self Object on which the function is called
138
+ * @param[in] rb_shape Shape of the plan.
139
+ * @param[in] rb_size Size of the plan.
140
+ * @param[in] rb_dim Dimension of the FFT to be performed.
141
+ * @param[in] rb_flags Number denoting the planner flags.
142
+ * @param[in] rb_direction Direction of FFT (can be -1 or +1). Specifies the
143
+ * sign of the exponent.
144
+ * @param[in] rb_type Number specifying the type of FFT being planned (one
145
+ * of :complex_complex, :complex_real, :real_complex and :real_real)
146
+ * @param[in] rb_real_real_kind Ruby Array specifying the kind of DFT to perform over
147
+ * each axis in case of a real input/real output FFT.
148
+ *
149
+ * \returns An object of type NMatrix::FFTW::Plan::Data that encapsulates the
150
+ * plan and relevant input/output arrays.
151
+ */
152
+ static VALUE nm_fftw_create_plan(VALUE self, VALUE rb_shape, VALUE rb_size,
153
+ VALUE rb_dim, VALUE rb_flags, VALUE rb_direction, VALUE rb_type, VALUE rb_real_real_kind)
154
+ {
155
+ const int dimensions = FIX2INT(rb_dim);
156
+ const int* shape = nm_fftw_interpret_shape(rb_shape, dimensions);
157
+ size_t size = FIX2INT(rb_size);
158
+ int sign = FIX2INT(rb_direction);
159
+ unsigned flags = FIX2INT(rb_flags);
160
+ fftw_data *data = ALLOC(fftw_data);
161
+
162
+ nm_fftw_actually_create_plan(data, size, dimensions, shape,
163
+ sign, flags, rb_type, rb_real_real_kind);
164
+
165
+ return Data_Wrap_Struct(cNMatrix_FFTW_Plan_Data, NULL, nm_fftw_cleanup, data);
166
+ }
167
+
168
+ // @private Used internally by the C API.
169
+ template <typename InputType>
170
+ static void nm_fftw_actually_set(VALUE nmatrix, VALUE plan_data)
171
+ {
172
+ fftw_data* data;
173
+ Data_Get_Struct(plan_data, fftw_data, data);
174
+ memcpy((InputType*)data->input, (InputType*)NM_DENSE_ELEMENTS(nmatrix),
175
+ sizeof(InputType)*NM_DENSE_COUNT(nmatrix));
176
+ }
177
+
178
+ /** \brief Here is a brief description of what this function does.
179
+ *
180
+ * @param[in,out] self Object on which the function is called.
181
+ * @param[in] plan_data An internal data structure of type
182
+ * NMatrix::FFTW::Plan::Data that is created by Data_Wrap_Struct in
183
+ * nm_fftw_create_plan and which encapsulates the FFTW plan in a Ruby object.
184
+ * @param[in] nmatrix An NMatrix object (pre-allocated) which contains the
185
+ * input elements for the fourier transform.
186
+ * @param[in] type A number representing the type of fourier transform
187
+ * being performed. (:complex_complex, :real_complex, :complex_real or :real_real).
188
+ *
189
+ * \returns self
190
+ */
191
+ static VALUE nm_fftw_set_input(VALUE self, VALUE nmatrix, VALUE plan_data,
192
+ VALUE type)
193
+ {
194
+ switch(FIX2INT(type))
195
+ {
196
+ case TYPE_COMPLEX_COMPLEX:
197
+ case TYPE_COMPLEX_REAL:
198
+ nm_fftw_actually_set<fftw_complex>(nmatrix, plan_data);
199
+ break;
200
+ case TYPE_REAL_COMPLEX:
201
+ case TYPE_REAL_REAL:
202
+ nm_fftw_actually_set<double>(nmatrix, plan_data);
203
+ break;
204
+ default:
205
+ rb_raise(rb_eArgError, "Invalid type of DFT.");
206
+ }
207
+
208
+ return self;
209
+ }
210
+
211
+ // @private Used internally by the C API.
212
+ // Call fftw_execute and copy the resulting data into the nmatrix object.
213
+ template <typename OutputType>
214
+ static void nm_fftw_actually_execute(VALUE nmatrix, VALUE plan_data)
215
+ {
216
+ fftw_data *data;
217
+ Data_Get_Struct(plan_data, fftw_data, data);
218
+ fftw_execute(data->plan);
219
+ memcpy((OutputType*)NM_DENSE_ELEMENTS(nmatrix), (OutputType*)data->output,
220
+ sizeof(OutputType)*NM_DENSE_COUNT(nmatrix));
221
+ }
222
+
223
+ /** \brief Executes the fourier transform by calling the fftw_execute function
224
+ * and copies the output to the output nmatrix object, which can be accessed from
225
+ * Ruby.
226
+ *
227
+ * @param[in] self Object on which the function is called.
228
+ * @param[in] plan_data An internal data structure of type
229
+ * NMatrix::FFTW::Plan::Data that is created by Data_Wrap_Struct in
230
+ * nm_fftw_create_plan and which encapsulates the FFTW plan in a Ruby object.
231
+ * @param[in] nmatrix An NMatrix object (pre-allocated) into which the computed
232
+ * data will be copied.
233
+ * @param[in] type A number representing the type of fourier transform being
234
+ * performed. (:complex_complex, :real_complex, :complex_real or :real_real).
235
+ *
236
+ * \returns TrueClass if computation completed without errors.
237
+ */
238
+ static VALUE nm_fftw_execute(VALUE self, VALUE nmatrix, VALUE plan_data, VALUE type)
239
+ {
240
+ switch(FIX2INT(type))
241
+ {
242
+ case TYPE_COMPLEX_COMPLEX:
243
+ case TYPE_REAL_COMPLEX:
244
+ nm_fftw_actually_execute<fftw_complex>(nmatrix, plan_data);
245
+ break;
246
+ case TYPE_COMPLEX_REAL:
247
+ case TYPE_REAL_REAL:
248
+ nm_fftw_actually_execute<double>(nmatrix, plan_data);
249
+ break;
250
+ default:
251
+ rb_raise(rb_eTypeError, "Invalid type of DFT.");
252
+ }
253
+
254
+ return Qtrue;
255
+ }
256
+
257
+ extern "C" {
258
+ void Init_nmatrix_fftw()
259
+ {
260
+ VALUE cNMatrix = rb_define_class("NMatrix", rb_cObject);
261
+ VALUE cNMatrix_FFTW = rb_define_module_under(cNMatrix, "FFTW");
262
+ VALUE cNMatrix_FFTW_Plan = rb_define_class_under(cNMatrix_FFTW, "Plan",
263
+ rb_cObject);
264
+ VALUE cNMatrix_FFTW_Plan_Data = rb_define_class_under(
265
+ cNMatrix_FFTW_Plan, "Data", rb_cObject);
266
+
267
+ rb_define_private_method(cNMatrix_FFTW_Plan, "c_create_plan",
268
+ (METHOD)nm_fftw_create_plan, 7);
269
+ rb_define_private_method(cNMatrix_FFTW_Plan, "c_set_input",
270
+ (METHOD)nm_fftw_set_input, 3);
271
+ rb_define_private_method(cNMatrix_FFTW_Plan, "c_execute",
272
+ (METHOD)nm_fftw_execute, 3);
273
+ }
274
+ }