[DRE-commits] [ruby-fftw3] 02/07: Imported Upstream version 1.0.1

Youhei SASAKI uwabami-guest at moszumanska.debian.org
Thu Jul 21 06:26:34 UTC 2016


This is an automated email from the git hooks/post-receive script.

uwabami-guest pushed a commit to branch master
in repository ruby-fftw3.

commit 51b808f9fc3eac34a6e9f60c1ab96f9ed592cf90
Author: Youhei SASAKI <uwabami at gfd-dennou.org>
Date:   Thu Jul 21 14:41:08 2016 +0900

    Imported Upstream version 1.0.1
---
 .gitignore                 |   1 -
 ChangeLog                  | 228 ++++++++++++++++++++++++
 LICENSE.txt                |   2 +-
 Rakefile                   |   6 +-
 doc/ruby-fftw3.html        | 116 -------------
 doc/ruby-fftw3.rd          | 115 -------------
 ext/numru/fftw3/extconf.rb |  40 ++++-
 ext/numru/fftw3/na_fftw3.c | 421 ++++++++++++++++++++++++++++++++++++++++++++-
 lib/numru/fftw3.rb         | 109 ++++++++++++
 lib/numru/fftw3/version.rb |   2 +-
 test/complexFFT.rb         |  85 +++++----
 test/r2rFFT.rb             |  77 +++++++++
 12 files changed, 919 insertions(+), 283 deletions(-)

diff --git a/.gitignore b/.gitignore
index 68242b8..cdc8549 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,5 @@
 *~
 *.so
 Makefile
-ChangeLog
 /pkg/
 /tmp/
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..70af2ac
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,228 @@
+2016-07-16  Takeshi Horinouchi  (HEAD, master)
+Updated the numru/narray support
+
+M	ext/numru/fftw3/na_fftw3.c
+M	lib/numru/fftw3.rb
+
+2016-07-16  Takeshi Horinouchi 
+To update to ver. 1.0.1
+
+M	lib/numru/fftw3/version.rb
+
+2016-07-16  Takeshi Horinouchi 
+Not to ignore ChangeLog
+
+M	.gitignore
+
+2016-07-16  Takeshi Horinouchi 
+deleted old (unused) part related windows
+
+M	ext/numru/fftw3/extconf.rb
+
+2016-07-16  Takeshi Horinouchi  (v1.0.0, origin/master, origin/HEAD)
+Updated the year range
+
+M	LICENSE.txt
+
+2016-07-16  Takeshi Horinouchi 
+deleted old document
+
+D	doc/ruby-fftw3.html
+D	doc/ruby-fftw3.rd
+
+2016-07-15  Takeshi Horinouchi 
+Document slightly updated
+
+M	ext/numru/fftw3/na_fftw3.c
+M	lib/numru/fftw3.rb
+
+2016-07-15  Takeshi Horinouchi 
+Supported NumRu::NArray
+
+M	ext/numru/fftw3/extconf.rb
+
+2016-07-15  Takeshi Horinouchi 
+Added RDoc document
+
+M	ext/numru/fftw3/na_fftw3.c
+M	lib/numru/fftw3.rb
+
+2016-07-15  Takeshi Horinouchi 
+ceased to create ruby-fftw3-bigmem
+
+M	Rakefile
+
+2016-07-02  Takeshi Horinouchi 
+to require rubygems if needed
+
+M	ext/numru/fftw3/extconf.rb
+
+2015-12-03  Takeshi Horinouchi 
+Added new module functions fft_fw and fft_bk for user-friendliness (forward complex FFT with normalization / backward complex FFT)
+
+M	lib/numru/fftw3.rb
+M	test/complexFFT.rb
+
+2015-12-03  Takeshi Horinouchi 
+Updated vergion # to 1.0.0
+
+M	lib/numru/fftw3/version.rb
+
+2015-12-03  Takeshi Horinouchi 
+Created. (test of real to real FFTs)
+
+A	test/r2rFFT.rb
+
+2015-12-03  Takeshi Horinouchi 
+Revised to use test/unit
+
+M	test/complexFFT.rb
+
+2015-12-03  Takeshi Horinouchi 
+Supported real2real FFTs (e.g. sine trans) / Added some constants (e.g. FORWARD)
+
+M	ext/numru/fftw3/na_fftw3.c
+
+2015-05-21  Takeshi Horinouchi 
+Created gemspec to depend on narray-bigmem
+
+M	Rakefile
+M	ext/numru/fftw3/extconf.rb
+A	ruby-fftw3-bigmem.gemspec
+
+2015-03-31  Eriko Nishimoto  (origin/rubygems)
+Modified git ignore list
+
+Added pkg and tmp folder
+
+M	.gitignore
+
+2015-03-31  Eriko Nishimoto 
+Modified test/complexFFT.rb
+
+* Required rubygems for ruby1.8
+* Required narray for rake test
+
+M	test/complexFFT.rb
+
+2015-03-31  Eriko Nishimoto 
+Changed lib path for extesion task
+
+To make fftw3.so under numru/fftw3/ directory.
+
+M	Rakefile
+
+2015-03-31  Eriko Nishimoto 
+Modified extconf.rb
+
+* To search narray.h in gem folder if it is isnstalled by gem
+* To create makefile numru/fftw3/fftw3
+
+M	ext/numru/fftw3/extconf.rb
+
+2015-03-31  Eriko Nishimoto 
+Moved extensional files to ext/numru/fftw3/
+
+A	ext/numru/fftw3/extconf.rb
+A	ext/numru/fftw3/na_fftw3.c
+D	extconf.rb
+D	na_fftw3.c
+
+2015-03-31  Eriko Nishimoto 
+Made lib folder
+
+Placed lib/numru/fftw3.rb, which requires lib/numru/fftw3/version.rb and
+ext/numru/fftw3/fftw3.so
+
+A	lib/numru/fftw3.rb
+A	lib/numru/fftw3/version.rb
+
+2015-03-31  Eriko Nishimoto 
+Added setting files for making rubygems
+
+A	Gemfile
+A	Rakefile
+A	ruby-fftw3.gemspec
+
+2015-03-30  Takeshi Horinouchi 
+Renamed the current ChangeLog to back up.
+
+A	.ChangeLog.until20110419
+D	ChangeLog
+
+2015-03-30  Takeshi Horinouchi 
+Registered files (patterns) to ignore in the repository
+
+A	.gitignore
+
+2011-04-19  Takeshi Horinouchi  (ruby-fftw3-0_4)
+	* doc/ruby-fftw3.rd and doc/ruby-fftw3.html : updated
+
+M	ChangeLog
+M	doc/ruby-fftw3.html
+M	doc/ruby-fftw3.rd
+
+2011-04-19  Takeshi Horinouchi 
+Tue Apr 19  2011 T Horinouchi
+	* version 0.4 released (cvs tag ruby-fftw3-0_4)
+
+M	ChangeLog
+
+2011-04-19  Takeshi Horinouchi 
+Tue Apr 19  2011 T Horinouchi
+	* na_fftw3.c: added rb_require("narray"); -- then you do
+	  not need to require "narray" separately.
+	* test/complexFFT.rb: removed the first line: require "narray"
+
+M	ChangeLog
+M	na_fftw3.c
+M	test/complexFFT.rb
+
+2011-04-19  Takeshi Horinouchi 
+Tue Apr 19  2011 T Horinouchi
+	* LICENSE.txt: changed --> BSD 2-clause license
+
+M	ChangeLog
+M	LICENSE.txt
+
+2011-04-12  Takeshi Horinouchi 
+Tue Apr 12  2011 T Horinouchi
+	* LICENSE.txt: changed
+
+M	ChangeLog
+M	LICENSE.txt
+
+2011-03-24  Takeshi Horinouchi  (ruby-fftw3-0_3)
+Thu Mar 24  2011 T Horinouchi
+	* version 0.3 released (cvs tag ruby-fftw3-0_3)
+	* LICENSE.txt: added
+
+M	ChangeLog
+A	LICENSE.txt
+
+2004-06-07  Takeshi Horinouchi  (ruby-fftw3-0_2)
+*** empty log message ***
+
+D	doc/fftw3.html
+D	doc/fftw3.rd
+A	doc/ruby-fftw3.html
+A	doc/ruby-fftw3.rd
+
+2004-06-07  Takeshi Horinouchi 
+Mon Jun  7  2004 T Horinouchi < T Koshiro
+	* version 0.2 released (cvs tag ruby-fftw3-0_2)
+	* extconf.rb: improved
+
+M	ChangeLog
+M	extconf.rb
+
+2004-06-07  Takeshi Horinouchi 
+Initial revision
+
+A	ChangeLog
+A	ToDo
+A	doc/fftw3.html
+A	doc/fftw3.rd
+A	extconf.rb
+A	na_fftw3.c
+A	test/complexFFT.rb
diff --git a/LICENSE.txt b/LICENSE.txt
index 3552ccb..a5cac98 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,7 +1,7 @@
 Ruby-FFTW3 is copyrighted free software by Takeshi Horinouchi and GFD
 Dennou Club (http://www.gfd-dennou.org/).
 
-Copyright 2001 (C) Takeshi Horinouchi and GFD Dennou Club
+Copyright 2001-2016 (C) Takeshi Horinouchi and GFD Dennou Club
 (http://www.gfd-dennou.org/) All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/Rakefile b/Rakefile
index 4b0575c..6e5e6d1 100644
--- a/Rakefile
+++ b/Rakefile
@@ -3,11 +3,15 @@ require 'rake/testtask'
 require 'rake/extensiontask'
 require 'rake/packagetask'
 begin
-  require 'bundler/gem_tasks'
+  require 'bundler/gem_helper'  # instead of 'bundler/gem_tasks' -> need manual
+                                # calls of install_tasks (see below)
 rescue LoadError
   puts 'If you want to create gem, You must install Bundler'
 end
 
+Bundler::GemHelper.install_tasks(name: "ruby-fftw3")
+##Bundler::GemHelper.install_tasks(name: "ruby-fftw3-bigmem")
+
 require './lib/numru/fftw3/version.rb'
 def version
   NumRu::FFTW3::VERSION
diff --git a/doc/ruby-fftw3.html b/doc/ruby-fftw3.html
deleted file mode 100644
index 119534e..0000000
--- a/doc/ruby-fftw3.html
+++ /dev/null
@@ -1,116 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE html 
-  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title>ruby-fftw3.rd</title>
-</head>
-<body>
-<h1><a name="label-0" id="label-0">module NumRu::FFTW3</a></h1><!-- RDLabel: "module NumRu::FFTW3" -->
-<p>Fast Fourier Transforms by using <a href="http://www.fftw.org">FFTW</a> Ver.3.</p>
-<p>Takeshi Horinouchi</p>
-<p>(C) Takeshi Horinouchi / GFD Dennou Club,
-2003</p>
-<p>NO WARRANTY</p>
-<h2><a name="label-1" id="label-1">Features</a></h2><!-- RDLabel: "Features" -->
-<ul>
-<li>Uses <a href="http://www.ruby-lang.org/en/raa-list.rhtml?name=NArray">NArray</a>.</li>
-<li>Multi-dimensional complex FFT. (Real data are coerced to complex).</li>
-<li>Supports both double and single float transforms.</li>
-<li>Not normalized as in FFTW</li>
-</ul>
-<h2><a name="label-2" id="label-2">Features yet to be introduced</a></h2><!-- RDLabel: "Features yet to be introduced" -->
-<ul>
-<li>Sine / cosine transforms</li>
-<li>User choice of optimization levels (i.e., FFTW_MEASURE etc in
-  addition to FFTW_ESTIMATE).</li>
-<li>Multi-threaded FFT3 support -- don't know whether it's really feasible.</li>
-</ul>
-<h2><a name="label-3" id="label-3">Installation</a></h2><!-- RDLabel: "Installation" -->
-<ul>
-<li>Install <a href="http://www.fftw.org">FFTW</a> Ver.3.
-<ul>
-<li>NOTE: 
-    To activate the single-float transform, you have to install FFTW3 with
-    the single-float compilation, in addition to the default double-float
-    version. This can be done by configuring FFTW3 with
-    the --enable-float option, and install it again. The single-float
-    version will coexist with the double-float version.
-    If you do not install the single-float version, FFT is always done
-    with the double precision, which is not bad if you are not time- and 
-    memory-conscious.</li>
-</ul></li>
-<li>Install <a href="http://www.ruby-lang.org/en/raa-list.rhtml?name=NArray">NArray</a>.</li>
-<li><p>Then, install this library as follows (replace "version" with
-  the actual version number):</p>
-<pre>% tar xvzf fftw3-version.tar.gz
-% cd fftw3-version
-% ruby extconf.rb
-% make
-% make site-install</pre>
-<p>Or</p>
-<pre>% make install</pre>
-<p>(If you are using Ruby 1.8, make install is the same make site-install.)</p></li>
-</ul>
-<h2><a name="label-4" id="label-4">How to use</a></h2><!-- RDLabel: "How to use" -->
-<p>See the following peice of code. (Install this library and copy and
-paste the following to the interactive shell irb).</p>
-<pre>require "numru/fftw3"
-include NumRu
-
-na = NArray.float(8,6)   # float -> will be corced to complex
-na[1,1]=1
-
-# <example 1>
-fc = FFTW3.fft(na, -1)/na.length  # forward 2D FFT and normalization
-nc = FFTW3.fft(fc, 1)       # backward 2D FFT (complex) --> 
-nb = nc.real                # should be equal to na except round errors  
-
-# <example 2>
-fc = FFTW3.fft(na, -1, 0) / na.shape[0]  # forward FFT with the first dim
-
-# <example 3>
-fc = FFTW3.fft(na, -1, 1) / na.shape[1]  # forward FFT with the second dim</pre>
-<h2><a name="label-5" id="label-5">API Reference</a></h2><!-- RDLabel: "API Reference" -->
-<h3><a name="label-6" id="label-6">Module methods</a></h3><!-- RDLabel: "Module methods" -->
-<dl>
-<dt><a name="label-7" id="label-7"><code>fft(<var>narray</var>, <var>dir</var> [,<var>dim</var>,<var>dim</var>,...])</code></a></dt><!-- RDLabel: "fft" -->
-<dd>
-<p>Complex FFT.</p>
-<p>The 3rd, 4th,... arguments are optional.</p>
-<p>ARGUMENTS</p>
-<ul>
-<li>narray (NArray or NArray-compatible Array) : array to be
-      transformed. If real, coerced to complex before transformation.
-      If narray is single-precision and the single-precision
-      version of FFTW3 is installed (before installing this module),
-      this method does a single-precision transform. 
-      Otherwise, a double-precision transform is used.</li>
-<li>dir (-1 or 1) : forward transform if -1; backward transform if 1.</li>
-<li>optional 3rd, 4th,... arguments (Integer) : Specifies dimensions 
-      to apply FFT. For example, if 0, the first dimension is
-      transformed (1D FFT); If -1, the last dimension is used (1D FFT);
-      If 0,2,4, the first, third, and fifth dimensions
-      are transformed (3D FFT); If entirely omitted, ALL DIMENSIONS
-      ARE SUBJECT TO FFT, so 3D FFT is done with a 3D array.</li>
-</ul>
-<p>RETURN VALUE</p>
-<ul>
-<li>a complex NArray</li>
-</ul>
-<p>NOTE</p>
-<ul>
-<li>As in FFTW, return value is NOT normalized. Thus, a consecutive
-      forward and backward transform would multiply the size of
-      data used for transform. You can normalize, for example,
-      the forward transform FFTW.fft(narray, -1, 0, 1)
-      (FFT regarding the first (dim 0) & second (dim 1) dimensions) by
-      dividing with (narray.shape[0]*narray.shape[1]). Likewise,
-      the result of FFTW.fft(narray, -1) (FFT for all dimensions)
-      can be normalized by narray.length.</li>
-</ul></dd>
-</dl>
-
-</body>
-</html>
diff --git a/doc/ruby-fftw3.rd b/doc/ruby-fftw3.rd
deleted file mode 100644
index 226b8e5..0000000
--- a/doc/ruby-fftw3.rd
+++ /dev/null
@@ -1,115 +0,0 @@
-=module NumRu::FFTW3
-
-Fast Fourier Transforms by using ((<FFTW|URL:http://www.fftw.org>)) Ver.3.
-
-Takeshi Horinouchi
-
-(C) Takeshi Horinouchi / GFD Dennou Club,
-2003
-
-NO WARRANTY
-
-==Features
-
-* Uses ((<NArray|URL:http://www.ruby-lang.org/en/raa-list.rhtml?name=NArray>)).
-* Multi-dimensional complex FFT. (Real data are coerced to complex).
-* Supports both double and single float transforms.
-* Not normalized as in FFTW
-
-==Features yet to be introduced
-
-* Sine / cosine transforms
-* User choice of optimization levels (i.e., FFTW_MEASURE etc in
-  addition to FFTW_ESTIMATE).
-* Multi-threaded FFT3 support -- don't know whether it's really feasible.
-
-==Installation
-
-* Install ((<FFTW|URL:http://www.fftw.org>)) Ver.3.
-
-  * NOTE: 
-    To activate the single-float transform, you have to install FFTW3 with
-    the single-float compilation, in addition to the default double-float
-    version. This can be done by configuring FFTW3 with
-    the --enable-float option, and install it again. The single-float
-    version will coexist with the double-float version.
-    If you do not install the single-float version, FFT is always done
-    with the double precision, which is not bad if you are not time- and 
-    memory-conscious.
-
-* Install ((<NArray|URL:http://www.ruby-lang.org/en/raa-list.rhtml?name=NArray>)).
-
-* Then, install this library as follows (replace "version" with
-  the actual version number):
-
-    % tar xvzf fftw3-version.tar.gz
-    % cd fftw3-version
-    % ruby extconf.rb
-    % make
-    % make site-install
-  Or
-    % make install
-  (If you are using Ruby 1.8, make install is the same make site-install.)
-
-==How to use
-
-See the following peice of code. (Install this library and copy and
-paste the following to the interactive shell irb).
-
-  require "numru/fftw3"
-  include NumRu
-
-  na = NArray.float(8,6)   # float -> will be corced to complex
-  na[1,1]=1
-
-  # <example 1>
-  fc = FFTW3.fft(na, -1)/na.length  # forward 2D FFT and normalization
-  nc = FFTW3.fft(fc, 1)       # backward 2D FFT (complex) --> 
-  nb = nc.real                # should be equal to na except round errors  
-
-  # <example 2>
-  fc = FFTW3.fft(na, -1, 0) / na.shape[0]  # forward FFT with the first dim
-
-  # <example 3>
-  fc = FFTW3.fft(na, -1, 1) / na.shape[1]  # forward FFT with the second dim
-
-==API Reference
-
-===Module methods
-
----fft(narray, dir [,dim,dim,...])
-
-    Complex FFT.
-
-    The 3rd, 4th,... arguments are optional.
-
-    ARGUMENTS
-    * narray (NArray or NArray-compatible Array) : array to be
-      transformed. If real, coerced to complex before transformation.
-      If narray is single-precision and the single-precision
-      version of FFTW3 is installed (before installing this module),
-      this method does a single-precision transform. 
-      Otherwise, a double-precision transform is used.
-    * dir (-1 or 1) : forward transform if -1; backward transform if 1.
-    * optional 3rd, 4th,... arguments (Integer) : Specifies dimensions 
-      to apply FFT. For example, if 0, the first dimension is
-      transformed (1D FFT); If -1, the last dimension is used (1D FFT);
-      If 0,2,4, the first, third, and fifth dimensions
-      are transformed (3D FFT); If entirely omitted, ALL DIMENSIONS
-      ARE SUBJECT TO FFT, so 3D FFT is done with a 3D array.
- 
-    RETURN VALUE
-    * a complex NArray
-
-    NOTE
-    * As in FFTW, return value is NOT normalized. Thus, a consecutive
-      forward and backward transform would multiply the size of
-      data used for transform. You can normalize, for example,
-      the forward transform FFTW.fft(narray, -1, 0, 1)
-      (FFT regarding the first (dim 0) & second (dim 1) dimensions) by
-      dividing with (narray.shape[0]*narray.shape[1]). Likewise,
-      the result of FFTW.fft(narray, -1) (FFT for all dimensions)
-      can be normalized by narray.length.
-
-
-
diff --git a/ext/numru/fftw3/extconf.rb b/ext/numru/fftw3/extconf.rb
index eec092e..fe5835d 100644
--- a/ext/numru/fftw3/extconf.rb
+++ b/ext/numru/fftw3/extconf.rb
@@ -1,12 +1,38 @@
 require "mkmf"
+require "rubygems" unless defined?(Gem)
 
-gem_narray_path=File::dirname(`gem which narray`)
-narray_include=gem_narray_path
-narray_lib=gem_narray_path
-dir_config('narray',narray_include,narray_lib)
- 
 dir_config('fftw3','/usr/local')
 
+require "rbconfig"
+so = RbConfig::CONFIG["DLEXT"]
+
+raise("Your gem is too old") unless Gem.respond_to?(:find_files) 
+
+env = ENV['NARRAY_TYPE']
+if env == "NArray" || env == "narray"
+  na_type = "narray"
+elsif env == "NumRu::NArray" || env == "numru-narray"
+  na_type = "numru-narray"
+elsif !env.nil?
+  raise "Unsupported value for the environment variable NARRAY_TYPE: #{env}"
+else
+  if Gem.find_files("narray.h").length > 0
+    na_type = "narray"
+  elsif Gem.find_files("numru/narray/narray.h").length > 0
+    na_type = "numru-narray"
+  end
+end
+
+case na_type
+when "narray"
+  narray_include = File.expand_path(File.dirname(Gem.find_files("narray.h")[0]))
+  narray_lib = File.expand_path(File.dirname(Gem.find_files("narray." + so)[0]))
+when "numru-narray"
+  narray_include = File.expand_path(File.dirname(Gem.find_files("numru/narray/narray.h")[0]))
+  narray_lib = File.expand_path(File.dirname(Gem.find_files("numru/narray/narray." + so)[0]))
+end
+
+dir_config('narray', narray_include, narray_lib)
 if ( ! ( have_header("narray.h") && have_header("narray_config.h") ) ) then
    print <<-EOS
    ** configure error **  
@@ -39,8 +65,4 @@ if have_library("fftw3f")
   $CFLAGS += ' -DFFTW3_HAS_SINGLE_SUPPORT'
 end
 
-if /cygwin|mingw/ =~ RUBY_PLATFORM
-   have_library("narray") || raise("ERROR: narray library is not found")
-end
-
 create_makefile("numru/fftw3/fftw3")
diff --git a/ext/numru/fftw3/na_fftw3.c b/ext/numru/fftw3/na_fftw3.c
index 276dea2..5cf7b7d 100644
--- a/ext/numru/fftw3/na_fftw3.c
+++ b/ext/numru/fftw3/na_fftw3.c
@@ -32,7 +32,7 @@ na_fftw3(int argc, VALUE *argv, VALUE self)
   volatile VALUE v1, v2;
 
   if (argc<2){
-    rb_raise(rb_eArgError, "Usage: fftw(narray, direction [,dim0,dim1,...])");
+    rb_raise(rb_eArgError, "Usage: fft(narray, direction [,dim0,dim1,...])");
   }
   val = argv[0];
   vdir = argv[1];
@@ -60,7 +60,7 @@ na_fftw3(int argc, VALUE *argv, VALUE self)
   } else {
       /* apply FFT to selected dimensions (by using the Guru interface) */
       { /* introduce a new scope for additonal local variables */
-	  int fft_rank, howmany_rank, ib, j, jf, je, dim;
+	  int fft_rank, howmany_rank, j, jf, je, dim;
 	  fftw_iodim *fft_dims, *howmany_dims;
 	  int *dimids;
 	  fft_rank = argc - 2;
@@ -151,7 +151,7 @@ na_fftw3_float(int argc, VALUE *argv, VALUE self)
   volatile VALUE v1, v2;
 
   if (argc<2){
-    rb_raise(rb_eArgError, "Usage: fftw(narray, direction [,dim0,dim1,...])");
+    rb_raise(rb_eArgError, "Usage: fft(narray, direction [,dim0,dim1,...])");
   }
   val = argv[0];
   vdir = argv[1];
@@ -179,7 +179,7 @@ na_fftw3_float(int argc, VALUE *argv, VALUE self)
   } else {
       /* apply FFT to selected dimensions (by using the Guru interface) */
       { /* introduce a new scope for additonal local variables */
-	  int fft_rank, howmany_rank, ib, j, jf, je, dim;
+	  int fft_rank, howmany_rank, j, jf, je, dim;
 	  fftw_iodim *fft_dims, *howmany_dims;
 	  int *dimids;
 	  fft_rank = argc - 2;
@@ -252,6 +252,44 @@ na_fftw3_float(int argc, VALUE *argv, VALUE self)
   return v2;
 }
 
+/*
+ * call-seq:
+ *   FFTW3.fft(narray, dir [, dim, dim, ...])
+ * 
+ * Conducts complex FFT (unnormalized). You can use more user-friendly wrappers
+ * fft_fw and fft_bk.
+ * 
+ * ARGUMENTS
+ * * narray (NArray or NArray-compatible Array) : array to be
+ *   transformed. If real, coerced to complex before transformation.
+ *   If narray is single-precision and the single-precision
+ *   version of FFTW3 is installed (before installing this module),
+ *   this method does a single-precision transform. 
+ *   Otherwise, a double-precision transform is used.
+ * * dir (FORWARD (which is simply equal to -1; 
+ *   referable as NumRu::FFTW3::FORWARD) or BACKWARD
+ *   (which is simply 1) ) : the direction of FFT,
+ *   forward if FORWARD and backward if BACKWARD.
+ * * optional 3rd, 4th,... arguments (Integer) : Specifies dimensions 
+ *   to apply FFT. For example, if 0, the first dimension is
+ *   transformed (1D FFT); If -1, the last dimension is used (1D FFT);
+ *   If 0,2,4, the first, third, and fifth dimensions
+ *   are transformed (3D FFT); If entirely omitted, ALL DIMENSIONS
+ *   ARE SUBJECT TO FFT, so 3D FFT is done with a 3D array.
+ * 
+ * RETURN VALUE
+ * * a complex NArray
+ * 
+ * NOTE
+ * * As in FFTW, return value is NOT normalized. Thus, a consecutive
+ *   forward and backward transform would multiply the size of
+ *   data used for transform. You can normalize, for example,
+ *   the forward transform FFTW.fft(narray, -1, 0, 1)
+ *   (FFT regarding the first (dim 0) & second (dim 1) dimensions) by
+ *   dividing with (narray.shape[0]*narray.shape[1]). Likewise,
+ *   the result of FFTW.fft(narray, -1) (FFT for all dimensions)
+ *   can be normalized by narray.length.
+ */
 static VALUE
 na_fftw3(int argc, VALUE *argv, VALUE self)
 {
@@ -260,7 +298,7 @@ na_fftw3(int argc, VALUE *argv, VALUE self)
   struct NARRAY *a1;
 
   if (argc<2){
-    rb_raise(rb_eArgError, "Usage: fftw(narray, direction [,dim0,dim1,...])");
+    rb_raise(rb_eArgError, "Usage: fft(narray, direction [,dim0,dim1,...])");
   }
   val = argv[0];
   v1 = na_to_narray(val);
@@ -275,11 +313,382 @@ na_fftw3(int argc, VALUE *argv, VALUE self)
 
 #endif
 
+static VALUE
+#ifdef FFTW3_HAS_SINGLE_SUPPORT
+na_fftw3_r2r_double(int argc, VALUE *argv, VALUE self)
+  /* to be called by na_fftw3_r2r */
+#else
+na_fftw3_r2r(int argc, VALUE *argv, VALUE self)
+  /* to be called directly */
+#endif
+{
+  VALUE val, vkinds;
+  struct NARRAY *a1, *a2;
+  int i, *shape, *bucket, len;
+  fftw_r2r_kind *kinds;
+  fftw_plan p;
+  double *in, *out;
+  volatile VALUE v1, v2;
+
+  if (argc<2){
+    rb_raise(rb_eArgError, "Usage: fft_r2r(narray, kinds [,dim0,dim1,...])");
+  }
+  val = argv[0];
+  vkinds = argv[1];
+
+  v1 = na_cast_object(val, NA_DFLOAT);
+  GetNArray(v1,a1);
+  v2 = na_make_object( NA_DFLOAT, a1->rank, a1->shape, CLASS_OF(v1) );
+  GetNArray(v2,a2);
+
+  shape = ALLOCA_N(int, a2->rank);
+  for (i=0; i<a2->rank; i++){
+      shape[i] = a2->shape[a2->rank-1-i];
+  }
+  in = (double*)a1->ptr;
+  out = (double*)a2->ptr;
+
+  switch (TYPE(vkinds)) {
+  case T_ARRAY:
+      len = RARRAY_LEN(vkinds);
+      kinds = ALLOCA_N(fftw_r2r_kind, len);
+      for (i = 0; i < len; i++) {
+	  kinds[i] = NUM2INT(RARRAY_PTR(vkinds)[len-1-i]);//column- to row-major
+      }
+      break;
+  case T_FIXNUM:
+      if (argc == 2) {
+	  len = a1->rank;
+      } else {
+	  len = argc-2;
+      }
+      kinds = ALLOCA_N(fftw_r2r_kind, len);
+      for (i = 0; i < len; i++) {
+	  kinds[i] = NUM2INT(vkinds);
+      }
+      break;
+  default:
+      rb_raise(rb_eTypeError, "unsupported kinds type");
+      break;
+  }
+
+  for (i = 0; i < len; i++) {
+      if ( kinds[i] < FFTW_R2HC || kinds[i] > FFTW_RODFT11 ){
+	  rb_raise(rb_eArgError, "unsupported kind (%d).", kinds[i]);
+      }
+  }
+
+  if (argc==2) {
+      /* apply FFT to all dimensions */
+      p = fftw_plan_r2r( a2->rank, shape,
+			 in, out, kinds, FFTW_ESTIMATE );
+  } else {
+      /* apply FFT to selected dimensions (by using the Guru interface) */
+      { /* introduce a new scope for additonal local variables */
+	  int fft_rank, howmany_rank, j, jf, je, dim;
+	  fftw_iodim *fft_dims, *howmany_dims;
+	  int *dimids;
+	  fft_rank = argc - 2;
+	  fft_dims = ALLOCA_N(fftw_iodim, fft_rank);
+	  dimids = ALLOCA_N(int, fft_rank);
+	  howmany_rank = fft_rank + 1;
+	  howmany_dims = ALLOCA_N(fftw_iodim, howmany_rank);
+
+	  for (i=2;i<argc;i++){
+	      dim = NUM2INT(argv[i]);
+	      if (dim<0) dim += a2->rank;  /* negative: count from the end */
+	      if (dim<0 || dim>=a2->rank){
+		  rb_raise(rb_eArgError, "dimension < 0 or >= rank");
+	      }
+	      dimids[i-2] = a2->rank - 1 - dim;
+	      if ( i>2 && dimids[i-2] == dimids[i-3] ){
+		  rb_raise(rb_eArgError, "redundant -- a same dimension is reppeated");
+	      }
+	  }
+
+	  /* bukcet sort in increasing order */
+	  bucket = ALLOCA_N(int,a2->rank);
+	  for(j=0; j<a2->rank; j++) bucket[j] = 0; /* initialize */
+	  for(i=0; i<fft_rank; i++) bucket[ dimids[i] ] = 1;
+	  for(j=0,i=0; j<a2->rank; j++) {
+	      if (bucket[j]==1){
+		  dimids[i] = j;
+		  i++;
+	      }
+	  }
+
+	  for(j=0; j<fft_rank; j++){
+	      fft_dims[j].n = shape[ dimids[j] ];
+	      fft_dims[j].is = 1;
+	      for (i=dimids[j]+1 ; i<a2->rank ; i++){
+		  fft_dims[j].is *= shape[i];
+	      }
+	      fft_dims[j].os = fft_dims[j].is;
+	      /* printf("fft_ %d  n:%d  is:%d\n",j,
+		       fft_dims[j].n,fft_dims[j].is);*/
+	  }
+	  for(j=0; j<=fft_rank; j++){
+	      howmany_dims[j].n = 1;
+	      jf = (j==0) ? 0 : (dimids[j-1]+1) ;
+	      je = (j==fft_rank) ? a2->rank : (dimids[j]) ;
+	      for (i=jf; i<je; i++){
+		  howmany_dims[j].n *= shape[i];
+	      }
+	      howmany_dims[j].is = 1;
+	      if (j<fft_rank){
+		  for (i=dimids[j]; i<a2->rank; i++){
+		      howmany_dims[j].is *= shape[i];
+		  }
+	      }
+	      howmany_dims[j].os = howmany_dims[j].is;
+	      /* printf("how_ %d  n:%d  is:%d\n",j,
+		        howmany_dims[j].n,howmany_dims[j].is); */
+	  }
+
+	  p = fftw_plan_guru_r2r( fft_rank, fft_dims,
+				  howmany_rank, howmany_dims,
+				  in, out, kinds, FFTW_ESTIMATE );
+
+      }
+  }
+
+  fftw_execute(p);
+  fftw_destroy_plan(p);
+
+  return v2;
+}
+
+static VALUE
+#ifdef FFTW3_HAS_SINGLE_SUPPORT
+na_fftw3_r2r_float(int argc, VALUE *argv, VALUE self)
+  /* to be called by na_fftw3_r2r */
+{
+  VALUE val, vkinds;
+  struct NARRAY *a1, *a2;
+  int i, *shape, *bucket, len;
+  fftwf_r2r_kind *kinds;
+  fftwf_plan p;
+  float *in, *out;
+  volatile VALUE v1, v2;
+
+  if (argc<2){
+    rb_raise(rb_eArgError, "Usage: fft_r2r(narray, kinds [,dim0,dim1,...])");
+  }
+  val = argv[0];
+  vkinds = argv[1];
+
+  v1 = na_cast_object(val, NA_SFLOAT);
+  GetNArray(v1,a1);
+  v2 = na_make_object( NA_SFLOAT, a1->rank, a1->shape, CLASS_OF(v1) );
+  GetNArray(v2,a2);
+
+  shape = ALLOCA_N(int, a2->rank);
+  for (i=0; i<a2->rank; i++){
+      shape[i] = a2->shape[a2->rank-1-i];
+  }
+  in = (float*)a1->ptr;
+  out = (float*)a2->ptr;
+
+  switch (TYPE(vkinds)) {
+  case T_ARRAY:
+      len = RARRAY_LEN(vkinds);
+      kinds = ALLOCA_N(fftwf_r2r_kind, len);
+      for (i = 0; i < len; i++) {
+	  kinds[i] = NUM2INT(RARRAY_PTR(vkinds)[len-1-i]);//column- to row-major
+      }
+      break;
+  case T_FIXNUM:
+      if (argc == 2) {
+	  len = a1->rank;
+      } else {
+	  len = argc-2;
+      }
+      kinds = ALLOCA_N(fftwf_r2r_kind, len);
+      for (i = 0; i < len; i++) {
+	  kinds[i] = NUM2INT(vkinds);
+      }
+      break;
+  default:
+      rb_raise(rb_eTypeError, "unsupported kinds type");
+      break;
+  }
+
+  for (i = 0; i < len; i++) {
+      if ( kinds[i] < FFTW_R2HC || kinds[i] > FFTW_RODFT11 ){
+	  rb_raise(rb_eArgError, "unsupported kind (%d).", kinds[i]);
+      }
+  }
+
+  if (argc==2) {
+      /* apply FFT to all dimensions */
+      p = fftwf_plan_r2r( a2->rank, shape,
+			 in, out, kinds, FFTW_ESTIMATE );
+  } else {
+      /* apply FFT to selected dimensions (by using the Guru interface) */
+      { /* introduce a new scope for additonal local variables */
+	  int fft_rank, howmany_rank, j, jf, je, dim;
+	  fftwf_iodim *fft_dims, *howmany_dims;
+	  int *dimids;
+	  fft_rank = argc - 2;
+	  fft_dims = ALLOCA_N(fftwf_iodim, fft_rank);
+	  dimids = ALLOCA_N(int, fft_rank);
+	  howmany_rank = fft_rank + 1;
+	  howmany_dims = ALLOCA_N(fftwf_iodim, howmany_rank);
+
+	  for (i=2;i<argc;i++){
+	      dim = NUM2INT(argv[i]);
+	      if (dim<0) dim += a2->rank;  /* negative: count from the end */
+	      if (dim<0 || dim>=a2->rank){
+		  rb_raise(rb_eArgError, "dimension < 0 or >= rank");
+	      }
+	      dimids[i-2] = a2->rank - 1 - dim;
+	      if ( i>2 && dimids[i-2] == dimids[i-3] ){
+		  rb_raise(rb_eArgError, "redundant -- a same dimension is reppeated");
+	      }
+	  }
+
+	  /* bukcet sort in increasing order */
+	  bucket = ALLOCA_N(int,a2->rank);
+	  for(j=0; j<a2->rank; j++) bucket[j] = 0; /* initialize */
+	  for(i=0; i<fft_rank; i++) bucket[ dimids[i] ] = 1;
+	  for(j=0,i=0; j<a2->rank; j++) {
+	      if (bucket[j]==1){
+		  dimids[i] = j;
+		  i++;
+	      }
+	  }
+
+	  for(j=0; j<fft_rank; j++){
+	      fft_dims[j].n = shape[ dimids[j] ];
+	      fft_dims[j].is = 1;
+	      for (i=dimids[j]+1 ; i<a2->rank ; i++){
+		  fft_dims[j].is *= shape[i];
+	      }
+	      fft_dims[j].os = fft_dims[j].is;
+	      /* printf("fft_ %d  n:%d  is:%d\n",j,
+		       fft_dims[j].n,fft_dims[j].is);*/
+	  }
+	  for(j=0; j<=fft_rank; j++){
+	      howmany_dims[j].n = 1;
+	      jf = (j==0) ? 0 : (dimids[j-1]+1) ;
+	      je = (j==fft_rank) ? a2->rank : (dimids[j]) ;
+	      for (i=jf; i<je; i++){
+		  howmany_dims[j].n *= shape[i];
+	      }
+	      howmany_dims[j].is = 1;
+	      if (j<fft_rank){
+		  for (i=dimids[j]; i<a2->rank; i++){
+		      howmany_dims[j].is *= shape[i];
+		  }
+	      }
+	      howmany_dims[j].os = howmany_dims[j].is;
+	      /* printf("how_ %d  n:%d  is:%d\n",j,
+		        howmany_dims[j].n,howmany_dims[j].is); */
+	  }
+
+	  p = fftwf_plan_guru_r2r( fft_rank, fft_dims,
+				  howmany_rank, howmany_dims,
+				  in, out, kinds, FFTW_ESTIMATE );
+
+      }
+  }
+
+  fftwf_execute(p);
+  fftwf_destroy_plan(p);
+
+  return v2;
+}
+
+/*
+ * call-seq:
+ *   FFTW3.fft_r2r(narray, kind [, dim, dim, ...])
+ * 
+ * Conducts real FFT (unnormalized).
+ * 
+ * ARGUMENTS
+ * * narray (NArray or NArray-compatible Array) : array to be
+ *   transformed. Cannot be complex.
+ * * kind : specifies the kind of FFT. One of the following:
+ *   R2HC, HC2R, DHT, REDFT00, REDFT01, REDFT10, REDFT11, RODFT00, RODFT01, 
+ *   RODFT10, or RODFT11 (referable as NumRu::FFTW3::REDFT10). See Ch.2 of
+ *   http://www.fftw.org/fftw3_doc/ (http://www.fftw.org/fftw3.pdf).
+ * * optional 3rd, 4th,... arguments (Integer) : See FFTW3.fft.
+ *   
+ * 
+ * RETURN VALUE
+ * * a real NArray
+ * 
+ * NOTE
+ * * As in FFTW, return value is NOT normalized, and the length needed
+ *   normalize is different for each kind.
+ */
+static VALUE
+na_fftw3_r2r(int argc, VALUE *argv, VALUE self)
+{
+  VALUE val;
+  volatile VALUE v1;
+  struct NARRAY *a1;
+
+  if (argc<2){
+    rb_raise(rb_eArgError, "Usage: fft_r2r(narray, kinds [,dim0,dim1,...])");
+  }
+  val = argv[0];
+  v1 = na_to_narray(val);
+  GetNArray(v1,a1);
+  if(a1->type <= NA_SFLOAT || a1->type == NA_SCOMPLEX ){
+      return( na_fftw3_r2r_float(argc, argv, self) );
+  } else {
+      return( na_fftw3_r2r_double(argc, argv, self) );
+  }
+
+}
+
+#endif
+
 void
  Init_fftw3()
 {
-  rb_require("narray");
   mNumRu = rb_define_module("NumRu");
   rb_mFFTW3 = rb_define_module_under(mNumRu, "FFTW3");
   rb_define_module_function(rb_mFFTW3, "fft", na_fftw3, -1);
+  rb_define_module_function(rb_mFFTW3, "fft_r2r", na_fftw3_r2r, -1);
+  /* Specifier of forward complex FFT. Integer equal to -1. */
+#ifdef NARRAY_BIGMEM
+  rb_define_const(rb_mFFTW3, "SUPPORT_BIGMEM", Qtrue);
+#else
+  rb_define_const(rb_mFFTW3, "SUPPORT_BIGMEM", Qfalse);
+#endif
+  rb_define_const(rb_mFFTW3, "FORWARD",  INT2NUM(FFTW_FORWARD));
+  /* Specifier of backward complex FFT. Integer equal to 1. */
+  rb_define_const(rb_mFFTW3, "BACKWARD", INT2NUM(FFTW_BACKWARD));
+  /* Specifier of real FFT kind. real to "halfcomplex" */
+  rb_define_const(rb_mFFTW3, "R2HC", INT2NUM(FFTW_R2HC));
+  /* Specifier of real FFT kind. "halfcomplex" to real */
+  rb_define_const(rb_mFFTW3, "HC2R", INT2NUM(FFTW_HC2R));
+  /* Specifier of real FFT kind. Discrete Hartley Transform */
+  rb_define_const(rb_mFFTW3, "DHT", INT2NUM(FFTW_DHT));
+  /* Specifier of real FFT kind. cosine (even) transform; 
+     logical data length 2*(n-1); inverse is itself  */
+  rb_define_const(rb_mFFTW3, "REDFT00", INT2NUM(FFTW_REDFT00));
+  /* Specifier of real FFT kind. cosine (even) transform;
+   * logical data length 2*n; inverse is REDFT10 */
+  rb_define_const(rb_mFFTW3, "REDFT01", INT2NUM(FFTW_REDFT01));
+  /* Specifier of real FFT kind. cosine (even) transform;
+   * logical data length 2*n; inverse is REDFT01 */
+  rb_define_const(rb_mFFTW3, "REDFT10", INT2NUM(FFTW_REDFT10));
+  /* Specifier of real FFT kind. cosine (even) transform;
+   * logical data length 2*n; inverse is itself */
+  rb_define_const(rb_mFFTW3, "REDFT11", INT2NUM(FFTW_REDFT11));
+  /* Specifier of real FFT kind. sine (odd) transform;
+   * logical data length 2*(n+1); inverse is itself */
+  rb_define_const(rb_mFFTW3, "RODFT00", INT2NUM(FFTW_RODFT00));
+  /* Specifier of real FFT kind. sine (odd) transform;
+   * logical data length 2*n; inverse is RODFT10 */
+  rb_define_const(rb_mFFTW3, "RODFT01", INT2NUM(FFTW_RODFT01));
+  /* Specifier of real FFT kind. sine (odd) transform;
+   * logical data length 2*n; inverse is RODFT01 */
+  rb_define_const(rb_mFFTW3, "RODFT10", INT2NUM(FFTW_RODFT10));
+  /* Specifier of real FFT kind. sine (odd) transform;
+   * logical data length 2*n; inverse is itself */
+  rb_define_const(rb_mFFTW3, "RODFT11", INT2NUM(FFTW_RODFT11));
 }
diff --git a/lib/numru/fftw3.rb b/lib/numru/fftw3.rb
index 84f48bb..2ced096 100644
--- a/lib/numru/fftw3.rb
+++ b/lib/numru/fftw3.rb
@@ -6,3 +6,112 @@ end
 require "numru/fftw3/version"
 require "numru/fftw3/fftw3"
 
+if NumRu::FFTW3::SUPPORT_BIGMEM
+  if Object.const_defined?(:NArray)
+    raise "Incompatibility found. The loaded NumRu::FFTW3 was compiled to " +
+          "use NumRu::NArray, but here NArray has already been loaded."
+  end
+  require("numru/narray");
+else
+  if ( RUBY_VERSION>="1.9" ? NumRu.const_defined?(:NArray,false) :
+       NumRu.const_defined?(:NArray) )
+    raise "Incompatibility found. The loaded NumRu::FFTW3 was compiled to " +
+          "use NArray, but here NumRu::NArray has already been loaded."
+  end
+  require("narray");
+end
+
+module NumRu
+
+  # Ruby wrapper of FFTW3, a fast discrete Fourier transform library. http://www.fftw.org
+  # 
+  # ==Features
+  # 
+  # * Uses NArray (https://github.com/masa16/narray). (Also it supports
+  #   NumRu::NArray as well, if this library is compiled to use it).
+  # * Multi-dimensional complex and real FFT.
+  # * Supports both double and single float transforms.
+  # 
+  # ==How to use
+  # 
+  # Copy and paste the following code line-by-line using irb.
+  # Or you can run it by saving it in a file fftw3test.rb (say) 
+  # and executing "ruby fftw3test.rb".
+  # 
+  #   require "numru/fftw3"
+  #   include NumRu
+  # 
+  #   na = NArray.float(8,6)   # float -> will be coerced to complex
+  #   na[1,1]=1
+  # 
+  #   # <example 1: complex FFT on all dimensions >
+  # 
+  #   fc = FFTW3.fft(na, FFTW3::FORWARD)/na.length  # forward 2D FFT and normalization
+  #   nc = FFTW3.fft(fc, FFTW3::BACKWARD)       # backward 2D FFT (complex) --> 
+  #   nb = nc.real              # should be equal to na except round errors  
+  #   p (nb - na).abs.max       # => 8.970743058303247e-17 (sufficiently small)
+  # 
+  #   # <example 2: complex FFT on all dimensions >
+  #   # Same as example 1 but using more user-friendly wrapper of FFTW3.fft
+  #   
+  #   fc = FFTW3.fft_fw(na)     # forward 2D FFT and normalization
+  #   nc = FFTW3.fft_bk(fc)     # backward 2D FFT (complex) --> 
+  #   nb = nc.real              # should be equal to na except round errors  
+  #   p (nb - na).abs.max       # => 8.970743058303247e-17 (sufficiently small)
+  # 
+  #   # <example 3: complex FFT along a dimension >
+  #   fc = FFTW3.fft_fw(na, 0)  # forward 1D FFT along the first dim
+  #   nc = FFTW3.fft_bk(fc, 0)  # backward 1D FFT along the first dim
+  #   p (nc.real - na).abs.max  # => 1.1102230246251565e-16 (sufficiently small)
+  # 
+  #   # <example 4: complex FFT along a dimension >
+  #   fc = FFTW3.fft_fw(na, 1)  # forward 1D FFT along the second dim
+  # 
+  #   # <example 5: real FFT along a dimension >
+  # 
+  #   fc = FFTW3.fft_r2r(na, FFTW3::RODFT00, 0)  # not normalized sine transform along the 1st dim
+  #   len = 2*(na.shape[0]+1)    # this is the supposed length of this transformation
+  #   nc = FFTW3.fft_r2r(fc/len, FFTW3::RODFT00, 0)  # forward==backward transformation
+  #   p (nc-na).abs.max          # => 2.220446049250313e-16 (sufficiently small)
+  # 
+  #   # <example 5b: real FFT on all dimensions >
+  # 
+  #   fc = FFTW3.fft_r2r(na, FFTW3::REDFT11)   # unnormalized cosine transform
+  #   len = 4*na.length          # from (2*na.shape[0]) * (2*na.shape[1])
+  #   nc = FFTW3.fft_r2r(fc/len, FFTW3::REDFT11)   # forward==backward transformation
+  #   p (nc-na).abs.max          # => 6.228190483314256e-17 (sufficiently small)
+  #   
+  # See the FFTW3 manual for the kinds of supported real FFTs. See Ch.2 of
+  # http://www.fftw.org/fftw3_doc/ (http://www.fftw.org/fftw3.pdf).
+  # Virtually all kinds are supported!
+  # 
+  module FFTW3
+
+    module_function
+
+    # Forward complex FFT with normalization
+    # 
+    # This calls FFW3.fft(na, FFW3::FORWARD, *dims) and normalizes the result
+    # by dividing by the length
+    # 
+    def fft_fw(na, *dims)
+      fc = fft(na, FORWARD, *dims)
+      if dims.length == 0
+        len = na.total
+      else
+        len = 1
+        shape = na.shape
+        dims.each{|d| len *= shape[d]}
+      end
+      fc / len
+    end
+
+    # Backward complex FFT
+    # 
+    # This method simply calls FFW3.fft(na, FFW3::BACKWARD, *dims)
+    # 
+    def fft_bk(na, *dims)
+      fft(na, BACKWARD, *dims)
+    end
+  end
+end
diff --git a/lib/numru/fftw3/version.rb b/lib/numru/fftw3/version.rb
index 775d97e..4fb22fe 100644
--- a/lib/numru/fftw3/version.rb
+++ b/lib/numru/fftw3/version.rb
@@ -1,5 +1,5 @@
 module NumRu
   module FFTW3
-    VERSION = "0.4.2"
+    VERSION = "1.0.1"
   end
 end
diff --git a/test/complexFFT.rb b/test/complexFFT.rb
index e8dde6d..9875bce 100644
--- a/test/complexFFT.rb
+++ b/test/complexFFT.rb
@@ -4,40 +4,59 @@ rescue LoadError
 end
 require "narray"  # This line is needed for rake test when making a gem package.
 require "numru/fftw3"
+require "test/unit"
 include NumRu
 
-print "\n**TEST** all dimensions\n\n"
-
-na = NArray.float(8,4).fill(1)  # will be corced to complex
-na[1,1]=5
-p na
-fc = FFTW3.fft(na, -1)/na.length 
-p fc
-p fc.real
-
-p FFTW3.fft(fc, 1).real
-
-print "\n**TEST** single float (treated as single if lib fftw3f exits)\n"
-print " --- see http://www.fftw.org/fftw3_doc/Precision.html for more info\n\n"
-na = NArray.sfloat(8,4).indgen!
-fc = FFTW3.fft(na, -1)/na.length 
-p fc
-p FFTW3.fft(fc, 1).real
-
-print "\n**TEST** dimension selection\n\n"
-
-fc = FFTW3.fft(na, -1, 0)/na.shape[0]
-p fc
-p FFTW3.fft(fc, 1, 0).real
-fc = FFTW3.fft(na, -1, 1)/na.shape[1]
-p fc
-p FFTW3.fft(fc, 1, 1).real
-
-na = NArray.float(4,3,8,3)
-na[1,1,1,0]= 1
-p( fc=FFTW3.fft(na, -1, 0,2) / (na.shape[0]*na.shape[2]) )
-p( fc=FFTW3.fft(na, -1, 1) / na.shape[1] )
-p( fc=FFTW3.fft(na, -1, 0,1,2)  / (na.shape[0]*na.shape[1]*na.shape[2]) )
-p FFTW3.fft(fc, 1, 0,1,2).real
+class FFTW3Test < Test::Unit::TestCase
+  def setup
+    @eps = 1e-10
+    @seps = 1e-6
+  end
+
+  def test_fft_fw_bk
+    na = NArray.float(8,4).fill(1)  # will be corced to complex
+    na[1,1]=5
+    fc = FFTW3.fft_fw(na)
+    nb = FFTW3.fft_bk(fc).real
+    assert( (na-nb).abs.max < @eps )
+
+    fc = FFTW3.fft_fw(na,1)
+    nb = FFTW3.fft_bk(fc,1).real
+    assert( (na-nb).abs.max < @eps )
+  end
+
+  def test_real_all_dims
+    na = NArray.float(8,4).fill(1)  # will be corced to complex
+    na[1,1]=5
+    fc = FFTW3.fft(na, FFTW3::FORWARD)/na.length 
+    nb = FFTW3.fft(fc, FFTW3::BACKWARD).real
+    assert( (na-nb).abs.max < @eps )
+  end
+
+  def test_complex_all_dims
+    na = NArray.complex(8,4).fill(1) * Complex::I
+    na[1,1]=5
+    fc = FFTW3.fft(na, -1)/na.length 
+    nb = FFTW3.fft(fc, 1)
+    assert( (na-nb).abs.max < @eps )
+  end
+
+  def test_dim_selection
+    na = NArray.float(8,4).indgen!
+    fc = FFTW3.fft(na, FFTW3::FORWARD, 0)
+    fc = FFTW3.fft(fc, FFTW3::FORWARD, 1)
+    fc2 = FFTW3.fft(na, FFTW3::FORWARD)
+    assert( (fc-fc2).abs.max < @eps )
+  end
+
+  # TEST: single float (treated as single if lib fftw3f exits).
+  # see http://www.fftw.org/fftw3_doc/Precision.html for more info
+  def test_single_float
+    na = NArray.sfloat(8,4).indgen!
+    fc = FFTW3.fft(na, -1)/na.length 
+    nb = FFTW3.fft(fc, 1).real
+    assert( (na-nb).abs.max < @seps )
+  end
+end
 
 
diff --git a/test/r2rFFT.rb b/test/r2rFFT.rb
new file mode 100644
index 0000000..96954a0
--- /dev/null
+++ b/test/r2rFFT.rb
@@ -0,0 +1,77 @@
+require "narray"  # This line is needed for rake test when making a gem package.
+require "numru/fftw3"
+require "test/unit"
+include NumRu
+
+class FFTW3_R2R_Test < Test::Unit::TestCase
+  def setup
+    @eps = 1e-10
+    @seps = 1e-5
+  end
+
+  def test_r2r_all_dims
+    nx = 8
+    ny = 4
+    na = NArray.float(nx,ny).indgen!
+
+    fc = FFTW3.fft_r2r(na, FFTW3::REDFT00)  # cosine trans at 0, 1, 2,...
+    c = 1.0 / (2*(nx-1)) / (2*(ny-1))
+    nb = FFTW3.fft_r2r(fc*c, FFTW3::REDFT00)
+    assert( (na-nb).abs.max < @eps )
+
+    fc = FFTW3.fft_r2r(na, FFTW3::REDFT11)  # cosine trans at 1/2, 1+1/2,...
+    c = 1.0 / (2*nx) / (2*ny)
+    nb = FFTW3.fft_r2r(fc*c, FFTW3::REDFT11)
+    assert( (na-nb).abs.max < @eps )
+
+    fc = FFTW3.fft_r2r(na, FFTW3::REDFT01)
+    c = 1.0 / (2*nx) / (2*ny)
+    nb = FFTW3.fft_r2r(fc*c, FFTW3::REDFT10)
+    assert( (na-nb).abs.max < @eps )
+
+    fc = FFTW3.fft_r2r(na, FFTW3::RODFT00)  # sine trans at 1, 2,...
+    c = 1.0 / (2*(nx+1)) / (2*(ny+1))
+    nb = FFTW3.fft_r2r(fc*c, FFTW3::RODFT00)
+    assert( (na-nb).abs.max < @eps )
+
+    fc = FFTW3.fft_r2r(na, FFTW3::RODFT11)  # sine trans at 1/2, 1+1/2,...
+    c = 1.0 / (2*nx) / (2*ny)
+    nb = FFTW3.fft_r2r(fc*c, FFTW3::RODFT11)
+    assert( (na-nb).abs.max < @eps )
+
+    fc = FFTW3.fft_r2r(na, FFTW3::RODFT01)  # sine trans
+    c = 1.0 / (2*nx) / (2*ny)
+    nb = FFTW3.fft_r2r(fc*c, FFTW3::RODFT10)
+    assert( (na-nb).abs.max < @eps )
+
+  end
+
+  def test_r2r_sigle
+    nx = 8
+    ny = 4
+    na = NArray.sfloat(nx,ny).indgen!
+
+    fc = FFTW3.fft_r2r(na, FFTW3::REDFT00)  # cosine trans at 0, 1, 2,...
+    c = 1.0 / (2*(nx-1)) / (2*(ny-1))
+    nb = FFTW3.fft_r2r(fc*c, FFTW3::REDFT00)
+    assert( (na-nb).abs.max < @seps )
+  end
+
+
+  def test_r2r_some_dims
+    nx = 8
+    ny = 4
+    na = NArray.float(nx,ny).indgen!
+
+    fc = FFTW3.fft_r2r(na, FFTW3::REDFT00, 0)
+    nb = FFTW3.fft_r2r(fc, FFTW3::REDFT00, 0) / (2*(nx-1))
+    assert( (na-nb).abs.max < @eps )
+
+    fc = FFTW3.fft_r2r(fc, FFTW3::RODFT11, 1)
+    fc2 = FFTW3.fft_r2r(na, [FFTW3::REDFT00, FFTW3::RODFT11])
+    fc3 = FFTW3.fft_r2r(na, [FFTW3::REDFT00, FFTW3::RODFT11], 0, 1)
+    assert( (fc-fc2).abs.max < @eps )
+    assert( (fc-fc3).abs.max < @eps )
+  end
+
+end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-fftw3.git



More information about the Pkg-ruby-extras-commits mailing list