[pyfftw] 02/10: Imported Upstream version 0.10.1+dfsg1

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Wed Feb 10 11:40:01 UTC 2016


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

ghisvail-guest pushed a commit to branch master
in repository pyfftw.

commit 2212bb090cd1bd81d81bdd5ea983031645b1961e
Author: Ghislain Antony Vaillant <ghisvail at gmail.com>
Date:   Fri Jan 29 18:23:40 2016 +0000

    Imported Upstream version 0.10.1+dfsg1
---
 CHANGELOG.md                         |   146 +
 COPYING.txt                          |   675 -
 LICENSE.txt                          |   699 +-
 MANIFEST.in                          |    13 +
 PKG-INFO                             |     4 +-
 README.rst                           |    79 +-
 include/cpu.h                        |    43 +-
 include/msvc_2010/stdint.h           |   264 +
 include/pyfftw_complex.h             |    44 +-
 PKG-INFO => pyFFTW.egg-info/PKG-INFO |     4 +-
 pyFFTW.egg-info/SOURCES.txt          |    81 +
 pyFFTW.egg-info/dependency_links.txt |     1 +
 pyFFTW.egg-info/top_level.txt        |     1 +
 pyfftw/__init__.py                   |    11 +-
 pyfftw/_version.py                   |     2 -
 pyfftw/builders/_utils.py            |   103 +-
 pyfftw/builders/builders.py          |    57 +-
 pyfftw/cpu.pxd                       |    38 +-
 pyfftw/interfaces/__init__.py        |    10 +-
 pyfftw/interfaces/_utils.py          |    56 +-
 pyfftw/interfaces/cache.py           |    50 +-
 pyfftw/interfaces/numpy_fft.py       |   108 +-
 pyfftw/interfaces/scipy_fftpack.py   |   178 +-
 pyfftw/np_fft.py                     |    43 -
 pyfftw/pyfftw.c                      | 30406 +++++++++++++++++++--------------
 pyfftw/pyfftw.pxd                    |    60 +-
 pyfftw/pyfftw.pyx                    |   621 +-
 pyfftw/utils.pxi                     |   219 +-
 pyfftw/version.py                    |    13 +
 setup.cfg                            |     5 +
 setup.py                             |   444 +-
 test/test_pyfftw_base.py             |    44 +-
 test/test_pyfftw_builders.py         |   346 +-
 test/test_pyfftw_call.py             |   200 +-
 test/test_pyfftw_class_misc.py       |   212 +-
 test/test_pyfftw_complex.py          |   202 +-
 test/test_pyfftw_interfaces_cache.py |    77 +-
 test/test_pyfftw_multithreaded.py    |    40 +-
 test/test_pyfftw_nbyte_align.py      |   240 +-
 test/test_pyfftw_numpy_interface.py  |   229 +-
 test/test_pyfftw_real_backward.py    |    57 +-
 test/test_pyfftw_real_forward.py     |    40 +-
 test/test_pyfftw_scipy_interface.py  |   108 +-
 test/test_pyfftw_utils.py            |    38 +-
 test/test_pyfftw_wisdom.py           |    44 +-
 45 files changed, 21027 insertions(+), 15328 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..5cebc79
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,146 @@
+# Change Log
+
+## [v0.10.1](https://github.com/hgomersall/pyFFTW/tree/v0.10.1) (2016-01-29)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.10.0...v0.10.1)
+
+## [v0.10.0](https://github.com/hgomersall/pyFFTW/tree/v0.10.0) (2016-01-29)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.9.2...v0.10.0)
+
+**Closed issues:**
+
+- Conda downloads are failing [\#76](https://github.com/hgomersall/pyFFTW/issues/76)
+- Python 3.4 and WinPython [\#74](https://github.com/hgomersall/pyFFTW/issues/74)
+- Installing pyfftw on Anaconda3 on Windows 7 [\#73](https://github.com/hgomersall/pyFFTW/issues/73)
+- is python 3.5 supported? [\#71](https://github.com/hgomersall/pyFFTW/issues/71)
+- deadlock of cache handler at interpreter shutdown [\#69](https://github.com/hgomersall/pyFFTW/issues/69)
+- pyFFTW breaks when forked [\#65](https://github.com/hgomersall/pyFFTW/issues/65)
+- build with mingw [\#62](https://github.com/hgomersall/pyFFTW/issues/62)
+- Striding in n\_byte\_align not on a uniform standard [\#61](https://github.com/hgomersall/pyFFTW/issues/61)
+- No exception on wrong arguments of function call of pyfftw.FFTW\(...\) [\#60](https://github.com/hgomersall/pyFFTW/issues/60)
+- pyfftw vs numpy.fft: faster and slower [\#58](https://github.com/hgomersall/pyFFTW/issues/58)
+- simple transposes? [\#57](https://github.com/hgomersall/pyFFTW/issues/57)
+- `Datatype not supported` with scipy [\#56](https://github.com/hgomersall/pyFFTW/issues/56)
+- Update tutorial with new byte align functions [\#53](https://github.com/hgomersall/pyFFTW/issues/53)
+- OS X Installation errors:  [\#52](https://github.com/hgomersall/pyFFTW/issues/52)
+- Wrong results for pyfftw's ifft? [\#51](https://github.com/hgomersall/pyFFTW/issues/51)
+- Installing on OS X Mavericks [\#49](https://github.com/hgomersall/pyFFTW/issues/49)
+- Install error. Ld cannot find -lfftw3f [\#48](https://github.com/hgomersall/pyFFTW/issues/48)
+- new source release with updated licensing  [\#43](https://github.com/hgomersall/pyFFTW/issues/43)
+- Crash during initialization of FFTW plan for r2c and c2r with Intel compiler [\#37](https://github.com/hgomersall/pyFFTW/issues/37)
+- Move FFTW class definition to pyfftw.pxd [\#36](https://github.com/hgomersall/pyFFTW/issues/36)
+- Provide transform metadata such as axes and direction [\#34](https://github.com/hgomersall/pyFFTW/issues/34)
+- Provide shape and dtype properties [\#33](https://github.com/hgomersall/pyFFTW/issues/33)
+- problem with very large arrays: OverflowError: value too large to convert to int [\#30](https://github.com/hgomersall/pyFFTW/issues/30)
+- add support for in-place multidimensional r2c  transform [\#29](https://github.com/hgomersall/pyFFTW/issues/29)
+- Add numpy interface for hfft [\#28](https://github.com/hgomersall/pyFFTW/issues/28)
+- add cython as a build dependency [\#25](https://github.com/hgomersall/pyFFTW/issues/25)
+- Potential memory leak in caching [\#22](https://github.com/hgomersall/pyFFTW/issues/22)
+- Allow GIL to be released with threads=1 [\#13](https://github.com/hgomersall/pyFFTW/issues/13)
+- Building for 64bit windows [\#12](https://github.com/hgomersall/pyFFTW/issues/12)
+- Test failure using numpy 1.6.2  [\#9](https://github.com/hgomersall/pyFFTW/issues/9)
+- Remove the requirement for users to specify alignment [\#8](https://github.com/hgomersall/pyFFTW/issues/8)
+- pyfftw.interfaces can only handle numpy arrays [\#7](https://github.com/hgomersall/pyFFTW/issues/7)
+
+**Merged pull requests:**
+
+- Release GIL during both single- and multi-thread execution \(cleaned up patch\) [\#81](https://github.com/hgomersall/pyFFTW/pull/81) ([zpincus](https://github.com/zpincus))
+- Support FFTW\_WISDOM\_ONLY \(cleaned up patch\) [\#80](https://github.com/hgomersall/pyFFTW/pull/80) ([zpincus](https://github.com/zpincus))
+- Release GIL around FFTW planning [\#78](https://github.com/hgomersall/pyFFTW/pull/78) ([zpincus](https://github.com/zpincus))
+- Updated the tutorial to reflect changes with new aligned array creation functions. [\#54](https://github.com/hgomersall/pyFFTW/pull/54) ([drwells](https://github.com/drwells))
+- Add description for installing on OS X [\#50](https://github.com/hgomersall/pyFFTW/pull/50) ([arve0](https://github.com/arve0))
+- close issue \#8 \(More numpy like aligned array creation functions\) [\#44](https://github.com/hgomersall/pyFFTW/pull/44) ([drwells](https://github.com/drwells))
+- Discrete sine transform imports [\#42](https://github.com/hgomersall/pyFFTW/pull/42) ([insertinterestingnamehere](https://github.com/insertinterestingnamehere))
+
+## [v0.9.2](https://github.com/hgomersall/pyFFTW/tree/v0.9.2) (2013-09-20)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.9.2_docs...v0.9.2)
+
+## [v0.9.2_docs](https://github.com/hgomersall/pyFFTW/tree/v0.9.2_docs) (2013-09-11)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.9.1_docs...v0.9.2_docs)
+
+## [v0.9.1_docs](https://github.com/hgomersall/pyFFTW/tree/v0.9.1_docs) (2013-09-11)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.9.1...v0.9.1_docs)
+
+## [v0.9.1](https://github.com/hgomersall/pyFFTW/tree/v0.9.1) (2013-09-11)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.9_docs...v0.9.1)
+
+**Closed issues:**
+
+- Overwriting previous input when cache is enabled. [\#23](https://github.com/hgomersall/pyFFTW/issues/23)
+- Race condition in cache culling [\#21](https://github.com/hgomersall/pyFFTW/issues/21)
+- Memory corruption at exit [\#19](https://github.com/hgomersall/pyFFTW/issues/19)
+- In-place transform? [\#18](https://github.com/hgomersall/pyFFTW/issues/18)
+- Support for 2.6? [\#17](https://github.com/hgomersall/pyFFTW/issues/17)
+- Install fails; can't find library? [\#16](https://github.com/hgomersall/pyFFTW/issues/16)
+- Please include cython source code [\#11](https://github.com/hgomersall/pyFFTW/issues/11)
+- Make repeated axes act like numpy.fft's repeated axes [\#2](https://github.com/hgomersall/pyFFTW/issues/2)
+- Implement numpy.fft API to pyfftw [\#1](https://github.com/hgomersall/pyFFTW/issues/1)
+
+**Merged pull requests:**
+
+- register fftw cleanup with Py\_AtExit [\#20](https://github.com/hgomersall/pyFFTW/pull/20) ([rainwoodman](https://github.com/rainwoodman))
+
+## [v0.9_docs](https://github.com/hgomersall/pyFFTW/tree/v0.9_docs) (2013-02-15)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.9...v0.9_docs)
+
+## [v0.9](https://github.com/hgomersall/pyFFTW/tree/v0.9) (2013-02-15)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.8.2_docs...v0.9)
+
+**Closed issues:**
+
+- Issue getting PyFFTW to import in Python 3 [\#6](https://github.com/hgomersall/pyFFTW/issues/6)
+- Some tests fail [\#5](https://github.com/hgomersall/pyFFTW/issues/5)
+- n\_byte\_array\(\) and n\_byte\_align\_empty\(\) break for large arrays [\#4](https://github.com/hgomersall/pyFFTW/issues/4)
+
+## [v0.8.2_docs](https://github.com/hgomersall/pyFFTW/tree/v0.8.2_docs) (2012-05-29)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.8.2...v0.8.2_docs)
+
+## [v0.8.2](https://github.com/hgomersall/pyFFTW/tree/v0.8.2) (2012-05-29)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.8.1_docs...v0.8.2)
+
+**Closed issues:**
+
+- export\_wisdom\(\) fails on windows 7 and vista [\#3](https://github.com/hgomersall/pyFFTW/issues/3)
+
+## [v0.8.1_docs](https://github.com/hgomersall/pyFFTW/tree/v0.8.1_docs) (2012-05-20)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.8.1...v0.8.1_docs)
+
+## [v0.8.1](https://github.com/hgomersall/pyFFTW/tree/v0.8.1) (2012-05-20)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.8.0_docs...v0.8.1)
+
+## [v0.8.0_docs](https://github.com/hgomersall/pyFFTW/tree/v0.8.0_docs) (2012-04-08)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.8.0...v0.8.0_docs)
+
+## [v0.8.0](https://github.com/hgomersall/pyFFTW/tree/v0.8.0) (2012-04-08)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.7.0_docs...v0.8.0)
+
+## [v0.7.0_docs](https://github.com/hgomersall/pyFFTW/tree/v0.7.0_docs) (2012-03-04)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.7.0...v0.7.0_docs)
+
+## [v0.7.0](https://github.com/hgomersall/pyFFTW/tree/v0.7.0) (2012-02-29)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.6.1_docs...v0.7.0)
+
+## [v0.6.1_docs](https://github.com/hgomersall/pyFFTW/tree/v0.6.1_docs) (2012-02-26)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.6.1...v0.6.1_docs)
+
+## [v0.6.1](https://github.com/hgomersall/pyFFTW/tree/v0.6.1) (2012-02-26)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.6.0_docs...v0.6.1)
+
+## [v0.6.0_docs](https://github.com/hgomersall/pyFFTW/tree/v0.6.0_docs) (2012-02-06)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.6.0...v0.6.0_docs)
+
+## [v0.6.0](https://github.com/hgomersall/pyFFTW/tree/v0.6.0) (2012-02-06)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.5.1_docs...v0.6.0)
+
+## [v0.5.1_docs](https://github.com/hgomersall/pyFFTW/tree/v0.5.1_docs) (2012-02-05)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.5.1...v0.5.1_docs)
+
+## [v0.5.1](https://github.com/hgomersall/pyFFTW/tree/v0.5.1) (2012-02-04)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.5.0...v0.5.1)
+
+## [v0.5.0](https://github.com/hgomersall/pyFFTW/tree/v0.5.0) (2012-02-01)
+[Full Changelog](https://github.com/hgomersall/pyFFTW/compare/v0.5.0_docs...v0.5.0)
+
+## [v0.5.0_docs](https://github.com/hgomersall/pyFFTW/tree/v0.5.0_docs) (2012-02-01)
+
+
+\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
\ No newline at end of file
diff --git a/COPYING.txt b/COPYING.txt
deleted file mode 100644
index 10926e8..0000000
--- a/COPYING.txt
+++ /dev/null
@@ -1,675 +0,0 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-
diff --git a/LICENSE.txt b/LICENSE.txt
index 10e50ff..0bf19ab 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,683 +1,34 @@
-Most of the code in this library are released under the GNU GPL 3, the
-license for which is set out below.
 
-Notable exceptions are fftw3.h and stdint.h in include/win/, the licenses,
-which are given inside the files, are the BSD 2- and 3-clause licenses
-respectively.
+Except for fftw3.h, all the code in pyfftw is released under the 3-clause
+BSD license (set out below).
 
+fftw3.h is released under the 2-clause BSD license.
 
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
+See each file for the copyright holder.
 
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
 
-                            Preamble
+* Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
 
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
+* Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
 
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
+* Neither the name of the copyright holder nor the names of its contributors
+may be used to endorse or promote products derived from this software without
+specific prior written permission.
 
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
 
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..b2c2cba
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,13 @@
+include CHANGELOG.md
+include LICENSE.txt
+include requirements.txt
+include README.rst
+include pyfftw/pyfftw.c
+include pyfftw/pyfftw.pyx
+include pyfftw/pyfftw.pxd
+include pyfftw/cpu.pxd
+include pyfftw/utils.pxi
+include test/test_*.py
+include test/__init__.py
+recursive-include include *.h
+recursive-include docs *.html *.css *.png *.js *.rst
diff --git a/PKG-INFO b/PKG-INFO
index d9dce81..8913dcb 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pyFFTW
-Version: 0.9.2
+Version: 0.10.1
 Summary: A pythonic wrapper around FFTW, the FFT library, presenting a unified interface for all the supported transforms.
 Home-page: http://hgomersall.github.com/pyFFTW/
 Author: Henry Gomersall
@@ -40,7 +40,7 @@ Platform: UNKNOWN
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
 Classifier: Development Status :: 4 - Beta
-Classifier: License :: OSI Approved :: GNU General Public License (GPL)
+Classifier: License :: OSI Approved :: BSD License
 Classifier: Operating System :: OS Independent
 Classifier: Intended Audience :: Developers
 Classifier: Intended Audience :: Science/Research
diff --git a/README.rst b/README.rst
index e0c2d28..e0d01c8 100644
--- a/README.rst
+++ b/README.rst
@@ -1,3 +1,19 @@
++----------+---------------+
+| CI       | Master branch |
++==========+===============+
+| Travis   | |travis_ci|   |
++----------+---------------+
+| Appveyor | |appveyor_ci| |
++----------+---------------+
+
+.. |travis_ci| image:: https://travis-ci.org/hgomersall/pyFFTW.png?branch=master
+   :align: middle
+   :target: https://travis-ci.org/hgomersall/pyFFTW
+
+.. |appveyor_ci| image:: https://ci.appveyor.com/api/projects/status/uf854abck4x1qsjj/branch/master?svg=true
+   :align: middle
+   :target: https://ci.appveyor.com/project/hgomersall/pyfftw
+
 PyFFTW
 ======
 
@@ -51,6 +67,15 @@ all the necessary DLLs.
 
 With FFTW installed, the PyPI release should install fine on Linux and Mac OSX. It doesn't mean it won't work anywhere else, just we don't have any information on it.
 
+Windows development builds are also automatically uploaded to 
+`bintray <https://bintray.com/hgomersall/generic/PyFFTW-development-builds/view>`_ 
+as wheels (which are built against numpy 1.9), from where they can be 
+downloaded and installed with something like::
+
+  pip install pyFFTW-0.10.0.dev0+79ec589-cp35-none-win_amd64.whl
+
+where the version and the revision hash are set accordingly.
+
 Read on if you do want to build from source...
 
 Building
@@ -69,7 +94,8 @@ normal C extension in the ``pyfftw`` directory.
 Further building does not depend on cython (as long as the .c file remains).
 
 For more ways of building and installing, see the 
-`distutils documentation <http://docs.python.org/distutils/builtdist.html>`_
+`distutils documentation <http://docs.python.org/distutils/builtdist.html>`_ 
+and `setuptools documentation <https://pythonhosted.org/setuptools/>`_.
 
 Platform specific build info
 ----------------------------
@@ -88,7 +114,7 @@ The builds on PyPI use mingw for the 32-bit release and the Windows SDK
 C++ compiler for the 64-bit release. The scripts should handle this 
 automatically. If you want to compile for 64-bit Windows, you have to use
 the MS Visual C++ compiler. Set up your environment as described 
-`here <http://wiki.cython.org/64BitCythonExtensionsOnWindows>`_ and then
+`here <https://github.com/cython/cython/wiki/CythonExtensionsOnWindows>`_ and then
 run `setup.py` with the version of python you wish to target and a suitable
 build command.
 
@@ -98,6 +124,53 @@ suitable `.lib` files as described on the
 
 Mac OSX
 ~~~~~~~
+Install FFTW from `homebrew <http://brew.sh>`_::
+
+  brew install fftw
+
+Set temporary environmental variables, such that pyfftw finds fftw::
+
+  export DYLD_LIBRARY_PATH=/usr/local/lib
+  export LDFLAGS="-L/usr/local/include"
+  export CFLAGS="-I/usr/local/include"
+
+Now install pyfftw from pip::
+
+  pip install pyfftw
+
+Notes: `pkgin <http://saveosx.org>`_ fftw package does not contain the long 
+or float implementations of fftw and so installation will fail.
+
+It has been suggested that `macports <http://www.macports.org/>`_ might also 
+work fine. You should then replace the LD environmental variables above with the 
+right ones.
+
+- DYLD - path for libfftw3.dylib etc - ``find /usr -name libfftw3.dylib``
+- LDFLAGS - path for fftw3.h - ``find /usr -name fftw3.h``
+
+Contributions
+-------------
+
+Contributions are always welcome and valued. The primary restriction on
+accepting contributions is that they are exhaustively tested. The bulk of
+pyFFTW has been developed in a test-driven way (i.e. the test to be 
+satisfied is written before the code). I strongly encourage potential
+contributors to adopt such an approach.
+
+See some of my philosophy on testing in development `here
+<https://hgomersall.wordpress.com/2014/10/03/from-test-driven-development-and-specifications/>`_.
+If you want to argue with the philosophy, there is probably a good place to
+do it.
+
+New contributions should adhere to pep-8, but this is only weakly enforced 
+(there is loads of legacy stuff that breaks it, and things like a single
+trailing whitespace is not a big deal).
+
+The best place to start with contributing is by raising an issue detailing the
+specifics of what you wish to achieve (there should be a clear use-case for
+any new functionality). I tend to respond pretty quickly and am happy to help
+where I can with any conceptual issues.
 
-It has been suggested that FFTW should be installed from `macports <http://www.macports.org/>`_.
+I suggest reading the issues already open in order that you know where things
+might be heading, or what others are working on.
 
diff --git a/include/cpu.h b/include/cpu.h
index 4c28ccd..e8b166e 100644
--- a/include/cpu.h
+++ b/include/cpu.h
@@ -1,21 +1,36 @@
 /*
- * Copyright 2013 Knowledge Economy Developments Ltd
+ * Copyright 2014 Knowledge Economy Developments Ltd
  * 
  * Henry Gomersall
  * heng at kedevelopments.co.uk
- * 
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 
 /* Small utilities for inspecting the CPU */
diff --git a/include/msvc_2010/stdint.h b/include/msvc_2010/stdint.h
new file mode 100644
index 0000000..ecf96e7
--- /dev/null
+++ b/include/msvc_2010/stdint.h
@@ -0,0 +1,264 @@
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006-2013 Alexander Chemeris
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+// 
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+// 
+//   3. Neither the name of the product nor the names of its contributors may
+//      be used to endorse or promote products derived from this software
+//      without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+// We comment out the restriction to use the default stdint.h
+// This fix is to make sure the stdint we define here is used by appveyor
+// for msvc 2010. This shouldn't need to be done, but it does. It's
+// probably safe regardless.
+//#if _MSC_VER >= 1600 // [
+//#if _MSC_VER >= 1600
+//#include <stdint.h>
+//#else // ] _MSC_VER >= 1600 [
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+#  include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#     define _W64 __w64
+#  else
+#     define _W64
+#  endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+   typedef signed char       int8_t;
+   typedef signed short      int16_t;
+   typedef signed int        int32_t;
+   typedef unsigned char     uint8_t;
+   typedef unsigned short    uint16_t;
+   typedef unsigned int      uint32_t;
+#else
+   typedef signed __int8     int8_t;
+   typedef signed __int16    int16_t;
+   typedef signed __int32    int32_t;
+   typedef unsigned __int8   uint8_t;
+   typedef unsigned __int16  uint16_t;
+   typedef unsigned __int32  uint32_t;
+#endif
+typedef signed __int64       int64_t;
+typedef unsigned __int64     uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t    int_least8_t;
+typedef int16_t   int_least16_t;
+typedef int32_t   int_least32_t;
+typedef int64_t   int_least64_t;
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+typedef uint64_t  uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t    int_fast8_t;
+typedef int16_t   int_fast16_t;
+typedef int32_t   int_fast32_t;
+typedef int64_t   int_fast64_t;
+typedef uint8_t   uint_fast8_t;
+typedef uint16_t  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+typedef uint64_t  uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+   typedef signed __int64    intptr_t;
+   typedef unsigned __int64  uintptr_t;
+#else // _WIN64 ][
+   typedef _W64 signed int   intptr_t;
+   typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t   intmax_t;
+typedef uint64_t  uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN     ((int8_t)_I8_MIN)
+#define INT8_MAX     _I8_MAX
+#define INT16_MIN    ((int16_t)_I16_MIN)
+#define INT16_MAX    _I16_MAX
+#define INT32_MIN    ((int32_t)_I32_MIN)
+#define INT32_MAX    _I32_MAX
+#define INT64_MIN    ((int64_t)_I64_MIN)
+#define INT64_MAX    _I64_MAX
+#define UINT8_MAX    _UI8_MAX
+#define UINT16_MAX   _UI16_MAX
+#define UINT32_MAX   _UI32_MAX
+#define UINT64_MAX   _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN    INT8_MIN
+#define INT_LEAST8_MAX    INT8_MAX
+#define INT_LEAST16_MIN   INT16_MIN
+#define INT_LEAST16_MAX   INT16_MAX
+#define INT_LEAST32_MIN   INT32_MIN
+#define INT_LEAST32_MAX   INT32_MAX
+#define INT_LEAST64_MIN   INT64_MIN
+#define INT_LEAST64_MAX   INT64_MAX
+#define UINT_LEAST8_MAX   UINT8_MAX
+#define UINT_LEAST16_MAX  UINT16_MAX
+#define UINT_LEAST32_MAX  UINT32_MAX
+#define UINT_LEAST64_MAX  UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN    INT8_MIN
+#define INT_FAST8_MAX    INT8_MAX
+#define INT_FAST16_MIN   INT16_MIN
+#define INT_FAST16_MAX   INT16_MAX
+#define INT_FAST32_MIN   INT32_MIN
+#define INT_FAST32_MAX   INT32_MAX
+#define INT_FAST64_MIN   INT64_MIN
+#define INT_FAST64_MAX   INT64_MAX
+#define UINT_FAST8_MAX   UINT8_MAX
+#define UINT_FAST16_MAX  UINT16_MAX
+#define UINT_FAST32_MAX  UINT32_MAX
+#define UINT_FAST64_MAX  UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+#  define INTPTR_MIN   INT64_MIN
+#  define INTPTR_MAX   INT64_MAX
+#  define UINTPTR_MAX  UINT64_MAX
+#else // _WIN64 ][
+#  define INTPTR_MIN   INT32_MIN
+#  define INTPTR_MAX   INT32_MAX
+#  define UINTPTR_MAX  UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN   INT64_MIN
+#define INTMAX_MAX   INT64_MAX
+#define UINTMAX_MAX  UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+#  define PTRDIFF_MIN  _I64_MIN
+#  define PTRDIFF_MAX  _I64_MAX
+#else  // _WIN64 ][
+#  define PTRDIFF_MIN  _I32_MIN
+#  define PTRDIFF_MAX  _I32_MAX
+#endif  // _WIN64 ]
+
+#define SIG_ATOMIC_MIN  INT_MIN
+#define SIG_ATOMIC_MAX  INT_MAX
+
+#ifndef SIZE_MAX // [
+#  ifdef _WIN64 // [
+#     define SIZE_MAX  _UI64_MAX
+#  else // _WIN64 ][
+#     define SIZE_MAX  _UI32_MAX
+#  endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+#  define WCHAR_MIN  0
+#endif  // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+#  define WCHAR_MAX  _UI16_MAX
+#endif  // WCHAR_MAX ]
+
+#define WINT_MIN  0
+#define WINT_MAX  _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val)  val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val)  val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
+// Check out Issue 9 for the details.
+#ifndef INTMAX_C //   [
+#  define INTMAX_C   INT64_C
+#endif // INTMAX_C    ]
+#ifndef UINTMAX_C //  [
+#  define UINTMAX_C  UINT64_C
+#endif // UINTMAX_C   ]
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+//#endif // _MSC_VER >= 1600 ]
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/include/pyfftw_complex.h b/include/pyfftw_complex.h
index 0d711ce..63a627a 100644
--- a/include/pyfftw_complex.h
+++ b/include/pyfftw_complex.h
@@ -1,22 +1,36 @@
-
 /*
- * Copyright 2013 Knowledge Economy Developments Ltd
+ * Copyright 2014 Knowledge Economy Developments Ltd
  * 
  * Henry Gomersall
  * heng at kedevelopments.co.uk
- * 
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 
 /* Defines complex types that are bit compatible with C99's complex.h
diff --git a/PKG-INFO b/pyFFTW.egg-info/PKG-INFO
similarity index 96%
copy from PKG-INFO
copy to pyFFTW.egg-info/PKG-INFO
index d9dce81..8913dcb 100644
--- a/PKG-INFO
+++ b/pyFFTW.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: pyFFTW
-Version: 0.9.2
+Version: 0.10.1
 Summary: A pythonic wrapper around FFTW, the FFT library, presenting a unified interface for all the supported transforms.
 Home-page: http://hgomersall.github.com/pyFFTW/
 Author: Henry Gomersall
@@ -40,7 +40,7 @@ Platform: UNKNOWN
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
 Classifier: Development Status :: 4 - Beta
-Classifier: License :: OSI Approved :: GNU General Public License (GPL)
+Classifier: License :: OSI Approved :: BSD License
 Classifier: Operating System :: OS Independent
 Classifier: Intended Audience :: Developers
 Classifier: Intended Audience :: Science/Research
diff --git a/pyFFTW.egg-info/SOURCES.txt b/pyFFTW.egg-info/SOURCES.txt
new file mode 100644
index 0000000..57278b4
--- /dev/null
+++ b/pyFFTW.egg-info/SOURCES.txt
@@ -0,0 +1,81 @@
+CHANGELOG.md
+LICENSE.txt
+MANIFEST.in
+README.rst
+requirements.txt
+setup.py
+/home/whg/Projects/github/pyFFTW/pyfftw/pyfftw.c
+/home/whg/Projects/github/pyFFTW/pyfftw/pyfftw.pyx
+/home/whg21/Projects/github/pyFFTW/pyfftw/pyfftw.c
+/home/whg21/Projects/github/pyFFTW/pyfftw/pyfftw.pyx
+docs/html/genindex.html
+docs/html/index.html
+docs/html/py-modindex.html
+docs/html/search.html
+docs/html/searchindex.js
+docs/html/_static/basic.css
+docs/html/_static/comment-bright.png
+docs/html/_static/comment-close.png
+docs/html/_static/comment.png
+docs/html/_static/default.css
+docs/html/_static/doctools.js
+docs/html/_static/down-pressed.png
+docs/html/_static/down.png
+docs/html/_static/file.png
+docs/html/_static/jquery.js
+docs/html/_static/minus.png
+docs/html/_static/plus.png
+docs/html/_static/pygments.css
+docs/html/_static/searchtools.js
+docs/html/_static/sidebar.js
+docs/html/_static/underscore.js
+docs/html/_static/up-pressed.png
+docs/html/_static/up.png
+docs/html/_static/websupport.js
+docs/html/pyfftw/pyfftw.html
+docs/html/pyfftw/builders/_utils.html
+docs/html/pyfftw/builders/builders.html
+docs/html/pyfftw/interfaces/interfaces.html
+docs/html/pyfftw/interfaces/numpy_fft.html
+docs/html/pyfftw/interfaces/scipy_fftpack.html
+docs/html/sphinx/api.html
+docs/html/sphinx/tutorial.html
+include/cpu.h
+include/pyfftw_complex.h
+include/msvc_2008/stdint.h
+include/msvc_2010/stdint.h
+include/win/fftw3.h
+pyFFTW.egg-info/PKG-INFO
+pyFFTW.egg-info/SOURCES.txt
+pyFFTW.egg-info/dependency_links.txt
+pyFFTW.egg-info/top_level.txt
+pyfftw/__init__.py
+pyfftw/cpu.pxd
+pyfftw/pyfftw.c
+pyfftw/pyfftw.pxd
+pyfftw/pyfftw.pyx
+pyfftw/utils.pxi
+pyfftw/version.py
+pyfftw/builders/__init__.py
+pyfftw/builders/_utils.py
+pyfftw/builders/builders.py
+pyfftw/interfaces/__init__.py
+pyfftw/interfaces/_utils.py
+pyfftw/interfaces/cache.py
+pyfftw/interfaces/numpy_fft.py
+pyfftw/interfaces/scipy_fftpack.py
+test/__init__.py
+test/test_pyfftw_base.py
+test/test_pyfftw_builders.py
+test/test_pyfftw_call.py
+test/test_pyfftw_class_misc.py
+test/test_pyfftw_complex.py
+test/test_pyfftw_interfaces_cache.py
+test/test_pyfftw_multithreaded.py
+test/test_pyfftw_nbyte_align.py
+test/test_pyfftw_numpy_interface.py
+test/test_pyfftw_real_backward.py
+test/test_pyfftw_real_forward.py
+test/test_pyfftw_scipy_interface.py
+test/test_pyfftw_utils.py
+test/test_pyfftw_wisdom.py
\ No newline at end of file
diff --git a/pyFFTW.egg-info/dependency_links.txt b/pyFFTW.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pyFFTW.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/pyFFTW.egg-info/top_level.txt b/pyFFTW.egg-info/top_level.txt
new file mode 100644
index 0000000..0ee0a82
--- /dev/null
+++ b/pyFFTW.egg-info/top_level.txt
@@ -0,0 +1 @@
+pyfftw
diff --git a/pyfftw/__init__.py b/pyfftw/__init__.py
index 6fa985d..a8b1541 100644
--- a/pyfftw/__init__.py
+++ b/pyfftw/__init__.py
@@ -11,7 +11,7 @@ library <http://www.fftw.org/>`_. However, users may find it easier to
 use the helper routines provided in :mod:`pyfftw.builders`.
 '''
 
-from ._version import version
+from .version import version as __version__
 
 from .pyfftw import (
         FFTW,
@@ -21,11 +21,16 @@ from .pyfftw import (
         simd_alignment,
         n_byte_align_empty,
         n_byte_align,
-        is_n_byte_aligned,)
+        is_n_byte_aligned,
+        byte_align,
+        is_byte_aligned,
+        empty_aligned,
+        ones_aligned,
+        zeros_aligned,
+)
 
 from . import builders
 from . import interfaces
 
 # clean up the namespace
 del builders.builders
-
diff --git a/pyfftw/_version.py b/pyfftw/_version.py
deleted file mode 100644
index 30ac598..0000000
--- a/pyfftw/_version.py
+++ /dev/null
@@ -1,2 +0,0 @@
-
-version = '0.9.2'
diff --git a/pyfftw/builders/_utils.py b/pyfftw/builders/_utils.py
index 7009b80..d3ded68 100644
--- a/pyfftw/builders/_utils.py
+++ b/pyfftw/builders/_utils.py
@@ -1,22 +1,41 @@
 #!/usr/bin/env python
 #
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
+# Copyright 2014 David Wells
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
+# David Wells
+# drwells <at> vt.edu
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 '''
 A set of utility functions for use with the builders. Users should
@@ -43,12 +62,14 @@ _valid_efforts = ('FFTW_ESTIMATE', 'FFTW_MEASURE',
 
 # Looking up a dtype in here returns the complex complement of the same
 # precision.
-_rc_dtype_pairs = {numpy.dtype('float32'): numpy.dtype('complex64'),
-        numpy.dtype('float64'): numpy.dtype('complex128'),
-        numpy.dtype('longdouble'): numpy.dtype('clongdouble'),
-        numpy.dtype('complex64'): numpy.dtype('float32'),
-        numpy.dtype('complex128'): numpy.dtype('float64'),
-        numpy.dtype('clongdouble'): numpy.dtype('longdouble')}
+# It is necessary to use .char as the keys due to MSVC mapping long
+# double to double and the way that numpy handles this.
+_rc_dtype_pairs = {numpy.dtype('float32').char: numpy.dtype('complex64'),
+        numpy.dtype('float64').char: numpy.dtype('complex128'),
+        numpy.dtype('longdouble').char: numpy.dtype('clongdouble'),
+        numpy.dtype('complex64').char: numpy.dtype('float32'),
+        numpy.dtype('complex128').char: numpy.dtype('float64'),
+        numpy.dtype('clongdouble').char: numpy.dtype('longdouble')}
 
 _default_dtype = numpy.dtype('float64')
 
@@ -77,33 +98,33 @@ def _Xfftn(a, s, axes, overwrite_input,
     a_is_complex = numpy.iscomplexobj(a)
 
     # Make the input dtype correct
-    if a.dtype not in _rc_dtype_pairs:
+    if a.dtype.char not in _rc_dtype_pairs:
         # We make it the default dtype
         if not real or inverse:
             # It's going to be complex
-            a = numpy.asarray(a, dtype=_rc_dtype_pairs[_default_dtype])
+            a = numpy.asarray(a, dtype=_rc_dtype_pairs[_default_dtype.char])
         else:
             a = numpy.asarray(a, dtype=_default_dtype)
     
     elif not (real and not inverse) and not a_is_complex:
         # We need to make it a complex dtype
-        a = numpy.asarray(a, dtype=_rc_dtype_pairs[a.dtype])
+        a = numpy.asarray(a, dtype=_rc_dtype_pairs[a.dtype.char])
 
     elif (real and not inverse) and a_is_complex:
         # It should be real
-        a = numpy.asarray(a, dtype=_rc_dtype_pairs[a.dtype])
+        a = numpy.asarray(a, dtype=_rc_dtype_pairs[a.dtype.char])
 
     # Make the output dtype correct
     if not real:
         output_dtype = a.dtype
     
     else:
-        output_dtype = _rc_dtype_pairs[a.dtype]
+        output_dtype = _rc_dtype_pairs[a.dtype.char]
 
     if not avoid_copy:
         a_copy = a.copy()
 
-    output_array = pyfftw.n_byte_align_empty(output_shape, 16, output_dtype)
+    output_array = pyfftw.empty_aligned(output_shape, output_dtype)
 
     flags = [planner_effort]
 
@@ -127,14 +148,14 @@ def _Xfftn(a, s, axes, overwrite_input,
 
         # Also, the input array will be a different shape to the shape of 
         # `a`, so we need to create a new array.
-        input_array = pyfftw.n_byte_align_empty(input_shape, 16, a.dtype)
+        input_array = pyfftw.empty_aligned(input_shape, a.dtype)
 
         FFTW_object = _FFTWWrapper(input_array, output_array, axes, direction,
                 flags, threads, input_array_slicer=update_input_array_slicer,
                 FFTW_array_slicer=FFTW_array_slicer)
 
         # We copy the data back into the internal FFTW object array
-        internal_array = FFTW_object.get_input_array()
+        internal_array = FFTW_object.input_array
         internal_array[:] = 0
         internal_array[FFTW_array_slicer] = (
                 a_copy[update_input_array_slicer])
@@ -153,24 +174,24 @@ def _Xfftn(a, s, axes, overwrite_input,
                             'The input array is not contiguous and '
                             'auto_contiguous is set. (from avoid_copy flag)')
 
-                input_array = pyfftw.n_byte_align_empty(a.shape, 16, a.dtype)
+                input_array = pyfftw.empty_aligned(a.shape, a.dtype)
 
-        if (auto_align_input and 
-                not pyfftw.is_n_byte_aligned(input_array, 16)):
+        if (auto_align_input and not pyfftw.is_byte_aligned(input_array)):
 
             if avoid_copy:
                 raise ValueError('Cannot avoid copy: '
                         'The input array is not aligned and '
                         'auto_align is set. (from avoid_copy flag)')
 
-            input_array = pyfftw.n_byte_align(input_array, 16)
+            input_array = pyfftw.byte_align(input_array)
+
 
         FFTW_object = pyfftw.FFTW(input_array, output_array, axes, direction,
                 flags, threads)
 
         if not avoid_copy:
             # Copy the data back into the (likely) destroyed array
-            FFTW_object.get_input_array()[:] = a_copy
+            FFTW_object.input_array[:] = a_copy
     
     return FFTW_object
 
@@ -182,7 +203,7 @@ class _FFTWWrapper(pyfftw.FFTW):
 
     def __init__(self, input_array, output_array, axes=[-1], 
             direction='FFTW_FORWARD', flags=['FFTW_MEASURE'], 
-            threads=1, *args, **kwargs):
+            threads=1, input_array_slicer=None, FFTW_array_slicer=None):
         '''The arguments are as per :class:`pyfftw.FFTW`, but with the addition
         of 2 keyword arguments: ``input_array_slicer`` and
         ``FFTW_array_slicer``.
@@ -196,16 +217,16 @@ class _FFTWWrapper(pyfftw.FFTW):
         input array into the sliced internal array.
         '''
 
-        self.__input_array_slicer = kwargs.pop('input_array_slicer')
-        self.__FFTW_array_slicer = kwargs.pop('FFTW_array_slicer')
+        self._input_array_slicer = input_array_slicer
+        self._FFTW_array_slicer = FFTW_array_slicer
 
         if 'FFTW_DESTROY_INPUT' in flags:
-            self.__input_destroyed = True
+            self._input_destroyed = True
         else:
-            self.__input_destroyed = False
+            self._input_destroyed = False
 
-        super(_FFTWWrapper, self).__init__(input_array, output_array, 
-                axes, direction, flags, threads, *args, **kwargs)
+        pyfftw.FFTW.__init__(self, input_array, output_array, 
+                             axes, direction, flags, threads)
 
     def __call__(self, input_array=None, output_array=None, 
             normalise_idft=True):
@@ -225,14 +246,14 @@ class _FFTWWrapper(pyfftw.FFTW):
             # Do the update here (which is a copy, so it's alignment
             # safe etc).
 
-            internal_input_array = self.get_input_array()
+            internal_input_array = self.input_array
             input_array = numpy.asanyarray(input_array)
 
-            if self.__input_destroyed:
+            if self._input_destroyed:
                 internal_input_array[:] = 0
 
-            sliced_internal = internal_input_array[self.__FFTW_array_slicer]
-            sliced_input = input_array[self.__input_array_slicer]
+            sliced_internal = internal_input_array[self._FFTW_array_slicer]
+            sliced_input = input_array[self._input_array_slicer]
 
             if sliced_internal.shape != sliced_input.shape:
                 raise ValueError('Invalid input shape: '
diff --git a/pyfftw/builders/builders.py b/pyfftw/builders/builders.py
index f6c4c05..badc6f2 100644
--- a/pyfftw/builders/builders.py
+++ b/pyfftw/builders/builders.py
@@ -1,22 +1,41 @@
 #!/usr/bin/env python
 #
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
+# Copyright 2014 David Wells
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
+# David Wells
+# drwells <at> vt.edu
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 '''
 Overview
@@ -52,7 +71,7 @@ When the internal input array is bigger along any axis than the input
 array that is passed in (due to ``s`` dictating a larger size), then the
 extra entries are padded with zeros. This is a one time action. If the
 internal input array is then extracted using
-:meth:`pyfftw.FFTW.get_input_array`, it is possible to
+:attr:`pyfftw.FFTW.input_array`, it is possible to
 persistently fill the padding space with whatever the user desires, so
 subsequent calls with a new input only overwrite the values that aren't
 padding (even if the array that is used for the call is bigger than the
@@ -73,14 +92,14 @@ Although the array that is internal to the :class:`pyfftw.FFTW` object
 will be correctly loaded with the values within the input array, it is
 not necessarily the case that the internal array *is* the input array.
 The actual internal input array can always be retrieved with 
-:meth:`pyfftw.FFTW.get_input_array`.
+:attr:`pyfftw.FFTW.input_array`.
 
 **Example:**
 
 .. doctest::
     
     >>> import pyfftw
-    >>> a = pyfftw.n_byte_align_empty(4, 16, dtype='complex128')
+    >>> a = pyfftw.empty_aligned(4, dtype='complex128')
     >>> fft = pyfftw.builders.fft(a)
     >>> a[:] = [1, 2, 3, 4]
     >>> fft() # returns the output
@@ -175,10 +194,10 @@ following additional keyword arguments:
   Setting this argument to ``True`` makes sure that the input array
   is correctly aligned. It is possible to correctly byte align the array
   prior to calling this function (using, for example,
-  :func:`pyfftw.n_byte_align`). If and only if a realignment is 
-  necessary is a new array created. If a new array *is* created, it is 
-  up to the calling code to acquire that new input array using 
-  :func:`pyfftw.FFTW.get_input_array`.
+  :func:`pyfftw.byte_align`). If and only if a realignment is
+  necessary is a new array created. If a new array *is* created, it is
+  up to the calling code to acquire that new input array using
+  :attr:`pyfftw.FFTW.input_array`.
 
   The resultant :class:`pyfftw.FFTW` object that is created will be
   designed to operate on arrays that are aligned. If the object is
@@ -207,7 +226,7 @@ following additional keyword arguments:
 
   Like ``auto_align_input``, If a new array is created, it is 
   up to the calling code to acquire that new input array using 
-  :func:`pyfftw.FFTW.get_input_array`.
+  :attr:`pyfftw.FFTW.input_array`.
 
 * ``avoid_copy``: By default, these functions will always create a copy 
   (and sometimes more than one) of the passed in input array. This is 
diff --git a/pyfftw/cpu.pxd b/pyfftw/cpu.pxd
index 84e9823..10f0acd 100644
--- a/pyfftw/cpu.pxd
+++ b/pyfftw/cpu.pxd
@@ -1,20 +1,36 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 cdef extern from "cpu.h":
 
diff --git a/pyfftw/interfaces/__init__.py b/pyfftw/interfaces/__init__.py
index 31112d6..6f83895 100644
--- a/pyfftw/interfaces/__init__.py
+++ b/pyfftw/interfaces/__init__.py
@@ -49,19 +49,19 @@ In practice, this means something like the following (taking
 .. doctest::
 
     >>> import pyfftw, numpy
-    >>> a = pyfftw.n_byte_align_empty((128, 64), 16, dtype='complex64')
+    >>> a = pyfftw.empty_aligned((128, 64), dtype='complex64', n=16)
     >>> a[:] = numpy.random.randn(*a.shape) + 1j*numpy.random.randn(*a.shape)
     >>> fft_a = pyfftw.interfaces.numpy_fft.fft2(a) # Will need to plan
 
 .. doctest::
 
-    >>> b = pyfftw.n_byte_align_empty((128, 64), 16, dtype='complex64')
+    >>> b = pyfftw.empty_aligned((128, 64), dtype='complex64', n=16)
     >>> b[:] = a
     >>> fft_b = pyfftw.interfaces.numpy_fft.fft2(b) # Already planned, so faster
 
 .. doctest::
 
-    >>> c = pyfftw.n_byte_align_empty(132, 16, dtype='complex128')
+    >>> c = pyfftw.empty_aligned(132, dtype='complex128', n=16)
     >>> fft_c = pyfftw.interfaces.numpy_fft.fft(c) # Needs a new plan
     >>> c[:] = numpy.random.randn(*c.shape) + 1j*numpy.random.randn(*c.shape)
 
@@ -113,6 +113,8 @@ being taken along that axes as many times as the axis occurs.
 * :func:`pyfftw.interfaces.numpy_fft.irfft2`
 * :func:`pyfftw.interfaces.numpy_fft.rfftn`
 * :func:`pyfftw.interfaces.numpy_fft.irfftn`
+* :func:`pyfftw.interfaces.numpy_fft.hfft`
+* :func:`pyfftw.interfaces.numpy_fft.ihfft`
 
 :mod:`~pyfftw.interfaces.scipy_fftpack`
 """""""""""""""""""""""""""""""""""""""
@@ -184,7 +186,7 @@ different defaults.
   This argument being ``True`` makes sure that the input array
   is correctly aligned. It is possible to correctly byte align the array
   prior to calling this function (using, for example,
-  :func:`pyfftw.n_byte_align`). If and only if a realignment is 
+  :func:`pyfftw.byte_align`). If and only if a realignment is
   necessary is a new array created.
 
   It's worth noting that just being aligned may not be sufficient to
diff --git a/pyfftw/interfaces/_utils.py b/pyfftw/interfaces/_utils.py
index 72836a5..cb42d20 100644
--- a/pyfftw/interfaces/_utils.py
+++ b/pyfftw/interfaces/_utils.py
@@ -1,22 +1,38 @@
 #!/usr/bin/env python
 #
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 '''
 Utility functions for the interfaces routines
@@ -24,14 +40,17 @@ Utility functions for the interfaces routines
 
 import pyfftw.builders as builders
 import pyfftw
+import numpy
 from . import cache
 
 def _Xfftn(a, s, axes, overwrite_input, planner_effort,
         threads, auto_align_input, auto_contiguous, 
-        calling_func):
+        calling_func, normalise_idft=True):
 
     reload_after_transform = False
 
+    a = numpy.asanyarray(a)
+
     try:
         s = tuple(s)
     except TypeError:
@@ -84,27 +103,28 @@ def _Xfftn(a, s, axes, overwrite_input, planner_effort,
     
         # Only copy if the input array is what was actually used
         # (otherwise it shouldn't be overwritten)
-        if FFTW_object.get_input_array() is a:
+        if FFTW_object.input_array is a:
             a[:] = a_copy
 
         if cache.is_enabled():
             cache._fftw_cache.insert(FFTW_object, key)
         
-        output_array = FFTW_object()
+        output_array = FFTW_object(normalise_idft=normalise_idft)
 
     else:
         if reload_after_transform:
             a_copy = a.copy()
 
-        orig_output_array = FFTW_object.get_output_array()
+        orig_output_array = FFTW_object.output_array
         output_shape = orig_output_array.shape
         output_dtype = orig_output_array.dtype
         output_alignment = FFTW_object.output_alignment
 
-        output_array = pyfftw.n_byte_align_empty(output_shape, 
-                output_alignment, output_dtype)
+        output_array = pyfftw.empty_aligned(
+            output_shape, output_dtype, n=output_alignment)
 
-        FFTW_object(input_array=a, output_array=output_array)
+        FFTW_object(input_array=a, output_array=output_array, 
+                normalise_idft=normalise_idft)
     
     if reload_after_transform:
         a[:] = a_copy
diff --git a/pyfftw/interfaces/cache.py b/pyfftw/interfaces/cache.py
index f82d9e7..8104705 100644
--- a/pyfftw/interfaces/cache.py
+++ b/pyfftw/interfaces/cache.py
@@ -1,22 +1,38 @@
 #!/usr/bin/env python
 #
-# Copyright 2013 Knowledge Economy Developments Ltd
+# Copyright 2015 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 '''
 During calls to functions implemented in :mod:`pyfftw.interfaces`, a
@@ -108,8 +124,9 @@ def set_keepalive_time(keepalive_time):
     removed from the cache. Using the object zeros the timer.
 
     The time is not precise, and sets a minimum time to be alive. In 
-    practice, it may be up to twice as long before the object is
-    deleted from the cache (due to implementational details).
+    practice, it may be quite a bit longer before the object is
+    deleted from the cache (due to implementational details - e.g. contention
+    from other threads).
     '''
     global _fftw_cache
     
@@ -138,6 +155,7 @@ class _Cache(object):
         self.initialised = _threading.Event()
 
         self._parent_thread = _threading.current_thread()
+        self._close_thread_now = _threading.Event()
 
         self._initialised = _threading.Event()
         self._initialised.clear() # Explicitly clear it for clarity
@@ -159,7 +177,8 @@ class _Cache(object):
         # exiting (which it will because a reference error will
         # be raised).
         try:
-            self._thread_object.join()
+            self._close_thread_now.set()
+        
         except TypeError:
             # Not sure what's going on here, but IPython baulks on exit
             pass
@@ -175,7 +194,8 @@ class _Cache(object):
             self._initialised.set()
 
             while True:
-                if not self._parent_thread.is_alive():
+                if (not self._parent_thread.is_alive() or 
+                    self._close_thread_now.is_set()):
                     break
 
                 if time.time() - last_cull_time > self._keepalive_time:
diff --git a/pyfftw/interfaces/numpy_fft.py b/pyfftw/interfaces/numpy_fft.py
index b09148e..221f095 100644
--- a/pyfftw/interfaces/numpy_fft.py
+++ b/pyfftw/interfaces/numpy_fft.py
@@ -1,22 +1,36 @@
 #!/usr/bin/env python
 #
-# Copyright 2013 Knowledge Economy Developments Ltd
-# 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 '''
 This module implements those functions that replace aspects of the
@@ -24,23 +38,30 @@ This module implements those functions that replace aspects of the
 of :mod:`numpy.fft`, but those functions that are not included here are imported
 directly from :mod:`numpy.fft`.
 
-The precision of the transform that is used is selected from the array that 
-is passed in, defaulting to double precision if any type conversion is 
-required.
+
+It is notable that unlike :mod:`numpy.fftpack`, these functions will 
+generally return an output array with the same precision as the input
+array, and the transform that is chosen is chosen based on the precision
+of the input array. That is, if the input array is 32-bit floating point,
+then the transform will be 32-bit floating point and so will the returned
+array. If any type conversion is required, the default will be double
+precision.
 
 One known caveat is that repeated axes are handled differently to
 :mod:`numpy.fft`; axes that are repeated in the axes argument are considered
 only once, as compared to :mod:`numpy.fft` in which repeated axes results in
 the DFT being taken along that axes as many times as the axis occurs.
 
-The exceptions raised by each of these functions are as per their
-equivalents in :mod:`numpy.fft`.
+The exceptions raised by each of these functions are mostly as per their
+equivalents in :mod:`numpy.fft`, though there are some corner cases in
+which this may not be true.
 '''
 
 from ._utils import _Xfftn
 
 # Complete the namespace (these are not actually used in this module)
-from numpy.fft import hfft, ihfft, fftfreq, fftshift, ifftshift
+from numpy.fft import fftfreq, fftshift, ifftshift
+import numpy
 
 __all__ = ['fft','ifft', 'fft2', 'ifft2', 'fftn', 'ifftn', 
            'rfft', 'irfft', 'rfft2', 'irfft2', 'rfftn', 'irfftn',
@@ -231,3 +252,54 @@ def irfftn(a, s=None, axes=None, overwrite_input=False,
             threads, auto_align_input, auto_contiguous, 
             calling_func)
 
+def hfft(a, n=None, axis=-1, overwrite_input=False,
+        planner_effort='FFTW_MEASURE', threads=1,
+        auto_align_input=True, auto_contiguous=True):
+    '''Perform a 1D FFT of a signal with hermitian symmetry.
+    This yields a real output spectrum. See :func:`numpy.fft.hfft`
+    for more information.
+
+    The first three arguments are as per :func:`numpy.fft.hfft`; 
+    the rest of the arguments are documented 
+    in the :ref:`additional arguments docs<interfaces_additional_args>`.
+    '''
+
+    # The hermitian symmetric transform is equivalent to the 
+    # irfft of the conjugate of the input (do the maths!) without
+    # any normalisation of the result (so normalise_idft is set to 
+    # False).
+    a = numpy.conjugate(a)
+
+    calling_func = 'irfft'
+
+    return _Xfftn(a, n, axis, overwrite_input, planner_effort,
+            threads, auto_align_input, auto_contiguous, 
+            calling_func, normalise_idft=False)
+
+def ihfft(a, n=None, axis=-1, overwrite_input=False,
+        planner_effort='FFTW_MEASURE', threads=1,
+        auto_align_input=True, auto_contiguous=True):
+    '''Perform a 1D inverse FFT of a real-spectrum, yielding
+    a signal with hermitian symmetry. See :func:`numpy.fft.ihfft`
+    for more information.
+    
+    The first three arguments are as per :func:`numpy.fft.ihfft`; 
+    the rest of the arguments are documented 
+    in the :ref:`additional arguments docs<interfaces_additional_args>`.
+    '''
+
+    # Result is equivalent to the conjugate of the output of
+    # the rfft of a.
+    # It is necessary to perform the inverse scaling, as this
+    # is not done by rfft.
+    if n is None:
+        if not isinstance(a, numpy.ndarray):
+            a = numpy.asarray(a)
+
+        n = a.shape[axis]
+
+    scaling = 1.0/n
+
+    return scaling * rfft(a, n, axis, overwrite_input, planner_effort,
+            threads, auto_align_input, auto_contiguous).conj()
+
diff --git a/pyfftw/interfaces/scipy_fftpack.py b/pyfftw/interfaces/scipy_fftpack.py
index aaf109e..2406b9f 100644
--- a/pyfftw/interfaces/scipy_fftpack.py
+++ b/pyfftw/interfaces/scipy_fftpack.py
@@ -1,31 +1,63 @@
 #!/usr/bin/env python
 #
-# Copyright 2012 Knowledge Economy Developments Ltd
-# 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 '''
 This module implements those functions that replace aspects of the
 :mod:`scipy.fftpack` module. This module *provides* the entire documented
 namespace of :mod:`scipy.fftpack`, but those functions that are not included
 here are imported directly from :mod:`scipy.fftpack`.
+
+The exceptions raised by each of these functions are mostly as per their
+equivalents in :mod:`scipy.fftpack`, though there are some corner cases in
+which this may not be true.
+
+It is notable that unlike :mod:`scipy.fftpack`, these functions will 
+generally return an output array with the same precision as the input
+array, and the transform that is chosen is chosen based on the precision
+of the input array. That is, if the input array is 32-bit floating point,
+then the transform will be 32-bit floating point and so will the returned
+array. If any type conversion is required, the default will be double
+precision.
+
+Some corner (mis)usages of :mod:`scipy.fftpack` may not transfer neatly.
+For example, using :func:`scipy.fftpack.fft2` with a non 1D array and
+a 2D `shape` argument will return without exception whereas 
+:func:`pyfftw.interfaces.scipy_fftpack.fft2` will raise a `ValueError`.
 '''
 
 from . import numpy_fft
+import numpy
 
 # Complete the namespace (these are not actually used in this module)
 from scipy.fftpack import (dct, idct, diff, tilbert, itilbert, 
@@ -33,6 +65,11 @@ from scipy.fftpack import (dct, idct, diff, tilbert, itilbert,
         shift, fftshift, ifftshift, fftfreq, rfftfreq, 
         convolve, _fftpack)
 
+try:
+    from scipy.fftpack import dst, idst
+except ImportError:
+    pass
+
 __all__ = ['fft','ifft','fftn','ifftn','rfft','irfft', 'fft2','ifft2', 
         'diff', 'tilbert','itilbert','hilbert','ihilbert', 'sc_diff',
         'cs_diff','cc_diff','ss_diff', 'shift', 'rfftfreq']
@@ -46,7 +83,6 @@ def fft(x, n=None, axis=-1, overwrite_x=False,
     the rest of the arguments are documented 
     in the :ref:`additional argument docs<interfaces_additional_args>`.
     '''
-
     return numpy_fft.fft(x, n, axis, overwrite_x, planner_effort,
             threads, auto_align_input, auto_contiguous)
 
@@ -102,6 +138,16 @@ def fftn(x, shape=None, axes=None, overwrite_x=False,
     in the :ref:`additional argument docs<interfaces_additional_args>`.
     '''
 
+    if shape is not None:
+        if ((axes is not None and len(shape) != len(axes)) or
+                (axes is None and len(shape) != x.ndim)):
+            raise ValueError('Shape error: In order to maintain better '
+                    'compatibility with scipy.fftpack.fftn, a ValueError '
+                    'is raised when the length of the shape argument is '
+                    'not the same as x.ndim if axes is None or the length '
+                    'of axes if it is not. If this is problematic, consider '
+                    'using the numpy interface.')
+
     return numpy_fft.fftn(x, shape, axes, overwrite_x, planner_effort,
             threads, auto_align_input, auto_contiguous)
 
@@ -116,9 +162,88 @@ def ifftn(x, shape=None, axes=None, overwrite_x=False,
     in the :ref:`additional argument docs<interfaces_additional_args>`.
     '''
 
+    if shape is not None:
+        if ((axes is not None and len(shape) != len(axes)) or
+                (axes is None and len(shape) != x.ndim)):
+            raise ValueError('Shape error: In order to maintain better '
+                    'compatibility with scipy.fftpack.ifftn, a ValueError '
+                    'is raised when the length of the shape argument is '
+                    'not the same as x.ndim if axes is None or the length '
+                    'of axes if it is not. If this is problematic, consider '
+                    'using the numpy interface.')
+
     return numpy_fft.ifftn(x, shape, axes, overwrite_x, planner_effort,
             threads, auto_align_input, auto_contiguous)
 
+def _complex_to_rfft_output(complex_output, output_shape, axis):
+    '''Convert the complex output from pyfftw to the real output expected 
+    from :func:`scipy.fftpack.rfft`.
+    '''
+
+    rfft_output = numpy.empty(output_shape, dtype=complex_output.real.dtype)
+    source_slicer = [slice(None)] * complex_output.ndim
+    target_slicer = [slice(None)] * complex_output.ndim
+
+    # First element
+    source_slicer[axis] = slice(0, 1)
+    target_slicer[axis] = slice(0, 1)
+    rfft_output[target_slicer] = complex_output[source_slicer].real
+
+    # Real part
+    source_slicer[axis] = slice(1, None)
+    target_slicer[axis] = slice(1, None, 2)
+    rfft_output[target_slicer] = complex_output[source_slicer].real
+
+    # Imaginary part
+    if output_shape[axis] % 2 == 0:
+        end_val = -1
+    else:
+        end_val = None
+
+    source_slicer[axis] = slice(1, end_val, None)
+    target_slicer[axis] = slice(2, None, 2)
+    rfft_output[target_slicer] = complex_output[source_slicer].imag
+
+    return rfft_output
+
+
+def _irfft_input_to_complex(irfft_input, axis):
+    '''Convert the expected real input to :func:`scipy.fftpack.irfft` to
+    the complex input needed by pyfftw.
+    '''
+    complex_dtype = numpy.result_type(irfft_input, 1j)
+
+    input_shape = list(irfft_input.shape)
+    input_shape[axis] = input_shape[axis]//2 + 1
+
+    complex_input = numpy.empty(input_shape, dtype=complex_dtype)
+    source_slicer = [slice(None)] * len(input_shape)
+    target_slicer = [slice(None)] * len(input_shape)
+
+    # First element
+    source_slicer[axis] = slice(0, 1)
+    target_slicer[axis] = slice(0, 1)
+    complex_input[target_slicer] = irfft_input[source_slicer]
+
+    # Real part
+    source_slicer[axis] = slice(1, None, 2)
+    target_slicer[axis] = slice(1, None)
+    complex_input[target_slicer].real = irfft_input[source_slicer]
+
+    # Imaginary part
+    if irfft_input.shape[axis] % 2 == 0:
+        end_val = -1
+        target_slicer[axis] = slice(-1, None)
+        complex_input[target_slicer].imag = 0.0
+    else:
+        end_val = None
+
+    source_slicer[axis] = slice(2, None, 2)
+    target_slicer[axis] = slice(1, end_val)
+    complex_input[target_slicer].imag = irfft_input[source_slicer]
+
+    return complex_input
+
 
 def rfft(x, n=None, axis=-1, overwrite_x=False,
         planner_effort='FFTW_MEASURE', threads=1,
@@ -129,10 +254,21 @@ def rfft(x, n=None, axis=-1, overwrite_x=False,
     the rest of the arguments are documented 
     in the :ref:`additional argument docs<interfaces_additional_args>`.
     '''
+    if not numpy.isrealobj(x):
+        raise TypeError('Input array must be real to maintain '
+                'compatibility with scipy.fftpack.rfft.')
+
+    x = numpy.asanyarray(x)
 
-    return numpy_fft.rfft(x, n, axis, overwrite_x, planner_effort,
+    complex_output = numpy_fft.rfft(x, n, axis, overwrite_x, planner_effort,
             threads, auto_align_input, auto_contiguous)
 
+    output_shape = list(x.shape)
+    if n is not None:
+        output_shape[axis] = n
+
+    return _complex_to_rfft_output(complex_output, output_shape, axis)
+
 def irfft(x, n=None, axis=-1, overwrite_x=False,
         planner_effort='FFTW_MEASURE', threads=1,
         auto_align_input=True, auto_contiguous=True):
@@ -142,7 +278,17 @@ def irfft(x, n=None, axis=-1, overwrite_x=False,
     the rest of the arguments are documented 
     in the :ref:`additional argument docs<interfaces_additional_args>`.
     '''
+    if not numpy.isrealobj(x):
+        raise TypeError('Input array must be real to maintain '
+                'compatibility with scipy.fftpack.irfft.')
 
-    return numpy_fft.irfft(x, n, axis, overwrite_x, planner_effort,
-            threads, auto_align_input, auto_contiguous)
+    x = numpy.asanyarray(x)
+
+    if n is None:
+        n = x.shape[axis]
+
+    complex_input = _irfft_input_to_complex(x, axis)
+
+    return numpy_fft.irfft(complex_input, n, axis, overwrite_x, 
+            planner_effort, threads, auto_align_input, auto_contiguous)
 
diff --git a/pyfftw/np_fft.py b/pyfftw/np_fft.py
deleted file mode 100644
index a2bb629..0000000
--- a/pyfftw/np_fft.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env python
-
-# Skeleton file to fill in the numpy like fft functions
-
-def fft(a, n=None, axis=-1):
-
-    pass
-
-def ifft(a, n=None, axis=-1):
-    pass
-
-def fft2(a, s=None, axes=(-1,-2)):
-    pass
-
-def ifft2(a, s=None, axes=(-1,-2)):
-    pass
-
-def fftn(a, s=None, axes=None):
-    if not len(set(axes)) == len(axes):
-        pass
-
-
-def ifftn(a, s=None, axes=None):
-    pass
-
-def rfft(a, n=None, axis=-1):
-    pass
-
-def irfft(a, n=None, axis=-1):
-    pass
-
-def rfft2(a, s=None, axes=(-2,-1)):
-    pass
-
-def irfft2(a, s=None, axes=(-2,-1)):
-    pass
-
-def rfftn(a, s=None, axes=None):
-    pass
-
-def irfftn(a, s=None, axes=None):
-    pass
-
diff --git a/pyfftw/pyfftw.c b/pyfftw/pyfftw.c
index dc19504..f1b9e09 100644
--- a/pyfftw/pyfftw.c
+++ b/pyfftw/pyfftw.c
@@ -1,13 +1,40 @@
-/* Generated by Cython 0.17.4 on Wed Sep 25 15:19:42 2013 */
+/* Generated by Cython 0.23.3 */
+
+/* BEGIN: Cython Metadata
+{
+    "distutils": {
+        "depends": [
+            "/home/whg/Projects/github/pyFFTW/include/cpu.h", 
+            "/home/whg/Projects/github/pyFFTW/include/pyfftw_complex.h", 
+            "/usr/lib/python2.7/dist-packages/numpy/core/include/numpy/arrayobject.h", 
+            "/usr/lib/python2.7/dist-packages/numpy/core/include/numpy/ufuncobject.h"
+        ], 
+        "include_dirs": [
+            "/home/whg/Projects/github/pyFFTW/include", 
+            "/home/whg/Projects/github/pyFFTW/pyfftw", 
+            "/usr/lib/python2.7/dist-packages/numpy/core/include"
+        ], 
+        "libraries": [
+            "fftw3", 
+            "fftw3f", 
+            "fftw3l", 
+            "fftw3_threads", 
+            "fftw3f_threads", 
+            "fftw3l_threads"
+        ]
+    }
+}
+END: Cython Metadata */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
 #ifndef Py_PYTHON_H
     #error Python headers needed to compile C extensions, please install development version of Python.
-#elif PY_VERSION_HEX < 0x02040000
-    #error Cython requires Python 2.4+.
+#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000)
+    #error Cython requires Python 2.6+ or Python 3.2+.
 #else
-#include <stddef.h> /* For offsetof */
+#define CYTHON_ABI "0_23_3"
+#include <stddef.h>
 #ifndef offsetof
 #define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
 #endif
@@ -41,94 +68,72 @@
 #define CYTHON_COMPILING_IN_PYPY 0
 #define CYTHON_COMPILING_IN_CPYTHON 1
 #endif
-#if PY_VERSION_HEX < 0x02050000
-  typedef int Py_ssize_t;
-  #define PY_SSIZE_T_MAX INT_MAX
-  #define PY_SSIZE_T_MIN INT_MIN
-  #define PY_FORMAT_SIZE_T ""
-  #define CYTHON_FORMAT_SSIZE_T ""
-  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
-  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
-  #define PyNumber_Index(o)    ((PyNumber_Check(o) && !PyFloat_Check(o)) ? PyNumber_Int(o) : \
-                                (PyErr_Format(PyExc_TypeError, \
-                                              "expected index value, got %.200s", Py_TYPE(o)->tp_name), \
-                                 (PyObject*)0))
-  #define __Pyx_PyIndex_Check(o) (PyNumber_Check(o) && !PyFloat_Check(o) && \
-                                  !PyComplex_Check(o))
-  #define PyIndex_Check __Pyx_PyIndex_Check
-  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
-  #define __PYX_BUILD_PY_SSIZE_T "i"
-#else
-  #define __PYX_BUILD_PY_SSIZE_T "n"
-  #define CYTHON_FORMAT_SSIZE_T "z"
-  #define __Pyx_PyIndex_Check PyIndex_Check
+#if !defined(CYTHON_USE_PYLONG_INTERNALS) && CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000
+#define CYTHON_USE_PYLONG_INTERNALS 1
 #endif
-#if PY_VERSION_HEX < 0x02060000
-  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
-  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
-  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
-  #define PyVarObject_HEAD_INIT(type, size) \
-          PyObject_HEAD_INIT(type) size,
-  #define PyType_Modified(t)
-  typedef struct {
-     void *buf;
-     PyObject *obj;
-     Py_ssize_t len;
-     Py_ssize_t itemsize;
-     int readonly;
-     int ndim;
-     char *format;
-     Py_ssize_t *shape;
-     Py_ssize_t *strides;
-     Py_ssize_t *suboffsets;
-     void *internal;
-  } Py_buffer;
-  #define PyBUF_SIMPLE 0
-  #define PyBUF_WRITABLE 0x0001
-  #define PyBUF_FORMAT 0x0004
-  #define PyBUF_ND 0x0008
-  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
-  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
-  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
-  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
-  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
-  #define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_FORMAT | PyBUF_WRITABLE)
-  #define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_FORMAT | PyBUF_WRITABLE)
-  typedef int (*getbufferproc)(PyObject *, Py_buffer *, int);
-  typedef void (*releasebufferproc)(PyObject *, Py_buffer *);
+#if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag)
+#define Py_OptimizeFlag 0
 #endif
+#define __PYX_BUILD_PY_SSIZE_T "n"
+#define CYTHON_FORMAT_SSIZE_T "z"
 #if PY_MAJOR_VERSION < 3
   #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
-  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
-          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
+          PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyClass_Type
 #else
   #define __Pyx_BUILTIN_MODULE_NAME "builtins"
-  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \
+  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
           PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
+  #define __Pyx_DefaultClassType PyType_Type
 #endif
-#if PY_MAJOR_VERSION < 3 && PY_MINOR_VERSION < 6
-  #define PyUnicode_FromString(s) PyUnicode_Decode(s, strlen(s), "UTF-8", "strict")
-#endif
-#if PY_MAJOR_VERSION >= 3
+#ifndef Py_TPFLAGS_CHECKTYPES
   #define Py_TPFLAGS_CHECKTYPES 0
+#endif
+#ifndef Py_TPFLAGS_HAVE_INDEX
   #define Py_TPFLAGS_HAVE_INDEX 0
 #endif
-#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
+#ifndef Py_TPFLAGS_HAVE_NEWBUFFER
   #define Py_TPFLAGS_HAVE_NEWBUFFER 0
 #endif
+#ifndef Py_TPFLAGS_HAVE_FINALIZE
+  #define Py_TPFLAGS_HAVE_FINALIZE 0
+#endif
 #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND)
   #define CYTHON_PEP393_ENABLED 1
-  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ? \
+  #define __Pyx_PyUnicode_READY(op)       (likely(PyUnicode_IS_READY(op)) ?\
                                               0 : _PyUnicode_Ready((PyObject *)(op)))
   #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_LENGTH(u)
   #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
+  #define __Pyx_PyUnicode_KIND(u)         PyUnicode_KIND(u)
+  #define __Pyx_PyUnicode_DATA(u)         PyUnicode_DATA(u)
   #define __Pyx_PyUnicode_READ(k, d, i)   PyUnicode_READ(k, d, i)
 #else
   #define CYTHON_PEP393_ENABLED 0
   #define __Pyx_PyUnicode_READY(op)       (0)
   #define __Pyx_PyUnicode_GET_LENGTH(u)   PyUnicode_GET_SIZE(u)
   #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
-  #define __Pyx_PyUnicode_READ(k, d, i)   ((k=k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+  #define __Pyx_PyUnicode_KIND(u)         (sizeof(Py_UNICODE))
+  #define __Pyx_PyUnicode_DATA(u)         ((void*)PyUnicode_AS_UNICODE(u))
+  #define __Pyx_PyUnicode_READ(k, d, i)   ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i]))
+#endif
+#if CYTHON_COMPILING_IN_PYPY
+  #define __Pyx_PyUnicode_Concat(a, b)      PyNumber_Add(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  PyNumber_Add(a, b)
+#else
+  #define __Pyx_PyUnicode_Concat(a, b)      PyUnicode_Concat(a, b)
+  #define __Pyx_PyUnicode_ConcatSafe(a, b)  ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\
+      PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b))
+#endif
+#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains)
+  #define PyUnicode_Contains(u, s)  PySequence_Contains(u, s)
+#endif
+#define __Pyx_PyString_FormatSafe(a, b)   ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b))
+#define __Pyx_PyUnicode_FormatSafe(a, b)  ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b))
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyString_Format(a, b)  PyUnicode_Format(a, b)
+#else
+  #define __Pyx_PyString_Format(a, b)  PyString_Format(a, b)
 #endif
 #if PY_MAJOR_VERSION >= 3
   #define PyBaseString_Type            PyUnicode_Type
@@ -137,27 +142,12 @@
   #define PyString_Check               PyUnicode_Check
   #define PyString_CheckExact          PyUnicode_CheckExact
 #endif
-#if PY_VERSION_HEX < 0x02060000
-  #define PyBytesObject                PyStringObject
-  #define PyBytes_Type                 PyString_Type
-  #define PyBytes_Check                PyString_Check
-  #define PyBytes_CheckExact           PyString_CheckExact
-  #define PyBytes_FromString           PyString_FromString
-  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
-  #define PyBytes_FromFormat           PyString_FromFormat
-  #define PyBytes_DecodeEscape         PyString_DecodeEscape
-  #define PyBytes_AsString             PyString_AsString
-  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
-  #define PyBytes_Size                 PyString_Size
-  #define PyBytes_AS_STRING            PyString_AS_STRING
-  #define PyBytes_GET_SIZE             PyString_GET_SIZE
-  #define PyBytes_Repr                 PyString_Repr
-  #define PyBytes_Concat               PyString_Concat
-  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
-#endif
-#if PY_VERSION_HEX < 0x02060000
-  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
-  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
+#if PY_MAJOR_VERSION >= 3
+  #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
+  #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj)
+#else
+  #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj))
+  #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj))
 #endif
 #ifndef PySet_CheckExact
   #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
@@ -178,11 +168,17 @@
   #define PyInt_AsSsize_t              PyLong_AsSsize_t
   #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
   #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
+  #define PyNumber_Int                 PyNumber_Long
 #endif
 #if PY_MAJOR_VERSION >= 3
   #define PyBoolObject                 PyLongObject
 #endif
-#if PY_VERSION_HEX < 0x03020000
+#if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY
+  #ifndef PyUnicode_InternFromString
+    #define PyUnicode_InternFromString(s) PyUnicode_FromString(s)
+  #endif
+#endif
+#if PY_VERSION_HEX < 0x030200A4
   typedef long Py_hash_t;
   #define __Pyx_PyInt_FromHash_t PyInt_FromLong
   #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
@@ -190,42 +186,61 @@
   #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
   #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
 #endif
-#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
-  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
-  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
-  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
-#else
-  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \
-        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \
-        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \
-            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
-  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \
-        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
-        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \
-            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
-  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \
-        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \
-        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \
-            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
-#endif
 #if PY_MAJOR_VERSION >= 3
-  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+  #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
+#else
+  #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass)
 #endif
-#if PY_VERSION_HEX < 0x02050000
-  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
-  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
-  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
+#if PY_VERSION_HEX >= 0x030500B1
+#define __Pyx_PyAsyncMethodsStruct PyAsyncMethods
+#define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async)
+#elif CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3
+typedef struct {
+    unaryfunc am_await;
+    unaryfunc am_aiter;
+    unaryfunc am_anext;
+} __Pyx_PyAsyncMethodsStruct;
+#define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved))
 #else
-  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
-  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
-  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
+#define __Pyx_PyType_AsAsync(obj) NULL
+#endif
+#ifndef CYTHON_RESTRICT
+  #if defined(__GNUC__)
+    #define CYTHON_RESTRICT __restrict__
+  #elif defined(_MSC_VER) && _MSC_VER >= 1400
+    #define CYTHON_RESTRICT __restrict
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_RESTRICT restrict
+  #else
+    #define CYTHON_RESTRICT
+  #endif
+#endif
+#define __Pyx_void_to_None(void_result) (void_result, Py_INCREF(Py_None), Py_None)
+
+#ifndef CYTHON_INLINE
+  #if defined(__GNUC__)
+    #define CYTHON_INLINE __inline__
+  #elif defined(_MSC_VER)
+    #define CYTHON_INLINE __inline
+  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define CYTHON_INLINE inline
+  #else
+    #define CYTHON_INLINE
+  #endif
+#endif
+
+#if defined(WIN32) || defined(MS_WINDOWS)
+  #define _USE_MATH_DEFINES
 #endif
-#if PY_VERSION_HEX < 0x02050000
-  #define __Pyx_NAMESTR(n) ((char *)(n))
-  #define __Pyx_DOCSTR(n)  ((char *)(n))
+#include <math.h>
+#ifdef NAN
+#define __PYX_NAN() ((float) NAN)
 #else
-  #define __Pyx_NAMESTR(n) (n)
-  #define __Pyx_DOCSTR(n)  (n)
+static CYTHON_INLINE float __PYX_NAN() {
+  float value;
+  memset(&value, 0xFF, sizeof(value));
+  return value;
+}
 #endif
 
 
@@ -245,12 +260,9 @@
   #endif
 #endif
 
-#if defined(WIN32) || defined(MS_WINDOWS)
-#define _USE_MATH_DEFINES
-#endif
-#include <math.h>
 #define __PYX_HAVE__pyfftw__pyfftw
 #define __PYX_HAVE_API__pyfftw__pyfftw
+#include "string.h"
 #include "stdio.h"
 #include "stdlib.h"
 #include "numpy/arrayobject.h"
@@ -268,21 +280,6 @@
 #define CYTHON_WITHOUT_ASSERTIONS
 #endif
 
-
-/* inline attribute */
-#ifndef CYTHON_INLINE
-  #if defined(__GNUC__)
-    #define CYTHON_INLINE __inline__
-  #elif defined(_MSC_VER)
-    #define CYTHON_INLINE __inline
-  #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-    #define CYTHON_INLINE inline
-  #else
-    #define CYTHON_INLINE
-  #endif
-#endif
-
-/* unused attribute */
 #ifndef CYTHON_UNUSED
 # if defined(__GNUC__)
 #   if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
@@ -296,46 +293,183 @@
 #   define CYTHON_UNUSED
 # endif
 #endif
-
-typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
-
-
-/* Type Conversion Predeclarations */
-
-#define __Pyx_PyBytes_FromUString(s) PyBytes_FromString((char*)s)
-#define __Pyx_PyBytes_AsUString(s)   ((unsigned char*) PyBytes_AsString(s))
-
-#define __Pyx_Owned_Py_None(b) (Py_INCREF(Py_None), Py_None)
-#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
+#ifndef CYTHON_NCP_UNUSED
+# if CYTHON_COMPILING_IN_CPYTHON
+#  define CYTHON_NCP_UNUSED
+# else
+#  define CYTHON_NCP_UNUSED CYTHON_UNUSED
+# endif
+#endif
+typedef struct {PyObject **p; char *s; const Py_ssize_t n; const char* encoding;
+                const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry;
+
+#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0
+#define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0
+#define __PYX_DEFAULT_STRING_ENCODING ""
+#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString
+#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#define __Pyx_uchar_cast(c) ((unsigned char)c)
+#define __Pyx_long_cast(x) ((long)x)
+#define __Pyx_fits_Py_ssize_t(v, type, is_signed)  (\
+    (sizeof(type) < sizeof(Py_ssize_t))  ||\
+    (sizeof(type) > sizeof(Py_ssize_t) &&\
+          likely(v < (type)PY_SSIZE_T_MAX ||\
+                 v == (type)PY_SSIZE_T_MAX)  &&\
+          (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\
+                                v == (type)PY_SSIZE_T_MIN)))  ||\
+    (sizeof(type) == sizeof(Py_ssize_t) &&\
+          (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\
+                               v == (type)PY_SSIZE_T_MAX)))  )
+#if defined (__cplusplus) && __cplusplus >= 201103L
+    #include <cstdlib>
+    #define __Pyx_sst_abs(value) std::abs(value)
+#elif SIZEOF_INT >= SIZEOF_SIZE_T
+    #define __Pyx_sst_abs(value) abs(value)
+#elif SIZEOF_LONG >= SIZEOF_SIZE_T
+    #define __Pyx_sst_abs(value) labs(value)
+#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+    #define __Pyx_sst_abs(value) llabs(value)
+#elif defined (_MSC_VER) && defined (_M_X64)
+    #define __Pyx_sst_abs(value) _abs64(value)
+#elif defined (__GNUC__)
+    #define __Pyx_sst_abs(value) __builtin_llabs(value)
+#else
+    #define __Pyx_sst_abs(value) ((value<0) ? -value : value)
+#endif
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*);
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length);
+#define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s))
+#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l)
+#define __Pyx_PyBytes_FromString        PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*);
+#if PY_MAJOR_VERSION < 3
+    #define __Pyx_PyStr_FromString        __Pyx_PyBytes_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize
+#else
+    #define __Pyx_PyStr_FromString        __Pyx_PyUnicode_FromString
+    #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize
+#endif
+#define __Pyx_PyObject_AsSString(s)    ((signed char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_AsUString(s)    ((unsigned char*) __Pyx_PyObject_AsString(s))
+#define __Pyx_PyObject_FromCString(s)  __Pyx_PyObject_FromString((const char*)s)
+#define __Pyx_PyBytes_FromCString(s)   __Pyx_PyBytes_FromString((const char*)s)
+#define __Pyx_PyByteArray_FromCString(s)   __Pyx_PyByteArray_FromString((const char*)s)
+#define __Pyx_PyStr_FromCString(s)     __Pyx_PyStr_FromString((const char*)s)
+#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s)
+#if PY_MAJOR_VERSION < 3
+static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u)
+{
+    const Py_UNICODE *u_end = u;
+    while (*u_end++) ;
+    return (size_t)(u_end - u - 1);
+}
+#else
+#define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen
+#endif
+#define __Pyx_PyUnicode_FromUnicode(u)       PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u))
+#define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode
+#define __Pyx_PyUnicode_AsUnicode            PyUnicode_AsUnicode
+#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj)
+#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None)
+#define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False))
 static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
 static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
-
 static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
 static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
-static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
-
 #if CYTHON_COMPILING_IN_CPYTHON
 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
 #else
 #define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x)
 #endif
 #define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x))
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+static int __Pyx_sys_getdefaultencoding_not_ascii;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    PyObject* ascii_chars_u = NULL;
+    PyObject* ascii_chars_b = NULL;
+    const char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    if (strcmp(default_encoding_c, "ascii") == 0) {
+        __Pyx_sys_getdefaultencoding_not_ascii = 0;
+    } else {
+        char ascii_chars[128];
+        int c;
+        for (c = 0; c < 128; c++) {
+            ascii_chars[c] = c;
+        }
+        __Pyx_sys_getdefaultencoding_not_ascii = 1;
+        ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL);
+        if (!ascii_chars_u) goto bad;
+        ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL);
+        if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) {
+            PyErr_Format(
+                PyExc_ValueError,
+                "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.",
+                default_encoding_c);
+            goto bad;
+        }
+        Py_DECREF(ascii_chars_u);
+        Py_DECREF(ascii_chars_b);
+    }
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    Py_XDECREF(ascii_chars_u);
+    Py_XDECREF(ascii_chars_b);
+    return -1;
+}
+#endif
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL)
+#else
+#define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL)
+#if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT
+static char* __PYX_DEFAULT_STRING_ENCODING;
+static int __Pyx_init_sys_getdefaultencoding_params(void) {
+    PyObject* sys;
+    PyObject* default_encoding = NULL;
+    char* default_encoding_c;
+    sys = PyImport_ImportModule("sys");
+    if (!sys) goto bad;
+    default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL);
+    Py_DECREF(sys);
+    if (!default_encoding) goto bad;
+    default_encoding_c = PyBytes_AsString(default_encoding);
+    if (!default_encoding_c) goto bad;
+    __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c));
+    if (!__PYX_DEFAULT_STRING_ENCODING) goto bad;
+    strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c);
+    Py_DECREF(default_encoding);
+    return 0;
+bad:
+    Py_XDECREF(default_encoding);
+    return -1;
+}
+#endif
+#endif
+
 
-#ifdef __GNUC__
-  /* Test for GCC > 2.95 */
-  #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
-    #define likely(x)   __builtin_expect(!!(x), 1)
-    #define unlikely(x) __builtin_expect(!!(x), 0)
-  #else /* __GNUC__ > 2 ... */
-    #define likely(x)   (x)
-    #define unlikely(x) (x)
-  #endif /* __GNUC__ > 2 ... */
-#else /* __GNUC__ */
+/* Test for GCC > 2.95 */
+#if defined(__GNUC__)     && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)))
+  #define likely(x)   __builtin_expect(!!(x), 1)
+  #define unlikely(x) __builtin_expect(!!(x), 0)
+#else /* !__GNUC__ or GCC < 2.95 */
   #define likely(x)   (x)
   #define unlikely(x) (x)
 #endif /* __GNUC__ */
-    
+
 static PyObject *__pyx_m;
+static PyObject *__pyx_d;
 static PyObject *__pyx_b;
 static PyObject *__pyx_empty_tuple;
 static PyObject *__pyx_empty_bytes;
@@ -367,13 +501,13 @@ static const char *__pyx_filename;
 
 
 static const char *__pyx_f[] = {
-  "pyfftw.pyx",
-  "utils.pxi",
-  "numpy.pxd",
+  "pyfftw/pyfftw.pyx",
+  "pyfftw/utils.pxi",
+  "__init__.pxd",
   "type.pxd",
 };
 
-/* "numpy.pxd":723
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":725
  * # in Cython to enable them only on the right systems.
  * 
  * ctypedef npy_int8       int8_t             # <<<<<<<<<<<<<<
@@ -382,7 +516,7 @@ static const char *__pyx_f[] = {
  */
 typedef npy_int8 __pyx_t_5numpy_int8_t;
 
-/* "numpy.pxd":724
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":726
  * 
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t             # <<<<<<<<<<<<<<
@@ -391,7 +525,7 @@ typedef npy_int8 __pyx_t_5numpy_int8_t;
  */
 typedef npy_int16 __pyx_t_5numpy_int16_t;
 
-/* "numpy.pxd":725
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":727
  * ctypedef npy_int8       int8_t
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t             # <<<<<<<<<<<<<<
@@ -400,7 +534,7 @@ typedef npy_int16 __pyx_t_5numpy_int16_t;
  */
 typedef npy_int32 __pyx_t_5numpy_int32_t;
 
-/* "numpy.pxd":726
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":728
  * ctypedef npy_int16      int16_t
  * ctypedef npy_int32      int32_t
  * ctypedef npy_int64      int64_t             # <<<<<<<<<<<<<<
@@ -409,7 +543,7 @@ typedef npy_int32 __pyx_t_5numpy_int32_t;
  */
 typedef npy_int64 __pyx_t_5numpy_int64_t;
 
-/* "numpy.pxd":730
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":732
  * #ctypedef npy_int128     int128_t
  * 
  * ctypedef npy_uint8      uint8_t             # <<<<<<<<<<<<<<
@@ -418,7 +552,7 @@ typedef npy_int64 __pyx_t_5numpy_int64_t;
  */
 typedef npy_uint8 __pyx_t_5numpy_uint8_t;
 
-/* "numpy.pxd":731
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":733
  * 
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t             # <<<<<<<<<<<<<<
@@ -427,7 +561,7 @@ typedef npy_uint8 __pyx_t_5numpy_uint8_t;
  */
 typedef npy_uint16 __pyx_t_5numpy_uint16_t;
 
-/* "numpy.pxd":732
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":734
  * ctypedef npy_uint8      uint8_t
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t             # <<<<<<<<<<<<<<
@@ -436,7 +570,7 @@ typedef npy_uint16 __pyx_t_5numpy_uint16_t;
  */
 typedef npy_uint32 __pyx_t_5numpy_uint32_t;
 
-/* "numpy.pxd":733
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":735
  * ctypedef npy_uint16     uint16_t
  * ctypedef npy_uint32     uint32_t
  * ctypedef npy_uint64     uint64_t             # <<<<<<<<<<<<<<
@@ -445,7 +579,7 @@ typedef npy_uint32 __pyx_t_5numpy_uint32_t;
  */
 typedef npy_uint64 __pyx_t_5numpy_uint64_t;
 
-/* "numpy.pxd":737
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":739
  * #ctypedef npy_uint128    uint128_t
  * 
  * ctypedef npy_float32    float32_t             # <<<<<<<<<<<<<<
@@ -454,7 +588,7 @@ typedef npy_uint64 __pyx_t_5numpy_uint64_t;
  */
 typedef npy_float32 __pyx_t_5numpy_float32_t;
 
-/* "numpy.pxd":738
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":740
  * 
  * ctypedef npy_float32    float32_t
  * ctypedef npy_float64    float64_t             # <<<<<<<<<<<<<<
@@ -463,7 +597,7 @@ typedef npy_float32 __pyx_t_5numpy_float32_t;
  */
 typedef npy_float64 __pyx_t_5numpy_float64_t;
 
-/* "numpy.pxd":747
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":749
  * # The int types are mapped a bit surprising --
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t             # <<<<<<<<<<<<<<
@@ -472,7 +606,7 @@ typedef npy_float64 __pyx_t_5numpy_float64_t;
  */
 typedef npy_long __pyx_t_5numpy_int_t;
 
-/* "numpy.pxd":748
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":750
  * # numpy.int corresponds to 'l' and numpy.long to 'q'
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t             # <<<<<<<<<<<<<<
@@ -481,7 +615,7 @@ typedef npy_long __pyx_t_5numpy_int_t;
  */
 typedef npy_longlong __pyx_t_5numpy_long_t;
 
-/* "numpy.pxd":749
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":751
  * ctypedef npy_long       int_t
  * ctypedef npy_longlong   long_t
  * ctypedef npy_longlong   longlong_t             # <<<<<<<<<<<<<<
@@ -490,7 +624,7 @@ typedef npy_longlong __pyx_t_5numpy_long_t;
  */
 typedef npy_longlong __pyx_t_5numpy_longlong_t;
 
-/* "numpy.pxd":751
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":753
  * ctypedef npy_longlong   longlong_t
  * 
  * ctypedef npy_ulong      uint_t             # <<<<<<<<<<<<<<
@@ -499,7 +633,7 @@ typedef npy_longlong __pyx_t_5numpy_longlong_t;
  */
 typedef npy_ulong __pyx_t_5numpy_uint_t;
 
-/* "numpy.pxd":752
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":754
  * 
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t             # <<<<<<<<<<<<<<
@@ -508,7 +642,7 @@ typedef npy_ulong __pyx_t_5numpy_uint_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
 
-/* "numpy.pxd":753
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":755
  * ctypedef npy_ulong      uint_t
  * ctypedef npy_ulonglong  ulong_t
  * ctypedef npy_ulonglong  ulonglong_t             # <<<<<<<<<<<<<<
@@ -517,7 +651,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulong_t;
  */
 typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
 
-/* "numpy.pxd":755
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":757
  * ctypedef npy_ulonglong  ulonglong_t
  * 
  * ctypedef npy_intp       intp_t             # <<<<<<<<<<<<<<
@@ -526,7 +660,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t;
  */
 typedef npy_intp __pyx_t_5numpy_intp_t;
 
-/* "numpy.pxd":756
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":758
  * 
  * ctypedef npy_intp       intp_t
  * ctypedef npy_uintp      uintp_t             # <<<<<<<<<<<<<<
@@ -535,7 +669,7 @@ typedef npy_intp __pyx_t_5numpy_intp_t;
  */
 typedef npy_uintp __pyx_t_5numpy_uintp_t;
 
-/* "numpy.pxd":758
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":760
  * ctypedef npy_uintp      uintp_t
  * 
  * ctypedef npy_double     float_t             # <<<<<<<<<<<<<<
@@ -544,7 +678,7 @@ typedef npy_uintp __pyx_t_5numpy_uintp_t;
  */
 typedef npy_double __pyx_t_5numpy_float_t;
 
-/* "numpy.pxd":759
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":761
  * 
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t             # <<<<<<<<<<<<<<
@@ -553,7 +687,7 @@ typedef npy_double __pyx_t_5numpy_float_t;
  */
 typedef npy_double __pyx_t_5numpy_double_t;
 
-/* "numpy.pxd":760
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":762
  * ctypedef npy_double     float_t
  * ctypedef npy_double     double_t
  * ctypedef npy_longdouble longdouble_t             # <<<<<<<<<<<<<<
@@ -585,7 +719,7 @@ typedef npy_longdouble __pyx_t_5numpy_longdouble_t;
 /*--- Type declarations ---*/
 struct __pyx_obj_6pyfftw_6pyfftw_FFTW;
 
-/* "numpy.pxd":762
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":764
  * ctypedef npy_longdouble longdouble_t
  * 
  * ctypedef npy_cfloat      cfloat_t             # <<<<<<<<<<<<<<
@@ -594,7 +728,7 @@ struct __pyx_obj_6pyfftw_6pyfftw_FFTW;
  */
 typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
 
-/* "numpy.pxd":763
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":765
  * 
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t             # <<<<<<<<<<<<<<
@@ -603,7 +737,7 @@ typedef npy_cfloat __pyx_t_5numpy_cfloat_t;
  */
 typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
 
-/* "numpy.pxd":764
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":766
  * ctypedef npy_cfloat      cfloat_t
  * ctypedef npy_cdouble     cdouble_t
  * ctypedef npy_clongdouble clongdouble_t             # <<<<<<<<<<<<<<
@@ -612,7 +746,7 @@ typedef npy_cdouble __pyx_t_5numpy_cdouble_t;
  */
 typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;
 
-/* "numpy.pxd":766
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":768
  * ctypedef npy_clongdouble clongdouble_t
  * 
  * ctypedef npy_cdouble     complex_t             # <<<<<<<<<<<<<<
@@ -624,8 +758,13 @@ struct __pyx_t_6pyfftw_6pyfftw__fftw_iodim;
 typedef struct __pyx_t_6pyfftw_6pyfftw__fftw_iodim __pyx_t_6pyfftw_6pyfftw__fftw_iodim;
 struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align_empty;
 struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align;
+struct __pyx_opt_args_6pyfftw_6pyfftw_byte_align;
+struct __pyx_opt_args_6pyfftw_6pyfftw_is_byte_aligned;
+struct __pyx_opt_args_6pyfftw_6pyfftw_empty_aligned;
+struct __pyx_opt_args_6pyfftw_6pyfftw_zeros_aligned;
+struct __pyx_opt_args_6pyfftw_6pyfftw_ones_aligned;
 
-/* "pyfftw/pyfftw.pxd":247
+/* "pyfftw/pyfftw.pxd":263
  * 
  * # Direction enum
  * cdef enum:             # <<<<<<<<<<<<<<
@@ -633,11 +772,11 @@ struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align;
  *     FFTW_BACKWARD = 1
  */
 enum  {
-  __pyx_e_6pyfftw_6pyfftw_FFTW_FORWARD = -1,
+  __pyx_e_6pyfftw_6pyfftw_FFTW_FORWARD = -1L,
   __pyx_e_6pyfftw_6pyfftw_FFTW_BACKWARD = 1
 };
 
-/* "pyfftw/pyfftw.pxd":252
+/* "pyfftw/pyfftw.pxd":268
  * 
  * # Documented flags
  * cdef enum:             # <<<<<<<<<<<<<<
@@ -652,10 +791,11 @@ enum  {
   __pyx_e_6pyfftw_6pyfftw_FFTW_EXHAUSTIVE = 8,
   __pyx_e_6pyfftw_6pyfftw_FFTW_PRESERVE_INPUT = 16,
   __pyx_e_6pyfftw_6pyfftw_FFTW_PATIENT = 32,
-  __pyx_e_6pyfftw_6pyfftw_FFTW_ESTIMATE = 64
+  __pyx_e_6pyfftw_6pyfftw_FFTW_ESTIMATE = 64,
+  __pyx_e_6pyfftw_6pyfftw_FFTW_WISDOM_ONLY = 0x200000
 };
 
-/* "pyfftw/pyfftw.pxd":22
+/* "pyfftw/pyfftw.pxd":38
  * from libc.stdint cimport int64_t
  * 
  * ctypedef struct _fftw_iodim:             # <<<<<<<<<<<<<<
@@ -668,17 +808,17 @@ struct __pyx_t_6pyfftw_6pyfftw__fftw_iodim {
   int _os;
 };
 
-/* "pyfftw/pyfftw.pxd":226
+/* "pyfftw/pyfftw.pxd":242
  * # has different function names and signatures for all the
  * # different precisions and dft types).
  * ctypedef void * (*fftw_generic_plan_guru)(             # <<<<<<<<<<<<<<
  *         int rank, fftw_iodim *dims,
  *         int howmany_rank, fftw_iodim *howmany_dims,
  */
-typedef void *(*__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, int);
+typedef void *(*__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, unsigned int);
 
-/* "pyfftw/pyfftw.pxd":232
- *         int sign, int flags)
+/* "pyfftw/pyfftw.pxd":248
+ *         int sign, unsigned flags) nogil
  * 
  * ctypedef void (*fftw_generic_execute)(void *_plan, void *_in, void *_out) nogil             # <<<<<<<<<<<<<<
  * 
@@ -686,7 +826,7 @@ typedef void *(*__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(int, fftw_iodim
  */
 typedef void (*__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(void *, void *, void *);
 
-/* "pyfftw/pyfftw.pxd":234
+/* "pyfftw/pyfftw.pxd":250
  * ctypedef void (*fftw_generic_execute)(void *_plan, void *_in, void *_out) nogil
  * 
  * ctypedef void (*fftw_generic_destroy_plan)(void *_plan)             # <<<<<<<<<<<<<<
@@ -695,7 +835,7 @@ typedef void (*__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(void *, void *, voi
  */
 typedef void (*__pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan)(void *);
 
-/* "pyfftw/pyfftw.pxd":236
+/* "pyfftw/pyfftw.pxd":252
  * ctypedef void (*fftw_generic_destroy_plan)(void *_plan)
  * 
  * ctypedef void (*fftw_generic_init_threads)()             # <<<<<<<<<<<<<<
@@ -704,7 +844,7 @@ typedef void (*__pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan)(void *);
  */
 typedef void (*__pyx_t_6pyfftw_6pyfftw_fftw_generic_init_threads)(void);
 
-/* "pyfftw/pyfftw.pxd":238
+/* "pyfftw/pyfftw.pxd":254
  * ctypedef void (*fftw_generic_init_threads)()
  * 
  * ctypedef void (*fftw_generic_plan_with_nthreads)(int n)             # <<<<<<<<<<<<<<
@@ -713,7 +853,7 @@ typedef void (*__pyx_t_6pyfftw_6pyfftw_fftw_generic_init_threads)(void);
  */
 typedef void (*__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads)(int);
 
-/* "pyfftw/pyfftw.pxd":240
+/* "pyfftw/pyfftw.pxd":256
  * ctypedef void (*fftw_generic_plan_with_nthreads)(int n)
  * 
  * ctypedef void (*fftw_generic_set_timelimit)(double seconds)             # <<<<<<<<<<<<<<
@@ -722,7 +862,7 @@ typedef void (*__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads)(int);
  */
 typedef void (*__pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit)(double);
 
-/* "pyfftw/pyfftw.pxd":242
+/* "pyfftw/pyfftw.pxd":258
  * ctypedef void (*fftw_generic_set_timelimit)(double seconds)
  * 
  * ctypedef bint (*validator)(np.ndarray input_array,             # <<<<<<<<<<<<<<
@@ -731,12 +871,12 @@ typedef void (*__pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit)(double);
  */
 typedef int (*__pyx_t_6pyfftw_6pyfftw_validator)(PyArrayObject *, PyArrayObject *, int64_t *, int64_t *, int64_t);
 
-/* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":39
+/* "pyfftw/utils.pxi":59
  *     _valid_simd_alignments = ()
  * 
  * cpdef n_byte_align_empty(shape, n, dtype='float64', order='C'):             # <<<<<<<<<<<<<<
  *     '''n_byte_align_empty(shape, n, dtype='float64', order='C')
- * 
+ *     **This function is deprecated:** ``empty_aligned`` **should be used
  */
 struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align_empty {
   int __pyx_n;
@@ -744,11 +884,11 @@ struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align_empty {
   PyObject *order;
 };
 
-/* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":75
- *     return array
+/* "pyfftw/utils.pxi":76
+ * 
  * 
  * cpdef n_byte_align(array, n, dtype=None):             # <<<<<<<<<<<<<<
- *     ''' n_byte_align(array, n, dtype=None)
+ *     '''n_byte_align(array, n, dtype=None)
  * 
  */
 struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align {
@@ -756,7 +896,74 @@ struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align {
   PyObject *dtype;
 };
 
-/* "pyfftw/pyfftw.pyx":568
+/* "pyfftw/utils.pxi":96
+ * 
+ * 
+ * cpdef byte_align(array, n=None, dtype=None):             # <<<<<<<<<<<<<<
+ *     '''byte_align(array, n=None, dtype=None)
+ * 
+ */
+struct __pyx_opt_args_6pyfftw_6pyfftw_byte_align {
+  int __pyx_n;
+  PyObject *n;
+  PyObject *dtype;
+};
+
+/* "pyfftw/utils.pxi":139
+ * 
+ * 
+ * cpdef is_byte_aligned(array, n=None):             # <<<<<<<<<<<<<<
+ *     ''' is_n_byte_aligned(array, n=None)
+ * 
+ */
+struct __pyx_opt_args_6pyfftw_6pyfftw_is_byte_aligned {
+  int __pyx_n;
+  PyObject *n;
+};
+
+/* "pyfftw/utils.pxi":172
+ * 
+ * 
+ * cpdef empty_aligned(shape, dtype='float64', order='C', n=None):             # <<<<<<<<<<<<<<
+ *     '''empty_aligned(shape, dtype='float64', order='C', n=None)
+ * 
+ */
+struct __pyx_opt_args_6pyfftw_6pyfftw_empty_aligned {
+  int __pyx_n;
+  PyObject *dtype;
+  PyObject *order;
+  PyObject *n;
+};
+
+/* "pyfftw/utils.pxi":214
+ * 
+ * 
+ * cpdef zeros_aligned(shape, dtype='float64', order='C', n=None):             # <<<<<<<<<<<<<<
+ *     '''zeros_aligned(shape, dtype='float64', order='C', n=None)
+ * 
+ */
+struct __pyx_opt_args_6pyfftw_6pyfftw_zeros_aligned {
+  int __pyx_n;
+  PyObject *dtype;
+  PyObject *order;
+  PyObject *n;
+};
+
+/* "pyfftw/utils.pxi":231
+ * 
+ * 
+ * cpdef ones_aligned(shape, dtype='float64', order='C', n=None):             # <<<<<<<<<<<<<<
+ *     '''ones_aligned(shape, dtype='float64', order='C', n=None)
+ * 
+ */
+struct __pyx_opt_args_6pyfftw_6pyfftw_ones_aligned {
+  int __pyx_n;
+  PyObject *dtype;
+  PyObject *order;
+  PyObject *n;
+};
+
+/* "pyfftw/pyfftw.pyx":597
  * # ======================
  * #
  * cdef class FFTW:             # <<<<<<<<<<<<<<
@@ -766,36 +973,35 @@ struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align {
 struct __pyx_obj_6pyfftw_6pyfftw_FFTW {
   PyObject_HEAD
   struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *__pyx_vtab;
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru __pyx___fftw_planner;
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_execute __pyx___fftw_execute;
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan __pyx___fftw_destroy;
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads __pyx___nthreads_plan_setter;
-  void *__pyx___plan;
-  PyArrayObject *__pyx___input_array;
-  PyArrayObject *__pyx___output_array;
-  int __pyx___direction;
-  int __pyx___flags;
-  int __pyx___simd_allowed;
-  int __pyx___input_array_alignment;
-  int __pyx___output_array_alignment;
-  int __pyx___use_threads;
-  PyObject *__pyx___input_strides;
-  PyObject *__pyx___input_byte_strides;
-  PyObject *__pyx___output_strides;
-  PyObject *__pyx___output_byte_strides;
-  PyObject *__pyx___input_shape;
-  PyObject *__pyx___output_shape;
-  PyObject *__pyx___input_dtype;
-  PyObject *__pyx___output_dtype;
-  PyObject *__pyx___flags_used;
-  float __pyx___normalisation_scaling;
-  int __pyx___rank;
-  __pyx_t_6pyfftw_6pyfftw__fftw_iodim *__pyx___dims;
-  int __pyx___howmany_rank;
-  __pyx_t_6pyfftw_6pyfftw__fftw_iodim *__pyx___howmany_dims;
-  int64_t *__pyx___axes;
-  int64_t *__pyx___not_axes;
-  int __pyx___N;
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru _fftw_planner;
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_execute _fftw_execute;
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan _fftw_destroy;
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads _nthreads_plan_setter;
+  void *_plan;
+  PyArrayObject *_input_array;
+  PyArrayObject *_output_array;
+  int _direction;
+  unsigned int _flags;
+  int _simd_allowed;
+  int _input_array_alignment;
+  int _output_array_alignment;
+  PyObject *_input_item_strides;
+  PyObject *_input_strides;
+  PyObject *_output_item_strides;
+  PyObject *_output_strides;
+  PyObject *_input_shape;
+  PyObject *_output_shape;
+  PyObject *_input_dtype;
+  PyObject *_output_dtype;
+  PyObject *_flags_used;
+  double _normalisation_scaling;
+  int _rank;
+  __pyx_t_6pyfftw_6pyfftw__fftw_iodim *_dims;
+  int _howmany_rank;
+  __pyx_t_6pyfftw_6pyfftw__fftw_iodim *_howmany_dims;
+  int64_t *_axes;
+  int64_t *_not_axes;
+  int64_t _N;
 };
 
 
@@ -806,6 +1012,8 @@ struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW {
   PyObject *(*execute)(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *, int __pyx_skip_dispatch);
 };
 static struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *__pyx_vtabptr_6pyfftw_6pyfftw_FFTW;
+
+/* --- Runtime support code (head) --- */
 #ifndef CYTHON_REFNANNY
   #define CYTHON_REFNANNY 0
 #endif
@@ -819,22 +1027,22 @@ static struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *__pyx_vtabptr_6pyfftw_6pyff
     void (*FinishContext)(void**);
   } __Pyx_RefNannyAPIStruct;
   static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
-  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
+  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname);
   #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
 #ifdef WITH_THREAD
-  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
-          if (acquire_gil) { \
-              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure(); \
-              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
-              PyGILState_Release(__pyx_gilstate_save); \
-          } else { \
-              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__); \
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)\
+          if (acquire_gil) {\
+              PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\
+              PyGILState_Release(__pyx_gilstate_save);\
+          } else {\
+              __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\
           }
 #else
-  #define __Pyx_RefNannySetupContext(name, acquire_gil) \
+  #define __Pyx_RefNannySetupContext(name, acquire_gil)\
           __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
 #endif
-  #define __Pyx_RefNannyFinishContext() \
+  #define __Pyx_RefNannyFinishContext()\
           __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
   #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
   #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
@@ -856,154 +1064,165 @@ static struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *__pyx_vtabptr_6pyfftw_6pyff
   #define __Pyx_XDECREF(r) Py_XDECREF(r)
   #define __Pyx_XGOTREF(r)
   #define __Pyx_XGIVEREF(r)
-#endif /* CYTHON_REFNANNY */
+#endif
+#define __Pyx_XDECREF_SET(r, v) do {\
+        PyObject *tmp = (PyObject *) r;\
+        r = v; __Pyx_XDECREF(tmp);\
+    } while (0)
+#define __Pyx_DECREF_SET(r, v) do {\
+        PyObject *tmp = (PyObject *) r;\
+        r = v; __Pyx_DECREF(tmp);\
+    } while (0)
 #define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
 #define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
 
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
-
-static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) {
+    PyTypeObject* tp = Py_TYPE(obj);
+    if (likely(tp->tp_getattro))
+        return tp->tp_getattro(obj, attr_name);
+#if PY_MAJOR_VERSION < 3
+    if (likely(tp->tp_getattr))
+        return tp->tp_getattr(obj, PyString_AS_STRING(attr_name));
+#endif
+    return PyObject_GetAttr(obj, attr_name);
+}
+#else
+#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n)
+#endif
 
-static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
-    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
+static PyObject *__Pyx_GetBuiltinName(PyObject *name);
 
-static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); /*proto*/
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name);
 
-static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
-    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
-    const char* function_name); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw);
+#else
+#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw)
+#endif
 
-static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
-static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
+    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found);
+
+static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name);
+
+static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\
+    PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\
+    const char* function_name);
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb);
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb);
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause);
+
+static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type);
+
+#define __Pyx_PyObject_DelSlice(obj, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop, wraparound)\
+    __Pyx_PyObject_SetSlice(obj, (PyObject*)NULL, cstart, cstop, py_start, py_stop, py_slice, has_cstart, has_cstop, wraparound)
+static CYTHON_INLINE int __Pyx_PyObject_SetSlice(
+        PyObject* obj, PyObject* value, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
+        int has_cstart, int has_cstop, int wraparound);
+
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(
+        PyObject* obj, Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** py_start, PyObject** py_stop, PyObject** py_slice,
+        int has_cstart, int has_cstop, int wraparound);
+
+static CYTHON_INLINE long __Pyx_div_long(long, long);
+
+#define __Pyx_GetItemInt(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\
+    __Pyx_GetItemInt_Fast(o, (Py_ssize_t)i, is_list, wraparound, boundscheck) :\
+    (is_list ? (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL) :\
+               __Pyx_GetItemInt_Generic(o, to_py_func(i))))
+#define __Pyx_GetItemInt_List(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\
+    __Pyx_GetItemInt_List_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\
+    (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+#define __Pyx_GetItemInt_Tuple(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck)\
+    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ?\
+    __Pyx_GetItemInt_Tuple_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) :\
+    (PyErr_SetString(PyExc_IndexError, "tuple index out of range"), (PyObject*)NULL))
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              int wraparound, int boundscheck);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j);
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i,
+                                                     int is_list, int wraparound, int boundscheck);
 
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause); /*proto*/
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+    PyListObject* L = (PyListObject*) list;
+    Py_ssize_t len = Py_SIZE(list);
+    if (likely(L->allocated > len) & likely(len > (L->allocated >> 1))) {
+        Py_INCREF(x);
+        PyList_SET_ITEM(list, len, x);
+        Py_SIZE(list) = len+1;
+        return 0;
+    }
+    return PyList_Append(list, x);
+}
+#else
+#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#endif
 
-static CYTHON_INLINE long __Pyx_div_long(long, long); /* proto */
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb);
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb);
 
-static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
 
-static CYTHON_INLINE int __Pyx_PySequence_Contains(PyObject* item, PyObject* seq, int eq) {
+static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) {
     int result = PySequence_Contains(seq, item);
     return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
 }
 
-static CYTHON_INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
-    if (likely(PyList_CheckExact(L))) {
-        if (unlikely(PyList_Append(L, x) < 0)) return NULL;
-        Py_INCREF(Py_None);
-        return Py_None; /* this is just to have an accurate signature */
-    } else {
-        PyObject *r, *m;
-        m = __Pyx_GetAttrString(L, "append");
-        if (!m) return NULL;
-        r = PyObject_CallFunctionObjArgs(m, x, NULL);
-        Py_DECREF(m);
-        return r;
-    }
-}
-
-static CYTHON_INLINE intptr_t __Pyx_mod_intptr_t(intptr_t, intptr_t); /* proto */
-
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
-    PyObject *r;
-    if (!j) return NULL;
-    r = PyObject_GetItem(o, j);
-    Py_DECREF(j);
-    return r;
-}
-#define __Pyx_GetItemInt_List(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
-                                                    __Pyx_GetItemInt_List_Fast(o, i) : \
-                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i) {
-#if CYTHON_COMPILING_IN_CPYTHON
-    if (likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
-        PyObject *r = PyList_GET_ITEM(o, i);
-        Py_INCREF(r);
-        return r;
-    }
-    else if ((-PyList_GET_SIZE(o) <= i) & (i < 0)) {
-        PyObject *r = PyList_GET_ITEM(o, PyList_GET_SIZE(o) + i);
-        Py_INCREF(r);
-        return r;
-    }
-    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
-#else
-    return PySequence_GetItem(o, i);
-#endif
-}
-#define __Pyx_GetItemInt_Tuple(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
-                                                    __Pyx_GetItemInt_Tuple_Fast(o, i) : \
-                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i) {
 #if CYTHON_COMPILING_IN_CPYTHON
-    if (likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
-        PyObject *r = PyTuple_GET_ITEM(o, i);
-        Py_INCREF(r);
-        return r;
-    }
-    else if ((-PyTuple_GET_SIZE(o) <= i) & (i < 0)) {
-        PyObject *r = PyTuple_GET_ITEM(o, PyTuple_GET_SIZE(o) + i);
-        Py_INCREF(r);
-        return r;
-    }
-    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+static PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, long intval, int inplace);
 #else
-    return PySequence_GetItem(o, i);
-#endif
-}
-#define __Pyx_GetItemInt(o, i, size, to_py_func) (((size) <= sizeof(Py_ssize_t)) ? \
-                                                    __Pyx_GetItemInt_Fast(o, i) : \
-                                                    __Pyx_GetItemInt_Generic(o, to_py_func(i)))
-static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i) {
+#define __Pyx_PyInt_EqObjC(op1, op2, intval, inplace)\
+    PyObject_RichCompare(op1, op2, Py_EQ)
+    #endif
+
 #if CYTHON_COMPILING_IN_CPYTHON
-    if (PyList_CheckExact(o)) {
-        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
-        if (likely((n >= 0) & (n < PyList_GET_SIZE(o)))) {
-            PyObject *r = PyList_GET_ITEM(o, n);
-            Py_INCREF(r);
-            return r;
-        }
-    }
-    else if (PyTuple_CheckExact(o)) {
-        Py_ssize_t n = (likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
-        if (likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
-            PyObject *r = PyTuple_GET_ITEM(o, n);
-            Py_INCREF(r);
-            return r;
-        }
-    } else {  /* inlined PySequence_GetItem() */
-        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
-        if (likely(m && m->sq_item)) {
-            if (unlikely(i < 0) && likely(m->sq_length)) {
-                Py_ssize_t l = m->sq_length(o);
-                if (unlikely(l < 0)) return NULL;
-                i += l;
-            }
-            return m->sq_item(o, i);
-        }
-    }
-#else
-    if (PySequence_Check(o)) {
-        return PySequence_GetItem(o, i);
-    }
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg);
 #endif
-    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
-}
 
-static double __Pyx__PyObject_AsDouble(PyObject* obj); /* proto */
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg);
+
+static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg);
+
+static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x);
+
+static CYTHON_INLINE intptr_t __Pyx_mod_intptr_t(intptr_t, intptr_t);
+
+static double __Pyx__PyObject_AsDouble(PyObject* obj);
 #if CYTHON_COMPILING_IN_PYPY
-#define __Pyx_PyObject_AsDouble(obj) \
-(likely(PyFloat_CheckExact(obj)) ? PyFloat_AS_DOUBLE(obj) : \
- likely(PyInt_CheckExact(obj)) ? \
+#define __Pyx_PyObject_AsDouble(obj)\
+(likely(PyFloat_CheckExact(obj)) ? PyFloat_AS_DOUBLE(obj) :\
+ likely(PyInt_CheckExact(obj)) ?\
  PyFloat_AsDouble(obj) : __Pyx__PyObject_AsDouble(obj))
 #else
-#define __Pyx_PyObject_AsDouble(obj) \
-((likely(PyFloat_CheckExact(obj))) ? \
+#define __Pyx_PyObject_AsDouble(obj)\
+((likely(PyFloat_CheckExact(obj))) ?\
  PyFloat_AS_DOUBLE(obj) : __Pyx__PyObject_AsDouble(obj))
 #endif
 
+#include <string.h>
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals);
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals);
+
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+
 #if CYTHON_COMPILING_IN_CPYTHON
-static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
+static CYTHON_INLINE int __Pyx_ListComp_Append(PyObject* list, PyObject* x) {
     PyListObject* L = (PyListObject*) list;
     Py_ssize_t len = Py_SIZE(list);
     if (likely(L->allocated > len)) {
@@ -1015,32 +1234,109 @@ static CYTHON_INLINE int __Pyx_PyList_Append(PyObject* list, PyObject* x) {
     return PyList_Append(list, x);
 }
 #else
-#define __Pyx_PyList_Append(L,x) PyList_Append(L,x)
+#define __Pyx_ListComp_Append(L,x) PyList_Append(L,x)
 #endif
 
-static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
+#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000
+static CYTHON_INLINE PyObject* __Pyx_PyObject_LookupSpecial(PyObject* obj, PyObject* attr_name) {
+    PyObject *res;
+    PyTypeObject *tp = Py_TYPE(obj);
+#if PY_MAJOR_VERSION < 3
+    if (unlikely(PyInstance_Check(obj)))
+        return __Pyx_PyObject_GetAttrStr(obj, attr_name);
+#endif
+    res = _PyType_Lookup(tp, attr_name);
+    if (likely(res)) {
+        descrgetfunc f = Py_TYPE(res)->tp_descr_get;
+        if (!f) {
+            Py_INCREF(res);
+        } else {
+            res = f(res, obj, (PyObject *)tp);
+        }
+    } else {
+        PyErr_SetObject(PyExc_AttributeError, attr_name);
+    }
+    return res;
+}
+#else
+#define __Pyx_PyObject_LookupSpecial(o,n) __Pyx_PyObject_GetAttrStr(o,n)
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func);
+#else
+#define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL)
+#endif
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb);
+
+#if PY_MAJOR_VERSION >= 3 && !CYTHON_COMPILING_IN_PYPY
+static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) {
+    PyObject *value;
+    value = PyDict_GetItemWithError(d, key);
+    if (unlikely(!value)) {
+        if (!PyErr_Occurred()) {
+            PyObject* args = PyTuple_Pack(1, key);
+            if (likely(args))
+                PyErr_SetObject(PyExc_KeyError, args);
+            Py_XDECREF(args);
+        }
+        return NULL;
+    }
+    Py_INCREF(value);
+    return value;
+}
+#else
+    #define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key)
+#endif
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected);
 
 static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index);
 
 static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void);
 
-static CYTHON_INLINE int __Pyx_IterFinish(void); /*proto*/
+static int __Pyx_SetVtable(PyObject *dict, void *vtable);
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level);
+
+static PyObject *__Pyx_GetNameInClass(PyObject *nmspace, PyObject *name);
+
+typedef struct {
+    int code_line;
+    PyCodeObject* code_object;
+} __Pyx_CodeObjectCacheEntry;
+struct __Pyx_CodeObjectCache {
+    int count;
+    int max_count;
+    __Pyx_CodeObjectCacheEntry* entries;
+};
+static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
+static PyCodeObject *__pyx_find_code_object(int code_line);
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename);
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value);
 
-static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); /*proto*/
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *);
 
-static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
-static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *);
 
-static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level); /*proto*/
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int64_t(int64_t value);
 
-static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_int64_t(int64_t);
+static CYTHON_INLINE int64_t __Pyx_PyInt_As_int64_t(PyObject *);
 
-static CYTHON_INLINE int64_t __Pyx_PyInt_from_py_int64_t(PyObject *);
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value);
 
 #ifndef __PYX_FORCE_INIT_THREADS
   #define __PYX_FORCE_INIT_THREADS 0
 #endif
 
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value);
+
 #if CYTHON_CCOMPLEX
   #ifdef __cplusplus
     #define __Pyx_CREAL(z) ((z).real())
@@ -1053,7 +1349,7 @@ static CYTHON_INLINE int64_t __Pyx_PyInt_from_py_int64_t(PyObject *);
     #define __Pyx_CREAL(z) ((z).real)
     #define __Pyx_CIMAG(z) ((z).imag)
 #endif
-#if defined(_WIN32) && defined(__cplusplus) && CYTHON_CCOMPLEX
+#if (defined(_WIN32) || defined(__clang__)) && defined(__cplusplus) && CYTHON_CCOMPLEX
     #define __Pyx_SET_CREAL(z,x) ((z).real(x))
     #define __Pyx_SET_CIMAG(z,y) ((z).imag(y))
 #else
@@ -1139,42 +1435,12 @@ static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_from_parts(do
     #endif
 #endif
 
-static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject *);
-
-static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject *);
-
-static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject *);
-
-static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject *);
-
-static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject *);
-
-static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject *);
-
-static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject *);
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value);
 
-static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject *);
-
-static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject *);
-
-static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject *);
-
-static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject *);
-
-static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject *);
-
-static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject *);
-
-static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject *);
-
-static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject *);
-
-static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject *);
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *);
 
 static int __Pyx_check_binary_version(void);
 
-static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
-
 #if !defined(__Pyx_PyIdentifier_FromString)
 #if PY_MAJOR_VERSION < 3
   #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
@@ -1183,43 +1449,33 @@ static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
 #endif
 #endif
 
-static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
-
-static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);  /*proto*/
-
-typedef struct {
-    int code_line;
-    PyCodeObject* code_object;
-} __Pyx_CodeObjectCacheEntry;
-struct __Pyx_CodeObjectCache {
-    int count;
-    int max_count;
-    __Pyx_CodeObjectCacheEntry* entries;
-};
-static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL};
-static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line);
-static PyCodeObject *__pyx_find_code_object(int code_line);
-static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object);
+static PyObject *__Pyx_ImportModule(const char *name);
 
-static void __Pyx_AddTraceback(const char *funcname, int c_line,
-                               int py_line, const char *filename); /*proto*/
+static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);
 
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t);
 
+static PyObject *__pyx_f_6pyfftw_6pyfftw_4FFTW_update_arrays(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_new_input_array, PyObject *__pyx_v_new_output_array, int __pyx_skip_dispatch); /* proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_4FFTW__update_arrays(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyArrayObject *__pyx_v_new_input_array, PyArrayObject *__pyx_v_new_output_array); /* proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_4FFTW_execute(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, int __pyx_skip_dispatch); /* proto*/
 
 /* Module declarations from 'cpython.buffer' */
 
-/* Module declarations from 'cpython.ref' */
+/* Module declarations from 'libc.string' */
 
 /* Module declarations from 'libc.stdio' */
 
-/* Module declarations from 'cpython.object' */
-
 /* Module declarations from '__builtin__' */
 
 /* Module declarations from 'cpython.type' */
 static PyTypeObject *__pyx_ptype_7cpython_4type_type = 0;
 
+/* Module declarations from 'cpython' */
+
+/* Module declarations from 'cpython.object' */
+
+/* Module declarations from 'cpython.ref' */
+
 /* Module declarations from 'libc.stdlib' */
 
 /* Module declarations from 'numpy' */
@@ -1244,7 +1500,9 @@ static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *, cha
 static PyTypeObject *__pyx_ptype_6pyfftw_6pyfftw_FFTW = 0;
 static int __pyx_v_6pyfftw_6pyfftw__simd_alignment;
 static PyObject *__pyx_v_6pyfftw_6pyfftw_directions = 0;
+static PyObject *__pyx_v_6pyfftw_6pyfftw_directions_lookup = 0;
 static PyObject *__pyx_v_6pyfftw_6pyfftw_flag_dict = 0;
+static PyObject *__pyx_v_6pyfftw_6pyfftw_plan_lock = 0;
 static __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru __pyx_v_6pyfftw_6pyfftw_planners[9];
 static __pyx_t_6pyfftw_6pyfftw_fftw_generic_execute __pyx_v_6pyfftw_6pyfftw_executors[9];
 static __pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan __pyx_v_6pyfftw_6pyfftw_destroyers[3];
@@ -1256,16 +1514,21 @@ static PyObject *__pyx_v_6pyfftw_6pyfftw_scheme_directions = 0;
 static PyObject *__pyx_v_6pyfftw_6pyfftw_scheme_functions = 0;
 static PyObject *__pyx_f_6pyfftw_6pyfftw_n_byte_align_empty(PyObject *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align_empty *__pyx_optional_args); /*proto*/
 static PyObject *__pyx_f_6pyfftw_6pyfftw_n_byte_align(PyObject *, PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align *__pyx_optional_args); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_byte_align(PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_byte_align *__pyx_optional_args); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_is_byte_aligned(PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_is_byte_aligned *__pyx_optional_args); /*proto*/
 static PyObject *__pyx_f_6pyfftw_6pyfftw_is_n_byte_aligned(PyObject *, PyObject *, int __pyx_skip_dispatch); /*proto*/
-static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, int); /*proto*/
-static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, int); /*proto*/
-static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, int); /*proto*/
-static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_r2c(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, int); /*proto*/
-static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_r2c(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, int); /*proto*/
-static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_r2c(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, int); /*proto*/
-static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_c2r(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, int); /*proto*/
-static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_c2r(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, int); /*proto*/
-static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_c2r(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, int); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_empty_aligned(PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_empty_aligned *__pyx_optional_args); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_zeros_aligned(PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_zeros_aligned *__pyx_optional_args); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_ones_aligned(PyObject *, int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_ones_aligned *__pyx_optional_args); /*proto*/
+static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, unsigned int); /*proto*/
+static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, unsigned int); /*proto*/
+static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, unsigned int); /*proto*/
+static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_r2c(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, unsigned int); /*proto*/
+static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_r2c(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, unsigned int); /*proto*/
+static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_r2c(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, unsigned int); /*proto*/
+static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_c2r(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, unsigned int); /*proto*/
+static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_c2r(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, unsigned int); /*proto*/
+static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_c2r(int, fftw_iodim *, int, fftw_iodim *, void *, void *, int, unsigned int); /*proto*/
 static void __pyx_f_6pyfftw_6pyfftw__fftw_execute_dft(void *, void *, void *); /*proto*/
 static void __pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft(void *, void *, void *); /*proto*/
 static void __pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft(void *, void *, void *); /*proto*/
@@ -1295,6 +1558,7 @@ int __pyx_module_is_main_pyfftw__pyfftw = 0;
 
 /* Implementation of 'pyfftw.pyfftw' */
 static PyObject *__pyx_builtin_property;
+static PyObject *__pyx_builtin_DeprecationWarning;
 static PyObject *__pyx_builtin_TypeError;
 static PyObject *__pyx_builtin_range;
 static PyObject *__pyx_builtin_ValueError;
@@ -1302,334 +1566,420 @@ static PyObject *__pyx_builtin_KeyError;
 static PyObject *__pyx_builtin_IndexError;
 static PyObject *__pyx_builtin_MemoryError;
 static PyObject *__pyx_builtin_RuntimeError;
+static char __pyx_k_B[] = "B";
+static char __pyx_k_C[] = "C";
+static char __pyx_k_H[] = "H";
+static char __pyx_k_I[] = "I";
+static char __pyx_k_L[] = "L";
+static char __pyx_k_N[] = "N";
+static char __pyx_k_O[] = "O";
+static char __pyx_k_Q[] = "Q";
+static char __pyx_k_b[] = "b";
+static char __pyx_k_d[] = "d";
+static char __pyx_k_f[] = "f";
+static char __pyx_k_g[] = "g";
+static char __pyx_k_h[] = "h";
+static char __pyx_k_i[] = "i";
+static char __pyx_k_l[] = "l";
+static char __pyx_k_n[] = "n";
+static char __pyx_k_q[] = "q";
+static char __pyx_k_32[] = "32";
+static char __pyx_k_64[] = "64";
+static char __pyx_k_Zd[] = "Zd";
+static char __pyx_k_Zf[] = "Zf";
+static char __pyx_k_Zg[] = "Zg";
+static char __pyx_k_ld[] = "ld";
+static char __pyx_k_np[] = "np";
+static char __pyx_k__17[] = "'";
+static char __pyx_k_c2c[] = "c2c";
+static char __pyx_k_c2r[] = "c2r";
+static char __pyx_k_r2c[] = "r2c";
+static char __pyx_k_Lock[] = "Lock";
+static char __pyx_k_axes[] = "axes";
+static char __pyx_k_copy[] = "copy";
+static char __pyx_k_data[] = "data";
+static char __pyx_k_exit[] = "__exit__";
+static char __pyx_k_fill[] = "fill";
+static char __pyx_k_int8[] = "int8";
+static char __pyx_k_main[] = "__main__";
+static char __pyx_k_real[] = "real";
+static char __pyx_k_test[] = "__test__";
+static char __pyx_k_type[] = "type";
+static char __pyx_k_view[] = "view";
+static char __pyx_k_warn[] = "warn";
+static char __pyx_k_array[] = "array";
+static char __pyx_k_class[] = "__class__";
+static char __pyx_k_dtype[] = "dtype";
+static char __pyx_k_empty[] = "empty";
+static char __pyx_k_enter[] = "__enter__";
+static char __pyx_k_flags[] = "flags";
+static char __pyx_k_get_N[] = "_get_N";
+static char __pyx_k_numpy[] = "numpy";
+static char __pyx_k_order[] = "order";
+static char __pyx_k_range[] = "range";
+static char __pyx_k_shape[] = "shape";
+static char __pyx_k_append[] = "append";
+static char __pyx_k_import[] = "__import__";
+static char __pyx_k_update[] = "update";
+static char __pyx_k_wisdom[] = "wisdom";
+static char __pyx_k_counter[] = "counter";
+static char __pyx_k_execute[] = "execute";
+static char __pyx_k_float32[] = "float32";
+static char __pyx_k_float64[] = "float64";
+static char __pyx_k_integer[] = "integer";
+static char __pyx_k_planner[] = "planner";
+static char __pyx_k_reshape[] = "reshape";
+static char __pyx_k_strides[] = "strides";
+static char __pyx_k_success[] = "success";
+static char __pyx_k_threads[] = "threads";
+static char __pyx_k_KeyError[] = "KeyError";
+static char __pyx_k_c_wisdom[] = "c_wisdom";
+static char __pyx_k_counterf[] = "counterf";
+static char __pyx_k_counterl[] = "counterl";
+static char __pyx_k_executor[] = "executor";
+static char __pyx_k_get_axes[] = "_get_axes";
+static char __pyx_k_itemsize[] = "itemsize";
+static char __pyx_k_property[] = "property";
+static char __pyx_k_successf[] = "successf";
+static char __pyx_k_successl[] = "successl";
+static char __pyx_k_warnings[] = "warnings";
+static char __pyx_k_TypeError[] = "TypeError";
+static char __pyx_k_alignment[] = "alignment";
+static char __pyx_k_c_wisdomf[] = "c_wisdomf";
+static char __pyx_k_c_wisdoml[] = "c_wisdoml";
+static char __pyx_k_complex64[] = "complex64";
+static char __pyx_k_direction[] = "direction";
+static char __pyx_k_flag_dict[] = "_flag_dict";
+static char __pyx_k_less_than[] = "less than ";
+static char __pyx_k_py_wisdom[] = "py_wisdom";
+static char __pyx_k_threading[] = "threading";
+static char __pyx_k_validator[] = "validator";
+static char __pyx_k_IndexError[] = "IndexError";
+static char __pyx_k_ValueError[] = "ValueError";
+static char __pyx_k_asanyarray[] = "asanyarray";
+static char __pyx_k_complex128[] = "complex128";
+static char __pyx_k_frombuffer[] = "frombuffer";
+static char __pyx_k_longdouble[] = "longdouble";
+static char __pyx_k_py_wisdomf[] = "py_wisdomf";
+static char __pyx_k_py_wisdoml[] = "py_wisdoml";
+static char __pyx_k_pyx_vtable[] = "__pyx_vtable__";
+static char __pyx_k_MemoryError[] = "MemoryError";
+static char __pyx_k_clongdouble[] = "clongdouble";
+static char __pyx_k_input_array[] = "input_array";
+static char __pyx_k_input_dtype[] = "input_dtype";
+static char __pyx_k_input_shape[] = "input_shape";
+static char __pyx_k_FFTW_FORWARD[] = "FFTW_FORWARD";
+static char __pyx_k_FFTW_MEASURE[] = "FFTW_MEASURE";
+static char __pyx_k_FFTW_PATIENT[] = "FFTW_PATIENT";
+static char __pyx_k_Invalid_flag[] = "Invalid flag: ";
+static char __pyx_k_RuntimeError[] = "RuntimeError";
+static char __pyx_k_c_wisdom_ptr[] = "c_wisdom_ptr";
+static char __pyx_k_output_array[] = "output_array";
+static char __pyx_k_output_dtype[] = "output_dtype";
+static char __pyx_k_output_shape[] = "output_shape";
+static char __pyx_k_simd_aligned[] = "simd_aligned";
+static char __pyx_k_FFTW_BACKWARD[] = "FFTW_BACKWARD";
+static char __pyx_k_FFTW_ESTIMATE[] = "FFTW_ESTIMATE";
+static char __pyx_k_c_wisdomf_ptr[] = "c_wisdomf_ptr";
+static char __pyx_k_c_wisdoml_ptr[] = "c_wisdoml_ptr";
+static char __pyx_k_empty_aligned[] = "empty_aligned";
+static char __pyx_k_export_wisdom[] = "export_wisdom";
+static char __pyx_k_forget_wisdom[] = "forget_wisdom";
+static char __pyx_k_get_direction[] = "_get_direction";
+static char __pyx_k_import_wisdom[] = "import_wisdom";
+static char __pyx_k_input_strides[] = "input_strides";
+static char __pyx_k_pyfftw_pyfftw[] = "pyfftw.pyfftw";
+static char __pyx_k_update_arrays[] = "update_arrays";
+static char __pyx_k_FFTW_UNALIGNED[] = "FFTW_UNALIGNED";
+static char __pyx_k_get_flags_used[] = "_get_flags_used";
+static char __pyx_k_normalise_idft[] = "normalise_idft";
+static char __pyx_k_output_strides[] = "output_strides";
+static char __pyx_k_simd_alignment[] = "simd_alignment";
+static char __pyx_k_FFTW_EXHAUSTIVE[] = "FFTW_EXHAUSTIVE";
+static char __pyx_k_get_input_array[] = "_get_input_array";
+static char __pyx_k_get_input_dtype[] = "_get_input_dtype";
+static char __pyx_k_get_input_shape[] = "_get_input_shape";
+static char __pyx_k_input_alignment[] = "input_alignment";
+static char __pyx_k_new_input_array[] = "new_input_array";
+static char __pyx_k_FFTW_WISDOM_ONLY[] = "FFTW_WISDOM_ONLY";
+static char __pyx_k_fft_shape_lookup[] = "fft_shape_lookup";
+static char __pyx_k_get_output_array[] = "_get_output_array";
+static char __pyx_k_get_output_dtype[] = "_get_output_dtype";
+static char __pyx_k_get_output_shape[] = "_get_output_shape";
+static char __pyx_k_get_simd_aligned[] = "_get_simd_aligned";
+static char __pyx_k_new_output_array[] = "new_output_array";
+static char __pyx_k_output_alignment[] = "output_alignment";
+static char __pyx_k_generic_precision[] = "generic_precision";
+static char __pyx_k_get_input_strides[] = "_get_input_strides";
+static char __pyx_k_DeprecationWarning[] = "DeprecationWarning";
+static char __pyx_k_FFTW_DESTROY_INPUT[] = "FFTW_DESTROY_INPUT";
+static char __pyx_k_get_output_strides[] = "_get_output_strides";
+static char __pyx_k_planning_timelimit[] = "planning_timelimit";
+static char __pyx_k_get_input_alignment[] = "_get_input_alignment";
+static char __pyx_k_get_output_alignment[] = "_get_output_alignment";
+static char __pyx_k_valid_simd_alignments[] = "_valid_simd_alignments";
+static char __pyx_k_lookup_shape_c2r_arrays[] = "_lookup_shape_c2r_arrays";
+static char __pyx_k_lookup_shape_r2c_arrays[] = "_lookup_shape_r2c_arrays";
+static char __pyx_k_is_not_a_valid_planner_flag[] = "' is not a valid planner flag.";
+static char __pyx_k_ndarray_is_not_C_contiguous[] = "ndarray is not C contiguous";
+static char __pyx_k_Invalid_array_is_n_byte_aligned[] = "Invalid array: is_n_byte_aligned requires a subclass of ndarray";
+static char __pyx_k_Invalid_direction_The_direction[] = "Invalid direction: The direction is not valid for the scheme. Try setting it explicitly if it is not already.";
+static char __pyx_k_Invalid_output_array_The_output[] = "Invalid output array: The output array needs to be an instance of numpy.ndarray";
+static char __pyx_k_Invalid_scheme_The_output_array[] = "Invalid scheme: The output array and input array dtypes do not correspond to a valid fftw scheme.";
+static char __pyx_k_Invalid_shapes_The_output_array[] = "Invalid shapes: The output array should be the same shape as the input array for the given array dtypes.";
+static char __pyx_k_Strides_of_the_input_array_must[] = "Strides of the input array must be ";
+static char __pyx_k_home_whg_Projects_github_pyFFTW[] = "/home/whg/Projects/github/pyFFTW/pyfftw/pyfftw.pyx";
+static char __pyx_k_unknown_dtype_code_in_numpy_pxd[] = "unknown dtype code in numpy.pxd (%d)";
+static char __pyx_k_Dimensions_of_the_input_array_mu[] = "Dimensions of the input array must be ";
+static char __pyx_k_Dimensions_of_the_output_array_m[] = "Dimensions of the output array must be ";
+static char __pyx_k_Format_string_allocated_too_shor[] = "Format string allocated too short, see comment in numpy.pxd";
+static char __pyx_k_Invalid_array_byte_align_require[] = "Invalid array: byte_align requires a subclass of ndarray";
+static char __pyx_k_Invalid_axes_The_axes_list_canno[] = "Invalid axes: The axes list cannot contain invalid axes.";
+static char __pyx_k_Invalid_input_alignment_The_inpu[] = "Invalid input alignment: The input array is expected to lie on a %d byte boundary.";
+static char __pyx_k_Invalid_input_alignment_The_orig[] = "Invalid input alignment: The original arrays were %d-byte aligned. It is necessary that the update input array is similarly aligned.";
+static char __pyx_k_Invalid_input_array_The_input_ar[] = "Invalid input array: The input array needs to be an instance of numpy.ndarray";
+static char __pyx_k_Invalid_input_array_The_new_inpu[] = "Invalid input array: The new input array needs to be an instance of numpy.ndarray";
+static char __pyx_k_Invalid_input_dtype_The_new_inpu[] = "Invalid input dtype: The new input array is not of the same dtype as was originally planned for.";
+static char __pyx_k_Invalid_input_shape_The_new_inpu[] = "Invalid input shape: The new input array should be the same shape as the input array used to instantiate the object.";
+static char __pyx_k_Invalid_input_striding_The_strid[] = "Invalid input striding: The strides should be identical for the new input array as for the old.";
+static char __pyx_k_Invalid_output_alignment_The_ori[] = "Invalid output alignment: The original arrays were %d-byte aligned. It is necessary that the update output array is similarly aligned.";
+static char __pyx_k_Invalid_output_alignment_The_out[] = "Invalid output alignment: The output array is expected to lie on a %d byte boundary.";
+static char __pyx_k_Invalid_output_array_The_new_out[] = "Invalid output array The new output array needs to be an instance of numpy.ndarray";
+static char __pyx_k_Invalid_output_dtype_The_new_out[] = "Invalid output dtype: The new output array is not of the same dtype as was originally planned for.";
+static char __pyx_k_Invalid_output_shape_The_new_out[] = "Invalid output shape: The new output array should be the same shape as the output array used to instantiate the object.";
+static char __pyx_k_Invalid_output_striding_The_stri[] = "Invalid output striding: The strides should be identical for the new output array as for the old.";
+static char __pyx_k_Invalid_planning_timelimit_The_p[] = "Invalid planning timelimit: The planning timelimit needs to be a float.";
+static char __pyx_k_Invalid_shapes_The_input_array_a[] = "Invalid shapes: The input array and output array are invalid complementary shapes for their dtypes.";
+static char __pyx_k_No_FFTW_wisdom_is_known_for_this[] = "No FFTW wisdom is known for this plan.";
+static char __pyx_k_Non_native_byte_order_not_suppor[] = "Non-native byte order not supported";
+static char __pyx_k_Strides_of_the_output_array_must[] = "Strides of the output array must be ";
+static char __pyx_k_The_data_has_an_uncaught_error_t[] = "The data has an uncaught error that led ";
+static char __pyx_k_This_function_is_deprecated_in_f[] = "This function is deprecated in favour of``empty_aligned``.";
+static char __pyx_k_Zero_length_array_The_input_arra[] = "Zero length array: The input array should have no zero lengthaxes over which the FFT is to be taken";
+static char __pyx_k_get_input_array_is_deprecated_Co[] = "get_input_array is deprecated. Consider using the input_array property instead.";
+static char __pyx_k_get_output_array_is_deprecated_C[] = "get_output_array is deprecated. Consider using the output_array property instead.";
+static char __pyx_k_ndarray_is_not_Fortran_contiguou[] = "ndarray is not Fortran contiguous";
+static char __pyx_k_to_the_planner_returning_NULL_Th[] = "to the planner returning NULL. This is a bug.";
+static char __pyx_k_Format_string_allocated_too_shor_2[] = "Format string allocated too short.";
+static char __pyx_k_This_function_is_deprecated_in_f_2[] = "This function is deprecated in favour of``byte_align``.";
+static PyObject *__pyx_kp_s_32;
+static PyObject *__pyx_kp_s_64;
+static PyObject *__pyx_n_s_C;
+static PyObject *__pyx_n_s_DeprecationWarning;
+static PyObject *__pyx_kp_s_Dimensions_of_the_input_array_mu;
+static PyObject *__pyx_kp_s_Dimensions_of_the_output_array_m;
+static PyObject *__pyx_n_s_FFTW_BACKWARD;
+static PyObject *__pyx_n_s_FFTW_DESTROY_INPUT;
+static PyObject *__pyx_n_s_FFTW_ESTIMATE;
+static PyObject *__pyx_n_s_FFTW_EXHAUSTIVE;
+static PyObject *__pyx_n_s_FFTW_FORWARD;
+static PyObject *__pyx_n_s_FFTW_MEASURE;
+static PyObject *__pyx_n_s_FFTW_PATIENT;
+static PyObject *__pyx_n_s_FFTW_UNALIGNED;
+static PyObject *__pyx_n_s_FFTW_WISDOM_ONLY;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor;
+static PyObject *__pyx_kp_u_Format_string_allocated_too_shor_2;
+static PyObject *__pyx_n_s_IndexError;
+static PyObject *__pyx_kp_s_Invalid_array_byte_align_require;
+static PyObject *__pyx_kp_s_Invalid_array_is_n_byte_aligned;
+static PyObject *__pyx_kp_s_Invalid_axes_The_axes_list_canno;
+static PyObject *__pyx_kp_s_Invalid_direction_The_direction;
+static PyObject *__pyx_kp_s_Invalid_flag;
+static PyObject *__pyx_kp_s_Invalid_input_alignment_The_inpu;
+static PyObject *__pyx_kp_s_Invalid_input_alignment_The_orig;
+static PyObject *__pyx_kp_s_Invalid_input_array_The_input_ar;
+static PyObject *__pyx_kp_s_Invalid_input_array_The_new_inpu;
+static PyObject *__pyx_kp_s_Invalid_input_dtype_The_new_inpu;
+static PyObject *__pyx_kp_s_Invalid_input_shape_The_new_inpu;
+static PyObject *__pyx_kp_s_Invalid_input_striding_The_strid;
+static PyObject *__pyx_kp_s_Invalid_output_alignment_The_ori;
+static PyObject *__pyx_kp_s_Invalid_output_alignment_The_out;
+static PyObject *__pyx_kp_s_Invalid_output_array_The_new_out;
+static PyObject *__pyx_kp_s_Invalid_output_array_The_output;
+static PyObject *__pyx_kp_s_Invalid_output_dtype_The_new_out;
+static PyObject *__pyx_kp_s_Invalid_output_shape_The_new_out;
+static PyObject *__pyx_kp_s_Invalid_output_striding_The_stri;
+static PyObject *__pyx_kp_s_Invalid_planning_timelimit_The_p;
+static PyObject *__pyx_kp_s_Invalid_scheme_The_output_array;
+static PyObject *__pyx_kp_s_Invalid_shapes_The_input_array_a;
+static PyObject *__pyx_kp_s_Invalid_shapes_The_output_array;
+static PyObject *__pyx_n_s_KeyError;
+static PyObject *__pyx_n_s_Lock;
+static PyObject *__pyx_n_s_MemoryError;
+static PyObject *__pyx_n_s_N;
+static PyObject *__pyx_kp_s_No_FFTW_wisdom_is_known_for_this;
+static PyObject *__pyx_kp_u_Non_native_byte_order_not_suppor;
+static PyObject *__pyx_n_s_RuntimeError;
+static PyObject *__pyx_kp_s_Strides_of_the_input_array_must;
+static PyObject *__pyx_kp_s_Strides_of_the_output_array_must;
+static PyObject *__pyx_kp_s_The_data_has_an_uncaught_error_t;
+static PyObject *__pyx_kp_s_This_function_is_deprecated_in_f;
+static PyObject *__pyx_kp_s_This_function_is_deprecated_in_f_2;
+static PyObject *__pyx_n_s_TypeError;
+static PyObject *__pyx_n_s_ValueError;
+static PyObject *__pyx_kp_s_Zero_length_array_The_input_arra;
+static PyObject *__pyx_kp_s__17;
+static PyObject *__pyx_n_s_alignment;
+static PyObject *__pyx_n_s_append;
+static PyObject *__pyx_n_s_array;
+static PyObject *__pyx_n_s_asanyarray;
+static PyObject *__pyx_n_s_axes;
+static PyObject *__pyx_n_s_c2c;
+static PyObject *__pyx_n_s_c2r;
+static PyObject *__pyx_n_s_c_wisdom;
+static PyObject *__pyx_n_s_c_wisdom_ptr;
+static PyObject *__pyx_n_s_c_wisdomf;
+static PyObject *__pyx_n_s_c_wisdomf_ptr;
+static PyObject *__pyx_n_s_c_wisdoml;
+static PyObject *__pyx_n_s_c_wisdoml_ptr;
+static PyObject *__pyx_n_s_class;
+static PyObject *__pyx_n_s_clongdouble;
+static PyObject *__pyx_n_s_complex128;
+static PyObject *__pyx_n_s_complex64;
+static PyObject *__pyx_n_s_copy;
+static PyObject *__pyx_n_s_counter;
+static PyObject *__pyx_n_s_counterf;
+static PyObject *__pyx_n_s_counterl;
+static PyObject *__pyx_n_s_data;
+static PyObject *__pyx_n_s_direction;
+static PyObject *__pyx_n_s_dtype;
+static PyObject *__pyx_n_s_empty;
+static PyObject *__pyx_n_s_empty_aligned;
+static PyObject *__pyx_n_s_enter;
+static PyObject *__pyx_n_s_execute;
+static PyObject *__pyx_n_s_executor;
+static PyObject *__pyx_n_s_exit;
+static PyObject *__pyx_n_s_export_wisdom;
+static PyObject *__pyx_n_s_fft_shape_lookup;
+static PyObject *__pyx_n_s_fill;
+static PyObject *__pyx_n_s_flag_dict;
+static PyObject *__pyx_n_s_flags;
+static PyObject *__pyx_n_s_float32;
+static PyObject *__pyx_n_s_float64;
+static PyObject *__pyx_n_s_forget_wisdom;
+static PyObject *__pyx_n_s_frombuffer;
+static PyObject *__pyx_n_s_generic_precision;
+static PyObject *__pyx_n_s_get_N;
+static PyObject *__pyx_n_s_get_axes;
+static PyObject *__pyx_n_s_get_direction;
+static PyObject *__pyx_n_s_get_flags_used;
+static PyObject *__pyx_n_s_get_input_alignment;
+static PyObject *__pyx_n_s_get_input_array;
+static PyObject *__pyx_kp_s_get_input_array_is_deprecated_Co;
+static PyObject *__pyx_n_s_get_input_dtype;
+static PyObject *__pyx_n_s_get_input_shape;
+static PyObject *__pyx_n_s_get_input_strides;
+static PyObject *__pyx_n_s_get_output_alignment;
+static PyObject *__pyx_n_s_get_output_array;
+static PyObject *__pyx_kp_s_get_output_array_is_deprecated_C;
+static PyObject *__pyx_n_s_get_output_dtype;
+static PyObject *__pyx_n_s_get_output_shape;
+static PyObject *__pyx_n_s_get_output_strides;
+static PyObject *__pyx_n_s_get_simd_aligned;
+static PyObject *__pyx_kp_s_home_whg_Projects_github_pyFFTW;
+static PyObject *__pyx_n_s_import;
+static PyObject *__pyx_n_s_import_wisdom;
+static PyObject *__pyx_n_s_input_alignment;
+static PyObject *__pyx_n_s_input_array;
+static PyObject *__pyx_n_s_input_dtype;
+static PyObject *__pyx_n_s_input_shape;
+static PyObject *__pyx_n_s_input_strides;
+static PyObject *__pyx_n_s_int8;
+static PyObject *__pyx_n_s_integer;
+static PyObject *__pyx_kp_s_is_not_a_valid_planner_flag;
+static PyObject *__pyx_n_s_itemsize;
+static PyObject *__pyx_n_s_ld;
+static PyObject *__pyx_kp_s_less_than;
+static PyObject *__pyx_n_s_longdouble;
+static PyObject *__pyx_n_s_lookup_shape_c2r_arrays;
+static PyObject *__pyx_n_s_lookup_shape_r2c_arrays;
+static PyObject *__pyx_n_s_main;
+static PyObject *__pyx_n_s_n;
+static PyObject *__pyx_kp_u_ndarray_is_not_C_contiguous;
+static PyObject *__pyx_kp_u_ndarray_is_not_Fortran_contiguou;
+static PyObject *__pyx_n_s_new_input_array;
+static PyObject *__pyx_n_s_new_output_array;
+static PyObject *__pyx_n_s_normalise_idft;
+static PyObject *__pyx_n_s_np;
+static PyObject *__pyx_n_s_numpy;
+static PyObject *__pyx_n_s_order;
+static PyObject *__pyx_n_s_output_alignment;
+static PyObject *__pyx_n_s_output_array;
+static PyObject *__pyx_n_s_output_dtype;
+static PyObject *__pyx_n_s_output_shape;
+static PyObject *__pyx_n_s_output_strides;
+static PyObject *__pyx_n_s_planner;
+static PyObject *__pyx_n_s_planning_timelimit;
+static PyObject *__pyx_n_s_property;
+static PyObject *__pyx_n_s_py_wisdom;
+static PyObject *__pyx_n_s_py_wisdomf;
+static PyObject *__pyx_n_s_py_wisdoml;
+static PyObject *__pyx_n_s_pyfftw_pyfftw;
+static PyObject *__pyx_n_s_pyx_vtable;
+static PyObject *__pyx_n_s_r2c;
+static PyObject *__pyx_n_s_range;
+static PyObject *__pyx_n_s_real;
+static PyObject *__pyx_n_s_reshape;
+static PyObject *__pyx_n_s_shape;
+static PyObject *__pyx_n_s_simd_aligned;
+static PyObject *__pyx_n_s_simd_alignment;
+static PyObject *__pyx_n_s_strides;
+static PyObject *__pyx_n_s_success;
+static PyObject *__pyx_n_s_successf;
+static PyObject *__pyx_n_s_successl;
+static PyObject *__pyx_n_s_test;
+static PyObject *__pyx_n_s_threading;
+static PyObject *__pyx_n_s_threads;
+static PyObject *__pyx_kp_s_to_the_planner_returning_NULL_Th;
+static PyObject *__pyx_n_s_type;
+static PyObject *__pyx_kp_u_unknown_dtype_code_in_numpy_pxd;
+static PyObject *__pyx_n_s_update;
+static PyObject *__pyx_n_s_update_arrays;
+static PyObject *__pyx_n_s_valid_simd_alignments;
+static PyObject *__pyx_n_s_validator;
+static PyObject *__pyx_n_s_view;
+static PyObject *__pyx_n_s_warn;
+static PyObject *__pyx_n_s_warnings;
+static PyObject *__pyx_n_s_wisdom;
 static PyObject *__pyx_pf_6pyfftw_6pyfftw_n_byte_align_empty(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_shape, PyObject *__pyx_v_n, PyObject *__pyx_v_dtype, PyObject *__pyx_v_order); /* proto */
 static PyObject *__pyx_pf_6pyfftw_6pyfftw_2n_byte_align(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_array, PyObject *__pyx_v_n, PyObject *__pyx_v_dtype); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4is_n_byte_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_array, PyObject *__pyx_v_n); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_6_lookup_shape_r2c_arrays(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_input_array, CYTHON_UNUSED PyObject *__pyx_v_output_array); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_8_lookup_shape_c2r_arrays(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW___get_N(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_2__get_simd_aligned(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_4__get_input_alignment(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_6__get_output_alignment(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_8__get_flags_used(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
-static int __pyx_pf_6pyfftw_6pyfftw_4FFTW_10__cinit__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array, PyObject *__pyx_v_axes, PyObject *__pyx_v_direction, PyObject *__pyx_v_flags, unsigned int __pyx_v_threads, PyObject *__pyx_v_planning_timelimit, CYTHON_UNUSED PyObject *__pyx_v_args, CYTHON_UNUSED PyObject *__pyx_v_kwargs); /* proto */
-static int __pyx_pf_6pyfftw_6pyfftw_4FFTW_12__init__(CYTHON_UNUSED struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_input_array, CYTHON_UNUSED PyObject *__pyx_v_output_array, CYTHON_UNUSED PyObject *__pyx_v_axes, CYTHON_UNUSED PyObject *__pyx_v_direction, CYTHON_UNUSED PyObject *__pyx_v_flags, CYTHON_UNUSED int __pyx_v_threads, CYTHON_UNUSED PyObject *__pyx_v_planning_timelimit, CYTHON_UNUSED PyObject *__pyx_v_args, CYTHON_UNUSED PyObject *__pyx_v_kwar [...]
-static void __pyx_pf_6pyfftw_6pyfftw_4FFTW_14__dealloc__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_16__call__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array, PyObject *__pyx_v_normalise_idft); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_18update_arrays(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_new_input_array, PyObject *__pyx_v_new_output_array); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_20get_input_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_22get_output_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_24execute(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_10export_wisdom(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_12import_wisdom(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_wisdom); /* proto */
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_14forget_wisdom(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4byte_align(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_array, PyObject *__pyx_v_n, PyObject *__pyx_v_dtype); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_6is_byte_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_array, PyObject *__pyx_v_n); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_8is_n_byte_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_array, PyObject *__pyx_v_n); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_10empty_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_shape, PyObject *__pyx_v_dtype, PyObject *__pyx_v_order, PyObject *__pyx_v_n); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_12zeros_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_shape, PyObject *__pyx_v_dtype, PyObject *__pyx_v_order, PyObject *__pyx_v_n); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_14ones_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_shape, PyObject *__pyx_v_dtype, PyObject *__pyx_v_order, PyObject *__pyx_v_n); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_16_lookup_shape_r2c_arrays(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_input_array, CYTHON_UNUSED PyObject *__pyx_v_output_array); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_18_lookup_shape_c2r_arrays(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW__get_N(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_2_get_simd_aligned(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_4_get_input_alignment(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_6_get_output_alignment(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_8_get_flags_used(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_10_get_input_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_12_get_output_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_14_get_input_strides(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_16_get_output_strides(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_18_get_input_shape(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_20_get_output_shape(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_22_get_input_dtype(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_24_get_output_dtype(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_26_get_direction(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_28_get_axes(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static int __pyx_pf_6pyfftw_6pyfftw_4FFTW_30__cinit__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array, PyObject *__pyx_v_axes, PyObject *__pyx_v_direction, PyObject *__pyx_v_flags, unsigned int __pyx_v_threads, PyObject *__pyx_v_planning_timelimit, CYTHON_UNUSED PyObject *__pyx_v_args, CYTHON_UNUSED PyObject *__pyx_v_kwargs); /* proto */
+static int __pyx_pf_6pyfftw_6pyfftw_4FFTW_32__init__(CYTHON_UNUSED struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_input_array, CYTHON_UNUSED PyObject *__pyx_v_output_array, CYTHON_UNUSED PyObject *__pyx_v_axes, CYTHON_UNUSED PyObject *__pyx_v_direction, CYTHON_UNUSED PyObject *__pyx_v_flags, CYTHON_UNUSED int __pyx_v_threads, CYTHON_UNUSED PyObject *__pyx_v_planning_timelimit); /* proto */
+static void __pyx_pf_6pyfftw_6pyfftw_4FFTW_34__dealloc__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_36__call__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array, PyObject *__pyx_v_normalise_idft); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_38update_arrays(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_new_input_array, PyObject *__pyx_v_new_output_array); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_40get_input_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_42get_output_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_44execute(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_20export_wisdom(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_22import_wisdom(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_wisdom); /* proto */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_24forget_wisdom(CYTHON_UNUSED PyObject *__pyx_self); /* proto */
 static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /* proto */
 static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info); /* proto */
-static char __pyx_k_1[] = "Invalid array: n_byte_align requires a subclass of ndarray";
-static char __pyx_k_3[] = "Invalid array: is_n_byte_aligned requires a subclass of ndarray";
-static char __pyx_k_7[] = "Invalid planning timelimit: The planning timelimit needs to be a float.";
-static char __pyx_k_9[] = "Invalid input array: The input array needs to be an instance of numpy.ndarray";
-static char __pyx_k_11[] = "Invalid output array: The output array needs to be an instance of numpy.ndarray";
-static char __pyx_k_13[] = "Invalid scheme: The output array and input array dtypes do not correspond to a valid fftw scheme.";
-static char __pyx_k_15[] = "_valid_simd_alignments";
-static char __pyx_k_16[] = "Invalid input alignment: The input array is expected to lie on a %d byte boundary.";
-static char __pyx_k_17[] = "Invalid output alignment: The output array is expected to lie on a %d byte boundary.";
-static char __pyx_k_18[] = "Invalid direction: The direction is not valid for the scheme. Try setting it explicitly if it is not already.";
-static char __pyx_k_20[] = "Invalid axes: The axes list cannot contain invalid axes.";
-static char __pyx_k_22[] = "Zero length array: The input array should have no zero lengthaxes over which the FFT is to be taken";
-static char __pyx_k_24[] = "Invalid shapes: The output array should be the same shape as the input array for the given array dtypes.";
-static char __pyx_k_26[] = "Invalid shapes: The input array and output array are invalid complementary shapes for their dtypes.";
-static char __pyx_k_28[] = "Invalid flag: ";
-static char __pyx_k_29[] = "'";
-static char __pyx_k_30[] = "' is not a valid planner flag.";
-static char __pyx_k_31[] = "Dimensions of the input array must be ";
-static char __pyx_k_32[] = "less than ";
-static char __pyx_k_33[] = "Strides of the input array must be ";
-static char __pyx_k_34[] = "Dimensions of the output array must be ";
-static char __pyx_k_35[] = "Strides of the output array must be ";
-static char __pyx_k_36[] = "The data has an uncaught error that led ";
-static char __pyx_k_37[] = "to the planner returning NULL. This is a bug.";
-static char __pyx_k_41[] = "Invalid input shape: The new input array should be the same shape as the input array used to instantiate the object.";
-static char __pyx_k_43[] = "Invalid input array: The new input array needs to be an instance of numpy.ndarray";
-static char __pyx_k_45[] = "Invalid output array The new output array needs to be an instance of numpy.ndarray";
-static char __pyx_k_47[] = "Invalid input alignment: The original arrays were %d-byte aligned. It is necessary that the update input array is similarly aligned.";
-static char __pyx_k_48[] = "Invalid output alignment: The original arrays were %d-byte aligned. It is necessary that the update output array is similarly aligned.";
-static char __pyx_k_49[] = "Invalid input dtype: The new input array is not of the same dtype as was originally planned for.";
-static char __pyx_k_51[] = "Invalid output dtype: The new output array is not of the same dtype as was originally planned for.";
-static char __pyx_k_54[] = "Invalid output shape: The new output array should be the same shape as the output array used to instantiate the object.";
-static char __pyx_k_56[] = "Invalid input striding: The strides should be identical for the new input array as for the old.";
-static char __pyx_k_58[] = "Invalid output striding: The strides should be identical for the new output array as for the old.";
-static char __pyx_k_60[] = "ndarray is not C contiguous";
-static char __pyx_k_62[] = "ndarray is not Fortran contiguous";
-static char __pyx_k_64[] = "Non-native byte order not supported";
-static char __pyx_k_66[] = "unknown dtype code in numpy.pxd (%d)";
-static char __pyx_k_67[] = "Format string allocated too short, see comment in numpy.pxd";
-static char __pyx_k_70[] = "Format string allocated too short.";
-static char __pyx_k_76[] = "_lookup_shape_r2c_arrays";
-static char __pyx_k_77[] = "/home/whg21/Projects/github/pyFFTW/pyfftw/pyfftw.pyx";
-static char __pyx_k_78[] = "pyfftw.pyfftw";
-static char __pyx_k_81[] = "_lookup_shape_c2r_arrays";
-static char __pyx_k__B[] = "B";
-static char __pyx_k__C[] = "C";
-static char __pyx_k__H[] = "H";
-static char __pyx_k__I[] = "I";
-static char __pyx_k__L[] = "L";
-static char __pyx_k__N[] = "N";
-static char __pyx_k__O[] = "O";
-static char __pyx_k__Q[] = "Q";
-static char __pyx_k__b[] = "b";
-static char __pyx_k__d[] = "d";
-static char __pyx_k__f[] = "f";
-static char __pyx_k__g[] = "g";
-static char __pyx_k__h[] = "h";
-static char __pyx_k__i[] = "i";
-static char __pyx_k__l[] = "l";
-static char __pyx_k__n[] = "n";
-static char __pyx_k__q[] = "q";
-static char __pyx_k_129[] = "__get_input_alignment";
-static char __pyx_k_130[] = "__get_output_alignment";
-static char __pyx_k__32[] = "32";
-static char __pyx_k__64[] = "64";
-static char __pyx_k__Zd[] = "Zd";
-static char __pyx_k__Zf[] = "Zf";
-static char __pyx_k__Zg[] = "Zg";
-static char __pyx_k__ld[] = "ld";
-static char __pyx_k__np[] = "np";
-static char __pyx_k__c2c[] = "c2c";
-static char __pyx_k__c2r[] = "c2r";
-static char __pyx_k__r2c[] = "r2c";
-static char __pyx_k__axes[] = "axes";
-static char __pyx_k__copy[] = "copy";
-static char __pyx_k__data[] = "data";
-static char __pyx_k__int8[] = "int8";
-static char __pyx_k__type[] = "type";
-static char __pyx_k__view[] = "view";
-static char __pyx_k__array[] = "array";
-static char __pyx_k__dtype[] = "dtype";
-static char __pyx_k__empty[] = "empty";
-static char __pyx_k__flags[] = "flags";
-static char __pyx_k__numpy[] = "numpy";
-static char __pyx_k__order[] = "order";
-static char __pyx_k__range[] = "range";
-static char __pyx_k__shape[] = "shape";
-static char __pyx_k__update[] = "update";
-static char __pyx_k__wisdom[] = "wisdom";
-static char __pyx_k____get_N[] = "__get_N";
-static char __pyx_k__counter[] = "counter";
-static char __pyx_k__execute[] = "execute";
-static char __pyx_k__float32[] = "float32";
-static char __pyx_k__float64[] = "float64";
-static char __pyx_k__integer[] = "integer";
-static char __pyx_k__planner[] = "planner";
-static char __pyx_k__reshape[] = "reshape";
-static char __pyx_k__strides[] = "strides";
-static char __pyx_k__success[] = "success";
-static char __pyx_k__threads[] = "threads";
-static char __pyx_k__KeyError[] = "KeyError";
-static char __pyx_k____main__[] = "__main__";
-static char __pyx_k____test__[] = "__test__";
-static char __pyx_k__c_wisdom[] = "c_wisdom";
-static char __pyx_k__counterf[] = "counterf";
-static char __pyx_k__counterl[] = "counterl";
-static char __pyx_k__executor[] = "executor";
-static char __pyx_k__itemsize[] = "itemsize";
-static char __pyx_k__property[] = "property";
-static char __pyx_k__successf[] = "successf";
-static char __pyx_k__successl[] = "successl";
-static char __pyx_k__TypeError[] = "TypeError";
-static char __pyx_k____class__[] = "__class__";
-static char __pyx_k__alignment[] = "alignment";
-static char __pyx_k__c_wisdomf[] = "c_wisdomf";
-static char __pyx_k__c_wisdoml[] = "c_wisdoml";
-static char __pyx_k__complex64[] = "complex64";
-static char __pyx_k__direction[] = "direction";
-static char __pyx_k__py_wisdom[] = "py_wisdom";
-static char __pyx_k__validator[] = "validator";
-static char __pyx_k__IndexError[] = "IndexError";
-static char __pyx_k__ValueError[] = "ValueError";
-static char __pyx_k___flag_dict[] = "_flag_dict";
-static char __pyx_k__asanyarray[] = "asanyarray";
-static char __pyx_k__complex128[] = "complex128";
-static char __pyx_k__frombuffer[] = "frombuffer";
-static char __pyx_k__longdouble[] = "longdouble";
-static char __pyx_k__py_wisdomf[] = "py_wisdomf";
-static char __pyx_k__py_wisdoml[] = "py_wisdoml";
-static char __pyx_k__MemoryError[] = "MemoryError";
-static char __pyx_k__clongdouble[] = "clongdouble";
-static char __pyx_k__input_array[] = "input_array";
-static char __pyx_k__FFTW_FORWARD[] = "FFTW_FORWARD";
-static char __pyx_k__FFTW_MEASURE[] = "FFTW_MEASURE";
-static char __pyx_k__FFTW_PATIENT[] = "FFTW_PATIENT";
-static char __pyx_k__RuntimeError[] = "RuntimeError";
-static char __pyx_k__c_wisdom_ptr[] = "c_wisdom_ptr";
-static char __pyx_k__output_array[] = "output_array";
-static char __pyx_k__simd_aligned[] = "simd_aligned";
-static char __pyx_k__FFTW_BACKWARD[] = "FFTW_BACKWARD";
-static char __pyx_k__FFTW_ESTIMATE[] = "FFTW_ESTIMATE";
-static char __pyx_k__c_wisdomf_ptr[] = "c_wisdomf_ptr";
-static char __pyx_k__c_wisdoml_ptr[] = "c_wisdoml_ptr";
-static char __pyx_k__export_wisdom[] = "export_wisdom";
-static char __pyx_k__forget_wisdom[] = "forget_wisdom";
-static char __pyx_k__import_wisdom[] = "import_wisdom";
-static char __pyx_k__update_arrays[] = "update_arrays";
-static char __pyx_k__FFTW_UNALIGNED[] = "FFTW_UNALIGNED";
-static char __pyx_k__normalise_idft[] = "normalise_idft";
-static char __pyx_k__simd_alignment[] = "simd_alignment";
-static char __pyx_k__FFTW_EXHAUSTIVE[] = "FFTW_EXHAUSTIVE";
-static char __pyx_k__input_alignment[] = "input_alignment";
-static char __pyx_k__new_input_array[] = "new_input_array";
-static char __pyx_k____get_flags_used[] = "__get_flags_used";
-static char __pyx_k__fft_shape_lookup[] = "fft_shape_lookup";
-static char __pyx_k__new_output_array[] = "new_output_array";
-static char __pyx_k__output_alignment[] = "output_alignment";
-static char __pyx_k__generic_precision[] = "generic_precision";
-static char __pyx_k__FFTW_DESTROY_INPUT[] = "FFTW_DESTROY_INPUT";
-static char __pyx_k____get_simd_aligned[] = "__get_simd_aligned";
-static char __pyx_k__planning_timelimit[] = "planning_timelimit";
-static PyObject *__pyx_kp_s_1;
-static PyObject *__pyx_kp_s_11;
-static PyObject *__pyx_n_s_129;
-static PyObject *__pyx_kp_s_13;
-static PyObject *__pyx_n_s_130;
-static PyObject *__pyx_n_s_15;
-static PyObject *__pyx_kp_s_16;
-static PyObject *__pyx_kp_s_17;
-static PyObject *__pyx_kp_s_18;
-static PyObject *__pyx_kp_s_20;
-static PyObject *__pyx_kp_s_22;
-static PyObject *__pyx_kp_s_24;
-static PyObject *__pyx_kp_s_26;
-static PyObject *__pyx_kp_s_28;
-static PyObject *__pyx_kp_s_29;
-static PyObject *__pyx_kp_s_3;
-static PyObject *__pyx_kp_s_30;
-static PyObject *__pyx_kp_s_31;
-static PyObject *__pyx_kp_s_32;
-static PyObject *__pyx_kp_s_33;
-static PyObject *__pyx_kp_s_34;
-static PyObject *__pyx_kp_s_35;
-static PyObject *__pyx_kp_s_36;
-static PyObject *__pyx_kp_s_37;
-static PyObject *__pyx_kp_s_41;
-static PyObject *__pyx_kp_s_43;
-static PyObject *__pyx_kp_s_45;
-static PyObject *__pyx_kp_s_47;
-static PyObject *__pyx_kp_s_48;
-static PyObject *__pyx_kp_s_49;
-static PyObject *__pyx_kp_s_51;
-static PyObject *__pyx_kp_s_54;
-static PyObject *__pyx_kp_s_56;
-static PyObject *__pyx_kp_s_58;
-static PyObject *__pyx_kp_u_60;
-static PyObject *__pyx_kp_u_62;
-static PyObject *__pyx_kp_u_64;
-static PyObject *__pyx_kp_u_66;
-static PyObject *__pyx_kp_u_67;
-static PyObject *__pyx_kp_s_7;
-static PyObject *__pyx_kp_u_70;
-static PyObject *__pyx_n_s_76;
-static PyObject *__pyx_kp_s_77;
-static PyObject *__pyx_n_s_78;
-static PyObject *__pyx_n_s_81;
-static PyObject *__pyx_kp_s_9;
-static PyObject *__pyx_kp_s__32;
-static PyObject *__pyx_kp_s__64;
-static PyObject *__pyx_n_s__C;
-static PyObject *__pyx_n_s__FFTW_BACKWARD;
-static PyObject *__pyx_n_s__FFTW_DESTROY_INPUT;
-static PyObject *__pyx_n_s__FFTW_ESTIMATE;
-static PyObject *__pyx_n_s__FFTW_EXHAUSTIVE;
-static PyObject *__pyx_n_s__FFTW_FORWARD;
-static PyObject *__pyx_n_s__FFTW_MEASURE;
-static PyObject *__pyx_n_s__FFTW_PATIENT;
-static PyObject *__pyx_n_s__FFTW_UNALIGNED;
-static PyObject *__pyx_n_s__IndexError;
-static PyObject *__pyx_n_s__KeyError;
-static PyObject *__pyx_n_s__MemoryError;
-static PyObject *__pyx_n_s__N;
-static PyObject *__pyx_n_s__RuntimeError;
-static PyObject *__pyx_n_s__TypeError;
-static PyObject *__pyx_n_s__ValueError;
-static PyObject *__pyx_n_s____class__;
-static PyObject *__pyx_n_s____get_N;
-static PyObject *__pyx_n_s____get_flags_used;
-static PyObject *__pyx_n_s____get_simd_aligned;
-static PyObject *__pyx_n_s____main__;
-static PyObject *__pyx_n_s____test__;
-static PyObject *__pyx_n_s___flag_dict;
-static PyObject *__pyx_n_s__alignment;
-static PyObject *__pyx_n_s__array;
-static PyObject *__pyx_n_s__asanyarray;
-static PyObject *__pyx_n_s__axes;
-static PyObject *__pyx_n_s__c2c;
-static PyObject *__pyx_n_s__c2r;
-static PyObject *__pyx_n_s__c_wisdom;
-static PyObject *__pyx_n_s__c_wisdom_ptr;
-static PyObject *__pyx_n_s__c_wisdomf;
-static PyObject *__pyx_n_s__c_wisdomf_ptr;
-static PyObject *__pyx_n_s__c_wisdoml;
-static PyObject *__pyx_n_s__c_wisdoml_ptr;
-static PyObject *__pyx_n_s__clongdouble;
-static PyObject *__pyx_n_s__complex128;
-static PyObject *__pyx_n_s__complex64;
-static PyObject *__pyx_n_s__copy;
-static PyObject *__pyx_n_s__counter;
-static PyObject *__pyx_n_s__counterf;
-static PyObject *__pyx_n_s__counterl;
-static PyObject *__pyx_n_s__data;
-static PyObject *__pyx_n_s__direction;
-static PyObject *__pyx_n_s__dtype;
-static PyObject *__pyx_n_s__empty;
-static PyObject *__pyx_n_s__execute;
-static PyObject *__pyx_n_s__executor;
-static PyObject *__pyx_n_s__export_wisdom;
-static PyObject *__pyx_n_s__fft_shape_lookup;
-static PyObject *__pyx_n_s__flags;
-static PyObject *__pyx_n_s__float32;
-static PyObject *__pyx_n_s__float64;
-static PyObject *__pyx_n_s__forget_wisdom;
-static PyObject *__pyx_n_s__frombuffer;
-static PyObject *__pyx_n_s__generic_precision;
-static PyObject *__pyx_n_s__import_wisdom;
-static PyObject *__pyx_n_s__input_alignment;
-static PyObject *__pyx_n_s__input_array;
-static PyObject *__pyx_n_s__int8;
-static PyObject *__pyx_n_s__integer;
-static PyObject *__pyx_n_s__itemsize;
-static PyObject *__pyx_n_s__ld;
-static PyObject *__pyx_n_s__longdouble;
-static PyObject *__pyx_n_s__n;
-static PyObject *__pyx_n_s__new_input_array;
-static PyObject *__pyx_n_s__new_output_array;
-static PyObject *__pyx_n_s__normalise_idft;
-static PyObject *__pyx_n_s__np;
-static PyObject *__pyx_n_s__numpy;
-static PyObject *__pyx_n_s__order;
-static PyObject *__pyx_n_s__output_alignment;
-static PyObject *__pyx_n_s__output_array;
-static PyObject *__pyx_n_s__planner;
-static PyObject *__pyx_n_s__planning_timelimit;
-static PyObject *__pyx_n_s__property;
-static PyObject *__pyx_n_s__py_wisdom;
-static PyObject *__pyx_n_s__py_wisdomf;
-static PyObject *__pyx_n_s__py_wisdoml;
-static PyObject *__pyx_n_s__r2c;
-static PyObject *__pyx_n_s__range;
-static PyObject *__pyx_n_s__reshape;
-static PyObject *__pyx_n_s__shape;
-static PyObject *__pyx_n_s__simd_aligned;
-static PyObject *__pyx_n_s__simd_alignment;
-static PyObject *__pyx_n_s__strides;
-static PyObject *__pyx_n_s__success;
-static PyObject *__pyx_n_s__successf;
-static PyObject *__pyx_n_s__successl;
-static PyObject *__pyx_n_s__threads;
-static PyObject *__pyx_n_s__type;
-static PyObject *__pyx_n_s__update;
-static PyObject *__pyx_n_s__update_arrays;
-static PyObject *__pyx_n_s__validator;
-static PyObject *__pyx_n_s__view;
-static PyObject *__pyx_n_s__wisdom;
+static PyObject *__pyx_tp_new_6pyfftw_6pyfftw_FFTW(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/
 static PyObject *__pyx_int_0;
 static PyObject *__pyx_int_1;
 static PyObject *__pyx_int_2;
@@ -1639,129 +1989,124 @@ static PyObject *__pyx_int_5;
 static PyObject *__pyx_int_6;
 static PyObject *__pyx_int_7;
 static PyObject *__pyx_int_8;
-static PyObject *__pyx_int_neg_1;
-static PyObject *__pyx_int_15;
 static PyObject *__pyx_int_16;
 static PyObject *__pyx_int_32;
-static PyObject *__pyx_k_40;
-static PyObject *__pyx_k_tuple_2;
-static PyObject *__pyx_k_tuple_4;
-static PyObject *__pyx_k_tuple_5;
-static PyObject *__pyx_k_tuple_6;
-static PyObject *__pyx_k_tuple_8;
-static PyObject *__pyx_k_tuple_10;
-static PyObject *__pyx_k_tuple_12;
-static PyObject *__pyx_k_tuple_14;
-static PyObject *__pyx_k_tuple_19;
-static PyObject *__pyx_k_tuple_21;
-static PyObject *__pyx_k_tuple_23;
-static PyObject *__pyx_k_tuple_25;
-static PyObject *__pyx_k_tuple_27;
-static PyObject *__pyx_k_tuple_38;
-static PyObject *__pyx_k_tuple_39;
-static PyObject *__pyx_k_tuple_42;
-static PyObject *__pyx_k_tuple_44;
-static PyObject *__pyx_k_tuple_46;
-static PyObject *__pyx_k_tuple_50;
-static PyObject *__pyx_k_tuple_52;
-static PyObject *__pyx_k_tuple_53;
-static PyObject *__pyx_k_tuple_55;
-static PyObject *__pyx_k_tuple_57;
-static PyObject *__pyx_k_tuple_59;
-static PyObject *__pyx_k_tuple_61;
-static PyObject *__pyx_k_tuple_63;
-static PyObject *__pyx_k_tuple_65;
-static PyObject *__pyx_k_tuple_68;
-static PyObject *__pyx_k_tuple_69;
-static PyObject *__pyx_k_tuple_71;
-static PyObject *__pyx_k_tuple_72;
-static PyObject *__pyx_k_tuple_73;
-static PyObject *__pyx_k_tuple_74;
-static PyObject *__pyx_k_tuple_79;
-static PyObject *__pyx_k_tuple_82;
-static PyObject *__pyx_k_tuple_83;
-static PyObject *__pyx_k_tuple_84;
-static PyObject *__pyx_k_tuple_85;
-static PyObject *__pyx_k_tuple_86;
-static PyObject *__pyx_k_tuple_87;
-static PyObject *__pyx_k_tuple_88;
-static PyObject *__pyx_k_tuple_89;
-static PyObject *__pyx_k_tuple_90;
-static PyObject *__pyx_k_tuple_91;
-static PyObject *__pyx_k_tuple_92;
-static PyObject *__pyx_k_tuple_93;
-static PyObject *__pyx_k_tuple_94;
-static PyObject *__pyx_k_tuple_95;
-static PyObject *__pyx_k_tuple_96;
-static PyObject *__pyx_k_tuple_97;
-static PyObject *__pyx_k_tuple_98;
-static PyObject *__pyx_k_tuple_99;
-static PyObject *__pyx_k_tuple_100;
-static PyObject *__pyx_k_tuple_101;
-static PyObject *__pyx_k_tuple_102;
-static PyObject *__pyx_k_tuple_103;
-static PyObject *__pyx_k_tuple_104;
-static PyObject *__pyx_k_tuple_105;
-static PyObject *__pyx_k_tuple_106;
-static PyObject *__pyx_k_tuple_107;
-static PyObject *__pyx_k_tuple_108;
-static PyObject *__pyx_k_tuple_109;
-static PyObject *__pyx_k_tuple_110;
-static PyObject *__pyx_k_tuple_111;
-static PyObject *__pyx_k_tuple_112;
-static PyObject *__pyx_k_tuple_113;
-static PyObject *__pyx_k_tuple_114;
-static PyObject *__pyx_k_tuple_115;
-static PyObject *__pyx_k_tuple_116;
-static PyObject *__pyx_k_tuple_117;
-static PyObject *__pyx_k_tuple_118;
-static PyObject *__pyx_k_tuple_119;
-static PyObject *__pyx_k_tuple_120;
-static PyObject *__pyx_k_tuple_121;
-static PyObject *__pyx_k_tuple_122;
-static PyObject *__pyx_k_tuple_123;
-static PyObject *__pyx_k_tuple_124;
-static PyObject *__pyx_k_tuple_125;
-static PyObject *__pyx_k_tuple_126;
-static PyObject *__pyx_k_tuple_127;
-static PyObject *__pyx_k_tuple_128;
-static PyObject *__pyx_k_tuple_131;
-static PyObject *__pyx_k_tuple_133;
-static PyObject *__pyx_k_codeobj_75;
-static PyObject *__pyx_k_codeobj_80;
-static PyObject *__pyx_k_codeobj_132;
-static PyObject *__pyx_k_codeobj_134;
-static PyObject *__pyx_k_codeobj_135;
-
-/* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":39
+static PyObject *__pyx_int_neg_1;
+static PyObject *__pyx_tuple_;
+static PyObject *__pyx_slice__2;
+static PyObject *__pyx_tuple__3;
+static PyObject *__pyx_tuple__4;
+static PyObject *__pyx_tuple__5;
+static PyObject *__pyx_tuple__6;
+static PyObject *__pyx_tuple__7;
+static PyObject *__pyx_tuple__8;
+static PyObject *__pyx_tuple__9;
+static PyObject *__pyx_slice__23;
+static PyObject *__pyx_tuple__10;
+static PyObject *__pyx_tuple__11;
+static PyObject *__pyx_tuple__12;
+static PyObject *__pyx_tuple__13;
+static PyObject *__pyx_tuple__14;
+static PyObject *__pyx_tuple__15;
+static PyObject *__pyx_tuple__16;
+static PyObject *__pyx_tuple__18;
+static PyObject *__pyx_tuple__19;
+static PyObject *__pyx_tuple__20;
+static PyObject *__pyx_tuple__21;
+static PyObject *__pyx_tuple__22;
+static PyObject *__pyx_tuple__24;
+static PyObject *__pyx_tuple__25;
+static PyObject *__pyx_tuple__26;
+static PyObject *__pyx_tuple__27;
+static PyObject *__pyx_tuple__28;
+static PyObject *__pyx_tuple__29;
+static PyObject *__pyx_tuple__30;
+static PyObject *__pyx_tuple__31;
+static PyObject *__pyx_tuple__32;
+static PyObject *__pyx_tuple__33;
+static PyObject *__pyx_tuple__34;
+static PyObject *__pyx_tuple__35;
+static PyObject *__pyx_tuple__36;
+static PyObject *__pyx_tuple__37;
+static PyObject *__pyx_tuple__38;
+static PyObject *__pyx_tuple__39;
+static PyObject *__pyx_tuple__40;
+static PyObject *__pyx_tuple__42;
+static PyObject *__pyx_tuple__44;
+static PyObject *__pyx_tuple__45;
+static PyObject *__pyx_tuple__46;
+static PyObject *__pyx_tuple__47;
+static PyObject *__pyx_tuple__48;
+static PyObject *__pyx_tuple__49;
+static PyObject *__pyx_tuple__50;
+static PyObject *__pyx_tuple__51;
+static PyObject *__pyx_tuple__52;
+static PyObject *__pyx_tuple__53;
+static PyObject *__pyx_tuple__54;
+static PyObject *__pyx_tuple__55;
+static PyObject *__pyx_tuple__56;
+static PyObject *__pyx_tuple__57;
+static PyObject *__pyx_tuple__58;
+static PyObject *__pyx_tuple__59;
+static PyObject *__pyx_tuple__60;
+static PyObject *__pyx_tuple__61;
+static PyObject *__pyx_tuple__62;
+static PyObject *__pyx_tuple__63;
+static PyObject *__pyx_tuple__64;
+static PyObject *__pyx_tuple__65;
+static PyObject *__pyx_tuple__66;
+static PyObject *__pyx_tuple__67;
+static PyObject *__pyx_tuple__68;
+static PyObject *__pyx_tuple__69;
+static PyObject *__pyx_tuple__70;
+static PyObject *__pyx_tuple__71;
+static PyObject *__pyx_tuple__72;
+static PyObject *__pyx_tuple__73;
+static PyObject *__pyx_tuple__74;
+static PyObject *__pyx_tuple__75;
+static PyObject *__pyx_tuple__76;
+static PyObject *__pyx_tuple__77;
+static PyObject *__pyx_tuple__78;
+static PyObject *__pyx_tuple__79;
+static PyObject *__pyx_tuple__80;
+static PyObject *__pyx_tuple__81;
+static PyObject *__pyx_tuple__82;
+static PyObject *__pyx_tuple__83;
+static PyObject *__pyx_tuple__84;
+static PyObject *__pyx_tuple__85;
+static PyObject *__pyx_tuple__86;
+static PyObject *__pyx_tuple__87;
+static PyObject *__pyx_tuple__88;
+static PyObject *__pyx_tuple__89;
+static PyObject *__pyx_tuple__90;
+static PyObject *__pyx_tuple__91;
+static PyObject *__pyx_tuple__93;
+static PyObject *__pyx_codeobj__41;
+static PyObject *__pyx_codeobj__43;
+static PyObject *__pyx_codeobj__92;
+static PyObject *__pyx_codeobj__94;
+static PyObject *__pyx_codeobj__95;
+
+/* "pyfftw/utils.pxi":59
  *     _valid_simd_alignments = ()
  * 
  * cpdef n_byte_align_empty(shape, n, dtype='float64', order='C'):             # <<<<<<<<<<<<<<
  *     '''n_byte_align_empty(shape, n, dtype='float64', order='C')
- * 
+ *     **This function is deprecated:** ``empty_aligned`` **should be used
  */
 
 static PyObject *__pyx_pw_6pyfftw_6pyfftw_1n_byte_align_empty(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static PyObject *__pyx_f_6pyfftw_6pyfftw_n_byte_align_empty(PyObject *__pyx_v_shape, PyObject *__pyx_v_n, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align_empty *__pyx_optional_args) {
-  PyObject *__pyx_v_dtype = ((PyObject *)__pyx_n_s__float64);
-  PyObject *__pyx_v_order = ((PyObject *)__pyx_n_s__C);
-  PyObject *__pyx_v_itemsize = NULL;
-  PyObject *__pyx_v_array_length = NULL;
-  PyObject *__pyx_v_each_dimension = NULL;
-  PyObject *__pyx_v__array_aligned = NULL;
-  PyObject *__pyx_v__array_aligned_offset = NULL;
-  PyObject *__pyx_v_array = NULL;
+  PyObject *__pyx_v_dtype = ((PyObject *)__pyx_n_s_float64);
+  PyObject *__pyx_v_order = ((PyObject *)__pyx_n_s_C);
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
-  int __pyx_t_3;
-  int __pyx_t_4;
-  Py_ssize_t __pyx_t_5;
-  PyObject *(*__pyx_t_6)(PyObject *);
-  PyObject *__pyx_t_7 = NULL;
-  PyObject *__pyx_t_8 = NULL;
-  Py_ssize_t __pyx_t_9;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  struct __pyx_opt_args_6pyfftw_6pyfftw_empty_aligned __pyx_t_6;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
@@ -1775,298 +2120,90 @@ static PyObject *__pyx_f_6pyfftw_6pyfftw_n_byte_align_empty(PyObject *__pyx_v_sh
     }
   }
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":49
+  /* "pyfftw/utils.pxi":71
+ *     :func:`numpy.empty`.
  *     '''
- * 
- *     itemsize = np.dtype(dtype).itemsize             # <<<<<<<<<<<<<<
- * 
- *     # Apparently there is an issue with numpy.prod wrapping around on 32-bits
+ *     warnings.warn('This function is deprecated in favour of'             # <<<<<<<<<<<<<<
+ *     '``empty_aligned``.', DeprecationWarning)
+ *     return empty_aligned(shape, dtype=dtype, order=order, n=n)
  */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_INCREF(__pyx_v_dtype);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_dtype);
-  __Pyx_GIVEREF(__pyx_v_dtype);
-  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_warnings); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_1 = PyInt_FromLong(((PyArray_Descr *)__pyx_t_2)->elsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 49; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_warn); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
   __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_v_itemsize = __pyx_t_1;
-  __pyx_t_1 = 0;
-
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":54
- *     # on Windows 64-bit. This shouldn't happen, but the following code
- *     # alleviates the problem.
- *     if not isinstance(shape, (int, np.integer)):             # <<<<<<<<<<<<<<
- *         array_length = 1
- *         for each_dimension in shape:
- */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__integer); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_INCREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)((PyObject*)(&PyInt_Type))));
-  __Pyx_GIVEREF(((PyObject *)((PyObject*)(&PyInt_Type))));
-  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_3 = PyObject_IsInstance(__pyx_v_shape, ((PyObject *)__pyx_t_1)); if (unlikely(__pyx_t_3 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_4 = (!__pyx_t_3);
-  if (__pyx_t_4) {
-
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":55
- *     # alleviates the problem.
- *     if not isinstance(shape, (int, np.integer)):
- *         array_length = 1             # <<<<<<<<<<<<<<
- *         for each_dimension in shape:
- *             array_length *= each_dimension
- */
-    __Pyx_INCREF(__pyx_int_1);
-    __pyx_v_array_length = __pyx_int_1;
-
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":56
- *     if not isinstance(shape, (int, np.integer)):
- *         array_length = 1
- *         for each_dimension in shape:             # <<<<<<<<<<<<<<
- *             array_length *= each_dimension
- * 
- */
-    if (PyList_CheckExact(__pyx_v_shape) || PyTuple_CheckExact(__pyx_v_shape)) {
-      __pyx_t_1 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_1); __pyx_t_5 = 0;
-      __pyx_t_6 = NULL;
-    } else {
-      __pyx_t_5 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_v_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_6 = Py_TYPE(__pyx_t_1)->tp_iternext;
-    }
-    for (;;) {
-      if (!__pyx_t_6 && PyList_CheckExact(__pyx_t_1)) {
-        if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_1)) break;
-        #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_2); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #else
-        __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #endif
-      } else if (!__pyx_t_6 && PyTuple_CheckExact(__pyx_t_1)) {
-        if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
-        #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_5); __Pyx_INCREF(__pyx_t_2); __pyx_t_5++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #else
-        __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #endif
-      } else {
-        __pyx_t_2 = __pyx_t_6(__pyx_t_1);
-        if (unlikely(!__pyx_t_2)) {
-          if (PyErr_Occurred()) {
-            if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-          }
-          break;
-        }
-        __Pyx_GOTREF(__pyx_t_2);
-      }
-      __Pyx_XDECREF(__pyx_v_each_dimension);
-      __pyx_v_each_dimension = __pyx_t_2;
-      __pyx_t_2 = 0;
 
-      /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":57
- *         array_length = 1
- *         for each_dimension in shape:
- *             array_length *= each_dimension             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":72
+ *     '''
+ *     warnings.warn('This function is deprecated in favour of'
+ *     '``empty_aligned``.', DeprecationWarning)             # <<<<<<<<<<<<<<
+ *     return empty_aligned(shape, dtype=dtype, order=order, n=n)
  * 
- *     else:
  */
-      __pyx_t_2 = PyNumber_InPlaceMultiply(__pyx_v_array_length, __pyx_v_each_dimension); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      __Pyx_DECREF(__pyx_v_array_length);
-      __pyx_v_array_length = __pyx_t_2;
-      __pyx_t_2 = 0;
+  __pyx_t_2 = NULL;
+  __pyx_t_4 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_2)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_2);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+      __pyx_t_4 = 1;
     }
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    goto __pyx_L3;
   }
-  /*else*/ {
-
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":60
- * 
- *     else:
- *         array_length = shape             # <<<<<<<<<<<<<<
- * 
- *     # Allocate a new array that will contain the aligned data
- */
-    __Pyx_INCREF(__pyx_v_shape);
-    __pyx_v_array_length = __pyx_v_shape;
+  __pyx_t_5 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (__pyx_t_2) {
+    __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __pyx_t_2 = NULL;
   }
-  __pyx_L3:;
-
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":63
- * 
- *     # Allocate a new array that will contain the aligned data
- *     _array_aligned = np.empty(array_length*itemsize+n, dtype='int8')             # <<<<<<<<<<<<<<
- * 
- *     # We now need to know how to offset _array_aligned
- */
-  __pyx_t_1 = __Pyx_GetName(__pyx_m, __pyx_n_s__np); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_GetAttr(__pyx_t_1, __pyx_n_s__empty); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyNumber_Multiply(__pyx_v_array_length, __pyx_v_itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_INCREF(__pyx_kp_s_This_function_is_deprecated_in_f);
+  __Pyx_GIVEREF(__pyx_kp_s_This_function_is_deprecated_in_f);
+  PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, __pyx_kp_s_This_function_is_deprecated_in_f);
+  __Pyx_INCREF(__pyx_builtin_DeprecationWarning);
+  __Pyx_GIVEREF(__pyx_builtin_DeprecationWarning);
+  PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_builtin_DeprecationWarning);
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_7 = PyNumber_Add(__pyx_t_1, __pyx_v_n); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_7);
-  __Pyx_GIVEREF(__pyx_t_7);
-  __pyx_t_7 = 0;
-  __pyx_t_7 = PyDict_New(); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_7));
-  if (PyDict_SetItem(__pyx_t_7, ((PyObject *)__pyx_n_s__dtype), ((PyObject *)__pyx_n_s__int8)) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = PyObject_Call(__pyx_t_2, ((PyObject *)__pyx_t_1), ((PyObject *)__pyx_t_7)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-  __pyx_v__array_aligned = __pyx_t_8;
-  __pyx_t_8 = 0;
-
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":67
- *     # We now need to know how to offset _array_aligned
- *     # so it is correctly aligned
- *     _array_aligned_offset = (n-<intptr_t>np.PyArray_DATA(_array_aligned))%n             # <<<<<<<<<<<<<<
- * 
- *     array = np.frombuffer(
- */
-  if (!(likely(((__pyx_v__array_aligned) == Py_None) || likely(__Pyx_TypeTest(__pyx_v__array_aligned, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = __pyx_v__array_aligned;
-  __Pyx_INCREF(__pyx_t_8);
-  __pyx_t_7 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_t_8)))); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  __pyx_t_8 = PyNumber_Subtract(__pyx_v_n, __pyx_t_7); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __pyx_t_7 = PyNumber_Remainder(__pyx_t_8, __pyx_v_n); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 67; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  __pyx_v__array_aligned_offset = __pyx_t_7;
-  __pyx_t_7 = 0;
-
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":69
- *     _array_aligned_offset = (n-<intptr_t>np.PyArray_DATA(_array_aligned))%n
- * 
- *     array = np.frombuffer(             # <<<<<<<<<<<<<<
- *             _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,
- *             dtype=dtype).reshape(shape, order=order)
- */
-  __pyx_t_7 = __Pyx_GetName(__pyx_m, __pyx_n_s__np); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_8 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__frombuffer); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":70
+  /* "pyfftw/utils.pxi":73
+ *     warnings.warn('This function is deprecated in favour of'
+ *     '``empty_aligned``.', DeprecationWarning)
+ *     return empty_aligned(shape, dtype=dtype, order=order, n=n)             # <<<<<<<<<<<<<<
  * 
- *     array = np.frombuffer(
- *             _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,             # <<<<<<<<<<<<<<
- *             dtype=dtype).reshape(shape, order=order)
  * 
  */
-  __pyx_t_5 = __Pyx_PyIndex_AsSsize_t(__pyx_v__array_aligned_offset); if (unlikely((__pyx_t_5 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_7 = PyNumber_Subtract(__pyx_v__array_aligned_offset, __pyx_v_n); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_t_7); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __pyx_t_7 = __Pyx_PySequence_GetSlice(__pyx_v__array_aligned, __pyx_t_5, __pyx_t_9); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  __pyx_t_1 = PyObject_GetAttr(__pyx_t_7, __pyx_n_s__data); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_6.__pyx_n = 3;
+  __pyx_t_6.dtype = __pyx_v_dtype;
+  __pyx_t_6.order = __pyx_v_order;
+  __pyx_t_6.n = __pyx_v_n;
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_empty_aligned(__pyx_v_shape, 0, &__pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
-  __pyx_t_7 = PyTuple_New(1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_7);
-  PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":69
- *     _array_aligned_offset = (n-<intptr_t>np.PyArray_DATA(_array_aligned))%n
- * 
- *     array = np.frombuffer(             # <<<<<<<<<<<<<<
- *             _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,
- *             dtype=dtype).reshape(shape, order=order)
- */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":71
- *     array = np.frombuffer(
- *             _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,
- *             dtype=dtype).reshape(shape, order=order)             # <<<<<<<<<<<<<<
- * 
- *     return array
- */
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__dtype), __pyx_v_dtype) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = PyObject_Call(__pyx_t_8, ((PyObject *)__pyx_t_7), ((PyObject *)__pyx_t_1)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-  __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_GetAttr(__pyx_t_2, __pyx_n_s__reshape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_INCREF(__pyx_v_shape);
-  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_shape);
-  __Pyx_GIVEREF(__pyx_v_shape);
-  __pyx_t_7 = PyDict_New(); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_7));
-  if (PyDict_SetItem(__pyx_t_7, ((PyObject *)__pyx_n_s__order), __pyx_v_order) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_8 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), ((PyObject *)__pyx_t_7)); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_8);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-  __Pyx_DECREF(((PyObject *)__pyx_t_7)); __pyx_t_7 = 0;
-  __pyx_v_array = __pyx_t_8;
-  __pyx_t_8 = 0;
-
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":73
- *             dtype=dtype).reshape(shape, order=order)
- * 
- *     return array             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":59
+ *     _valid_simd_alignments = ()
  * 
- * cpdef n_byte_align(array, n, dtype=None):
+ * cpdef n_byte_align_empty(shape, n, dtype='float64', order='C'):             # <<<<<<<<<<<<<<
+ *     '''n_byte_align_empty(shape, n, dtype='float64', order='C')
+ *     **This function is deprecated:** ``empty_aligned`` **should be used
  */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(__pyx_v_array);
-  __pyx_r = __pyx_v_array;
-  goto __pyx_L0;
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
+  /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_7);
-  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pyfftw.pyfftw.n_byte_align_empty", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_itemsize);
-  __Pyx_XDECREF(__pyx_v_array_length);
-  __Pyx_XDECREF(__pyx_v_each_dimension);
-  __Pyx_XDECREF(__pyx_v__array_aligned);
-  __Pyx_XDECREF(__pyx_v__array_aligned_offset);
-  __Pyx_XDECREF(__pyx_v_array);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
@@ -2074,20 +2211,23 @@ static PyObject *__pyx_f_6pyfftw_6pyfftw_n_byte_align_empty(PyObject *__pyx_v_sh
 
 /* Python wrapper */
 static PyObject *__pyx_pw_6pyfftw_6pyfftw_1n_byte_align_empty(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_n_byte_align_empty[] = "n_byte_align_empty(shape, n, dtype='float64', order='C')\n\n    Function that returns an empty numpy array\n    that is n-byte aligned.\n\n    The alignment is given by the second argument, ``n``.\n    The rest of the arguments are as per :func:`numpy.empty`.\n    ";
+static char __pyx_doc_6pyfftw_6pyfftw_n_byte_align_empty[] = "n_byte_align_empty(shape, n, dtype='float64', order='C')\n    **This function is deprecated:** ``empty_aligned`` **should be used\n    instead.**\n\n    Function that returns an empty numpy array that is n-byte aligned.\n\n    The alignment is given by the first optional argument, ``n``. If\n    ``n`` is not provided then this function will inspect the CPU to\n    determine alignment. The rest of the arguments are as per\n     [...]
 static PyObject *__pyx_pw_6pyfftw_6pyfftw_1n_byte_align_empty(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_shape = 0;
   PyObject *__pyx_v_n = 0;
   PyObject *__pyx_v_dtype = 0;
   PyObject *__pyx_v_order = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("n_byte_align_empty (wrapper)", 0);
   {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__shape,&__pyx_n_s__n,&__pyx_n_s__dtype,&__pyx_n_s__order,0};
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_n,&__pyx_n_s_dtype,&__pyx_n_s_order,0};
     PyObject* values[4] = {0,0,0,0};
-    values[2] = ((PyObject *)__pyx_n_s__float64);
-    values[3] = ((PyObject *)__pyx_n_s__C);
+    values[2] = ((PyObject *)__pyx_n_s_float64);
+    values[3] = ((PyObject *)__pyx_n_s_C);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
@@ -2102,26 +2242,26 @@ static PyObject *__pyx_pw_6pyfftw_6pyfftw_1n_byte_align_empty(PyObject *__pyx_se
       kw_args = PyDict_Size(__pyx_kwds);
       switch (pos_args) {
         case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__shape)) != 0)) kw_args--;
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
         else goto __pyx_L5_argtuple_error;
         case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__n)) != 0)) kw_args--;
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("n_byte_align_empty", 0, 2, 4, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("n_byte_align_empty", 0, 2, 4, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__dtype);
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype);
           if (value) { values[2] = value; kw_args--; }
         }
         case  3:
         if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__order);
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_order);
           if (value) { values[3] = value; kw_args--; }
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "n_byte_align_empty") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "n_byte_align_empty") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -2140,25 +2280,19 @@ static PyObject *__pyx_pw_6pyfftw_6pyfftw_1n_byte_align_empty(PyObject *__pyx_se
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("n_byte_align_empty", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("n_byte_align_empty", 0, 2, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("pyfftw.pyfftw.n_byte_align_empty", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_6pyfftw_6pyfftw_n_byte_align_empty(__pyx_self, __pyx_v_shape, __pyx_v_n, __pyx_v_dtype, __pyx_v_order);
+
+  /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":39
- *     _valid_simd_alignments = ()
- * 
- * cpdef n_byte_align_empty(shape, n, dtype='float64', order='C'):             # <<<<<<<<<<<<<<
- *     '''n_byte_align_empty(shape, n, dtype='float64', order='C')
- * 
- */
-
 static PyObject *__pyx_pf_6pyfftw_6pyfftw_n_byte_align_empty(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_shape, PyObject *__pyx_v_n, PyObject *__pyx_v_dtype, PyObject *__pyx_v_order) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
@@ -2172,14 +2306,13 @@ static PyObject *__pyx_pf_6pyfftw_6pyfftw_n_byte_align_empty(CYTHON_UNUSED PyObj
   __pyx_t_2.__pyx_n = 2;
   __pyx_t_2.dtype = __pyx_v_dtype;
   __pyx_t_2.order = __pyx_v_order;
-  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_n_byte_align_empty(__pyx_v_shape, __pyx_v_n, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_n_byte_align_empty(__pyx_v_shape, __pyx_v_n, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
+  /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_AddTraceback("pyfftw.pyfftw.n_byte_align_empty", __pyx_clineno, __pyx_lineno, __pyx_filename);
@@ -2190,28 +2323,25 @@ static PyObject *__pyx_pf_6pyfftw_6pyfftw_n_byte_align_empty(CYTHON_UNUSED PyObj
   return __pyx_r;
 }
 
-/* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":75
- *     return array
+/* "pyfftw/utils.pxi":76
+ * 
  * 
  * cpdef n_byte_align(array, n, dtype=None):             # <<<<<<<<<<<<<<
- *     ''' n_byte_align(array, n, dtype=None)
+ *     '''n_byte_align(array, n, dtype=None)
  * 
  */
 
 static PyObject *__pyx_pw_6pyfftw_6pyfftw_3n_byte_align(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
 static PyObject *__pyx_f_6pyfftw_6pyfftw_n_byte_align(PyObject *__pyx_v_array, PyObject *__pyx_v_n, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align *__pyx_optional_args) {
   PyObject *__pyx_v_dtype = ((PyObject *)Py_None);
-  int __pyx_v_update_dtype;
-  PyObject *__pyx_v_offset = NULL;
-  PyObject *__pyx_v__array_aligned = NULL;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
-  int __pyx_t_2;
-  int __pyx_t_3;
-  PyObject *__pyx_t_4 = NULL;
-  struct __pyx_opt_args_6pyfftw_6pyfftw_n_byte_align_empty __pyx_t_5;
-  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  struct __pyx_opt_args_6pyfftw_6pyfftw_byte_align __pyx_t_6;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
@@ -2221,215 +2351,90 @@ static PyObject *__pyx_f_6pyfftw_6pyfftw_n_byte_align(PyObject *__pyx_v_array, P
       __pyx_v_dtype = __pyx_optional_args->dtype;
     }
   }
-  __Pyx_INCREF(__pyx_v_array);
-  __Pyx_INCREF(__pyx_v_dtype);
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":87
+  /* "pyfftw/utils.pxi":91
+ *     of that dtype.
  *     '''
- * 
- *     if not isinstance(array, np.ndarray):             # <<<<<<<<<<<<<<
- *         raise TypeError('Invalid array: n_byte_align requires a subclass '
- *                 'of ndarray')
- */
-  __pyx_t_1 = ((PyObject *)((PyObject*)__pyx_ptype_5numpy_ndarray));
-  __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_array, __pyx_t_1); 
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = (!__pyx_t_2);
-  if (__pyx_t_3) {
-
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":88
- * 
- *     if not isinstance(array, np.ndarray):
- *         raise TypeError('Invalid array: n_byte_align requires a subclass '             # <<<<<<<<<<<<<<
- *                 'of ndarray')
- * 
- */
-    __pyx_t_1 = PyObject_Call(__pyx_builtin_TypeError, ((PyObject *)__pyx_k_tuple_2), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
-
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":91
- *                 'of ndarray')
- * 
- *     if dtype is not None:             # <<<<<<<<<<<<<<
- *         if not array.dtype == dtype:
- *             update_dtype = True
- */
-  __pyx_t_3 = (__pyx_v_dtype != Py_None);
-  if (__pyx_t_3) {
-
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":92
- * 
- *     if dtype is not None:
- *         if not array.dtype == dtype:             # <<<<<<<<<<<<<<
- *             update_dtype = True
- * 
+ *     warnings.warn('This function is deprecated in favour of'             # <<<<<<<<<<<<<<
+ *     '``byte_align``.', DeprecationWarning)
+ *     return byte_align(array, n=n, dtype=dtype)
  */
-    __pyx_t_1 = PyObject_GetAttr(__pyx_v_array, __pyx_n_s__dtype); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = PyObject_RichCompare(__pyx_t_1, __pyx_v_dtype, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 92; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_2 = (!__pyx_t_3);
-    if (__pyx_t_2) {
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_warnings); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_warn); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":93
- *     if dtype is not None:
- *         if not array.dtype == dtype:
- *             update_dtype = True             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":92
+ *     '''
+ *     warnings.warn('This function is deprecated in favour of'
+ *     '``byte_align``.', DeprecationWarning)             # <<<<<<<<<<<<<<
+ *     return byte_align(array, n=n, dtype=dtype)
  * 
- *     else:
  */
-      __pyx_v_update_dtype = 1;
-      goto __pyx_L5;
+  __pyx_t_2 = NULL;
+  __pyx_t_4 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_2)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_2);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+      __pyx_t_4 = 1;
     }
-    __pyx_L5:;
-    goto __pyx_L4;
   }
-  /*else*/ {
-
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":96
- * 
- *     else:
- *         dtype = array.dtype             # <<<<<<<<<<<<<<
- *         update_dtype = False
- * 
- */
-    __pyx_t_4 = PyObject_GetAttr(__pyx_v_array, __pyx_n_s__dtype); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_DECREF(__pyx_v_dtype);
-    __pyx_v_dtype = __pyx_t_4;
-    __pyx_t_4 = 0;
-
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":97
- *     else:
- *         dtype = array.dtype
- *         update_dtype = False             # <<<<<<<<<<<<<<
- * 
- *     # See if we're already n byte aligned. If so, do nothing.
- */
-    __pyx_v_update_dtype = 0;
+  __pyx_t_5 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (__pyx_t_2) {
+    __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __pyx_t_2 = NULL;
   }
-  __pyx_L4:;
-
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":100
- * 
- *     # See if we're already n byte aligned. If so, do nothing.
- *     offset = <intptr_t>np.PyArray_DATA(array) %n             # <<<<<<<<<<<<<<
- * 
- *     if offset is not 0 or update_dtype:
- */
-  if (!(likely(((__pyx_v_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_4 = __pyx_v_array;
-  __Pyx_INCREF(__pyx_t_4);
-  __pyx_t_1 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_t_4)))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_INCREF(__pyx_kp_s_This_function_is_deprecated_in_f_2);
+  __Pyx_GIVEREF(__pyx_kp_s_This_function_is_deprecated_in_f_2);
+  PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, __pyx_kp_s_This_function_is_deprecated_in_f_2);
+  __Pyx_INCREF(__pyx_builtin_DeprecationWarning);
+  __Pyx_GIVEREF(__pyx_builtin_DeprecationWarning);
+  PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_builtin_DeprecationWarning);
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_t_4 = PyNumber_Remainder(__pyx_t_1, __pyx_v_n); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_v_offset = __pyx_t_4;
-  __pyx_t_4 = 0;
-
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":102
- *     offset = <intptr_t>np.PyArray_DATA(array) %n
- * 
- *     if offset is not 0 or update_dtype:             # <<<<<<<<<<<<<<
- * 
- *         _array_aligned = n_byte_align_empty(array.shape, n, dtype)
- */
-  __pyx_t_2 = (__pyx_v_offset != __pyx_int_0);
-  if (!__pyx_t_2) {
-    __pyx_t_3 = __pyx_v_update_dtype;
-  } else {
-    __pyx_t_3 = __pyx_t_2;
-  }
-  if (__pyx_t_3) {
-
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":104
- *     if offset is not 0 or update_dtype:
- * 
- *         _array_aligned = n_byte_align_empty(array.shape, n, dtype)             # <<<<<<<<<<<<<<
- * 
- *         _array_aligned[:] = array
- */
-    __pyx_t_4 = PyObject_GetAttr(__pyx_v_array, __pyx_n_s__shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5.__pyx_n = 1;
-    __pyx_t_5.dtype = __pyx_v_dtype;
-    __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_n_byte_align_empty(__pyx_t_4, __pyx_v_n, 0, &__pyx_t_5); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 104; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_v__array_aligned = __pyx_t_1;
-    __pyx_t_1 = 0;
 
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":106
- *         _array_aligned = n_byte_align_empty(array.shape, n, dtype)
+  /* "pyfftw/utils.pxi":93
+ *     warnings.warn('This function is deprecated in favour of'
+ *     '``byte_align``.', DeprecationWarning)
+ *     return byte_align(array, n=n, dtype=dtype)             # <<<<<<<<<<<<<<
  * 
- *         _array_aligned[:] = array             # <<<<<<<<<<<<<<
  * 
- *         array = _array_aligned.view(type=array.__class__)
  */
-    if (__Pyx_PySequence_SetSlice(__pyx_v__array_aligned, 0, PY_SSIZE_T_MAX, __pyx_v_array) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_6.__pyx_n = 2;
+  __pyx_t_6.n = __pyx_v_n;
+  __pyx_t_6.dtype = __pyx_v_dtype;
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_byte_align(__pyx_v_array, 0, &__pyx_t_6); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 93; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":108
- *         _array_aligned[:] = array
+  /* "pyfftw/utils.pxi":76
  * 
- *         array = _array_aligned.view(type=array.__class__)             # <<<<<<<<<<<<<<
- * 
- *     return array
- */
-    __pyx_t_1 = PyObject_GetAttr(__pyx_v__array_aligned, __pyx_n_s__view); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(((PyObject *)__pyx_t_4));
-    __pyx_t_6 = PyObject_GetAttr(__pyx_v_array, __pyx_n_s____class__); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    if (PyDict_SetItem(__pyx_t_4, ((PyObject *)__pyx_n_s__type), __pyx_t_6) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_6 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_t_4)); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_v_array);
-    __pyx_v_array = __pyx_t_6;
-    __pyx_t_6 = 0;
-    goto __pyx_L6;
-  }
-  __pyx_L6:;
-
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":110
- *         array = _array_aligned.view(type=array.__class__)
  * 
- *     return array             # <<<<<<<<<<<<<<
+ * cpdef n_byte_align(array, n, dtype=None):             # <<<<<<<<<<<<<<
+ *     '''n_byte_align(array, n, dtype=None)
  * 
- * cpdef is_n_byte_aligned(array, n):
  */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(__pyx_v_array);
-  __pyx_r = __pyx_v_array;
-  goto __pyx_L0;
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
+  /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
   __Pyx_AddTraceback("pyfftw.pyfftw.n_byte_align", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_offset);
-  __Pyx_XDECREF(__pyx_v__array_aligned);
-  __Pyx_XDECREF(__pyx_v_array);
-  __Pyx_XDECREF(__pyx_v_dtype);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
@@ -2437,25 +2442,20 @@ static PyObject *__pyx_f_6pyfftw_6pyfftw_n_byte_align(PyObject *__pyx_v_array, P
 
 /* Python wrapper */
 static PyObject *__pyx_pw_6pyfftw_6pyfftw_3n_byte_align(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_2n_byte_align[] = " n_byte_align(array, n, dtype=None)\n\n    Function that takes a numpy array and checks it is aligned on an n-byte\n    boundary, where ``n`` is a passed parameter. If it is, the array is\n    returned without further ado.  If it is not, a new array is created and\n    the data copied in, but aligned on the n-byte boundary.\n\n    ``dtype`` is an optional argument that forces the resultant array to be\n    of that dtype.\n    ";
+static char __pyx_doc_6pyfftw_6pyfftw_2n_byte_align[] = "n_byte_align(array, n, dtype=None)\n\n    **This function is deprecated:** ``byte_align`` **should be used instead.**\n\n    Function that takes a numpy array and checks it is aligned on an n-byte\n    boundary, where ``n`` is an optional parameter. If ``n`` is not provided\n    then this function will inspect the CPU to determine alignment. If the\n    array is aligned then it is returned without further ado.  If it is not\n    al [...]
 static PyObject *__pyx_pw_6pyfftw_6pyfftw_3n_byte_align(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_array = 0;
   PyObject *__pyx_v_n = 0;
   PyObject *__pyx_v_dtype = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
   __Pyx_RefNannySetupContext("n_byte_align (wrapper)", 0);
   {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__array,&__pyx_n_s__n,&__pyx_n_s__dtype,0};
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_array,&__pyx_n_s_n,&__pyx_n_s_dtype,0};
     PyObject* values[3] = {0,0,0};
-
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":75
- *     return array
- * 
- * cpdef n_byte_align(array, n, dtype=None):             # <<<<<<<<<<<<<<
- *     ''' n_byte_align(array, n, dtype=None)
- * 
- */
     values[2] = ((PyObject *)Py_None);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
@@ -2470,21 +2470,21 @@ static PyObject *__pyx_pw_6pyfftw_6pyfftw_3n_byte_align(PyObject *__pyx_self, Py
       kw_args = PyDict_Size(__pyx_kwds);
       switch (pos_args) {
         case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__array)) != 0)) kw_args--;
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_array)) != 0)) kw_args--;
         else goto __pyx_L5_argtuple_error;
         case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__n)) != 0)) kw_args--;
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("n_byte_align", 0, 2, 3, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("n_byte_align", 0, 2, 3, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__dtype);
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype);
           if (value) { values[2] = value; kw_args--; }
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "n_byte_align") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "n_byte_align") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -2501,13 +2501,15 @@ static PyObject *__pyx_pw_6pyfftw_6pyfftw_3n_byte_align(PyObject *__pyx_self, Py
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("n_byte_align", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("n_byte_align", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_AddTraceback("pyfftw.pyfftw.n_byte_align", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
   __pyx_r = __pyx_pf_6pyfftw_6pyfftw_2n_byte_align(__pyx_self, __pyx_v_array, __pyx_v_n, __pyx_v_dtype);
+
+  /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
@@ -2524,14 +2526,13 @@ static PyObject *__pyx_pf_6pyfftw_6pyfftw_2n_byte_align(CYTHON_UNUSED PyObject *
   __Pyx_XDECREF(__pyx_r);
   __pyx_t_2.__pyx_n = 1;
   __pyx_t_2.dtype = __pyx_v_dtype;
-  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_n_byte_align(__pyx_v_array, __pyx_v_n, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_n_byte_align(__pyx_v_array, __pyx_v_n, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
+  /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
   __Pyx_AddTraceback("pyfftw.pyfftw.n_byte_align", __pyx_clineno, __pyx_lineno, __pyx_filename);
@@ -2542,120 +2543,357 @@ static PyObject *__pyx_pf_6pyfftw_6pyfftw_2n_byte_align(CYTHON_UNUSED PyObject *
   return __pyx_r;
 }
 
-/* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":112
- *     return array
+/* "pyfftw/utils.pxi":96
  * 
- * cpdef is_n_byte_aligned(array, n):             # <<<<<<<<<<<<<<
- *     ''' is_n_byte_aligned(array, n)
+ * 
+ * cpdef byte_align(array, n=None, dtype=None):             # <<<<<<<<<<<<<<
+ *     '''byte_align(array, n=None, dtype=None)
  * 
  */
 
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_5is_n_byte_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyObject *__pyx_f_6pyfftw_6pyfftw_is_n_byte_aligned(PyObject *__pyx_v_array, PyObject *__pyx_v_n, CYTHON_UNUSED int __pyx_skip_dispatch) {
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_5byte_align(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_byte_align(PyObject *__pyx_v_array, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_byte_align *__pyx_optional_args) {
+  PyObject *__pyx_v_n = ((PyObject *)Py_None);
+  PyObject *__pyx_v_dtype = ((PyObject *)Py_None);
+  int __pyx_v_update_dtype;
   PyObject *__pyx_v_offset = NULL;
+  PyObject *__pyx_v__array_aligned = NULL;
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_1;
   int __pyx_t_2;
-  int __pyx_t_3;
+  PyObject *__pyx_t_3 = NULL;
   PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("is_n_byte_aligned", 0);
+  __Pyx_RefNannySetupContext("byte_align", 0);
+  if (__pyx_optional_args) {
+    if (__pyx_optional_args->__pyx_n > 0) {
+      __pyx_v_n = __pyx_optional_args->n;
+      if (__pyx_optional_args->__pyx_n > 1) {
+        __pyx_v_dtype = __pyx_optional_args->dtype;
+      }
+    }
+  }
+  __Pyx_INCREF(__pyx_v_array);
+  __Pyx_INCREF(__pyx_v_n);
+  __Pyx_INCREF(__pyx_v_dtype);
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":119
- *     and ``False`` if it is not.
+  /* "pyfftw/utils.pxi":110
  *     '''
+ * 
  *     if not isinstance(array, np.ndarray):             # <<<<<<<<<<<<<<
- *         raise TypeError('Invalid array: is_n_byte_aligned requires a subclass '
+ *         raise TypeError('Invalid array: byte_align requires a subclass '
  *                 'of ndarray')
  */
-  __pyx_t_1 = ((PyObject *)((PyObject*)__pyx_ptype_5numpy_ndarray));
-  __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_array, __pyx_t_1); 
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_3 = (!__pyx_t_2);
-  if (__pyx_t_3) {
+  __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_array, __pyx_ptype_5numpy_ndarray); 
+  __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+  if (__pyx_t_2) {
 
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":120
- *     '''
+    /* "pyfftw/utils.pxi":111
+ * 
  *     if not isinstance(array, np.ndarray):
- *         raise TypeError('Invalid array: is_n_byte_aligned requires a subclass '             # <<<<<<<<<<<<<<
+ *         raise TypeError('Invalid array: byte_align requires a subclass '             # <<<<<<<<<<<<<<
  *                 'of ndarray')
  * 
  */
-    __pyx_t_1 = PyObject_Call(__pyx_builtin_TypeError, ((PyObject *)__pyx_k_tuple_4), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L3;
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "pyfftw/utils.pxi":110
+ *     '''
+ * 
+ *     if not isinstance(array, np.ndarray):             # <<<<<<<<<<<<<<
+ *         raise TypeError('Invalid array: byte_align requires a subclass '
+ *                 'of ndarray')
+ */
   }
-  __pyx_L3:;
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":124
+  /* "pyfftw/utils.pxi":114
+ *                 'of ndarray')
  * 
- *     # See if we're n byte aligned.
- *     offset = <intptr_t>np.PyArray_DATA(array) %n             # <<<<<<<<<<<<<<
+ *     if n is None:             # <<<<<<<<<<<<<<
+ *         n = _simd_alignment
  * 
- *     return not bool(offset)
  */
-  if (!(likely(((__pyx_v_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = __pyx_v_array;
-  __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_4 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_t_1)))); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyNumber_Remainder(__pyx_t_4, __pyx_v_n); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 124; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-  __pyx_v_offset = __pyx_t_1;
-  __pyx_t_1 = 0;
+  __pyx_t_2 = (__pyx_v_n == Py_None);
+  __pyx_t_1 = (__pyx_t_2 != 0);
+  if (__pyx_t_1) {
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":126
- *     offset = <intptr_t>np.PyArray_DATA(array) %n
+    /* "pyfftw/utils.pxi":115
  * 
- *     return not bool(offset)             # <<<<<<<<<<<<<<
+ *     if n is None:
+ *         n = _simd_alignment             # <<<<<<<<<<<<<<
+ * 
+ *     if dtype is not None:
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_v_offset); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = __Pyx_PyBool_FromLong((!(!(!__pyx_t_3)))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
+    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_6pyfftw_6pyfftw__simd_alignment); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF_SET(__pyx_v_n, __pyx_t_3);
+    __pyx_t_3 = 0;
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+    /* "pyfftw/utils.pxi":114
+ *                 'of ndarray')
+ * 
+ *     if n is None:             # <<<<<<<<<<<<<<
+ *         n = _simd_alignment
+ * 
+ */
+  }
+
+  /* "pyfftw/utils.pxi":117
+ *         n = _simd_alignment
+ * 
+ *     if dtype is not None:             # <<<<<<<<<<<<<<
+ *         if not array.dtype == dtype:
+ *             update_dtype = True
+ */
+  __pyx_t_1 = (__pyx_v_dtype != Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "pyfftw/utils.pxi":118
+ * 
+ *     if dtype is not None:
+ *         if not array.dtype == dtype:             # <<<<<<<<<<<<<<
+ *             update_dtype = True
+ * 
+ */
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_array, __pyx_n_s_dtype); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_dtype, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 118; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_1 = ((!__pyx_t_2) != 0);
+    if (__pyx_t_1) {
+
+      /* "pyfftw/utils.pxi":119
+ *     if dtype is not None:
+ *         if not array.dtype == dtype:
+ *             update_dtype = True             # <<<<<<<<<<<<<<
+ * 
+ *     else:
+ */
+      __pyx_v_update_dtype = 1;
+
+      /* "pyfftw/utils.pxi":118
+ * 
+ *     if dtype is not None:
+ *         if not array.dtype == dtype:             # <<<<<<<<<<<<<<
+ *             update_dtype = True
+ * 
+ */
+    }
+
+    /* "pyfftw/utils.pxi":117
+ *         n = _simd_alignment
+ * 
+ *     if dtype is not None:             # <<<<<<<<<<<<<<
+ *         if not array.dtype == dtype:
+ *             update_dtype = True
+ */
+    goto __pyx_L5;
+  }
+
+  /* "pyfftw/utils.pxi":122
+ * 
+ *     else:
+ *         dtype = array.dtype             # <<<<<<<<<<<<<<
+ *         update_dtype = False
+ * 
+ */
+  /*else*/ {
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_array, __pyx_n_s_dtype); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 122; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_DECREF_SET(__pyx_v_dtype, __pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "pyfftw/utils.pxi":123
+ *     else:
+ *         dtype = array.dtype
+ *         update_dtype = False             # <<<<<<<<<<<<<<
+ * 
+ *     # See if we're already n byte aligned. If so, do nothing.
+ */
+    __pyx_v_update_dtype = 0;
+  }
+  __pyx_L5:;
+
+  /* "pyfftw/utils.pxi":126
+ * 
+ *     # See if we're already n byte aligned. If so, do nothing.
+ *     offset = <intptr_t>np.PyArray_DATA(array) %n             # <<<<<<<<<<<<<<
+ * 
+ *     if offset is not 0 or update_dtype:
+ */
+  if (!(likely(((__pyx_v_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_v_array)))); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = PyNumber_Remainder(__pyx_t_4, __pyx_v_n); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 126; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_v_offset = __pyx_t_3;
+  __pyx_t_3 = 0;
+
+  /* "pyfftw/utils.pxi":128
+ *     offset = <intptr_t>np.PyArray_DATA(array) %n
+ * 
+ *     if offset is not 0 or update_dtype:             # <<<<<<<<<<<<<<
+ * 
+ *         _array_aligned = empty_aligned(array.shape, dtype, n=n)
+ */
+  __pyx_t_2 = (__pyx_v_offset != __pyx_int_0);
+  __pyx_t_5 = (__pyx_t_2 != 0);
+  if (!__pyx_t_5) {
+  } else {
+    __pyx_t_1 = __pyx_t_5;
+    goto __pyx_L8_bool_binop_done;
+  }
+  __pyx_t_5 = (__pyx_v_update_dtype != 0);
+  __pyx_t_1 = __pyx_t_5;
+  __pyx_L8_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "pyfftw/utils.pxi":130
+ *     if offset is not 0 or update_dtype:
+ * 
+ *         _array_aligned = empty_aligned(array.shape, dtype, n=n)             # <<<<<<<<<<<<<<
+ * 
+ *         _array_aligned[:] = array
+ */
+    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_empty_aligned); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_array, __pyx_n_s_shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_GIVEREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4);
+    __Pyx_INCREF(__pyx_v_dtype);
+    __Pyx_GIVEREF(__pyx_v_dtype);
+    PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_v_dtype);
+    __pyx_t_4 = 0;
+    __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_n, __pyx_v_n) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_7 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, __pyx_t_4); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_v__array_aligned = __pyx_t_7;
+    __pyx_t_7 = 0;
+
+    /* "pyfftw/utils.pxi":132
+ *         _array_aligned = empty_aligned(array.shape, dtype, n=n)
+ * 
+ *         _array_aligned[:] = array             # <<<<<<<<<<<<<<
+ * 
+ *         array = _array_aligned.view(type=array.__class__)
+ */
+    if (__Pyx_PyObject_SetSlice(__pyx_v__array_aligned, __pyx_v_array, 0, 0, NULL, NULL, &__pyx_slice__2, 0, 0, 1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "pyfftw/utils.pxi":134
+ *         _array_aligned[:] = array
+ * 
+ *         array = _array_aligned.view(type=array.__class__)             # <<<<<<<<<<<<<<
+ * 
+ *     return array
+ */
+    __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v__array_aligned, __pyx_n_s_view); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_array, __pyx_n_s_class); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_type, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_empty_tuple, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF_SET(__pyx_v_array, __pyx_t_6);
+    __pyx_t_6 = 0;
+
+    /* "pyfftw/utils.pxi":128
+ *     offset = <intptr_t>np.PyArray_DATA(array) %n
+ * 
+ *     if offset is not 0 or update_dtype:             # <<<<<<<<<<<<<<
+ * 
+ *         _array_aligned = empty_aligned(array.shape, dtype, n=n)
+ */
+  }
+
+  /* "pyfftw/utils.pxi":136
+ *         array = _array_aligned.view(type=array.__class__)
+ * 
+ *     return array             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_array);
+  __pyx_r = __pyx_v_array;
   goto __pyx_L0;
+
+  /* "pyfftw/utils.pxi":96
+ * 
+ * 
+ * cpdef byte_align(array, n=None, dtype=None):             # <<<<<<<<<<<<<<
+ *     '''byte_align(array, n=None, dtype=None)
+ * 
+ */
+
+  /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_AddTraceback("pyfftw.pyfftw.is_n_byte_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("pyfftw.pyfftw.byte_align", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
   __Pyx_XDECREF(__pyx_v_offset);
+  __Pyx_XDECREF(__pyx_v__array_aligned);
+  __Pyx_XDECREF(__pyx_v_array);
+  __Pyx_XDECREF(__pyx_v_n);
+  __Pyx_XDECREF(__pyx_v_dtype);
   __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
 /* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_5is_n_byte_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4is_n_byte_aligned[] = " is_n_byte_aligned(array, n)\n\n    Function that takes a numpy array and checks it is aligned on an n-byte\n    boundary, where ``n`` is a passed parameter, returning ``True`` if it is,\n    and ``False`` if it is not.\n    ";
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_5is_n_byte_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_5byte_align(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4byte_align[] = "byte_align(array, n=None, dtype=None)\n\n    Function that takes a numpy array and checks it is aligned on an n-byte\n    boundary, where ``n`` is an optional parameter. If ``n`` is not provided\n    then this function will inspect the CPU to determine alignment. If the\n    array is aligned then it is returned without further ado.  If it is not\n    aligned then a new array is created and the data copied in, but aligned\n    on the  [...]
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_5byte_align(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
   PyObject *__pyx_v_array = 0;
   PyObject *__pyx_v_n = 0;
+  PyObject *__pyx_v_dtype = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
   PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("is_n_byte_aligned (wrapper)", 0);
+  __Pyx_RefNannySetupContext("byte_align (wrapper)", 0);
   {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__array,&__pyx_n_s__n,0};
-    PyObject* values[2] = {0,0};
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_array,&__pyx_n_s_n,&__pyx_n_s_dtype,0};
+    PyObject* values[3] = {0,0,0};
+    values[1] = ((PyObject *)Py_None);
+    values[2] = ((PyObject *)Py_None);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
       const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
       switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
         case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
         case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
         case  0: break;
@@ -2664,67 +2902,73 @@ static PyObject *__pyx_pw_6pyfftw_6pyfftw_5is_n_byte_aligned(PyObject *__pyx_sel
       kw_args = PyDict_Size(__pyx_kwds);
       switch (pos_args) {
         case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__array)) != 0)) kw_args--;
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_array)) != 0)) kw_args--;
         else goto __pyx_L5_argtuple_error;
         case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__n)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("is_n_byte_aligned", 1, 2, 2, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype);
+          if (value) { values[2] = value; kw_args--; }
         }
       }
       if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "is_n_byte_aligned") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "byte_align") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
     } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
     }
     __pyx_v_array = values[0];
     __pyx_v_n = values[1];
+    __pyx_v_dtype = values[2];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("is_n_byte_aligned", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("byte_align", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
-  __Pyx_AddTraceback("pyfftw.pyfftw.is_n_byte_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pyfftw.pyfftw.byte_align", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return NULL;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4is_n_byte_aligned(__pyx_self, __pyx_v_array, __pyx_v_n);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4byte_align(__pyx_self, __pyx_v_array, __pyx_v_n, __pyx_v_dtype);
+
+  /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":112
- *     return array
- * 
- * cpdef is_n_byte_aligned(array, n):             # <<<<<<<<<<<<<<
- *     ''' is_n_byte_aligned(array, n)
- * 
- */
-
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4is_n_byte_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_array, PyObject *__pyx_v_n) {
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4byte_align(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_array, PyObject *__pyx_v_n, PyObject *__pyx_v_dtype) {
   PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
+  struct __pyx_opt_args_6pyfftw_6pyfftw_byte_align __pyx_t_2;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("is_n_byte_aligned", 0);
+  __Pyx_RefNannySetupContext("byte_align", 0);
   __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_is_n_byte_aligned(__pyx_v_array, __pyx_v_n, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 112; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2.__pyx_n = 2;
+  __pyx_t_2.n = __pyx_v_n;
+  __pyx_t_2.dtype = __pyx_v_dtype;
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_byte_align(__pyx_v_array, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
   __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
+  /* function exit code */
   __pyx_L1_error:;
   __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pyfftw.pyfftw.is_n_byte_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pyfftw.pyfftw.byte_align", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
   __Pyx_XGIVEREF(__pyx_r);
@@ -2732,4981 +2976,4424 @@ static PyObject *__pyx_pf_6pyfftw_6pyfftw_4is_n_byte_aligned(CYTHON_UNUSED PyObj
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":57
- * #
- * # Complex double precision
- * cdef void* _fftw_plan_guru_dft(             # <<<<<<<<<<<<<<
- *             int rank, fftw_iodim *dims,
- *             int howmany_rank, fftw_iodim *howmany_dims,
+/* "pyfftw/utils.pxi":139
+ * 
+ * 
+ * cpdef is_byte_aligned(array, n=None):             # <<<<<<<<<<<<<<
+ *     ''' is_n_byte_aligned(array, n=None)
+ * 
  */
 
-static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, int __pyx_v_sign, int __pyx_v_flags) {
-  void *__pyx_r;
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_7is_byte_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_is_byte_aligned(PyObject *__pyx_v_array, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_is_byte_aligned *__pyx_optional_args) {
+  PyObject *__pyx_v_n = ((PyObject *)Py_None);
+  PyObject *__pyx_v_offset = NULL;
+  PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftw_plan_guru_dft", 0);
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("is_byte_aligned", 0);
+  if (__pyx_optional_args) {
+    if (__pyx_optional_args->__pyx_n > 0) {
+      __pyx_v_n = __pyx_optional_args->n;
+    }
+  }
+  __Pyx_INCREF(__pyx_v_n);
 
-  /* "pyfftw/pyfftw.pyx":66
- *             howmany_rank, howmany_dims,
- *             <cdouble *>_in, <cdouble *>_out,
- *             sign, flags)             # <<<<<<<<<<<<<<
- * 
- * # Complex single precision
+  /* "pyfftw/utils.pxi":147
+ *     inspect the CPU to determine alignment.
+ *     '''
+ *     if not isinstance(array, np.ndarray):             # <<<<<<<<<<<<<<
+ *         raise TypeError('Invalid array: is_n_byte_aligned requires a subclass '
+ *                 'of ndarray')
  */
-  __pyx_r = ((void *)fftw_plan_guru_dft(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((cdouble *)__pyx_v__in), ((cdouble *)__pyx_v__out), __pyx_v_sign, __pyx_v_flags));
-  goto __pyx_L0;
-
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_array, __pyx_ptype_5numpy_ndarray); 
+  __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+  if (__pyx_t_2) {
 
-/* "pyfftw/pyfftw.pyx":69
+    /* "pyfftw/utils.pxi":148
+ *     '''
+ *     if not isinstance(array, np.ndarray):
+ *         raise TypeError('Invalid array: is_n_byte_aligned requires a subclass '             # <<<<<<<<<<<<<<
+ *                 'of ndarray')
  * 
- * # Complex single precision
- * cdef void* _fftwf_plan_guru_dft(             # <<<<<<<<<<<<<<
- *             int rank, fftw_iodim *dims,
- *             int howmany_rank, fftw_iodim *howmany_dims,
  */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__3, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, int __pyx_v_sign, int __pyx_v_flags) {
-  void *__pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftwf_plan_guru_dft", 0);
+    /* "pyfftw/utils.pxi":147
+ *     inspect the CPU to determine alignment.
+ *     '''
+ *     if not isinstance(array, np.ndarray):             # <<<<<<<<<<<<<<
+ *         raise TypeError('Invalid array: is_n_byte_aligned requires a subclass '
+ *                 'of ndarray')
+ */
+  }
 
-  /* "pyfftw/pyfftw.pyx":78
- *             howmany_rank, howmany_dims,
- *             <cfloat *>_in, <cfloat *>_out,
- *             sign, flags)             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":151
+ *                 'of ndarray')
+ * 
+ *     if n is None:             # <<<<<<<<<<<<<<
+ *         n = _simd_alignment
  * 
- * # Complex long double precision
  */
-  __pyx_r = ((void *)fftwf_plan_guru_dft(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((cfloat *)__pyx_v__in), ((cfloat *)__pyx_v__out), __pyx_v_sign, __pyx_v_flags));
-  goto __pyx_L0;
-
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  __pyx_t_2 = (__pyx_v_n == Py_None);
+  __pyx_t_1 = (__pyx_t_2 != 0);
+  if (__pyx_t_1) {
 
-/* "pyfftw/pyfftw.pyx":81
+    /* "pyfftw/utils.pxi":152
  * 
- * # Complex long double precision
- * cdef void* _fftwl_plan_guru_dft(             # <<<<<<<<<<<<<<
- *             int rank, fftw_iodim *dims,
- *             int howmany_rank, fftw_iodim *howmany_dims,
+ *     if n is None:
+ *         n = _simd_alignment             # <<<<<<<<<<<<<<
+ * 
+ *     # See if we're n byte aligned.
  */
+    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_6pyfftw_6pyfftw__simd_alignment); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF_SET(__pyx_v_n, __pyx_t_3);
+    __pyx_t_3 = 0;
 
-static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, int __pyx_v_sign, int __pyx_v_flags) {
-  void *__pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftwl_plan_guru_dft", 0);
-
-  /* "pyfftw/pyfftw.pyx":90
- *             howmany_rank, howmany_dims,
- *             <clongdouble *>_in, <clongdouble *>_out,
- *             sign, flags)             # <<<<<<<<<<<<<<
+    /* "pyfftw/utils.pxi":151
+ *                 'of ndarray')
+ * 
+ *     if n is None:             # <<<<<<<<<<<<<<
+ *         n = _simd_alignment
  * 
- * # real to complex double precision
  */
-  __pyx_r = ((void *)fftwl_plan_guru_dft(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((clongdouble *)__pyx_v__in), ((clongdouble *)__pyx_v__out), __pyx_v_sign, __pyx_v_flags));
-  goto __pyx_L0;
-
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  }
 
-/* "pyfftw/pyfftw.pyx":93
+  /* "pyfftw/utils.pxi":155
  * 
- * # real to complex double precision
- * cdef void* _fftw_plan_guru_dft_r2c(             # <<<<<<<<<<<<<<
- *             int rank, fftw_iodim *dims,
- *             int howmany_rank, fftw_iodim *howmany_dims,
+ *     # See if we're n byte aligned.
+ *     offset = <intptr_t>np.PyArray_DATA(array) %n             # <<<<<<<<<<<<<<
+ * 
+ *     return not bool(offset)
  */
+  if (!(likely(((__pyx_v_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_v_array)))); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = PyNumber_Remainder(__pyx_t_3, __pyx_v_n); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_v_offset = __pyx_t_4;
+  __pyx_t_4 = 0;
 
-static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_r2c(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, int __pyx_v_flags) {
-  void *__pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftw_plan_guru_dft_r2c", 0);
-
-  /* "pyfftw/pyfftw.pyx":102
- *             howmany_rank, howmany_dims,
- *             <double *>_in, <cdouble *>_out,
- *             flags)             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":157
+ *     offset = <intptr_t>np.PyArray_DATA(array) %n
+ * 
+ *     return not bool(offset)             # <<<<<<<<<<<<<<
+ * 
  * 
- * # real to complex single precision
  */
-  __pyx_r = ((void *)fftw_plan_guru_dft_r2c(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((double *)__pyx_v__in), ((cdouble *)__pyx_v__out), __pyx_v_flags));
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_offset); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_4 = __Pyx_PyBool_FromLong((!((!(!__pyx_t_1)) != 0))); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_r = __pyx_t_4;
+  __pyx_t_4 = 0;
   goto __pyx_L0;
 
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pyfftw/pyfftw.pyx":105
+  /* "pyfftw/utils.pxi":139
  * 
- * # real to complex single precision
- * cdef void* _fftwf_plan_guru_dft_r2c(             # <<<<<<<<<<<<<<
- *             int rank, fftw_iodim *dims,
- *             int howmany_rank, fftw_iodim *howmany_dims,
- */
-
-static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_r2c(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, int __pyx_v_flags) {
-  void *__pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftwf_plan_guru_dft_r2c", 0);
-
-  /* "pyfftw/pyfftw.pyx":114
- *             howmany_rank, howmany_dims,
- *             <float *>_in, <cfloat *>_out,
- *             flags)             # <<<<<<<<<<<<<<
  * 
- * # real to complex long double precision
+ * cpdef is_byte_aligned(array, n=None):             # <<<<<<<<<<<<<<
+ *     ''' is_n_byte_aligned(array, n=None)
+ * 
  */
-  __pyx_r = ((void *)fftwf_plan_guru_dft_r2c(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((float *)__pyx_v__in), ((cfloat *)__pyx_v__out), __pyx_v_flags));
-  goto __pyx_L0;
 
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("pyfftw.pyfftw.is_byte_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_offset);
+  __Pyx_XDECREF(__pyx_v_n);
+  __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":117
- * 
- * # real to complex long double precision
- * cdef void* _fftwl_plan_guru_dft_r2c(             # <<<<<<<<<<<<<<
- *             int rank, fftw_iodim *dims,
- *             int howmany_rank, fftw_iodim *howmany_dims,
- */
-
-static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_r2c(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, int __pyx_v_flags) {
-  void *__pyx_r;
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_7is_byte_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_6is_byte_aligned[] = " is_n_byte_aligned(array, n=None)\n\n    Function that takes a numpy array and checks it is aligned on an n-byte\n    boundary, where ``n`` is an optional parameter, returning ``True`` if it is,\n    and ``False`` if it is not. If ``n`` is not provided then this function will\n    inspect the CPU to determine alignment.\n    ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_7is_byte_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_array = 0;
+  PyObject *__pyx_v_n = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftwl_plan_guru_dft_r2c", 0);
-
-  /* "pyfftw/pyfftw.pyx":126
- *             howmany_rank, howmany_dims,
- *             <long double *>_in, <clongdouble *>_out,
- *             flags)             # <<<<<<<<<<<<<<
- * 
- * # complex to real double precision
- */
-  __pyx_r = ((void *)fftwl_plan_guru_dft_r2c(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((long double *)__pyx_v__in), ((clongdouble *)__pyx_v__out), __pyx_v_flags));
-  goto __pyx_L0;
+  __Pyx_RefNannySetupContext("is_byte_aligned (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_array,&__pyx_n_s_n,0};
+    PyObject* values[2] = {0,0};
+    values[1] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_array)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n);
+          if (value) { values[1] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "is_byte_aligned") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_array = values[0];
+    __pyx_v_n = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("is_byte_aligned", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pyfftw.pyfftw.is_byte_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_6is_byte_aligned(__pyx_self, __pyx_v_array, __pyx_v_n);
 
-  __pyx_r = 0;
-  __pyx_L0:;
+  /* function exit code */
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":129
- * 
- * # complex to real double precision
- * cdef void* _fftw_plan_guru_dft_c2r(             # <<<<<<<<<<<<<<
- *             int rank, fftw_iodim *dims,
- *             int howmany_rank, fftw_iodim *howmany_dims,
- */
-
-static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_c2r(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, int __pyx_v_flags) {
-  void *__pyx_r;
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_6is_byte_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_array, PyObject *__pyx_v_n) {
+  PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftw_plan_guru_dft_c2r", 0);
-
-  /* "pyfftw/pyfftw.pyx":138
- *             howmany_rank, howmany_dims,
- *             <cdouble *>_in, <double *>_out,
- *             flags)             # <<<<<<<<<<<<<<
- * 
- * # complex to real single precision
- */
-  __pyx_r = ((void *)fftw_plan_guru_dft_c2r(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((cdouble *)__pyx_v__in), ((double *)__pyx_v__out), __pyx_v_flags));
+  PyObject *__pyx_t_1 = NULL;
+  struct __pyx_opt_args_6pyfftw_6pyfftw_is_byte_aligned __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("is_byte_aligned", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2.__pyx_n = 1;
+  __pyx_t_2.n = __pyx_v_n;
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_is_byte_aligned(__pyx_v_array, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  __pyx_r = 0;
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.is_byte_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
   __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":141
+/* "pyfftw/utils.pxi":160
  * 
- * # complex to real single precision
- * cdef void* _fftwf_plan_guru_dft_c2r(             # <<<<<<<<<<<<<<
- *             int rank, fftw_iodim *dims,
- *             int howmany_rank, fftw_iodim *howmany_dims,
+ * 
+ * cpdef is_n_byte_aligned(array, n):             # <<<<<<<<<<<<<<
+ *     ''' is_n_byte_aligned(array, n)
+ *     **This function is deprecated:** ``is_byte_aligned`` **should be used
  */
 
-static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_c2r(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, int __pyx_v_flags) {
-  void *__pyx_r;
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_9is_n_byte_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_is_n_byte_aligned(PyObject *__pyx_v_array, PyObject *__pyx_v_n, CYTHON_UNUSED int __pyx_skip_dispatch) {
+  PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftwf_plan_guru_dft_c2r", 0);
+  PyObject *__pyx_t_1 = NULL;
+  struct __pyx_opt_args_6pyfftw_6pyfftw_is_byte_aligned __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("is_n_byte_aligned", 0);
 
-  /* "pyfftw/pyfftw.pyx":150
- *             howmany_rank, howmany_dims,
- *             <cfloat *>_in, <float *>_out,
- *             flags)             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":169
+ *     and ``False`` if it is not.
+ *     '''
+ *     return is_byte_aligned(array, n=n)             # <<<<<<<<<<<<<<
+ * 
  * 
- * # complex to real long double precision
  */
-  __pyx_r = ((void *)fftwf_plan_guru_dft_c2r(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((cfloat *)__pyx_v__in), ((float *)__pyx_v__out), __pyx_v_flags));
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2.__pyx_n = 1;
+  __pyx_t_2.n = __pyx_v_n;
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_is_byte_aligned(__pyx_v_array, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
   goto __pyx_L0;
 
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pyfftw/pyfftw.pyx":153
+  /* "pyfftw/utils.pxi":160
  * 
- * # complex to real long double precision
- * cdef void* _fftwl_plan_guru_dft_c2r(             # <<<<<<<<<<<<<<
- *             int rank, fftw_iodim *dims,
- *             int howmany_rank, fftw_iodim *howmany_dims,
- */
-
-static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_c2r(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, int __pyx_v_flags) {
-  void *__pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftwl_plan_guru_dft_c2r", 0);
-
-  /* "pyfftw/pyfftw.pyx":162
- *             howmany_rank, howmany_dims,
- *             <clongdouble *>_in, <long double *>_out,
- *             flags)             # <<<<<<<<<<<<<<
  * 
- * #    Executors
+ * cpdef is_n_byte_aligned(array, n):             # <<<<<<<<<<<<<<
+ *     ''' is_n_byte_aligned(array, n)
+ *     **This function is deprecated:** ``is_byte_aligned`` **should be used
  */
-  __pyx_r = ((void *)fftwl_plan_guru_dft_c2r(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((clongdouble *)__pyx_v__in), ((long double *)__pyx_v__out), __pyx_v_flags));
-  goto __pyx_L0;
 
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.is_n_byte_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = 0;
   __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":168
- * #
- * # Complex double precision
- * cdef void _fftw_execute_dft(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
- * 
- *     fftw_execute_dft(<fftw_plan>_plan,
- */
-
-static void __pyx_f_6pyfftw_6pyfftw__fftw_execute_dft(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
-
-  /* "pyfftw/pyfftw.pyx":171
- * 
- *     fftw_execute_dft(<fftw_plan>_plan,
- *             <cdouble *>_in, <cdouble *>_out)             # <<<<<<<<<<<<<<
- * 
- * # Complex single precision
- */
-  fftw_execute_dft(((fftw_plan)__pyx_v__plan), ((cdouble *)__pyx_v__in), ((cdouble *)__pyx_v__out));
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_9is_n_byte_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_8is_n_byte_aligned[] = " is_n_byte_aligned(array, n)\n    **This function is deprecated:** ``is_byte_aligned`` **should be used\n    instead.**\n\n    Function that takes a numpy array and checks it is aligned on an n-byte\n    boundary, where ``n`` is a passed parameter, returning ``True`` if it is,\n    and ``False`` if it is not.\n    ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_9is_n_byte_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_array = 0;
+  PyObject *__pyx_v_n = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("is_n_byte_aligned (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_array,&__pyx_n_s_n,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_array)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("is_n_byte_aligned", 1, 2, 2, 1); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "is_n_byte_aligned") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_array = values[0];
+    __pyx_v_n = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("is_n_byte_aligned", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pyfftw.pyfftw.is_n_byte_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_8is_n_byte_aligned(__pyx_self, __pyx_v_array, __pyx_v_n);
 
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":174
- * 
- * # Complex single precision
- * cdef void _fftwf_execute_dft(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
- * 
- *     fftwf_execute_dft(<fftwf_plan>_plan,
- */
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_8is_n_byte_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_array, PyObject *__pyx_v_n) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("is_n_byte_aligned", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_is_n_byte_aligned(__pyx_v_array, __pyx_v_n, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-static void __pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.is_n_byte_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":177
+/* "pyfftw/utils.pxi":172
  * 
- *     fftwf_execute_dft(<fftwf_plan>_plan,
- *             <cfloat *>_in, <cfloat *>_out)             # <<<<<<<<<<<<<<
  * 
- * # Complex long double precision
+ * cpdef empty_aligned(shape, dtype='float64', order='C', n=None):             # <<<<<<<<<<<<<<
+ *     '''empty_aligned(shape, dtype='float64', order='C', n=None)
+ * 
  */
-  fftwf_execute_dft(((fftwf_plan)__pyx_v__plan), ((cfloat *)__pyx_v__in), ((cfloat *)__pyx_v__out));
 
-}
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_11empty_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_empty_aligned(PyObject *__pyx_v_shape, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_empty_aligned *__pyx_optional_args) {
+  PyObject *__pyx_v_dtype = ((PyObject *)__pyx_n_s_float64);
+  PyObject *__pyx_v_order = ((PyObject *)__pyx_n_s_C);
+  PyObject *__pyx_v_n = ((PyObject *)Py_None);
+  PyObject *__pyx_v_itemsize = NULL;
+  PyObject *__pyx_v_array_length = NULL;
+  PyObject *__pyx_v_each_dimension = NULL;
+  PyObject *__pyx_v__array_aligned = NULL;
+  PyObject *__pyx_v__array_aligned_offset = NULL;
+  PyObject *__pyx_v_array = NULL;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  Py_ssize_t __pyx_t_6;
+  PyObject *(*__pyx_t_7)(PyObject *);
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("empty_aligned", 0);
+  if (__pyx_optional_args) {
+    if (__pyx_optional_args->__pyx_n > 0) {
+      __pyx_v_dtype = __pyx_optional_args->dtype;
+      if (__pyx_optional_args->__pyx_n > 1) {
+        __pyx_v_order = __pyx_optional_args->order;
+        if (__pyx_optional_args->__pyx_n > 2) {
+          __pyx_v_n = __pyx_optional_args->n;
+        }
+      }
+    }
+  }
+  __Pyx_INCREF(__pyx_v_n);
 
-/* "pyfftw/pyfftw.pyx":180
- * 
- * # Complex long double precision
- * cdef void _fftwl_execute_dft(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":184
+ *     :func:`numpy.empty`.
+ *     '''
+ *     if n is None:             # <<<<<<<<<<<<<<
+ *         n = _simd_alignment
  * 
- *     fftwl_execute_dft(<fftwl_plan>_plan,
  */
+  __pyx_t_1 = (__pyx_v_n == Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
 
-static void __pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
-
-  /* "pyfftw/pyfftw.pyx":183
- * 
- *     fftwl_execute_dft(<fftwl_plan>_plan,
- *             <clongdouble *>_in, <clongdouble *>_out)             # <<<<<<<<<<<<<<
+    /* "pyfftw/utils.pxi":185
+ *     '''
+ *     if n is None:
+ *         n = _simd_alignment             # <<<<<<<<<<<<<<
  * 
- * # real to complex double precision
+ *     itemsize = np.dtype(dtype).itemsize
  */
-  fftwl_execute_dft(((fftwl_plan)__pyx_v__plan), ((clongdouble *)__pyx_v__in), ((clongdouble *)__pyx_v__out));
-
-}
+    __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_6pyfftw_6pyfftw__simd_alignment); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF_SET(__pyx_v_n, __pyx_t_3);
+    __pyx_t_3 = 0;
 
-/* "pyfftw/pyfftw.pyx":186
- * 
- * # real to complex double precision
- * cdef void _fftw_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+    /* "pyfftw/utils.pxi":184
+ *     :func:`numpy.empty`.
+ *     '''
+ *     if n is None:             # <<<<<<<<<<<<<<
+ *         n = _simd_alignment
  * 
- *     fftw_execute_dft_r2c(<fftw_plan>_plan,
  */
+  }
 
-static void __pyx_f_6pyfftw_6pyfftw__fftw_execute_dft_r2c(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
-
-  /* "pyfftw/pyfftw.pyx":189
+  /* "pyfftw/utils.pxi":187
+ *         n = _simd_alignment
  * 
- *     fftw_execute_dft_r2c(<fftw_plan>_plan,
- *             <double *>_in, <cdouble *>_out)             # <<<<<<<<<<<<<<
+ *     itemsize = np.dtype(dtype).itemsize             # <<<<<<<<<<<<<<
  * 
- * # real to complex single precision
+ *     # Apparently there is an issue with numpy.prod wrapping around on 32-bits
  */
-  fftw_execute_dft_r2c(((fftw_plan)__pyx_v__plan), ((double *)__pyx_v__in), ((cdouble *)__pyx_v__out));
-
-}
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_dtype);
+  __Pyx_GIVEREF(__pyx_v_dtype);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_dtype);
+  __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_t_3, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = __Pyx_PyInt_From_int(((PyArray_Descr *)__pyx_t_4)->elsize); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_v_itemsize = __pyx_t_3;
+  __pyx_t_3 = 0;
 
-/* "pyfftw/pyfftw.pyx":192
- * 
- * # real to complex single precision
- * cdef void _fftwf_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
- * 
- *     fftwf_execute_dft_r2c(<fftwf_plan>_plan,
+  /* "pyfftw/utils.pxi":192
+ *     # on Windows 64-bit. This shouldn't happen, but the following code
+ *     # alleviates the problem.
+ *     if not isinstance(shape, (int, np.integer)):             # <<<<<<<<<<<<<<
+ *         array_length = 1
+ *         for each_dimension in shape:
  */
+  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_integer); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_1 = PyInt_Check(__pyx_v_shape); 
+  __pyx_t_5 = (__pyx_t_1 != 0);
+  if (!__pyx_t_5) {
+  } else {
+    __pyx_t_2 = __pyx_t_5;
+    goto __pyx_L5_bool_binop_done;
+  }
+  __pyx_t_5 = PyObject_IsInstance(__pyx_v_shape, __pyx_t_4); 
+  __pyx_t_1 = (__pyx_t_5 != 0);
+  __pyx_t_2 = __pyx_t_1;
+  __pyx_L5_bool_binop_done:;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_1 = ((!(__pyx_t_2 != 0)) != 0);
+  if (__pyx_t_1) {
 
-static void __pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft_r2c(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
+    /* "pyfftw/utils.pxi":193
+ *     # alleviates the problem.
+ *     if not isinstance(shape, (int, np.integer)):
+ *         array_length = 1             # <<<<<<<<<<<<<<
+ *         for each_dimension in shape:
+ *             array_length *= each_dimension
+ */
+    __Pyx_INCREF(__pyx_int_1);
+    __pyx_v_array_length = __pyx_int_1;
 
-  /* "pyfftw/pyfftw.pyx":195
- * 
- *     fftwf_execute_dft_r2c(<fftwf_plan>_plan,
- *             <float *>_in, <cfloat *>_out)             # <<<<<<<<<<<<<<
+    /* "pyfftw/utils.pxi":194
+ *     if not isinstance(shape, (int, np.integer)):
+ *         array_length = 1
+ *         for each_dimension in shape:             # <<<<<<<<<<<<<<
+ *             array_length *= each_dimension
  * 
- * # real to complex long double precision
  */
-  fftwf_execute_dft_r2c(((fftwf_plan)__pyx_v__plan), ((float *)__pyx_v__in), ((cfloat *)__pyx_v__out));
-
-}
+    if (likely(PyList_CheckExact(__pyx_v_shape)) || PyTuple_CheckExact(__pyx_v_shape)) {
+      __pyx_t_4 = __pyx_v_shape; __Pyx_INCREF(__pyx_t_4); __pyx_t_6 = 0;
+      __pyx_t_7 = NULL;
+    } else {
+      __pyx_t_6 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_shape); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_7 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    for (;;) {
+      if (likely(!__pyx_t_7)) {
+        if (likely(PyList_CheckExact(__pyx_t_4))) {
+          if (__pyx_t_6 >= PyList_GET_SIZE(__pyx_t_4)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_3);
+          #endif
+        } else {
+          if (__pyx_t_6 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_6); __Pyx_INCREF(__pyx_t_3); __pyx_t_6++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_6); __pyx_t_6++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_3);
+          #endif
+        }
+      } else {
+        __pyx_t_3 = __pyx_t_7(__pyx_t_4);
+        if (unlikely(!__pyx_t_3)) {
+          PyObject* exc_type = PyErr_Occurred();
+          if (exc_type) {
+            if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[1]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_3);
+      }
+      __Pyx_XDECREF_SET(__pyx_v_each_dimension, __pyx_t_3);
+      __pyx_t_3 = 0;
 
-/* "pyfftw/pyfftw.pyx":198
- * 
- * # real to complex long double precision
- * cdef void _fftwl_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+      /* "pyfftw/utils.pxi":195
+ *         array_length = 1
+ *         for each_dimension in shape:
+ *             array_length *= each_dimension             # <<<<<<<<<<<<<<
  * 
- *     fftwl_execute_dft_r2c(<fftwl_plan>_plan,
+ *     else:
  */
+      __pyx_t_3 = PyNumber_InPlaceMultiply(__pyx_v_array_length, __pyx_v_each_dimension); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_DECREF_SET(__pyx_v_array_length, __pyx_t_3);
+      __pyx_t_3 = 0;
 
-static void __pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft_r2c(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
-
-  /* "pyfftw/pyfftw.pyx":201
- * 
- *     fftwl_execute_dft_r2c(<fftwl_plan>_plan,
- *             <long double *>_in, <clongdouble *>_out)             # <<<<<<<<<<<<<<
+      /* "pyfftw/utils.pxi":194
+ *     if not isinstance(shape, (int, np.integer)):
+ *         array_length = 1
+ *         for each_dimension in shape:             # <<<<<<<<<<<<<<
+ *             array_length *= each_dimension
  * 
- * # complex to real double precision
  */
-  fftwl_execute_dft_r2c(((fftwl_plan)__pyx_v__plan), ((long double *)__pyx_v__in), ((clongdouble *)__pyx_v__out));
+    }
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-}
+    /* "pyfftw/utils.pxi":192
+ *     # on Windows 64-bit. This shouldn't happen, but the following code
+ *     # alleviates the problem.
+ *     if not isinstance(shape, (int, np.integer)):             # <<<<<<<<<<<<<<
+ *         array_length = 1
+ *         for each_dimension in shape:
+ */
+    goto __pyx_L4;
+  }
 
-/* "pyfftw/pyfftw.pyx":204
+  /* "pyfftw/utils.pxi":198
  * 
- * # complex to real double precision
- * cdef void _fftw_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ *     else:
+ *         array_length = shape             # <<<<<<<<<<<<<<
  * 
- *     fftw_execute_dft_c2r(<fftw_plan>_plan,
+ *     # Allocate a new array that will contain the aligned data
  */
+  /*else*/ {
+    __Pyx_INCREF(__pyx_v_shape);
+    __pyx_v_array_length = __pyx_v_shape;
+  }
+  __pyx_L4:;
 
-static void __pyx_f_6pyfftw_6pyfftw__fftw_execute_dft_c2r(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
-
-  /* "pyfftw/pyfftw.pyx":207
+  /* "pyfftw/utils.pxi":201
  * 
- *     fftw_execute_dft_c2r(<fftw_plan>_plan,
- *             <cdouble *>_in, <double *>_out)             # <<<<<<<<<<<<<<
+ *     # Allocate a new array that will contain the aligned data
+ *     _array_aligned = np.empty(array_length*itemsize+n, dtype='int8')             # <<<<<<<<<<<<<<
  * 
- * # complex to real single precision
+ *     # We now need to know how to offset _array_aligned
  */
-  fftw_execute_dft_c2r(((fftw_plan)__pyx_v__plan), ((cdouble *)__pyx_v__in), ((double *)__pyx_v__out));
-
-}
+  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_empty); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyNumber_Multiply(__pyx_v_array_length, __pyx_v_itemsize); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_8 = PyNumber_Add(__pyx_t_4, __pyx_v_n); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_8);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_8);
+  __pyx_t_8 = 0;
+  __pyx_t_8 = PyDict_New(); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  if (PyDict_SetItem(__pyx_t_8, __pyx_n_s_dtype, __pyx_n_s_int8) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_9 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_8); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __pyx_v__array_aligned = __pyx_t_9;
+  __pyx_t_9 = 0;
 
-/* "pyfftw/pyfftw.pyx":210
- * 
- * # complex to real single precision
- * cdef void _fftwf_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":205
+ *     # We now need to know how to offset _array_aligned
+ *     # so it is correctly aligned
+ *     _array_aligned_offset = (n-<intptr_t>np.PyArray_DATA(_array_aligned))%n             # <<<<<<<<<<<<<<
  * 
- *     fftwf_execute_dft_c2r(<fftwf_plan>_plan,
+ *     array = np.frombuffer(
  */
+  if (!(likely(((__pyx_v__array_aligned) == Py_None) || likely(__Pyx_TypeTest(__pyx_v__array_aligned, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_9 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_v__array_aligned)))); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __pyx_t_8 = PyNumber_Subtract(__pyx_v_n, __pyx_t_9); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  __pyx_t_9 = PyNumber_Remainder(__pyx_t_8, __pyx_v_n); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __pyx_v__array_aligned_offset = __pyx_t_9;
+  __pyx_t_9 = 0;
 
-static void __pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft_c2r(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
-
-  /* "pyfftw/pyfftw.pyx":213
- * 
- *     fftwf_execute_dft_c2r(<fftwf_plan>_plan,
- *             <cfloat *>_in, <float *>_out)             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":207
+ *     _array_aligned_offset = (n-<intptr_t>np.PyArray_DATA(_array_aligned))%n
  * 
- * # complex to real long double precision
+ *     array = np.frombuffer(             # <<<<<<<<<<<<<<
+ *             _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,
+ *             dtype=dtype).reshape(shape, order=order)
  */
-  fftwf_execute_dft_c2r(((fftwf_plan)__pyx_v__plan), ((cfloat *)__pyx_v__in), ((float *)__pyx_v__out));
-
-}
+  __pyx_t_9 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_9, __pyx_n_s_frombuffer); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-/* "pyfftw/pyfftw.pyx":216
+  /* "pyfftw/utils.pxi":208
  * 
- * # complex to real long double precision
- * cdef void _fftwl_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ *     array = np.frombuffer(
+ *             _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,             # <<<<<<<<<<<<<<
+ *             dtype=dtype).reshape(shape, order=order)
  * 
- *     fftwl_execute_dft_c2r(<fftwl_plan>_plan,
  */
+  __pyx_t_9 = PyNumber_Subtract(__pyx_v__array_aligned_offset, __pyx_v_n); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __pyx_t_4 = __Pyx_PyObject_GetSlice(__pyx_v__array_aligned, 0, 0, &__pyx_v__array_aligned_offset, &__pyx_t_9, NULL, 0, 0, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_data); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-static void __pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft_c2r(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
-
-  /* "pyfftw/pyfftw.pyx":219
- * 
- *     fftwl_execute_dft_c2r(<fftwl_plan>_plan,
- *             <clongdouble *>_in, <long double *>_out)             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":207
+ *     _array_aligned_offset = (n-<intptr_t>np.PyArray_DATA(_array_aligned))%n
  * 
- * #    Destroyers
+ *     array = np.frombuffer(             # <<<<<<<<<<<<<<
+ *             _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,
+ *             dtype=dtype).reshape(shape, order=order)
  */
-  fftwl_execute_dft_c2r(((fftwl_plan)__pyx_v__plan), ((clongdouble *)__pyx_v__in), ((long double *)__pyx_v__out));
-
-}
+  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_9);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_9);
+  __pyx_t_9 = 0;
 
-/* "pyfftw/pyfftw.pyx":225
- * #
- * # Double precision
- * cdef void _fftw_destroy_plan(void *_plan):             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":209
+ *     array = np.frombuffer(
+ *             _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,
+ *             dtype=dtype).reshape(shape, order=order)             # <<<<<<<<<<<<<<
  * 
- *     fftw_destroy_plan(<fftw_plan>_plan)
+ *     return array
  */
+  __pyx_t_9 = PyDict_New(); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_dtype, __pyx_v_dtype) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-static void __pyx_f_6pyfftw_6pyfftw__fftw_destroy_plan(void *__pyx_v__plan) {
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftw_destroy_plan", 0);
-
-  /* "pyfftw/pyfftw.pyx":227
- * cdef void _fftw_destroy_plan(void *_plan):
- * 
- *     fftw_destroy_plan(<fftw_plan>_plan)             # <<<<<<<<<<<<<<
+  /* "pyfftw/utils.pxi":207
+ *     _array_aligned_offset = (n-<intptr_t>np.PyArray_DATA(_array_aligned))%n
  * 
- * # Single precision
+ *     array = np.frombuffer(             # <<<<<<<<<<<<<<
+ *             _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,
+ *             dtype=dtype).reshape(shape, order=order)
  */
-  fftw_destroy_plan(((fftw_plan)__pyx_v__plan));
+  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_8, __pyx_t_4, __pyx_t_9); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-  __Pyx_RefNannyFinishContext();
-}
+  /* "pyfftw/utils.pxi":209
+ *     array = np.frombuffer(
+ *             _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,
+ *             dtype=dtype).reshape(shape, order=order)             # <<<<<<<<<<<<<<
+ * 
+ *     return array
+ */
+  __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_reshape); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_v_shape);
+  __Pyx_GIVEREF(__pyx_v_shape);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_shape);
+  __pyx_t_4 = PyDict_New(); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_order, __pyx_v_order) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_9, __pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_8);
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_v_array = __pyx_t_8;
+  __pyx_t_8 = 0;
 
-/* "pyfftw/pyfftw.pyx":230
+  /* "pyfftw/utils.pxi":211
+ *             dtype=dtype).reshape(shape, order=order)
+ * 
+ *     return array             # <<<<<<<<<<<<<<
  * 
- * # Single precision
- * cdef void _fftwf_destroy_plan(void *_plan):             # <<<<<<<<<<<<<<
  * 
- *     fftwf_destroy_plan(<fftwf_plan>_plan)
  */
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_array);
+  __pyx_r = __pyx_v_array;
+  goto __pyx_L0;
 
-static void __pyx_f_6pyfftw_6pyfftw__fftwf_destroy_plan(void *__pyx_v__plan) {
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftwf_destroy_plan", 0);
-
-  /* "pyfftw/pyfftw.pyx":232
- * cdef void _fftwf_destroy_plan(void *_plan):
+  /* "pyfftw/utils.pxi":172
  * 
- *     fftwf_destroy_plan(<fftwf_plan>_plan)             # <<<<<<<<<<<<<<
  * 
- * # Long double precision
+ * cpdef empty_aligned(shape, dtype='float64', order='C', n=None):             # <<<<<<<<<<<<<<
+ *     '''empty_aligned(shape, dtype='float64', order='C', n=None)
+ * 
  */
-  fftwf_destroy_plan(((fftwf_plan)__pyx_v__plan));
 
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_8);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_AddTraceback("pyfftw.pyfftw.empty_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_itemsize);
+  __Pyx_XDECREF(__pyx_v_array_length);
+  __Pyx_XDECREF(__pyx_v_each_dimension);
+  __Pyx_XDECREF(__pyx_v__array_aligned);
+  __Pyx_XDECREF(__pyx_v__array_aligned_offset);
+  __Pyx_XDECREF(__pyx_v_array);
+  __Pyx_XDECREF(__pyx_v_n);
+  __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
+  return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":235
- * 
- * # Long double precision
- * cdef void _fftwl_destroy_plan(void *_plan):             # <<<<<<<<<<<<<<
- * 
- *     fftwl_destroy_plan(<fftwl_plan>_plan)
- */
-
-static void __pyx_f_6pyfftw_6pyfftw__fftwl_destroy_plan(void *__pyx_v__plan) {
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_11empty_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_10empty_aligned[] = "empty_aligned(shape, dtype='float64', order='C', n=None)\n\n    Function that returns an empty numpy array that is n-byte aligned,\n    where ``n`` is determined by inspecting the CPU if it is not\n    provided.\n\n    The alignment is given by the final optional argument, ``n``. If\n    ``n`` is not provided then this function will inspect the CPU to\n    determine alignment. The rest of the arguments are as per\n    :func:`nump [...]
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_11empty_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_shape = 0;
+  PyObject *__pyx_v_dtype = 0;
+  PyObject *__pyx_v_order = 0;
+  PyObject *__pyx_v_n = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_fftwl_destroy_plan", 0);
+  __Pyx_RefNannySetupContext("empty_aligned (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_dtype,&__pyx_n_s_order,&__pyx_n_s_n,0};
+    PyObject* values[4] = {0,0,0,0};
+    values[1] = ((PyObject *)__pyx_n_s_float64);
+    values[2] = ((PyObject *)__pyx_n_s_C);
+    values[3] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_order);
+          if (value) { values[2] = value; kw_args--; }
+        }
+        case  3:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n);
+          if (value) { values[3] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "empty_aligned") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_shape = values[0];
+    __pyx_v_dtype = values[1];
+    __pyx_v_order = values[2];
+    __pyx_v_n = values[3];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("empty_aligned", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pyfftw.pyfftw.empty_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_10empty_aligned(__pyx_self, __pyx_v_shape, __pyx_v_dtype, __pyx_v_order, __pyx_v_n);
 
-  /* "pyfftw/pyfftw.pyx":237
- * cdef void _fftwl_destroy_plan(void *_plan):
- * 
- *     fftwl_destroy_plan(<fftwl_plan>_plan)             # <<<<<<<<<<<<<<
- * 
- * 
- */
-  fftwl_destroy_plan(((fftwl_plan)__pyx_v__plan));
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_10empty_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_shape, PyObject *__pyx_v_dtype, PyObject *__pyx_v_order, PyObject *__pyx_v_n) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  struct __pyx_opt_args_6pyfftw_6pyfftw_empty_aligned __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("empty_aligned", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2.__pyx_n = 3;
+  __pyx_t_2.dtype = __pyx_v_dtype;
+  __pyx_t_2.order = __pyx_v_order;
+  __pyx_t_2.n = __pyx_v_n;
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_empty_aligned(__pyx_v_shape, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.empty_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
+  return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":246
- * cdef fftw_generic_plan_guru planners[9]
+/* "pyfftw/utils.pxi":214
  * 
- * cdef fftw_generic_plan_guru * _build_planner_list():             # <<<<<<<<<<<<<<
  * 
- *     planners[0] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft
+ * cpdef zeros_aligned(shape, dtype='float64', order='C', n=None):             # <<<<<<<<<<<<<<
+ *     '''zeros_aligned(shape, dtype='float64', order='C', n=None)
+ * 
  */
 
-static __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru *__pyx_f_6pyfftw_6pyfftw__build_planner_list(void) {
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru *__pyx_r;
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_13zeros_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_zeros_aligned(PyObject *__pyx_v_shape, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_zeros_aligned *__pyx_optional_args) {
+  PyObject *__pyx_v_dtype = ((PyObject *)__pyx_n_s_float64);
+  PyObject *__pyx_v_order = ((PyObject *)__pyx_n_s_C);
+  PyObject *__pyx_v_n = ((PyObject *)Py_None);
+  PyObject *__pyx_v_array = NULL;
+  PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_build_planner_list", 0);
+  PyObject *__pyx_t_1 = NULL;
+  struct __pyx_opt_args_6pyfftw_6pyfftw_empty_aligned __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("zeros_aligned", 0);
+  if (__pyx_optional_args) {
+    if (__pyx_optional_args->__pyx_n > 0) {
+      __pyx_v_dtype = __pyx_optional_args->dtype;
+      if (__pyx_optional_args->__pyx_n > 1) {
+        __pyx_v_order = __pyx_optional_args->order;
+        if (__pyx_optional_args->__pyx_n > 2) {
+          __pyx_v_n = __pyx_optional_args->n;
+        }
+      }
+    }
+  }
 
-  /* "pyfftw/pyfftw.pyx":248
- * cdef fftw_generic_plan_guru * _build_planner_list():
- * 
- *     planners[0] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft             # <<<<<<<<<<<<<<
- *     planners[1] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft
- *     planners[2] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft
+  /* "pyfftw/utils.pxi":226
+ *     :func:`numpy.zeros`.
+ *     '''
+ *     array = empty_aligned(shape, dtype=dtype, order=order, n=n)             # <<<<<<<<<<<<<<
+ *     array.fill(0)
+ *     return array
  */
-  (__pyx_v_6pyfftw_6pyfftw_planners[0]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft));
+  __pyx_t_2.__pyx_n = 3;
+  __pyx_t_2.dtype = __pyx_v_dtype;
+  __pyx_t_2.order = __pyx_v_order;
+  __pyx_t_2.n = __pyx_v_n;
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_empty_aligned(__pyx_v_shape, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 226; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_array = __pyx_t_1;
+  __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":249
+  /* "pyfftw/utils.pxi":227
+ *     '''
+ *     array = empty_aligned(shape, dtype=dtype, order=order, n=n)
+ *     array.fill(0)             # <<<<<<<<<<<<<<
+ *     return array
  * 
- *     planners[0] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft
- *     planners[1] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft             # <<<<<<<<<<<<<<
- *     planners[2] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft
- *     planners[3] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_r2c
- */
-  (__pyx_v_6pyfftw_6pyfftw_planners[1]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft));
-
-  /* "pyfftw/pyfftw.pyx":250
- *     planners[0] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft
- *     planners[1] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft
- *     planners[2] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft             # <<<<<<<<<<<<<<
- *     planners[3] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_r2c
- *     planners[4] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_r2c
  */
-  (__pyx_v_6pyfftw_6pyfftw_planners[2]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft));
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_array, __pyx_n_s_fill); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pyfftw/pyfftw.pyx":251
- *     planners[1] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft
- *     planners[2] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft
- *     planners[3] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_r2c             # <<<<<<<<<<<<<<
- *     planners[4] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_r2c
- *     planners[5] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_r2c
+  /* "pyfftw/utils.pxi":228
+ *     array = empty_aligned(shape, dtype=dtype, order=order, n=n)
+ *     array.fill(0)
+ *     return array             # <<<<<<<<<<<<<<
+ * 
+ * 
  */
-  (__pyx_v_6pyfftw_6pyfftw_planners[3]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_r2c));
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_array);
+  __pyx_r = __pyx_v_array;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":252
- *     planners[2] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft
- *     planners[3] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_r2c
- *     planners[4] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_r2c             # <<<<<<<<<<<<<<
- *     planners[5] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_r2c
- *     planners[6] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_c2r
+  /* "pyfftw/utils.pxi":214
+ * 
+ * 
+ * cpdef zeros_aligned(shape, dtype='float64', order='C', n=None):             # <<<<<<<<<<<<<<
+ *     '''zeros_aligned(shape, dtype='float64', order='C', n=None)
+ * 
  */
-  (__pyx_v_6pyfftw_6pyfftw_planners[4]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_r2c));
 
-  /* "pyfftw/pyfftw.pyx":253
- *     planners[3] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_r2c
- *     planners[4] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_r2c
- *     planners[5] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_r2c             # <<<<<<<<<<<<<<
- *     planners[6] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_c2r
- *     planners[7] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_c2r
- */
-  (__pyx_v_6pyfftw_6pyfftw_planners[5]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_r2c));
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("pyfftw.pyfftw.zeros_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_array);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":254
- *     planners[4] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_r2c
- *     planners[5] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_r2c
- *     planners[6] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_c2r             # <<<<<<<<<<<<<<
- *     planners[7] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_c2r
- *     planners[8] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_c2r
- */
-  (__pyx_v_6pyfftw_6pyfftw_planners[6]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_c2r));
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_13zeros_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_12zeros_aligned[] = "zeros_aligned(shape, dtype='float64', order='C', n=None)\n\n    Function that returns a numpy array of zeros that is n-byte aligned,\n    where ``n`` is determined by inspecting the CPU if it is not\n    provided.\n\n    The alignment is given by the final optional argument, ``n``. If\n    ``n`` is not provided then this function will inspect the CPU to\n    determine alignment. The rest of the arguments are as per\n    :func:`nu [...]
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_13zeros_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_shape = 0;
+  PyObject *__pyx_v_dtype = 0;
+  PyObject *__pyx_v_order = 0;
+  PyObject *__pyx_v_n = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("zeros_aligned (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_dtype,&__pyx_n_s_order,&__pyx_n_s_n,0};
+    PyObject* values[4] = {0,0,0,0};
+    values[1] = ((PyObject *)__pyx_n_s_float64);
+    values[2] = ((PyObject *)__pyx_n_s_C);
+    values[3] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_order);
+          if (value) { values[2] = value; kw_args--; }
+        }
+        case  3:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n);
+          if (value) { values[3] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "zeros_aligned") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_shape = values[0];
+    __pyx_v_dtype = values[1];
+    __pyx_v_order = values[2];
+    __pyx_v_n = values[3];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("zeros_aligned", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pyfftw.pyfftw.zeros_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_12zeros_aligned(__pyx_self, __pyx_v_shape, __pyx_v_dtype, __pyx_v_order, __pyx_v_n);
 
-  /* "pyfftw/pyfftw.pyx":255
- *     planners[5] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_r2c
- *     planners[6] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_c2r
- *     planners[7] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_c2r             # <<<<<<<<<<<<<<
- *     planners[8] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_c2r
- * 
- */
-  (__pyx_v_6pyfftw_6pyfftw_planners[7]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_c2r));
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":256
- *     planners[6] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_c2r
- *     planners[7] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_c2r
- *     planners[8] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_c2r             # <<<<<<<<<<<<<<
- * 
- * # Executor table (of size the number of executors)
- */
-  (__pyx_v_6pyfftw_6pyfftw_planners[8]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_c2r));
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_12zeros_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_shape, PyObject *__pyx_v_dtype, PyObject *__pyx_v_order, PyObject *__pyx_v_n) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  struct __pyx_opt_args_6pyfftw_6pyfftw_zeros_aligned __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("zeros_aligned", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2.__pyx_n = 3;
+  __pyx_t_2.dtype = __pyx_v_dtype;
+  __pyx_t_2.order = __pyx_v_order;
+  __pyx_t_2.n = __pyx_v_n;
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_zeros_aligned(__pyx_v_shape, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-  __pyx_r = 0;
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.zeros_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":261
- * cdef fftw_generic_execute executors[9]
+/* "pyfftw/utils.pxi":231
  * 
- * cdef fftw_generic_execute * _build_executor_list():             # <<<<<<<<<<<<<<
  * 
- *     executors[0] = <fftw_generic_execute>&_fftw_execute_dft
+ * cpdef ones_aligned(shape, dtype='float64', order='C', n=None):             # <<<<<<<<<<<<<<
+ *     '''ones_aligned(shape, dtype='float64', order='C', n=None)
+ * 
  */
 
-static __pyx_t_6pyfftw_6pyfftw_fftw_generic_execute *__pyx_f_6pyfftw_6pyfftw__build_executor_list(void) {
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_execute *__pyx_r;
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_15ones_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_ones_aligned(PyObject *__pyx_v_shape, CYTHON_UNUSED int __pyx_skip_dispatch, struct __pyx_opt_args_6pyfftw_6pyfftw_ones_aligned *__pyx_optional_args) {
+  PyObject *__pyx_v_dtype = ((PyObject *)__pyx_n_s_float64);
+  PyObject *__pyx_v_order = ((PyObject *)__pyx_n_s_C);
+  PyObject *__pyx_v_n = ((PyObject *)Py_None);
+  PyObject *__pyx_v_array = NULL;
+  PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_build_executor_list", 0);
+  PyObject *__pyx_t_1 = NULL;
+  struct __pyx_opt_args_6pyfftw_6pyfftw_empty_aligned __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("ones_aligned", 0);
+  if (__pyx_optional_args) {
+    if (__pyx_optional_args->__pyx_n > 0) {
+      __pyx_v_dtype = __pyx_optional_args->dtype;
+      if (__pyx_optional_args->__pyx_n > 1) {
+        __pyx_v_order = __pyx_optional_args->order;
+        if (__pyx_optional_args->__pyx_n > 2) {
+          __pyx_v_n = __pyx_optional_args->n;
+        }
+      }
+    }
+  }
 
-  /* "pyfftw/pyfftw.pyx":263
- * cdef fftw_generic_execute * _build_executor_list():
- * 
- *     executors[0] = <fftw_generic_execute>&_fftw_execute_dft             # <<<<<<<<<<<<<<
- *     executors[1] = <fftw_generic_execute>&_fftwf_execute_dft
- *     executors[2] = <fftw_generic_execute>&_fftwl_execute_dft
+  /* "pyfftw/utils.pxi":243
+ *     :func:`numpy.ones`.
+ *     '''
+ *     array = empty_aligned(shape, dtype=dtype, order=order, n=n)             # <<<<<<<<<<<<<<
+ *     array.fill(1)
+ *     return array
  */
-  (__pyx_v_6pyfftw_6pyfftw_executors[0]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftw_execute_dft));
+  __pyx_t_2.__pyx_n = 3;
+  __pyx_t_2.dtype = __pyx_v_dtype;
+  __pyx_t_2.order = __pyx_v_order;
+  __pyx_t_2.n = __pyx_v_n;
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_empty_aligned(__pyx_v_shape, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_array = __pyx_t_1;
+  __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":264
- * 
- *     executors[0] = <fftw_generic_execute>&_fftw_execute_dft
- *     executors[1] = <fftw_generic_execute>&_fftwf_execute_dft             # <<<<<<<<<<<<<<
- *     executors[2] = <fftw_generic_execute>&_fftwl_execute_dft
- *     executors[3] = <fftw_generic_execute>&_fftw_execute_dft_r2c
+  /* "pyfftw/utils.pxi":244
+ *     '''
+ *     array = empty_aligned(shape, dtype=dtype, order=order, n=n)
+ *     array.fill(1)             # <<<<<<<<<<<<<<
+ *     return array
  */
-  (__pyx_v_6pyfftw_6pyfftw_executors[1]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft));
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_array, __pyx_n_s_fill); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 
-  /* "pyfftw/pyfftw.pyx":265
- *     executors[0] = <fftw_generic_execute>&_fftw_execute_dft
- *     executors[1] = <fftw_generic_execute>&_fftwf_execute_dft
- *     executors[2] = <fftw_generic_execute>&_fftwl_execute_dft             # <<<<<<<<<<<<<<
- *     executors[3] = <fftw_generic_execute>&_fftw_execute_dft_r2c
- *     executors[4] = <fftw_generic_execute>&_fftwf_execute_dft_r2c
+  /* "pyfftw/utils.pxi":245
+ *     array = empty_aligned(shape, dtype=dtype, order=order, n=n)
+ *     array.fill(1)
+ *     return array             # <<<<<<<<<<<<<<
  */
-  (__pyx_v_6pyfftw_6pyfftw_executors[2]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft));
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_array);
+  __pyx_r = __pyx_v_array;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":266
- *     executors[1] = <fftw_generic_execute>&_fftwf_execute_dft
- *     executors[2] = <fftw_generic_execute>&_fftwl_execute_dft
- *     executors[3] = <fftw_generic_execute>&_fftw_execute_dft_r2c             # <<<<<<<<<<<<<<
- *     executors[4] = <fftw_generic_execute>&_fftwf_execute_dft_r2c
- *     executors[5] = <fftw_generic_execute>&_fftwl_execute_dft_r2c
+  /* "pyfftw/utils.pxi":231
+ * 
+ * 
+ * cpdef ones_aligned(shape, dtype='float64', order='C', n=None):             # <<<<<<<<<<<<<<
+ *     '''ones_aligned(shape, dtype='float64', order='C', n=None)
+ * 
  */
-  (__pyx_v_6pyfftw_6pyfftw_executors[3]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftw_execute_dft_r2c));
 
-  /* "pyfftw/pyfftw.pyx":267
- *     executors[2] = <fftw_generic_execute>&_fftwl_execute_dft
- *     executors[3] = <fftw_generic_execute>&_fftw_execute_dft_r2c
- *     executors[4] = <fftw_generic_execute>&_fftwf_execute_dft_r2c             # <<<<<<<<<<<<<<
- *     executors[5] = <fftw_generic_execute>&_fftwl_execute_dft_r2c
- *     executors[6] = <fftw_generic_execute>&_fftw_execute_dft_c2r
- */
-  (__pyx_v_6pyfftw_6pyfftw_executors[4]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft_r2c));
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("pyfftw.pyfftw.ones_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_array);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":268
- *     executors[3] = <fftw_generic_execute>&_fftw_execute_dft_r2c
- *     executors[4] = <fftw_generic_execute>&_fftwf_execute_dft_r2c
- *     executors[5] = <fftw_generic_execute>&_fftwl_execute_dft_r2c             # <<<<<<<<<<<<<<
- *     executors[6] = <fftw_generic_execute>&_fftw_execute_dft_c2r
- *     executors[7] = <fftw_generic_execute>&_fftwf_execute_dft_c2r
- */
-  (__pyx_v_6pyfftw_6pyfftw_executors[5]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft_r2c));
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_15ones_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_14ones_aligned[] = "ones_aligned(shape, dtype='float64', order='C', n=None)\n\n    Function that returns a numpy array of ones that is n-byte aligned,\n    where ``n`` is determined by inspecting the CPU if it is not\n    provided.\n\n    The alignment is given by the final optional argument, ``n``. If\n    ``n`` is not provided then this function will inspect the CPU to\n    determine alignment. The rest of the arguments are as per\n    :func:`numpy [...]
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_15ones_aligned(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_shape = 0;
+  PyObject *__pyx_v_dtype = 0;
+  PyObject *__pyx_v_order = 0;
+  PyObject *__pyx_v_n = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("ones_aligned (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_shape,&__pyx_n_s_dtype,&__pyx_n_s_order,&__pyx_n_s_n,0};
+    PyObject* values[4] = {0,0,0,0};
+    values[1] = ((PyObject *)__pyx_n_s_float64);
+    values[2] = ((PyObject *)__pyx_n_s_C);
+    values[3] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_shape)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_dtype);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_order);
+          if (value) { values[2] = value; kw_args--; }
+        }
+        case  3:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_n);
+          if (value) { values[3] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "ones_aligned") < 0)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_shape = values[0];
+    __pyx_v_dtype = values[1];
+    __pyx_v_order = values[2];
+    __pyx_v_n = values[3];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("ones_aligned", 0, 1, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[1]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pyfftw.pyfftw.ones_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_14ones_aligned(__pyx_self, __pyx_v_shape, __pyx_v_dtype, __pyx_v_order, __pyx_v_n);
 
-  /* "pyfftw/pyfftw.pyx":269
- *     executors[4] = <fftw_generic_execute>&_fftwf_execute_dft_r2c
- *     executors[5] = <fftw_generic_execute>&_fftwl_execute_dft_r2c
- *     executors[6] = <fftw_generic_execute>&_fftw_execute_dft_c2r             # <<<<<<<<<<<<<<
- *     executors[7] = <fftw_generic_execute>&_fftwf_execute_dft_c2r
- *     executors[8] = <fftw_generic_execute>&_fftwl_execute_dft_c2r
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_14ones_aligned(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_shape, PyObject *__pyx_v_dtype, PyObject *__pyx_v_order, PyObject *__pyx_v_n) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  struct __pyx_opt_args_6pyfftw_6pyfftw_ones_aligned __pyx_t_2;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("ones_aligned", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_2.__pyx_n = 3;
+  __pyx_t_2.dtype = __pyx_v_dtype;
+  __pyx_t_2.order = __pyx_v_order;
+  __pyx_t_2.n = __pyx_v_n;
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_ones_aligned(__pyx_v_shape, 0, &__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.ones_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":85
+ * #
+ * # Complex double precision
+ * cdef void* _fftw_plan_guru_dft(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-  (__pyx_v_6pyfftw_6pyfftw_executors[6]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftw_execute_dft_c2r));
 
-  /* "pyfftw/pyfftw.pyx":270
- *     executors[5] = <fftw_generic_execute>&_fftwl_execute_dft_r2c
- *     executors[6] = <fftw_generic_execute>&_fftw_execute_dft_c2r
- *     executors[7] = <fftw_generic_execute>&_fftwf_execute_dft_c2r             # <<<<<<<<<<<<<<
- *     executors[8] = <fftw_generic_execute>&_fftwl_execute_dft_c2r
+static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, int __pyx_v_sign, unsigned int __pyx_v_flags) {
+  void *__pyx_r;
+
+  /* "pyfftw/pyfftw.pyx":91
+ *             int sign, unsigned flags) nogil:
  * 
+ *     return <void *>fftw_plan_guru_dft(rank, dims,             # <<<<<<<<<<<<<<
+ *             howmany_rank, howmany_dims,
+ *             <cdouble *>_in, <cdouble *>_out,
  */
-  (__pyx_v_6pyfftw_6pyfftw_executors[7]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft_c2r));
+  __pyx_r = ((void *)fftw_plan_guru_dft(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((cdouble *)__pyx_v__in), ((cdouble *)__pyx_v__out), __pyx_v_sign, __pyx_v_flags));
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":271
- *     executors[6] = <fftw_generic_execute>&_fftw_execute_dft_c2r
- *     executors[7] = <fftw_generic_execute>&_fftwf_execute_dft_c2r
- *     executors[8] = <fftw_generic_execute>&_fftwl_execute_dft_c2r             # <<<<<<<<<<<<<<
- * 
- * # Destroyer table (of size the number of destroyers)
+  /* "pyfftw/pyfftw.pyx":85
+ * #
+ * # Complex double precision
+ * cdef void* _fftw_plan_guru_dft(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-  (__pyx_v_6pyfftw_6pyfftw_executors[8]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft_c2r));
 
-  __pyx_r = 0;
-  __Pyx_RefNannyFinishContext();
+  /* function exit code */
+  __pyx_L0:;
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":276
- * cdef fftw_generic_destroy_plan destroyers[3]
- * 
- * cdef fftw_generic_destroy_plan * _build_destroyer_list():             # <<<<<<<<<<<<<<
+/* "pyfftw/pyfftw.pyx":97
  * 
- *     destroyers[0] = <fftw_generic_destroy_plan>&_fftw_destroy_plan
+ * # Complex single precision
+ * cdef void* _fftwf_plan_guru_dft(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
 
-static __pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan *__pyx_f_6pyfftw_6pyfftw__build_destroyer_list(void) {
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan *__pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_build_destroyer_list", 0);
-
-  /* "pyfftw/pyfftw.pyx":278
- * cdef fftw_generic_destroy_plan * _build_destroyer_list():
- * 
- *     destroyers[0] = <fftw_generic_destroy_plan>&_fftw_destroy_plan             # <<<<<<<<<<<<<<
- *     destroyers[1] = <fftw_generic_destroy_plan>&_fftwf_destroy_plan
- *     destroyers[2] = <fftw_generic_destroy_plan>&_fftwl_destroy_plan
- */
-  (__pyx_v_6pyfftw_6pyfftw_destroyers[0]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan)(&__pyx_f_6pyfftw_6pyfftw__fftw_destroy_plan));
+static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, int __pyx_v_sign, unsigned int __pyx_v_flags) {
+  void *__pyx_r;
 
-  /* "pyfftw/pyfftw.pyx":279
- * 
- *     destroyers[0] = <fftw_generic_destroy_plan>&_fftw_destroy_plan
- *     destroyers[1] = <fftw_generic_destroy_plan>&_fftwf_destroy_plan             # <<<<<<<<<<<<<<
- *     destroyers[2] = <fftw_generic_destroy_plan>&_fftwl_destroy_plan
+  /* "pyfftw/pyfftw.pyx":103
+ *             int sign, unsigned flags) nogil:
  * 
+ *     return <void *>fftwf_plan_guru_dft(rank, dims,             # <<<<<<<<<<<<<<
+ *             howmany_rank, howmany_dims,
+ *             <cfloat *>_in, <cfloat *>_out,
  */
-  (__pyx_v_6pyfftw_6pyfftw_destroyers[1]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan)(&__pyx_f_6pyfftw_6pyfftw__fftwf_destroy_plan));
+  __pyx_r = ((void *)fftwf_plan_guru_dft(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((cfloat *)__pyx_v__in), ((cfloat *)__pyx_v__out), __pyx_v_sign, __pyx_v_flags));
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":280
- *     destroyers[0] = <fftw_generic_destroy_plan>&_fftw_destroy_plan
- *     destroyers[1] = <fftw_generic_destroy_plan>&_fftwf_destroy_plan
- *     destroyers[2] = <fftw_generic_destroy_plan>&_fftwl_destroy_plan             # <<<<<<<<<<<<<<
- * 
+  /* "pyfftw/pyfftw.pyx":97
  * 
+ * # Complex single precision
+ * cdef void* _fftwf_plan_guru_dft(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-  (__pyx_v_6pyfftw_6pyfftw_destroyers[2]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan)(&__pyx_f_6pyfftw_6pyfftw__fftwl_destroy_plan));
 
-  __pyx_r = 0;
-  __Pyx_RefNannyFinishContext();
+  /* function exit code */
+  __pyx_L0:;
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":286
- * cdef fftw_generic_plan_with_nthreads nthreads_plan_setters[3]
+/* "pyfftw/pyfftw.pyx":109
  * 
- * cdef fftw_generic_plan_with_nthreads * _build_nthreads_plan_setters_list():             # <<<<<<<<<<<<<<
- *     nthreads_plan_setters[0] = (
- *             <fftw_generic_plan_with_nthreads>&fftw_plan_with_nthreads)
+ * # Complex long double precision
+ * cdef void* _fftwl_plan_guru_dft(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
 
-static __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads *__pyx_f_6pyfftw_6pyfftw__build_nthreads_plan_setters_list(void) {
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads *__pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_build_nthreads_plan_setters_list", 0);
+static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, int __pyx_v_sign, unsigned int __pyx_v_flags) {
+  void *__pyx_r;
 
-  /* "pyfftw/pyfftw.pyx":287
+  /* "pyfftw/pyfftw.pyx":115
+ *             int sign, unsigned flags) nogil:
  * 
- * cdef fftw_generic_plan_with_nthreads * _build_nthreads_plan_setters_list():
- *     nthreads_plan_setters[0] = (             # <<<<<<<<<<<<<<
- *             <fftw_generic_plan_with_nthreads>&fftw_plan_with_nthreads)
- *     nthreads_plan_setters[1] = (
- */
-  (__pyx_v_6pyfftw_6pyfftw_nthreads_plan_setters[0]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads)(&fftw_plan_with_nthreads));
-
-  /* "pyfftw/pyfftw.pyx":289
- *     nthreads_plan_setters[0] = (
- *             <fftw_generic_plan_with_nthreads>&fftw_plan_with_nthreads)
- *     nthreads_plan_setters[1] = (             # <<<<<<<<<<<<<<
- *             <fftw_generic_plan_with_nthreads>&fftwf_plan_with_nthreads)
- *     nthreads_plan_setters[2] = (
+ *     return <void *>fftwl_plan_guru_dft(rank, dims,             # <<<<<<<<<<<<<<
+ *             howmany_rank, howmany_dims,
+ *             <clongdouble *>_in, <clongdouble *>_out,
  */
-  (__pyx_v_6pyfftw_6pyfftw_nthreads_plan_setters[1]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads)(&fftwf_plan_with_nthreads));
+  __pyx_r = ((void *)fftwl_plan_guru_dft(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((clongdouble *)__pyx_v__in), ((clongdouble *)__pyx_v__out), __pyx_v_sign, __pyx_v_flags));
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":291
- *     nthreads_plan_setters[1] = (
- *             <fftw_generic_plan_with_nthreads>&fftwf_plan_with_nthreads)
- *     nthreads_plan_setters[2] = (             # <<<<<<<<<<<<<<
- *             <fftw_generic_plan_with_nthreads>&fftwl_plan_with_nthreads)
+  /* "pyfftw/pyfftw.pyx":109
  * 
+ * # Complex long double precision
+ * cdef void* _fftwl_plan_guru_dft(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-  (__pyx_v_6pyfftw_6pyfftw_nthreads_plan_setters[2]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads)(&fftwl_plan_with_nthreads));
 
-  __pyx_r = 0;
-  __Pyx_RefNannyFinishContext();
+  /* function exit code */
+  __pyx_L0:;
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":297
- * cdef fftw_generic_set_timelimit set_timelimit_funcs[3]
+/* "pyfftw/pyfftw.pyx":121
  * 
- * cdef fftw_generic_set_timelimit * _build_set_timelimit_funcs_list():             # <<<<<<<<<<<<<<
- *     set_timelimit_funcs[0] = (
- *             <fftw_generic_set_timelimit>&fftw_set_timelimit)
+ * # real to complex double precision
+ * cdef void* _fftw_plan_guru_dft_r2c(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
 
-static __pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit *__pyx_f_6pyfftw_6pyfftw__build_set_timelimit_funcs_list(void) {
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit *__pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_build_set_timelimit_funcs_list", 0);
+static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_r2c(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, unsigned int __pyx_v_flags) {
+  void *__pyx_r;
 
-  /* "pyfftw/pyfftw.pyx":298
+  /* "pyfftw/pyfftw.pyx":127
+ *             int sign, unsigned flags) nogil:
  * 
- * cdef fftw_generic_set_timelimit * _build_set_timelimit_funcs_list():
- *     set_timelimit_funcs[0] = (             # <<<<<<<<<<<<<<
- *             <fftw_generic_set_timelimit>&fftw_set_timelimit)
- *     set_timelimit_funcs[1] = (
- */
-  (__pyx_v_6pyfftw_6pyfftw_set_timelimit_funcs[0]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit)(&fftw_set_timelimit));
-
-  /* "pyfftw/pyfftw.pyx":300
- *     set_timelimit_funcs[0] = (
- *             <fftw_generic_set_timelimit>&fftw_set_timelimit)
- *     set_timelimit_funcs[1] = (             # <<<<<<<<<<<<<<
- *             <fftw_generic_set_timelimit>&fftwf_set_timelimit)
- *     set_timelimit_funcs[2] = (
+ *     return <void *>fftw_plan_guru_dft_r2c(rank, dims,             # <<<<<<<<<<<<<<
+ *             howmany_rank, howmany_dims,
+ *             <double *>_in, <cdouble *>_out,
  */
-  (__pyx_v_6pyfftw_6pyfftw_set_timelimit_funcs[1]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit)(&fftwf_set_timelimit));
+  __pyx_r = ((void *)fftw_plan_guru_dft_r2c(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((double *)__pyx_v__in), ((cdouble *)__pyx_v__out), __pyx_v_flags));
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":302
- *     set_timelimit_funcs[1] = (
- *             <fftw_generic_set_timelimit>&fftwf_set_timelimit)
- *     set_timelimit_funcs[2] = (             # <<<<<<<<<<<<<<
- *             <fftw_generic_set_timelimit>&fftwl_set_timelimit)
+  /* "pyfftw/pyfftw.pyx":121
  * 
+ * # real to complex double precision
+ * cdef void* _fftw_plan_guru_dft_r2c(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-  (__pyx_v_6pyfftw_6pyfftw_set_timelimit_funcs[2]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit)(&fftwl_set_timelimit));
 
-  __pyx_r = 0;
-  __Pyx_RefNannyFinishContext();
+  /* function exit code */
+  __pyx_L0:;
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":309
- * cdef validator validators[2]
+/* "pyfftw/pyfftw.pyx":133
  * 
- * cdef validator * _build_validators_list():             # <<<<<<<<<<<<<<
- *     validators[0] = &_validate_r2c_arrays
- *     validators[1] = &_validate_c2r_arrays
+ * # real to complex single precision
+ * cdef void* _fftwf_plan_guru_dft_r2c(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
 
-static __pyx_t_6pyfftw_6pyfftw_validator *__pyx_f_6pyfftw_6pyfftw__build_validators_list(void) {
-  __pyx_t_6pyfftw_6pyfftw_validator *__pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_build_validators_list", 0);
+static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_r2c(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, unsigned int __pyx_v_flags) {
+  void *__pyx_r;
 
-  /* "pyfftw/pyfftw.pyx":310
- * 
- * cdef validator * _build_validators_list():
- *     validators[0] = &_validate_r2c_arrays             # <<<<<<<<<<<<<<
- *     validators[1] = &_validate_c2r_arrays
+  /* "pyfftw/pyfftw.pyx":139
+ *             int sign, unsigned flags) nogil:
  * 
+ *     return <void *>fftwf_plan_guru_dft_r2c(rank, dims,             # <<<<<<<<<<<<<<
+ *             howmany_rank, howmany_dims,
+ *             <float *>_in, <cfloat *>_out,
  */
-  (__pyx_v_6pyfftw_6pyfftw_validators[0]) = (&__pyx_f_6pyfftw_6pyfftw__validate_r2c_arrays);
+  __pyx_r = ((void *)fftwf_plan_guru_dft_r2c(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((float *)__pyx_v__in), ((cfloat *)__pyx_v__out), __pyx_v_flags));
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":311
- * cdef validator * _build_validators_list():
- *     validators[0] = &_validate_r2c_arrays
- *     validators[1] = &_validate_c2r_arrays             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":133
  * 
- * # Validator functions
+ * # real to complex single precision
+ * cdef void* _fftwf_plan_guru_dft_r2c(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-  (__pyx_v_6pyfftw_6pyfftw_validators[1]) = (&__pyx_f_6pyfftw_6pyfftw__validate_c2r_arrays);
 
-  __pyx_r = 0;
-  __Pyx_RefNannyFinishContext();
+  /* function exit code */
+  __pyx_L0:;
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":315
- * # Validator functions
- * # ===================
- * cdef bint _validate_r2c_arrays(np.ndarray input_array,             # <<<<<<<<<<<<<<
- *         np.ndarray output_array, int64_t *axes, int64_t *not_axes,
- *         int64_t axes_length):
+/* "pyfftw/pyfftw.pyx":145
+ * 
+ * # real to complex long double precision
+ * cdef void* _fftwl_plan_guru_dft_r2c(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
 
-static int __pyx_f_6pyfftw_6pyfftw__validate_r2c_arrays(PyArrayObject *__pyx_v_input_array, PyArrayObject *__pyx_v_output_array, int64_t *__pyx_v_axes, int64_t *__pyx_v_not_axes, int64_t __pyx_v_axes_length) {
-  npy_intp *__pyx_v_in_shape;
-  npy_intp *__pyx_v_out_shape;
-  long __pyx_v_n;
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  npy_intp *__pyx_t_2;
-  long __pyx_t_3;
-  long __pyx_t_4;
-  int64_t __pyx_t_5;
-  __Pyx_RefNannySetupContext("_validate_r2c_arrays", 0);
+static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_r2c(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, unsigned int __pyx_v_flags) {
+  void *__pyx_r;
 
-  /* "pyfftw/pyfftw.pyx":323
- *     # We firstly need to confirm that the dimenions of the arrays
- *     # are the same
- *     if not (input_array.ndim == output_array.ndim):             # <<<<<<<<<<<<<<
- *         return False
+  /* "pyfftw/pyfftw.pyx":151
+ *             int sign, unsigned flags) nogil:
  * 
+ *     return <void *>fftwl_plan_guru_dft_r2c(rank, dims,             # <<<<<<<<<<<<<<
+ *             howmany_rank, howmany_dims,
+ *             <long double *>_in, <clongdouble *>_out,
  */
-  __pyx_t_1 = (!(__pyx_v_input_array->nd == __pyx_v_output_array->nd));
-  if (__pyx_t_1) {
+  __pyx_r = ((void *)fftwl_plan_guru_dft_r2c(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((long double *)__pyx_v__in), ((clongdouble *)__pyx_v__out), __pyx_v_flags));
+  goto __pyx_L0;
 
-    /* "pyfftw/pyfftw.pyx":324
- *     # are the same
- *     if not (input_array.ndim == output_array.ndim):
- *         return False             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":145
  * 
- *     in_shape = input_array.shape
+ * # real to complex long double precision
+ * cdef void* _fftwl_plan_guru_dft_r2c(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-    __pyx_r = 0;
-    goto __pyx_L0;
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
 
-  /* "pyfftw/pyfftw.pyx":326
- *         return False
- * 
- *     in_shape = input_array.shape             # <<<<<<<<<<<<<<
- *     out_shape = output_array.shape
+  /* function exit code */
+  __pyx_L0:;
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":157
  * 
+ * # complex to real double precision
+ * cdef void* _fftw_plan_guru_dft_c2r(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-  __pyx_t_2 = __pyx_v_input_array->dimensions;
-  __pyx_v_in_shape = __pyx_t_2;
 
-  /* "pyfftw/pyfftw.pyx":327
- * 
- *     in_shape = input_array.shape
- *     out_shape = output_array.shape             # <<<<<<<<<<<<<<
+static void *__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_c2r(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, unsigned int __pyx_v_flags) {
+  void *__pyx_r;
+
+  /* "pyfftw/pyfftw.pyx":163
+ *             int sign, unsigned flags) nogil:
  * 
- *     for n in range(axes_length - 1):
+ *     return <void *>fftw_plan_guru_dft_c2r(rank, dims,             # <<<<<<<<<<<<<<
+ *             howmany_rank, howmany_dims,
+ *             <cdouble *>_in, <double *>_out,
  */
-  __pyx_t_2 = __pyx_v_output_array->dimensions;
-  __pyx_v_out_shape = __pyx_t_2;
+  __pyx_r = ((void *)fftw_plan_guru_dft_c2r(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((cdouble *)__pyx_v__in), ((double *)__pyx_v__out), __pyx_v_flags));
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":329
- *     out_shape = output_array.shape
+  /* "pyfftw/pyfftw.pyx":157
  * 
- *     for n in range(axes_length - 1):             # <<<<<<<<<<<<<<
- *         if not out_shape[axes[n]] == in_shape[axes[n]]:
- *             return False
+ * # complex to real double precision
+ * cdef void* _fftw_plan_guru_dft_c2r(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-  __pyx_t_3 = (__pyx_v_axes_length - 1);
-  for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
-    __pyx_v_n = __pyx_t_4;
 
-    /* "pyfftw/pyfftw.pyx":330
- * 
- *     for n in range(axes_length - 1):
- *         if not out_shape[axes[n]] == in_shape[axes[n]]:             # <<<<<<<<<<<<<<
- *             return False
+  /* function exit code */
+  __pyx_L0:;
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":169
  * 
+ * # complex to real single precision
+ * cdef void* _fftwf_plan_guru_dft_c2r(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-    __pyx_t_1 = (!((__pyx_v_out_shape[(__pyx_v_axes[__pyx_v_n])]) == (__pyx_v_in_shape[(__pyx_v_axes[__pyx_v_n])])));
-    if (__pyx_t_1) {
 
-      /* "pyfftw/pyfftw.pyx":331
- *     for n in range(axes_length - 1):
- *         if not out_shape[axes[n]] == in_shape[axes[n]]:
- *             return False             # <<<<<<<<<<<<<<
+static void *__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_c2r(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, unsigned int __pyx_v_flags) {
+  void *__pyx_r;
+
+  /* "pyfftw/pyfftw.pyx":175
+ *             int sign, unsigned flags) nogil:
  * 
- *     # The critical axis is the last of those over which the
+ *     return <void *>fftwf_plan_guru_dft_c2r(rank, dims,             # <<<<<<<<<<<<<<
+ *             howmany_rank, howmany_dims,
+ *             <cfloat *>_in, <float *>_out,
  */
-      __pyx_r = 0;
-      goto __pyx_L0;
-      goto __pyx_L6;
-    }
-    __pyx_L6:;
-  }
+  __pyx_r = ((void *)fftwf_plan_guru_dft_c2r(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((cfloat *)__pyx_v__in), ((float *)__pyx_v__out), __pyx_v_flags));
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":336
- *     # FFT is taken.
- *     if not (out_shape[axes[axes_length-1]]
- *             == in_shape[axes[axes_length-1]]//2 + 1):             # <<<<<<<<<<<<<<
- *         return False
+  /* "pyfftw/pyfftw.pyx":169
  * 
+ * # complex to real single precision
+ * cdef void* _fftwf_plan_guru_dft_c2r(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-  __pyx_t_1 = (!((__pyx_v_out_shape[(__pyx_v_axes[(__pyx_v_axes_length - 1)])]) == (__Pyx_div_long((__pyx_v_in_shape[(__pyx_v_axes[(__pyx_v_axes_length - 1)])]), 2) + 1)));
-  if (__pyx_t_1) {
 
-    /* "pyfftw/pyfftw.pyx":337
- *     if not (out_shape[axes[axes_length-1]]
- *             == in_shape[axes[axes_length-1]]//2 + 1):
- *         return False             # <<<<<<<<<<<<<<
+  /* function exit code */
+  __pyx_L0:;
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":181
  * 
- *     for n in range(input_array.ndim - axes_length):
+ * # complex to real long double precision
+ * cdef void* _fftwl_plan_guru_dft_c2r(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-    __pyx_r = 0;
-    goto __pyx_L0;
-    goto __pyx_L7;
-  }
-  __pyx_L7:;
 
-  /* "pyfftw/pyfftw.pyx":339
- *         return False
+static void *__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_c2r(int __pyx_v_rank, fftw_iodim *__pyx_v_dims, int __pyx_v_howmany_rank, fftw_iodim *__pyx_v_howmany_dims, void *__pyx_v__in, void *__pyx_v__out, CYTHON_UNUSED int __pyx_v_sign, unsigned int __pyx_v_flags) {
+  void *__pyx_r;
+
+  /* "pyfftw/pyfftw.pyx":187
+ *             int sign, unsigned flags) nogil:
  * 
- *     for n in range(input_array.ndim - axes_length):             # <<<<<<<<<<<<<<
- *         if not out_shape[not_axes[n]] == in_shape[not_axes[n]]:
- *             return False
+ *     return <void *>fftwl_plan_guru_dft_c2r(rank, dims,             # <<<<<<<<<<<<<<
+ *             howmany_rank, howmany_dims,
+ *             <clongdouble *>_in, <long double *>_out,
  */
-  __pyx_t_5 = (__pyx_v_input_array->nd - __pyx_v_axes_length);
-  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
-    __pyx_v_n = __pyx_t_3;
+  __pyx_r = ((void *)fftwl_plan_guru_dft_c2r(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, ((clongdouble *)__pyx_v__in), ((long double *)__pyx_v__out), __pyx_v_flags));
+  goto __pyx_L0;
 
-    /* "pyfftw/pyfftw.pyx":340
- * 
- *     for n in range(input_array.ndim - axes_length):
- *         if not out_shape[not_axes[n]] == in_shape[not_axes[n]]:             # <<<<<<<<<<<<<<
- *             return False
+  /* "pyfftw/pyfftw.pyx":181
  * 
+ * # complex to real long double precision
+ * cdef void* _fftwl_plan_guru_dft_c2r(             # <<<<<<<<<<<<<<
+ *             int rank, fftw_iodim *dims,
+ *             int howmany_rank, fftw_iodim *howmany_dims,
  */
-    __pyx_t_1 = (!((__pyx_v_out_shape[(__pyx_v_not_axes[__pyx_v_n])]) == (__pyx_v_in_shape[(__pyx_v_not_axes[__pyx_v_n])])));
-    if (__pyx_t_1) {
 
-      /* "pyfftw/pyfftw.pyx":341
- *     for n in range(input_array.ndim - axes_length):
- *         if not out_shape[not_axes[n]] == in_shape[not_axes[n]]:
- *             return False             # <<<<<<<<<<<<<<
+  /* function exit code */
+  __pyx_L0:;
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":196
+ * #
+ * # Complex double precision
+ * cdef void _fftw_execute_dft(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
  * 
- *     return True
+ *     fftw_execute_dft(<fftw_plan>_plan,
  */
-      __pyx_r = 0;
-      goto __pyx_L0;
-      goto __pyx_L10;
-    }
-    __pyx_L10:;
-  }
 
-  /* "pyfftw/pyfftw.pyx":343
- *             return False
+static void __pyx_f_6pyfftw_6pyfftw__fftw_execute_dft(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
+
+  /* "pyfftw/pyfftw.pyx":198
+ * cdef void _fftw_execute_dft(void *_plan, void *_in, void *_out) nogil:
  * 
- *     return True             # <<<<<<<<<<<<<<
+ *     fftw_execute_dft(<fftw_plan>_plan,             # <<<<<<<<<<<<<<
+ *             <cdouble *>_in, <cdouble *>_out)
  * 
+ */
+  fftw_execute_dft(((fftw_plan)__pyx_v__plan), ((cdouble *)__pyx_v__in), ((cdouble *)__pyx_v__out));
+
+  /* "pyfftw/pyfftw.pyx":196
+ * #
+ * # Complex double precision
+ * cdef void _fftw_execute_dft(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
  * 
+ *     fftw_execute_dft(<fftw_plan>_plan,
  */
-  __pyx_r = 1;
-  goto __pyx_L0;
 
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
+  /* function exit code */
 }
 
-/* "pyfftw/pyfftw.pyx":346
+/* "pyfftw/pyfftw.pyx":202
  * 
+ * # Complex single precision
+ * cdef void _fftwf_execute_dft(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
  * 
- * cdef bint _validate_c2r_arrays(np.ndarray input_array,             # <<<<<<<<<<<<<<
- *         np.ndarray output_array, int64_t *axes, int64_t *not_axes,
- *         int64_t axes_length):
+ *     fftwf_execute_dft(<fftwf_plan>_plan,
  */
 
-static int __pyx_f_6pyfftw_6pyfftw__validate_c2r_arrays(PyArrayObject *__pyx_v_input_array, PyArrayObject *__pyx_v_output_array, int64_t *__pyx_v_axes, int64_t *__pyx_v_not_axes, int64_t __pyx_v_axes_length) {
-  npy_intp *__pyx_v_in_shape;
-  npy_intp *__pyx_v_out_shape;
-  long __pyx_v_n;
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  npy_intp *__pyx_t_2;
-  long __pyx_t_3;
-  long __pyx_t_4;
-  int64_t __pyx_t_5;
-  __Pyx_RefNannySetupContext("_validate_c2r_arrays", 0);
+static void __pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
 
-  /* "pyfftw/pyfftw.pyx":355
- *     # We firstly need to confirm that the dimenions of the arrays
- *     # are the same
- *     if not (input_array.ndim == output_array.ndim):             # <<<<<<<<<<<<<<
- *         return False
+  /* "pyfftw/pyfftw.pyx":204
+ * cdef void _fftwf_execute_dft(void *_plan, void *_in, void *_out) nogil:
+ * 
+ *     fftwf_execute_dft(<fftwf_plan>_plan,             # <<<<<<<<<<<<<<
+ *             <cfloat *>_in, <cfloat *>_out)
  * 
  */
-  __pyx_t_1 = (!(__pyx_v_input_array->nd == __pyx_v_output_array->nd));
-  if (__pyx_t_1) {
+  fftwf_execute_dft(((fftwf_plan)__pyx_v__plan), ((cfloat *)__pyx_v__in), ((cfloat *)__pyx_v__out));
 
-    /* "pyfftw/pyfftw.pyx":356
- *     # are the same
- *     if not (input_array.ndim == output_array.ndim):
- *         return False             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":202
  * 
- *     in_shape = input_array.shape
+ * # Complex single precision
+ * cdef void _fftwf_execute_dft(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ * 
+ *     fftwf_execute_dft(<fftwf_plan>_plan,
  */
-    __pyx_r = 0;
-    goto __pyx_L0;
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
 
-  /* "pyfftw/pyfftw.pyx":358
- *         return False
+  /* function exit code */
+}
+
+/* "pyfftw/pyfftw.pyx":208
  * 
- *     in_shape = input_array.shape             # <<<<<<<<<<<<<<
- *     out_shape = output_array.shape
+ * # Complex long double precision
+ * cdef void _fftwl_execute_dft(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
  * 
+ *     fftwl_execute_dft(<fftwl_plan>_plan,
  */
-  __pyx_t_2 = __pyx_v_input_array->dimensions;
-  __pyx_v_in_shape = __pyx_t_2;
 
-  /* "pyfftw/pyfftw.pyx":359
+static void __pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
+
+  /* "pyfftw/pyfftw.pyx":210
+ * cdef void _fftwl_execute_dft(void *_plan, void *_in, void *_out) nogil:
  * 
- *     in_shape = input_array.shape
- *     out_shape = output_array.shape             # <<<<<<<<<<<<<<
+ *     fftwl_execute_dft(<fftwl_plan>_plan,             # <<<<<<<<<<<<<<
+ *             <clongdouble *>_in, <clongdouble *>_out)
  * 
- *     for n in range(axes_length - 1):
  */
-  __pyx_t_2 = __pyx_v_output_array->dimensions;
-  __pyx_v_out_shape = __pyx_t_2;
+  fftwl_execute_dft(((fftwl_plan)__pyx_v__plan), ((clongdouble *)__pyx_v__in), ((clongdouble *)__pyx_v__out));
 
-  /* "pyfftw/pyfftw.pyx":361
- *     out_shape = output_array.shape
+  /* "pyfftw/pyfftw.pyx":208
  * 
- *     for n in range(axes_length - 1):             # <<<<<<<<<<<<<<
- *         if not in_shape[axes[n]] == out_shape[axes[n]]:
- *             return False
+ * # Complex long double precision
+ * cdef void _fftwl_execute_dft(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ * 
+ *     fftwl_execute_dft(<fftwl_plan>_plan,
  */
-  __pyx_t_3 = (__pyx_v_axes_length - 1);
-  for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
-    __pyx_v_n = __pyx_t_4;
 
-    /* "pyfftw/pyfftw.pyx":362
+  /* function exit code */
+}
+
+/* "pyfftw/pyfftw.pyx":214
  * 
- *     for n in range(axes_length - 1):
- *         if not in_shape[axes[n]] == out_shape[axes[n]]:             # <<<<<<<<<<<<<<
- *             return False
+ * # real to complex double precision
+ * cdef void _fftw_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
  * 
+ *     fftw_execute_dft_r2c(<fftw_plan>_plan,
  */
-    __pyx_t_1 = (!((__pyx_v_in_shape[(__pyx_v_axes[__pyx_v_n])]) == (__pyx_v_out_shape[(__pyx_v_axes[__pyx_v_n])])));
-    if (__pyx_t_1) {
 
-      /* "pyfftw/pyfftw.pyx":363
- *     for n in range(axes_length - 1):
- *         if not in_shape[axes[n]] == out_shape[axes[n]]:
- *             return False             # <<<<<<<<<<<<<<
+static void __pyx_f_6pyfftw_6pyfftw__fftw_execute_dft_r2c(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
+
+  /* "pyfftw/pyfftw.pyx":216
+ * cdef void _fftw_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:
+ * 
+ *     fftw_execute_dft_r2c(<fftw_plan>_plan,             # <<<<<<<<<<<<<<
+ *             <double *>_in, <cdouble *>_out)
  * 
- *     # The critical axis is the last of those over which the
  */
-      __pyx_r = 0;
-      goto __pyx_L0;
-      goto __pyx_L6;
-    }
-    __pyx_L6:;
-  }
+  fftw_execute_dft_r2c(((fftw_plan)__pyx_v__plan), ((double *)__pyx_v__in), ((cdouble *)__pyx_v__out));
 
-  /* "pyfftw/pyfftw.pyx":368
- *     # FFT is taken.
- *     if not (in_shape[axes[axes_length-1]]
- *             == out_shape[axes[axes_length-1]]//2 + 1):             # <<<<<<<<<<<<<<
- *         return False
+  /* "pyfftw/pyfftw.pyx":214
  * 
+ * # real to complex double precision
+ * cdef void _fftw_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ * 
+ *     fftw_execute_dft_r2c(<fftw_plan>_plan,
  */
-  __pyx_t_1 = (!((__pyx_v_in_shape[(__pyx_v_axes[(__pyx_v_axes_length - 1)])]) == (__Pyx_div_long((__pyx_v_out_shape[(__pyx_v_axes[(__pyx_v_axes_length - 1)])]), 2) + 1)));
-  if (__pyx_t_1) {
 
-    /* "pyfftw/pyfftw.pyx":369
- *     if not (in_shape[axes[axes_length-1]]
- *             == out_shape[axes[axes_length-1]]//2 + 1):
- *         return False             # <<<<<<<<<<<<<<
+  /* function exit code */
+}
+
+/* "pyfftw/pyfftw.pyx":220
  * 
- *     for n in range(input_array.ndim - axes_length):
+ * # real to complex single precision
+ * cdef void _fftwf_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ * 
+ *     fftwf_execute_dft_r2c(<fftwf_plan>_plan,
  */
-    __pyx_r = 0;
-    goto __pyx_L0;
-    goto __pyx_L7;
-  }
-  __pyx_L7:;
 
-  /* "pyfftw/pyfftw.pyx":371
- *         return False
+static void __pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft_r2c(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
+
+  /* "pyfftw/pyfftw.pyx":222
+ * cdef void _fftwf_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:
+ * 
+ *     fftwf_execute_dft_r2c(<fftwf_plan>_plan,             # <<<<<<<<<<<<<<
+ *             <float *>_in, <cfloat *>_out)
  * 
- *     for n in range(input_array.ndim - axes_length):             # <<<<<<<<<<<<<<
- *         if not in_shape[not_axes[n]] == out_shape[not_axes[n]]:
- *             return False
  */
-  __pyx_t_5 = (__pyx_v_input_array->nd - __pyx_v_axes_length);
-  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_5; __pyx_t_3+=1) {
-    __pyx_v_n = __pyx_t_3;
+  fftwf_execute_dft_r2c(((fftwf_plan)__pyx_v__plan), ((float *)__pyx_v__in), ((cfloat *)__pyx_v__out));
 
-    /* "pyfftw/pyfftw.pyx":372
+  /* "pyfftw/pyfftw.pyx":220
  * 
- *     for n in range(input_array.ndim - axes_length):
- *         if not in_shape[not_axes[n]] == out_shape[not_axes[n]]:             # <<<<<<<<<<<<<<
- *             return False
+ * # real to complex single precision
+ * cdef void _fftwf_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
  * 
+ *     fftwf_execute_dft_r2c(<fftwf_plan>_plan,
  */
-    __pyx_t_1 = (!((__pyx_v_in_shape[(__pyx_v_not_axes[__pyx_v_n])]) == (__pyx_v_out_shape[(__pyx_v_not_axes[__pyx_v_n])])));
-    if (__pyx_t_1) {
 
-      /* "pyfftw/pyfftw.pyx":373
- *     for n in range(input_array.ndim - axes_length):
- *         if not in_shape[not_axes[n]] == out_shape[not_axes[n]]:
- *             return False             # <<<<<<<<<<<<<<
+  /* function exit code */
+}
+
+/* "pyfftw/pyfftw.pyx":226
  * 
- *     return True
+ * # real to complex long double precision
+ * cdef void _fftwl_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ * 
+ *     fftwl_execute_dft_r2c(<fftwl_plan>_plan,
  */
-      __pyx_r = 0;
-      goto __pyx_L0;
-      goto __pyx_L10;
-    }
-    __pyx_L10:;
-  }
 
-  /* "pyfftw/pyfftw.pyx":375
- *             return False
- * 
- *     return True             # <<<<<<<<<<<<<<
+static void __pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft_r2c(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
+
+  /* "pyfftw/pyfftw.pyx":228
+ * cdef void _fftwl_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:
  * 
+ *     fftwl_execute_dft_r2c(<fftwl_plan>_plan,             # <<<<<<<<<<<<<<
+ *             <long double *>_in, <clongdouble *>_out)
  * 
  */
-  __pyx_r = 1;
-  goto __pyx_L0;
+  fftwl_execute_dft_r2c(((fftwl_plan)__pyx_v__plan), ((long double *)__pyx_v__in), ((clongdouble *)__pyx_v__out));
 
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  /* "pyfftw/pyfftw.pyx":226
+ * 
+ * # real to complex long double precision
+ * cdef void _fftwl_execute_dft_r2c(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ * 
+ *     fftwl_execute_dft_r2c(<fftwl_plan>_plan,
+ */
 
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_7_lookup_shape_r2c_arrays(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_6pyfftw_6pyfftw_7_lookup_shape_r2c_arrays = {__Pyx_NAMESTR("_lookup_shape_r2c_arrays"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_7_lookup_shape_r2c_arrays, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_7_lookup_shape_r2c_arrays(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_input_array = 0;
-  CYTHON_UNUSED PyObject *__pyx_v_output_array = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_lookup_shape_r2c_arrays (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__input_array,&__pyx_n_s__output_array,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__input_array)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__output_array)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("_lookup_shape_r2c_arrays", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_lookup_shape_r2c_arrays") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_input_array = values[0];
-    __pyx_v_output_array = values[1];
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("_lookup_shape_r2c_arrays", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("pyfftw.pyfftw._lookup_shape_r2c_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_6_lookup_shape_r2c_arrays(__pyx_self, __pyx_v_input_array, __pyx_v_output_array);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
+  /* function exit code */
 }
 
-/* "pyfftw/pyfftw.pyx":380
- * # Shape lookup functions
- * # ======================
- * def _lookup_shape_r2c_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
- *     return input_array.shape
+/* "pyfftw/pyfftw.pyx":232
+ * 
+ * # complex to real double precision
+ * cdef void _fftw_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
  * 
+ *     fftw_execute_dft_c2r(<fftw_plan>_plan,
  */
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_6_lookup_shape_r2c_arrays(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_input_array, CYTHON_UNUSED PyObject *__pyx_v_output_array) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("_lookup_shape_r2c_arrays", 0);
+static void __pyx_f_6pyfftw_6pyfftw__fftw_execute_dft_c2r(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
 
-  /* "pyfftw/pyfftw.pyx":381
- * # ======================
- * def _lookup_shape_r2c_arrays(input_array, output_array):
- *     return input_array.shape             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":234
+ * cdef void _fftw_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:
+ * 
+ *     fftw_execute_dft_c2r(<fftw_plan>_plan,             # <<<<<<<<<<<<<<
+ *             <cdouble *>_in, <double *>_out)
  * 
- * def _lookup_shape_c2r_arrays(input_array, output_array):
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_input_array, __pyx_n_s__shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 381; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
+  fftw_execute_dft_c2r(((fftw_plan)__pyx_v__plan), ((cdouble *)__pyx_v__in), ((double *)__pyx_v__out));
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pyfftw.pyfftw._lookup_shape_r2c_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
+  /* "pyfftw/pyfftw.pyx":232
+ * 
+ * # complex to real double precision
+ * cdef void _fftw_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ * 
+ *     fftw_execute_dft_c2r(<fftw_plan>_plan,
+ */
+
+  /* function exit code */
 }
 
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_9_lookup_shape_c2r_arrays(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyMethodDef __pyx_mdef_6pyfftw_6pyfftw_9_lookup_shape_c2r_arrays = {__Pyx_NAMESTR("_lookup_shape_c2r_arrays"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_9_lookup_shape_c2r_arrays, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(0)};
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_9_lookup_shape_c2r_arrays(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  CYTHON_UNUSED PyObject *__pyx_v_input_array = 0;
-  PyObject *__pyx_v_output_array = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_lookup_shape_c2r_arrays (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__input_array,&__pyx_n_s__output_array,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__input_array)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__output_array)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("_lookup_shape_c2r_arrays", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_lookup_shape_c2r_arrays") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_input_array = values[0];
-    __pyx_v_output_array = values[1];
-  }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("_lookup_shape_c2r_arrays", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("pyfftw.pyfftw._lookup_shape_c2r_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_8_lookup_shape_c2r_arrays(__pyx_self, __pyx_v_input_array, __pyx_v_output_array);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pyfftw/pyfftw.pyx":383
- *     return input_array.shape
+/* "pyfftw/pyfftw.pyx":238
  * 
- * def _lookup_shape_c2r_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
- *     return output_array.shape
+ * # complex to real single precision
+ * cdef void _fftwf_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
  * 
+ *     fftwf_execute_dft_c2r(<fftwf_plan>_plan,
  */
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_8_lookup_shape_c2r_arrays(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("_lookup_shape_c2r_arrays", 0);
+static void __pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft_c2r(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
 
-  /* "pyfftw/pyfftw.pyx":384
+  /* "pyfftw/pyfftw.pyx":240
+ * cdef void _fftwf_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:
  * 
- * def _lookup_shape_c2r_arrays(input_array, output_array):
- *     return output_array.shape             # <<<<<<<<<<<<<<
+ *     fftwf_execute_dft_c2r(<fftwf_plan>_plan,             # <<<<<<<<<<<<<<
+ *             <cfloat *>_in, <float *>_out)
  * 
- * # fftw_schemes is a dictionary with a mapping from a keys,
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_output_array, __pyx_n_s__shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 384; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
+  fftwf_execute_dft_c2r(((fftwf_plan)__pyx_v__plan), ((cfloat *)__pyx_v__in), ((float *)__pyx_v__out));
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pyfftw.pyfftw._lookup_shape_c2r_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
+  /* "pyfftw/pyfftw.pyx":238
+ * 
+ * # complex to real single precision
+ * cdef void _fftwf_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ * 
+ *     fftwf_execute_dft_c2r(<fftwf_plan>_plan,
+ */
+
+  /* function exit code */
 }
 
-/* "pyfftw/pyfftw.pyx":490
+/* "pyfftw/pyfftw.pyx":244
  * 
- * # Set the cleanup routine
- * cdef void _cleanup():             # <<<<<<<<<<<<<<
- *     fftw_cleanup()
- *     fftwf_cleanup()
+ * # complex to real long double precision
+ * cdef void _fftwl_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ * 
+ *     fftwl_execute_dft_c2r(<fftwl_plan>_plan,
  */
 
-static void __pyx_f_6pyfftw_6pyfftw__cleanup(void) {
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_cleanup", 0);
+static void __pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft_c2r(void *__pyx_v__plan, void *__pyx_v__in, void *__pyx_v__out) {
 
-  /* "pyfftw/pyfftw.pyx":491
- * # Set the cleanup routine
- * cdef void _cleanup():
- *     fftw_cleanup()             # <<<<<<<<<<<<<<
- *     fftwf_cleanup()
- *     fftwl_cleanup()
+  /* "pyfftw/pyfftw.pyx":246
+ * cdef void _fftwl_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:
+ * 
+ *     fftwl_execute_dft_c2r(<fftwl_plan>_plan,             # <<<<<<<<<<<<<<
+ *             <clongdouble *>_in, <long double *>_out)
+ * 
  */
-  fftw_cleanup();
+  fftwl_execute_dft_c2r(((fftwl_plan)__pyx_v__plan), ((clongdouble *)__pyx_v__in), ((long double *)__pyx_v__out));
 
-  /* "pyfftw/pyfftw.pyx":492
- * cdef void _cleanup():
- *     fftw_cleanup()
- *     fftwf_cleanup()             # <<<<<<<<<<<<<<
- *     fftwl_cleanup()
- *     fftw_cleanup_threads()
+  /* "pyfftw/pyfftw.pyx":244
+ * 
+ * # complex to real long double precision
+ * cdef void _fftwl_execute_dft_c2r(void *_plan, void *_in, void *_out) nogil:             # <<<<<<<<<<<<<<
+ * 
+ *     fftwl_execute_dft_c2r(<fftwl_plan>_plan,
  */
-  fftwf_cleanup();
 
-  /* "pyfftw/pyfftw.pyx":493
- *     fftw_cleanup()
- *     fftwf_cleanup()
- *     fftwl_cleanup()             # <<<<<<<<<<<<<<
- *     fftw_cleanup_threads()
- *     fftwf_cleanup_threads()
- */
-  fftwl_cleanup();
+  /* function exit code */
+}
 
-  /* "pyfftw/pyfftw.pyx":494
- *     fftwf_cleanup()
- *     fftwl_cleanup()
- *     fftw_cleanup_threads()             # <<<<<<<<<<<<<<
- *     fftwf_cleanup_threads()
- *     fftwl_cleanup_threads()
+/* "pyfftw/pyfftw.pyx":253
+ * #
+ * # Double precision
+ * cdef void _fftw_destroy_plan(void *_plan):             # <<<<<<<<<<<<<<
+ * 
+ *     fftw_destroy_plan(<fftw_plan>_plan)
  */
-  fftw_cleanup_threads();
 
-  /* "pyfftw/pyfftw.pyx":495
- *     fftwl_cleanup()
- *     fftw_cleanup_threads()
- *     fftwf_cleanup_threads()             # <<<<<<<<<<<<<<
- *     fftwl_cleanup_threads()
+static void __pyx_f_6pyfftw_6pyfftw__fftw_destroy_plan(void *__pyx_v__plan) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fftw_destroy_plan", 0);
+
+  /* "pyfftw/pyfftw.pyx":255
+ * cdef void _fftw_destroy_plan(void *_plan):
+ * 
+ *     fftw_destroy_plan(<fftw_plan>_plan)             # <<<<<<<<<<<<<<
  * 
+ * # Single precision
  */
-  fftwf_cleanup_threads();
+  fftw_destroy_plan(((fftw_plan)__pyx_v__plan));
 
-  /* "pyfftw/pyfftw.pyx":496
- *     fftw_cleanup_threads()
- *     fftwf_cleanup_threads()
- *     fftwl_cleanup_threads()             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":253
+ * #
+ * # Double precision
+ * cdef void _fftw_destroy_plan(void *_plan):             # <<<<<<<<<<<<<<
  * 
- * Py_AtExit(_cleanup)
+ *     fftw_destroy_plan(<fftw_plan>_plan)
  */
-  fftwl_cleanup_threads();
 
+  /* function exit code */
   __Pyx_RefNannyFinishContext();
 }
 
-/* "pyfftw/pyfftw.pyx":501
+/* "pyfftw/pyfftw.pyx":258
  * 
- * # Helper functions
- * cdef void make_axes_unique(int64_t *axes, int64_t axes_length,             # <<<<<<<<<<<<<<
- *         int64_t **unique_axes, int64_t **not_axes, int64_t dimensions,
- *         int64_t *unique_axes_length):
+ * # Single precision
+ * cdef void _fftwf_destroy_plan(void *_plan):             # <<<<<<<<<<<<<<
+ * 
+ *     fftwf_destroy_plan(<fftwf_plan>_plan)
  */
 
-static void __pyx_f_6pyfftw_6pyfftw_make_axes_unique(int64_t *__pyx_v_axes, int64_t __pyx_v_axes_length, int64_t **__pyx_v_unique_axes, int64_t **__pyx_v_not_axes, int64_t __pyx_v_dimensions, int64_t *__pyx_v_unique_axes_length) {
-  int64_t __pyx_v_unique_axes_count;
-  int64_t __pyx_v_holding_offset;
-  int64_t *__pyx_v_axes_holding;
-  int64_t *__pyx_v_axes_holding_offset;
-  int64_t __pyx_v_n;
-  int64_t __pyx_v_not_axes_count;
+static void __pyx_f_6pyfftw_6pyfftw__fftwf_destroy_plan(void *__pyx_v__plan) {
   __Pyx_RefNannyDeclarations
-  int64_t __pyx_t_1;
-  int64_t __pyx_t_2;
-  int __pyx_t_3;
-  __Pyx_RefNannySetupContext("make_axes_unique", 0);
+  __Pyx_RefNannySetupContext("_fftwf_destroy_plan", 0);
 
-  /* "pyfftw/pyfftw.pyx":516
- *     '''
+  /* "pyfftw/pyfftw.pyx":260
+ * cdef void _fftwf_destroy_plan(void *_plan):
  * 
- *     cdef int64_t unique_axes_count = 0             # <<<<<<<<<<<<<<
- *     cdef int64_t holding_offset = 0
+ *     fftwf_destroy_plan(<fftwf_plan>_plan)             # <<<<<<<<<<<<<<
  * 
+ * # Long double precision
  */
-  __pyx_v_unique_axes_count = 0;
+  fftwf_destroy_plan(((fftwf_plan)__pyx_v__plan));
 
-  /* "pyfftw/pyfftw.pyx":517
+  /* "pyfftw/pyfftw.pyx":258
  * 
- *     cdef int64_t unique_axes_count = 0
- *     cdef int64_t holding_offset = 0             # <<<<<<<<<<<<<<
+ * # Single precision
+ * cdef void _fftwf_destroy_plan(void *_plan):             # <<<<<<<<<<<<<<
  * 
- *     cdef int64_t *axes_holding = (
+ *     fftwf_destroy_plan(<fftwf_plan>_plan)
  */
-  __pyx_v_holding_offset = 0;
 
-  /* "pyfftw/pyfftw.pyx":520
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "pyfftw/pyfftw.pyx":263
  * 
- *     cdef int64_t *axes_holding = (
- *             <int64_t *>calloc(dimensions, sizeof(int64_t)))             # <<<<<<<<<<<<<<
- *     cdef int64_t *axes_holding_offset = (
- *             <int64_t *>calloc(dimensions, sizeof(int64_t)))
+ * # Long double precision
+ * cdef void _fftwl_destroy_plan(void *_plan):             # <<<<<<<<<<<<<<
+ * 
+ *     fftwl_destroy_plan(<fftwl_plan>_plan)
  */
-  __pyx_v_axes_holding = ((int64_t *)calloc(__pyx_v_dimensions, (sizeof(int64_t))));
 
-  /* "pyfftw/pyfftw.pyx":522
- *             <int64_t *>calloc(dimensions, sizeof(int64_t)))
- *     cdef int64_t *axes_holding_offset = (
- *             <int64_t *>calloc(dimensions, sizeof(int64_t)))             # <<<<<<<<<<<<<<
+static void __pyx_f_6pyfftw_6pyfftw__fftwl_destroy_plan(void *__pyx_v__plan) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_fftwl_destroy_plan", 0);
+
+  /* "pyfftw/pyfftw.pyx":265
+ * cdef void _fftwl_destroy_plan(void *_plan):
+ * 
+ *     fftwl_destroy_plan(<fftwl_plan>_plan)             # <<<<<<<<<<<<<<
+ * 
  * 
- *     for n in range(dimensions):
  */
-  __pyx_v_axes_holding_offset = ((int64_t *)calloc(__pyx_v_dimensions, (sizeof(int64_t))));
+  fftwl_destroy_plan(((fftwl_plan)__pyx_v__plan));
 
-  /* "pyfftw/pyfftw.pyx":524
- *             <int64_t *>calloc(dimensions, sizeof(int64_t)))
+  /* "pyfftw/pyfftw.pyx":263
  * 
- *     for n in range(dimensions):             # <<<<<<<<<<<<<<
- *         axes_holding[n] = -1
+ * # Long double precision
+ * cdef void _fftwl_destroy_plan(void *_plan):             # <<<<<<<<<<<<<<
  * 
+ *     fftwl_destroy_plan(<fftwl_plan>_plan)
  */
-  __pyx_t_1 = __pyx_v_dimensions;
-  for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
-    __pyx_v_n = __pyx_t_2;
 
-    /* "pyfftw/pyfftw.pyx":525
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "pyfftw/pyfftw.pyx":274
+ * cdef fftw_generic_plan_guru planners[9]
  * 
- *     for n in range(dimensions):
- *         axes_holding[n] = -1             # <<<<<<<<<<<<<<
+ * cdef fftw_generic_plan_guru * _build_planner_list():             # <<<<<<<<<<<<<<
  * 
- *     # Iterate over all the axes and store each index if it hasn't already
+ *     planners[0] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft
  */
-    (__pyx_v_axes_holding[__pyx_v_n]) = -1;
-  }
 
-  /* "pyfftw/pyfftw.pyx":532
- *     #
- *     # axes_holding_offset holds the shift due to repeated axes
- *     for n in range(axes_length):             # <<<<<<<<<<<<<<
- *         if axes_holding[axes[n]] == -1:
- *             axes_holding[axes[n]] = n
+static __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru *__pyx_f_6pyfftw_6pyfftw__build_planner_list(void) {
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru *__pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_build_planner_list", 0);
+
+  /* "pyfftw/pyfftw.pyx":276
+ * cdef fftw_generic_plan_guru * _build_planner_list():
+ * 
+ *     planners[0] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft             # <<<<<<<<<<<<<<
+ *     planners[1] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft
+ *     planners[2] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft
  */
-  __pyx_t_1 = __pyx_v_axes_length;
-  for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
-    __pyx_v_n = __pyx_t_2;
+  (__pyx_v_6pyfftw_6pyfftw_planners[0]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft));
 
-    /* "pyfftw/pyfftw.pyx":533
- *     # axes_holding_offset holds the shift due to repeated axes
- *     for n in range(axes_length):
- *         if axes_holding[axes[n]] == -1:             # <<<<<<<<<<<<<<
- *             axes_holding[axes[n]] = n
- *             axes_holding_offset[axes[n]] = holding_offset
+  /* "pyfftw/pyfftw.pyx":277
+ * 
+ *     planners[0] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft
+ *     planners[1] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft             # <<<<<<<<<<<<<<
+ *     planners[2] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft
+ *     planners[3] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_r2c
  */
-    __pyx_t_3 = ((__pyx_v_axes_holding[(__pyx_v_axes[__pyx_v_n])]) == -1);
-    if (__pyx_t_3) {
+  (__pyx_v_6pyfftw_6pyfftw_planners[1]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft));
 
-      /* "pyfftw/pyfftw.pyx":534
- *     for n in range(axes_length):
- *         if axes_holding[axes[n]] == -1:
- *             axes_holding[axes[n]] = n             # <<<<<<<<<<<<<<
- *             axes_holding_offset[axes[n]] = holding_offset
- *             unique_axes_count += 1
+  /* "pyfftw/pyfftw.pyx":278
+ *     planners[0] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft
+ *     planners[1] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft
+ *     planners[2] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft             # <<<<<<<<<<<<<<
+ *     planners[3] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_r2c
+ *     planners[4] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_r2c
  */
-      (__pyx_v_axes_holding[(__pyx_v_axes[__pyx_v_n])]) = __pyx_v_n;
+  (__pyx_v_6pyfftw_6pyfftw_planners[2]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft));
 
-      /* "pyfftw/pyfftw.pyx":535
- *         if axes_holding[axes[n]] == -1:
- *             axes_holding[axes[n]] = n
- *             axes_holding_offset[axes[n]] = holding_offset             # <<<<<<<<<<<<<<
- *             unique_axes_count += 1
- *         else:
+  /* "pyfftw/pyfftw.pyx":279
+ *     planners[1] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft
+ *     planners[2] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft
+ *     planners[3] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_r2c             # <<<<<<<<<<<<<<
+ *     planners[4] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_r2c
+ *     planners[5] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_r2c
  */
-      (__pyx_v_axes_holding_offset[(__pyx_v_axes[__pyx_v_n])]) = __pyx_v_holding_offset;
+  (__pyx_v_6pyfftw_6pyfftw_planners[3]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_r2c));
 
-      /* "pyfftw/pyfftw.pyx":536
- *             axes_holding[axes[n]] = n
- *             axes_holding_offset[axes[n]] = holding_offset
- *             unique_axes_count += 1             # <<<<<<<<<<<<<<
- *         else:
- *             holding_offset += 1
+  /* "pyfftw/pyfftw.pyx":280
+ *     planners[2] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft
+ *     planners[3] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_r2c
+ *     planners[4] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_r2c             # <<<<<<<<<<<<<<
+ *     planners[5] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_r2c
+ *     planners[6] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_c2r
  */
-      __pyx_v_unique_axes_count = (__pyx_v_unique_axes_count + 1);
-      goto __pyx_L7;
-    }
-    /*else*/ {
+  (__pyx_v_6pyfftw_6pyfftw_planners[4]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_r2c));
 
-      /* "pyfftw/pyfftw.pyx":538
- *             unique_axes_count += 1
- *         else:
- *             holding_offset += 1             # <<<<<<<<<<<<<<
- * 
- *     unique_axes[0] = <int64_t *>malloc(
+  /* "pyfftw/pyfftw.pyx":281
+ *     planners[3] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_r2c
+ *     planners[4] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_r2c
+ *     planners[5] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_r2c             # <<<<<<<<<<<<<<
+ *     planners[6] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_c2r
+ *     planners[7] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_c2r
  */
-      __pyx_v_holding_offset = (__pyx_v_holding_offset + 1);
-    }
-    __pyx_L7:;
-  }
+  (__pyx_v_6pyfftw_6pyfftw_planners[5]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_r2c));
 
-  /* "pyfftw/pyfftw.pyx":540
- *             holding_offset += 1
+  /* "pyfftw/pyfftw.pyx":282
+ *     planners[4] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_r2c
+ *     planners[5] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_r2c
+ *     planners[6] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_c2r             # <<<<<<<<<<<<<<
+ *     planners[7] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_c2r
+ *     planners[8] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_c2r
+ */
+  (__pyx_v_6pyfftw_6pyfftw_planners[6]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftw_plan_guru_dft_c2r));
+
+  /* "pyfftw/pyfftw.pyx":283
+ *     planners[5] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_r2c
+ *     planners[6] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_c2r
+ *     planners[7] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_c2r             # <<<<<<<<<<<<<<
+ *     planners[8] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_c2r
  * 
- *     unique_axes[0] = <int64_t *>malloc(             # <<<<<<<<<<<<<<
- *             unique_axes_count * sizeof(int64_t))
+ */
+  (__pyx_v_6pyfftw_6pyfftw_planners[7]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwf_plan_guru_dft_c2r));
+
+  /* "pyfftw/pyfftw.pyx":284
+ *     planners[6] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft_c2r
+ *     planners[7] = <fftw_generic_plan_guru>&_fftwf_plan_guru_dft_c2r
+ *     planners[8] = <fftw_generic_plan_guru>&_fftwl_plan_guru_dft_c2r             # <<<<<<<<<<<<<<
  * 
+ * # Executor table (of size the number of executors)
  */
-  (__pyx_v_unique_axes[0]) = ((int64_t *)malloc((__pyx_v_unique_axes_count * (sizeof(int64_t)))));
+  (__pyx_v_6pyfftw_6pyfftw_planners[8]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru)(&__pyx_f_6pyfftw_6pyfftw__fftwl_plan_guru_dft_c2r));
 
-  /* "pyfftw/pyfftw.pyx":543
- *             unique_axes_count * sizeof(int64_t))
+  /* "pyfftw/pyfftw.pyx":274
+ * cdef fftw_generic_plan_guru planners[9]
  * 
- *     not_axes[0] = <int64_t *>malloc(             # <<<<<<<<<<<<<<
- *             (dimensions - unique_axes_count) * sizeof(int64_t))
+ * cdef fftw_generic_plan_guru * _build_planner_list():             # <<<<<<<<<<<<<<
  * 
+ *     planners[0] = <fftw_generic_plan_guru>&_fftw_plan_guru_dft
  */
-  (__pyx_v_not_axes[0]) = ((int64_t *)malloc(((__pyx_v_dimensions - __pyx_v_unique_axes_count) * (sizeof(int64_t)))));
 
-  /* "pyfftw/pyfftw.pyx":547
+  /* function exit code */
+  __pyx_r = 0;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":289
+ * cdef fftw_generic_execute executors[9]
  * 
- *     # Now we need to write back the unique axes to a tmp axes
- *     cdef int64_t not_axes_count = 0             # <<<<<<<<<<<<<<
+ * cdef fftw_generic_execute * _build_executor_list():             # <<<<<<<<<<<<<<
  * 
- *     for n in range(dimensions):
+ *     executors[0] = <fftw_generic_execute>&_fftw_execute_dft
  */
-  __pyx_v_not_axes_count = 0;
 
-  /* "pyfftw/pyfftw.pyx":549
- *     cdef int64_t not_axes_count = 0
+static __pyx_t_6pyfftw_6pyfftw_fftw_generic_execute *__pyx_f_6pyfftw_6pyfftw__build_executor_list(void) {
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_execute *__pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_build_executor_list", 0);
+
+  /* "pyfftw/pyfftw.pyx":291
+ * cdef fftw_generic_execute * _build_executor_list():
  * 
- *     for n in range(dimensions):             # <<<<<<<<<<<<<<
- *         if axes_holding[n] != -1:
- *             unique_axes[0][axes_holding[n] - axes_holding_offset[n]] = (
+ *     executors[0] = <fftw_generic_execute>&_fftw_execute_dft             # <<<<<<<<<<<<<<
+ *     executors[1] = <fftw_generic_execute>&_fftwf_execute_dft
+ *     executors[2] = <fftw_generic_execute>&_fftwl_execute_dft
  */
-  __pyx_t_1 = __pyx_v_dimensions;
-  for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
-    __pyx_v_n = __pyx_t_2;
+  (__pyx_v_6pyfftw_6pyfftw_executors[0]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftw_execute_dft));
 
-    /* "pyfftw/pyfftw.pyx":550
+  /* "pyfftw/pyfftw.pyx":292
  * 
- *     for n in range(dimensions):
- *         if axes_holding[n] != -1:             # <<<<<<<<<<<<<<
- *             unique_axes[0][axes_holding[n] - axes_holding_offset[n]] = (
- *                     axes[axes_holding[n]])
+ *     executors[0] = <fftw_generic_execute>&_fftw_execute_dft
+ *     executors[1] = <fftw_generic_execute>&_fftwf_execute_dft             # <<<<<<<<<<<<<<
+ *     executors[2] = <fftw_generic_execute>&_fftwl_execute_dft
+ *     executors[3] = <fftw_generic_execute>&_fftw_execute_dft_r2c
  */
-    __pyx_t_3 = ((__pyx_v_axes_holding[__pyx_v_n]) != -1);
-    if (__pyx_t_3) {
+  (__pyx_v_6pyfftw_6pyfftw_executors[1]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft));
 
-      /* "pyfftw/pyfftw.pyx":551
- *     for n in range(dimensions):
- *         if axes_holding[n] != -1:
- *             unique_axes[0][axes_holding[n] - axes_holding_offset[n]] = (             # <<<<<<<<<<<<<<
- *                     axes[axes_holding[n]])
- * 
+  /* "pyfftw/pyfftw.pyx":293
+ *     executors[0] = <fftw_generic_execute>&_fftw_execute_dft
+ *     executors[1] = <fftw_generic_execute>&_fftwf_execute_dft
+ *     executors[2] = <fftw_generic_execute>&_fftwl_execute_dft             # <<<<<<<<<<<<<<
+ *     executors[3] = <fftw_generic_execute>&_fftw_execute_dft_r2c
+ *     executors[4] = <fftw_generic_execute>&_fftwf_execute_dft_r2c
  */
-      ((__pyx_v_unique_axes[0])[((__pyx_v_axes_holding[__pyx_v_n]) - (__pyx_v_axes_holding_offset[__pyx_v_n]))]) = (__pyx_v_axes[(__pyx_v_axes_holding[__pyx_v_n])]);
-      goto __pyx_L10;
-    }
-    /*else*/ {
+  (__pyx_v_6pyfftw_6pyfftw_executors[2]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft));
 
-      /* "pyfftw/pyfftw.pyx":555
- * 
- *         else:
- *             not_axes[0][not_axes_count] = n             # <<<<<<<<<<<<<<
- *             not_axes_count += 1
- * 
+  /* "pyfftw/pyfftw.pyx":294
+ *     executors[1] = <fftw_generic_execute>&_fftwf_execute_dft
+ *     executors[2] = <fftw_generic_execute>&_fftwl_execute_dft
+ *     executors[3] = <fftw_generic_execute>&_fftw_execute_dft_r2c             # <<<<<<<<<<<<<<
+ *     executors[4] = <fftw_generic_execute>&_fftwf_execute_dft_r2c
+ *     executors[5] = <fftw_generic_execute>&_fftwl_execute_dft_r2c
  */
-      ((__pyx_v_not_axes[0])[__pyx_v_not_axes_count]) = __pyx_v_n;
+  (__pyx_v_6pyfftw_6pyfftw_executors[3]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftw_execute_dft_r2c));
 
-      /* "pyfftw/pyfftw.pyx":556
- *         else:
- *             not_axes[0][not_axes_count] = n
- *             not_axes_count += 1             # <<<<<<<<<<<<<<
- * 
- *     free(axes_holding)
+  /* "pyfftw/pyfftw.pyx":295
+ *     executors[2] = <fftw_generic_execute>&_fftwl_execute_dft
+ *     executors[3] = <fftw_generic_execute>&_fftw_execute_dft_r2c
+ *     executors[4] = <fftw_generic_execute>&_fftwf_execute_dft_r2c             # <<<<<<<<<<<<<<
+ *     executors[5] = <fftw_generic_execute>&_fftwl_execute_dft_r2c
+ *     executors[6] = <fftw_generic_execute>&_fftw_execute_dft_c2r
  */
-      __pyx_v_not_axes_count = (__pyx_v_not_axes_count + 1);
-    }
-    __pyx_L10:;
-  }
+  (__pyx_v_6pyfftw_6pyfftw_executors[4]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft_r2c));
 
-  /* "pyfftw/pyfftw.pyx":558
- *             not_axes_count += 1
- * 
- *     free(axes_holding)             # <<<<<<<<<<<<<<
- *     free(axes_holding_offset)
- * 
+  /* "pyfftw/pyfftw.pyx":296
+ *     executors[3] = <fftw_generic_execute>&_fftw_execute_dft_r2c
+ *     executors[4] = <fftw_generic_execute>&_fftwf_execute_dft_r2c
+ *     executors[5] = <fftw_generic_execute>&_fftwl_execute_dft_r2c             # <<<<<<<<<<<<<<
+ *     executors[6] = <fftw_generic_execute>&_fftw_execute_dft_c2r
+ *     executors[7] = <fftw_generic_execute>&_fftwf_execute_dft_c2r
  */
-  free(__pyx_v_axes_holding);
+  (__pyx_v_6pyfftw_6pyfftw_executors[5]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft_r2c));
 
-  /* "pyfftw/pyfftw.pyx":559
- * 
- *     free(axes_holding)
- *     free(axes_holding_offset)             # <<<<<<<<<<<<<<
- * 
- *     unique_axes_length[0] = unique_axes_count
+  /* "pyfftw/pyfftw.pyx":297
+ *     executors[4] = <fftw_generic_execute>&_fftwf_execute_dft_r2c
+ *     executors[5] = <fftw_generic_execute>&_fftwl_execute_dft_r2c
+ *     executors[6] = <fftw_generic_execute>&_fftw_execute_dft_c2r             # <<<<<<<<<<<<<<
+ *     executors[7] = <fftw_generic_execute>&_fftwf_execute_dft_c2r
+ *     executors[8] = <fftw_generic_execute>&_fftwl_execute_dft_c2r
  */
-  free(__pyx_v_axes_holding_offset);
+  (__pyx_v_6pyfftw_6pyfftw_executors[6]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftw_execute_dft_c2r));
 
-  /* "pyfftw/pyfftw.pyx":561
- *     free(axes_holding_offset)
+  /* "pyfftw/pyfftw.pyx":298
+ *     executors[5] = <fftw_generic_execute>&_fftwl_execute_dft_r2c
+ *     executors[6] = <fftw_generic_execute>&_fftw_execute_dft_c2r
+ *     executors[7] = <fftw_generic_execute>&_fftwf_execute_dft_c2r             # <<<<<<<<<<<<<<
+ *     executors[8] = <fftw_generic_execute>&_fftwl_execute_dft_c2r
  * 
- *     unique_axes_length[0] = unique_axes_count             # <<<<<<<<<<<<<<
+ */
+  (__pyx_v_6pyfftw_6pyfftw_executors[7]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwf_execute_dft_c2r));
+
+  /* "pyfftw/pyfftw.pyx":299
+ *     executors[6] = <fftw_generic_execute>&_fftw_execute_dft_c2r
+ *     executors[7] = <fftw_generic_execute>&_fftwf_execute_dft_c2r
+ *     executors[8] = <fftw_generic_execute>&_fftwl_execute_dft_c2r             # <<<<<<<<<<<<<<
  * 
- *     return
+ * # Destroyer table (of size the number of destroyers)
  */
-  (__pyx_v_unique_axes_length[0]) = __pyx_v_unique_axes_count;
+  (__pyx_v_6pyfftw_6pyfftw_executors[8]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_execute)(&__pyx_f_6pyfftw_6pyfftw__fftwl_execute_dft_c2r));
 
-  /* "pyfftw/pyfftw.pyx":563
- *     unique_axes_length[0] = unique_axes_count
+  /* "pyfftw/pyfftw.pyx":289
+ * cdef fftw_generic_execute executors[9]
  * 
- *     return             # <<<<<<<<<<<<<<
+ * cdef fftw_generic_execute * _build_executor_list():             # <<<<<<<<<<<<<<
  * 
- * # The External Interface
+ *     executors[0] = <fftw_generic_execute>&_fftw_execute_dft
  */
-  goto __pyx_L0;
-
-  __pyx_L0:;
-  __Pyx_RefNannyFinishContext();
-}
 
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_1__get_N(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4FFTW___get_N[] = "\n        The product of the lengths of the DFT over all DFT axes.\n        1/N is the normalisation constant. For any input array A, \n        and for any set of axes, 1/N * ifft(fft(A)) = A\n        ";
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_1__get_N(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__get_N (wrapper)", 0);
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW___get_N(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+  /* function exit code */
+  __pyx_r = 0;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":639
+/* "pyfftw/pyfftw.pyx":304
+ * cdef fftw_generic_destroy_plan destroyers[3]
  * 
- *     cdef int __N
- *     def __get_N(self):             # <<<<<<<<<<<<<<
- *         '''
- *         The product of the lengths of the DFT over all DFT axes.
+ * cdef fftw_generic_destroy_plan * _build_destroyer_list():             # <<<<<<<<<<<<<<
+ * 
+ *     destroyers[0] = <fftw_generic_destroy_plan>&_fftw_destroy_plan
  */
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW___get_N(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
+static __pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan *__pyx_f_6pyfftw_6pyfftw__build_destroyer_list(void) {
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan *__pyx_r;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("__get_N", 0);
+  __Pyx_RefNannySetupContext("_build_destroyer_list", 0);
 
-  /* "pyfftw/pyfftw.pyx":645
- *         and for any set of axes, 1/N * ifft(fft(A)) = A
- *         '''
- *         return self.__N             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":306
+ * cdef fftw_generic_destroy_plan * _build_destroyer_list():
  * 
- *     N = property(__get_N)
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->__pyx___N); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__get_N", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_3__get_simd_aligned(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_2__get_simd_aligned[] = "\n        Return whether or not this FFTW object requires simd aligned\n        input and output data.\n        ";
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_3__get_simd_aligned(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__get_simd_aligned (wrapper)", 0);
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_2__get_simd_aligned(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+ *     destroyers[0] = <fftw_generic_destroy_plan>&_fftw_destroy_plan             # <<<<<<<<<<<<<<
+ *     destroyers[1] = <fftw_generic_destroy_plan>&_fftwf_destroy_plan
+ *     destroyers[2] = <fftw_generic_destroy_plan>&_fftwl_destroy_plan
+ */
+  (__pyx_v_6pyfftw_6pyfftw_destroyers[0]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan)(&__pyx_f_6pyfftw_6pyfftw__fftw_destroy_plan));
 
-/* "pyfftw/pyfftw.pyx":649
- *     N = property(__get_N)
+  /* "pyfftw/pyfftw.pyx":307
+ * 
+ *     destroyers[0] = <fftw_generic_destroy_plan>&_fftw_destroy_plan
+ *     destroyers[1] = <fftw_generic_destroy_plan>&_fftwf_destroy_plan             # <<<<<<<<<<<<<<
+ *     destroyers[2] = <fftw_generic_destroy_plan>&_fftwl_destroy_plan
  * 
- *     def __get_simd_aligned(self):             # <<<<<<<<<<<<<<
- *         '''
- *         Return whether or not this FFTW object requires simd aligned
  */
+  (__pyx_v_6pyfftw_6pyfftw_destroyers[1]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan)(&__pyx_f_6pyfftw_6pyfftw__fftwf_destroy_plan));
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_2__get_simd_aligned(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("__get_simd_aligned", 0);
+  /* "pyfftw/pyfftw.pyx":308
+ *     destroyers[0] = <fftw_generic_destroy_plan>&_fftw_destroy_plan
+ *     destroyers[1] = <fftw_generic_destroy_plan>&_fftwf_destroy_plan
+ *     destroyers[2] = <fftw_generic_destroy_plan>&_fftwl_destroy_plan             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  (__pyx_v_6pyfftw_6pyfftw_destroyers[2]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_destroy_plan)(&__pyx_f_6pyfftw_6pyfftw__fftwl_destroy_plan));
 
-  /* "pyfftw/pyfftw.pyx":654
- *         input and output data.
- *         '''
- *         return self.__simd_allowed             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":304
+ * cdef fftw_generic_destroy_plan destroyers[3]
+ * 
+ * cdef fftw_generic_destroy_plan * _build_destroyer_list():             # <<<<<<<<<<<<<<
  * 
- *     simd_aligned = property(__get_simd_aligned)
+ *     destroyers[0] = <fftw_generic_destroy_plan>&_fftw_destroy_plan
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_self->__pyx___simd_allowed); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 654; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__get_simd_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
+  /* function exit code */
+  __pyx_r = 0;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_5__get_input_alignment(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_4__get_input_alignment[] = "\n        Returns the byte alignment of the input arrays for which the\n        :class:`~pyfftw.FFTW` object was created.\n\n        Input array updates with arrays that are not aligned on this\n        byte boundary will result in a ValueError being raised, or\n        a copy being made if the :meth:`~pyfftw.FFTW.__call__` \n        interface is used.\n        ";
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_5__get_input_alignment(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
+/* "pyfftw/pyfftw.pyx":314
+ * cdef fftw_generic_plan_with_nthreads nthreads_plan_setters[3]
+ * 
+ * cdef fftw_generic_plan_with_nthreads * _build_nthreads_plan_setters_list():             # <<<<<<<<<<<<<<
+ *     nthreads_plan_setters[0] = (
+ *             <fftw_generic_plan_with_nthreads>&fftw_plan_with_nthreads)
+ */
+
+static __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads *__pyx_f_6pyfftw_6pyfftw__build_nthreads_plan_setters_list(void) {
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads *__pyx_r;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__get_input_alignment (wrapper)", 0);
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_4__get_input_alignment(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  __Pyx_RefNannySetupContext("_build_nthreads_plan_setters_list", 0);
 
-/* "pyfftw/pyfftw.pyx":658
- *     simd_aligned = property(__get_simd_aligned)
+  /* "pyfftw/pyfftw.pyx":315
  * 
- *     def __get_input_alignment(self):             # <<<<<<<<<<<<<<
- *         '''
- *         Returns the byte alignment of the input arrays for which the
+ * cdef fftw_generic_plan_with_nthreads * _build_nthreads_plan_setters_list():
+ *     nthreads_plan_setters[0] = (             # <<<<<<<<<<<<<<
+ *             <fftw_generic_plan_with_nthreads>&fftw_plan_with_nthreads)
+ *     nthreads_plan_setters[1] = (
  */
+  (__pyx_v_6pyfftw_6pyfftw_nthreads_plan_setters[0]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads)(&fftw_plan_with_nthreads));
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_4__get_input_alignment(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("__get_input_alignment", 0);
+  /* "pyfftw/pyfftw.pyx":317
+ *     nthreads_plan_setters[0] = (
+ *             <fftw_generic_plan_with_nthreads>&fftw_plan_with_nthreads)
+ *     nthreads_plan_setters[1] = (             # <<<<<<<<<<<<<<
+ *             <fftw_generic_plan_with_nthreads>&fftwf_plan_with_nthreads)
+ *     nthreads_plan_setters[2] = (
+ */
+  (__pyx_v_6pyfftw_6pyfftw_nthreads_plan_setters[1]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads)(&fftwf_plan_with_nthreads));
 
-  /* "pyfftw/pyfftw.pyx":668
- *         interface is used.
- *         '''
- *         return self.__input_array_alignment             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":319
+ *     nthreads_plan_setters[1] = (
+ *             <fftw_generic_plan_with_nthreads>&fftwf_plan_with_nthreads)
+ *     nthreads_plan_setters[2] = (             # <<<<<<<<<<<<<<
+ *             <fftw_generic_plan_with_nthreads>&fftwl_plan_with_nthreads)
  * 
- *     input_alignment = property(__get_input_alignment)
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->__pyx___input_array_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 668; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
+  (__pyx_v_6pyfftw_6pyfftw_nthreads_plan_setters[2]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_with_nthreads)(&fftwl_plan_with_nthreads));
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__get_input_alignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  /* "pyfftw/pyfftw.pyx":314
+ * cdef fftw_generic_plan_with_nthreads nthreads_plan_setters[3]
+ * 
+ * cdef fftw_generic_plan_with_nthreads * _build_nthreads_plan_setters_list():             # <<<<<<<<<<<<<<
+ *     nthreads_plan_setters[0] = (
+ *             <fftw_generic_plan_with_nthreads>&fftw_plan_with_nthreads)
+ */
 
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_7__get_output_alignment(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_6__get_output_alignment[] = "\n        Returns the byte alignment of the output arrays for which the\n        :class:`~pyfftw.FFTW` object was created.\n\n        Output array updates with arrays that are not aligned on this\n        byte boundary will result in a ValueError being raised.\n        ";
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_7__get_output_alignment(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__get_output_alignment (wrapper)", 0);
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_6__get_output_alignment(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+  /* function exit code */
+  __pyx_r = 0;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":672
- *     input_alignment = property(__get_input_alignment)
+/* "pyfftw/pyfftw.pyx":325
+ * cdef fftw_generic_set_timelimit set_timelimit_funcs[3]
  * 
- *     def __get_output_alignment(self):             # <<<<<<<<<<<<<<
- *         '''
- *         Returns the byte alignment of the output arrays for which the
+ * cdef fftw_generic_set_timelimit * _build_set_timelimit_funcs_list():             # <<<<<<<<<<<<<<
+ *     set_timelimit_funcs[0] = (
+ *             <fftw_generic_set_timelimit>&fftw_set_timelimit)
  */
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_6__get_output_alignment(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
+static __pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit *__pyx_f_6pyfftw_6pyfftw__build_set_timelimit_funcs_list(void) {
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit *__pyx_r;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("__get_output_alignment", 0);
+  __Pyx_RefNannySetupContext("_build_set_timelimit_funcs_list", 0);
 
-  /* "pyfftw/pyfftw.pyx":680
- *         byte boundary will result in a ValueError being raised.
- *         '''
- *         return self.__output_array_alignment             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":326
  * 
- *     output_alignment = property(__get_output_alignment)
+ * cdef fftw_generic_set_timelimit * _build_set_timelimit_funcs_list():
+ *     set_timelimit_funcs[0] = (             # <<<<<<<<<<<<<<
+ *             <fftw_generic_set_timelimit>&fftw_set_timelimit)
+ *     set_timelimit_funcs[1] = (
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyInt_FromLong(__pyx_v_self->__pyx___output_array_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 680; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
+  (__pyx_v_6pyfftw_6pyfftw_set_timelimit_funcs[0]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit)(&fftw_set_timelimit));
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__get_output_alignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  /* "pyfftw/pyfftw.pyx":328
+ *     set_timelimit_funcs[0] = (
+ *             <fftw_generic_set_timelimit>&fftw_set_timelimit)
+ *     set_timelimit_funcs[1] = (             # <<<<<<<<<<<<<<
+ *             <fftw_generic_set_timelimit>&fftwf_set_timelimit)
+ *     set_timelimit_funcs[2] = (
+ */
+  (__pyx_v_6pyfftw_6pyfftw_set_timelimit_funcs[1]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit)(&fftwf_set_timelimit));
 
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_9__get_flags_used(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_8__get_flags_used[] = "\n        Return which flags were used to construct the FFTW object.\n        \n        This includes flags that were added during initialisation.\n        ";
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_9__get_flags_used(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__get_flags_used (wrapper)", 0);
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_8__get_flags_used(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+  /* "pyfftw/pyfftw.pyx":330
+ *     set_timelimit_funcs[1] = (
+ *             <fftw_generic_set_timelimit>&fftwf_set_timelimit)
+ *     set_timelimit_funcs[2] = (             # <<<<<<<<<<<<<<
+ *             <fftw_generic_set_timelimit>&fftwl_set_timelimit)
+ * 
+ */
+  (__pyx_v_6pyfftw_6pyfftw_set_timelimit_funcs[2]) = ((__pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit)(&fftwl_set_timelimit));
+
+  /* "pyfftw/pyfftw.pyx":325
+ * cdef fftw_generic_set_timelimit set_timelimit_funcs[3]
+ * 
+ * cdef fftw_generic_set_timelimit * _build_set_timelimit_funcs_list():             # <<<<<<<<<<<<<<
+ *     set_timelimit_funcs[0] = (
+ *             <fftw_generic_set_timelimit>&fftw_set_timelimit)
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "pyfftw/pyfftw.pyx":684
- *     output_alignment = property(__get_output_alignment)
+/* "pyfftw/pyfftw.pyx":337
+ * cdef validator validators[2]
  * 
- *     def __get_flags_used(self):             # <<<<<<<<<<<<<<
- *         '''
- *         Return which flags were used to construct the FFTW object.
+ * cdef validator * _build_validators_list():             # <<<<<<<<<<<<<<
+ *     validators[0] = &_validate_r2c_arrays
+ *     validators[1] = &_validate_c2r_arrays
  */
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_8__get_flags_used(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
+static __pyx_t_6pyfftw_6pyfftw_validator *__pyx_f_6pyfftw_6pyfftw__build_validators_list(void) {
+  __pyx_t_6pyfftw_6pyfftw_validator *__pyx_r;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("__get_flags_used", 0);
+  __Pyx_RefNannySetupContext("_build_validators_list", 0);
 
-  /* "pyfftw/pyfftw.pyx":690
- *         This includes flags that were added during initialisation.
- *         '''
- *         return tuple(self.__flags_used)             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":338
+ * 
+ * cdef validator * _build_validators_list():
+ *     validators[0] = &_validate_r2c_arrays             # <<<<<<<<<<<<<<
+ *     validators[1] = &_validate_c2r_arrays
  * 
- *     flags = property(__get_flags_used)
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 690; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_INCREF(__pyx_v_self->__pyx___flags_used);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_self->__pyx___flags_used);
-  __Pyx_GIVEREF(__pyx_v_self->__pyx___flags_used);
-  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyTuple_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 690; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __pyx_r = __pyx_t_2;
-  __pyx_t_2 = 0;
-  goto __pyx_L0;
+  (__pyx_v_6pyfftw_6pyfftw_validators[0]) = (&__pyx_f_6pyfftw_6pyfftw__validate_r2c_arrays);
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__get_flags_used", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
+  /* "pyfftw/pyfftw.pyx":339
+ * cdef validator * _build_validators_list():
+ *     validators[0] = &_validate_r2c_arrays
+ *     validators[1] = &_validate_c2r_arrays             # <<<<<<<<<<<<<<
+ * 
+ * # Validator functions
+ */
+  (__pyx_v_6pyfftw_6pyfftw_validators[1]) = (&__pyx_f_6pyfftw_6pyfftw__validate_c2r_arrays);
+
+  /* "pyfftw/pyfftw.pyx":337
+ * cdef validator validators[2]
+ * 
+ * cdef validator * _build_validators_list():             # <<<<<<<<<<<<<<
+ *     validators[0] = &_validate_r2c_arrays
+ *     validators[1] = &_validate_c2r_arrays
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* Python wrapper */
-static int __pyx_pw_6pyfftw_6pyfftw_4FFTW_11__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static int __pyx_pw_6pyfftw_6pyfftw_4FFTW_11__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_input_array = 0;
-  PyObject *__pyx_v_output_array = 0;
-  PyObject *__pyx_v_axes = 0;
-  PyObject *__pyx_v_direction = 0;
-  PyObject *__pyx_v_flags = 0;
-  unsigned int __pyx_v_threads;
-  PyObject *__pyx_v_planning_timelimit = 0;
-  CYTHON_UNUSED PyObject *__pyx_v_args = 0;
-  CYTHON_UNUSED PyObject *__pyx_v_kwargs = 0;
+/* "pyfftw/pyfftw.pyx":343
+ * # Validator functions
+ * # ===================
+ * cdef bint _validate_r2c_arrays(np.ndarray input_array,             # <<<<<<<<<<<<<<
+ *         np.ndarray output_array, int64_t *axes, int64_t *not_axes,
+ *         int64_t axes_length):
+ */
+
+static int __pyx_f_6pyfftw_6pyfftw__validate_r2c_arrays(PyArrayObject *__pyx_v_input_array, PyArrayObject *__pyx_v_output_array, int64_t *__pyx_v_axes, int64_t *__pyx_v_not_axes, int64_t __pyx_v_axes_length) {
+  npy_intp *__pyx_v_in_shape;
+  npy_intp *__pyx_v_out_shape;
+  int64_t __pyx_v_n;
   int __pyx_r;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
-  __pyx_v_kwargs = PyDict_New(); if (unlikely(!__pyx_v_kwargs)) return -1;
-  __Pyx_GOTREF(__pyx_v_kwargs);
-  if (PyTuple_GET_SIZE(__pyx_args) > 7) {
-    __pyx_v_args = PyTuple_GetSlice(__pyx_args, 7, PyTuple_GET_SIZE(__pyx_args));
-    if (unlikely(!__pyx_v_args)) {
-      __Pyx_DECREF(__pyx_v_kwargs); __pyx_v_kwargs = 0;
-      __Pyx_RefNannyFinishContext();
-      return -1;
-    }
-    __Pyx_GOTREF(__pyx_v_args);
-  } else {
-    __pyx_v_args = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
-  }
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__input_array,&__pyx_n_s__output_array,&__pyx_n_s__axes,&__pyx_n_s__direction,&__pyx_n_s__flags,&__pyx_n_s__threads,&__pyx_n_s__planning_timelimit,0};
-    PyObject* values[7] = {0,0,0,0,0,0,0};
+  int __pyx_t_1;
+  npy_intp *__pyx_t_2;
+  int64_t __pyx_t_3;
+  int64_t __pyx_t_4;
+  __Pyx_RefNannySetupContext("_validate_r2c_arrays", 0);
 
-    /* "pyfftw/pyfftw.pyx":694
- *     flags = property(__get_flags_used)
+  /* "pyfftw/pyfftw.pyx":351
+ *     # We firstly need to confirm that the dimenions of the arrays
+ *     # are the same
+ *     if not (input_array.ndim == output_array.ndim):             # <<<<<<<<<<<<<<
+ *         return False
  * 
- *     def __cinit__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
- *             unsigned int threads=1, planning_timelimit=None,
  */
-    values[2] = ((PyObject *)__pyx_k_tuple_5);
-    values[3] = ((PyObject *)__pyx_n_s__FFTW_FORWARD);
+  __pyx_t_1 = ((!((__pyx_v_input_array->nd == __pyx_v_output_array->nd) != 0)) != 0);
+  if (__pyx_t_1) {
 
-    /* "pyfftw/pyfftw.pyx":695
+    /* "pyfftw/pyfftw.pyx":352
+ *     # are the same
+ *     if not (input_array.ndim == output_array.ndim):
+ *         return False             # <<<<<<<<<<<<<<
  * 
- *     def __cinit__(self, input_array, output_array, axes=(-1,),
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),             # <<<<<<<<<<<<<<
- *             unsigned int threads=1, planning_timelimit=None,
- *             *args, **kwargs):
+ *     in_shape = input_array.shape
  */
-    values[4] = ((PyObject *)__pyx_k_tuple_6);
+    __pyx_r = 0;
+    goto __pyx_L0;
 
-    /* "pyfftw/pyfftw.pyx":696
- *     def __cinit__(self, input_array, output_array, axes=(-1,),
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
- *             unsigned int threads=1, planning_timelimit=None,             # <<<<<<<<<<<<<<
- *             *args, **kwargs):
+    /* "pyfftw/pyfftw.pyx":351
+ *     # We firstly need to confirm that the dimenions of the arrays
+ *     # are the same
+ *     if not (input_array.ndim == output_array.ndim):             # <<<<<<<<<<<<<<
+ *         return False
  * 
  */
-    values[6] = ((PyObject *)Py_None);
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        default:
-        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
-        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
-        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__input_array)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__output_array)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 694; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-        case  2:
-        if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__axes);
-          if (value) { values[2] = value; kw_args--; }
-        }
-        case  3:
-        if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__direction);
-          if (value) { values[3] = value; kw_args--; }
-        }
-        case  4:
-        if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__flags);
-          if (value) { values[4] = value; kw_args--; }
-        }
-        case  5:
-        if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__threads);
-          if (value) { values[5] = value; kw_args--; }
-        }
-        case  6:
-        if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__planning_timelimit);
-          if (value) { values[6] = value; kw_args--; }
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        const Py_ssize_t used_pos_args = (pos_args < 7) ? pos_args : 7;
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, __pyx_v_kwargs, values, used_pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 694; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else {
-      switch (PyTuple_GET_SIZE(__pyx_args)) {
-        default:
-        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
-        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
-        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
-        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        break;
-        case  1:
-        case  0:
-        goto __pyx_L5_argtuple_error;
-      }
-    }
-    __pyx_v_input_array = values[0];
-    __pyx_v_output_array = values[1];
-    __pyx_v_axes = values[2];
-    __pyx_v_direction = values[3];
-    __pyx_v_flags = values[4];
-    if (values[5]) {
-      __pyx_v_threads = __Pyx_PyInt_AsUnsignedInt(values[5]); if (unlikely((__pyx_v_threads == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 696; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-    } else {
-      __pyx_v_threads = ((unsigned int)1);
-    }
-    __pyx_v_planning_timelimit = values[6];
   }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 694; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_DECREF(__pyx_v_args); __pyx_v_args = 0;
-  __Pyx_DECREF(__pyx_v_kwargs); __pyx_v_kwargs = 0;
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return -1;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_10__cinit__(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self), __pyx_v_input_array, __pyx_v_output_array, __pyx_v_axes, __pyx_v_direction, __pyx_v_flags, __pyx_v_threads, __pyx_v_planning_timelimit, __pyx_v_args, __pyx_v_kwargs);
-  __Pyx_XDECREF(__pyx_v_args);
-  __Pyx_XDECREF(__pyx_v_kwargs);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
 
-/* "pyfftw/pyfftw.pyx":694
- *     flags = property(__get_flags_used)
+  /* "pyfftw/pyfftw.pyx":354
+ *         return False
  * 
- *     def __cinit__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
- *             unsigned int threads=1, planning_timelimit=None,
- */
-
-static int __pyx_pf_6pyfftw_6pyfftw_4FFTW_10__cinit__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array, PyObject *__pyx_v_axes, PyObject *__pyx_v_direction, PyObject *__pyx_v_flags, unsigned int __pyx_v_threads, PyObject *__pyx_v_planning_timelimit, CYTHON_UNUSED PyObject *__pyx_v_args, CYTHON_UNUSED PyObject *__pyx_v_kwargs) {
-  double __pyx_v__planning_timelimit;
-  PyObject *__pyx_v_input_dtype = NULL;
-  PyObject *__pyx_v_output_dtype = NULL;
-  PyObject *__pyx_v_scheme = NULL;
-  PyObject *__pyx_v_functions = NULL;
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit __pyx_v_set_timelimit_func;
-  PyObject *__pyx_v_each_alignment = NULL;
-  PyObject *__pyx_v_n = NULL;
-  int64_t __pyx_v_array_dimension;
-  int64_t __pyx_v_unique_axes_length;
-  int64_t *__pyx_v_unique_axes;
-  int64_t *__pyx_v_not_axes;
-  PyObject *__pyx_v_total_N = NULL;
-  __pyx_t_6pyfftw_6pyfftw_validator __pyx_v__validator;
-  PyObject *__pyx_v_each_flag = NULL;
-  int __pyx_v_i;
-  PyObject *__pyx_v_fft_shape_lookup = NULL;
-  PyObject *__pyx_v_fft_shape = NULL;
-  PyObject *__pyx_v_input_strides_array = NULL;
-  PyObject *__pyx_v_output_strides_array = NULL;
-  PyObject *__pyx_v_stride = NULL;
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  int __pyx_t_3;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  double __pyx_t_7;
-  int __pyx_t_8;
-  PyObject *__pyx_t_9 = NULL;
-  PyObject *__pyx_t_10 = NULL;
-  int __pyx_t_11;
-  Py_ssize_t __pyx_t_12;
-  PyObject *(*__pyx_t_13)(PyObject *);
-  int __pyx_t_14;
-  intptr_t __pyx_t_15;
-  int64_t __pyx_t_16;
-  Py_ssize_t __pyx_t_17;
-  Py_ssize_t __pyx_t_18;
-  PyObject *__pyx_t_19 = NULL;
-  PyObject *__pyx_t_20 = NULL;
-  int __pyx_t_21;
-  int __pyx_t_22;
-  int __pyx_t_23;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("__cinit__", 0);
-  __Pyx_INCREF(__pyx_v_flags);
-
-  /* "pyfftw/pyfftw.pyx":700
+ *     in_shape = input_array.shape             # <<<<<<<<<<<<<<
+ *     out_shape = output_array.shape
  * 
- *         # Initialise the pointers that need to be freed
- *         self.__plan = NULL             # <<<<<<<<<<<<<<
- *         self.__dims = NULL
- *         self.__howmany_dims = NULL
  */
-  __pyx_v_self->__pyx___plan = NULL;
+  __pyx_t_2 = __pyx_v_input_array->dimensions;
+  __pyx_v_in_shape = __pyx_t_2;
 
-  /* "pyfftw/pyfftw.pyx":701
- *         # Initialise the pointers that need to be freed
- *         self.__plan = NULL
- *         self.__dims = NULL             # <<<<<<<<<<<<<<
- *         self.__howmany_dims = NULL
+  /* "pyfftw/pyfftw.pyx":355
+ * 
+ *     in_shape = input_array.shape
+ *     out_shape = output_array.shape             # <<<<<<<<<<<<<<
  * 
+ *     for n in range(axes_length - 1):
  */
-  __pyx_v_self->__pyx___dims = NULL;
+  __pyx_t_2 = __pyx_v_output_array->dimensions;
+  __pyx_v_out_shape = __pyx_t_2;
 
-  /* "pyfftw/pyfftw.pyx":702
- *         self.__plan = NULL
- *         self.__dims = NULL
- *         self.__howmany_dims = NULL             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":357
+ *     out_shape = output_array.shape
  * 
- *         self.__axes = NULL
+ *     for n in range(axes_length - 1):             # <<<<<<<<<<<<<<
+ *         if not out_shape[axes[n]] == in_shape[axes[n]]:
+ *             return False
  */
-  __pyx_v_self->__pyx___howmany_dims = NULL;
+  __pyx_t_3 = (__pyx_v_axes_length - 1);
+  for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+    __pyx_v_n = __pyx_t_4;
 
-  /* "pyfftw/pyfftw.pyx":704
- *         self.__howmany_dims = NULL
+    /* "pyfftw/pyfftw.pyx":358
  * 
- *         self.__axes = NULL             # <<<<<<<<<<<<<<
- *         self.__not_axes = NULL
+ *     for n in range(axes_length - 1):
+ *         if not out_shape[axes[n]] == in_shape[axes[n]]:             # <<<<<<<<<<<<<<
+ *             return False
  * 
  */
-  __pyx_v_self->__pyx___axes = NULL;
+    __pyx_t_1 = ((!(((__pyx_v_out_shape[(__pyx_v_axes[__pyx_v_n])]) == (__pyx_v_in_shape[(__pyx_v_axes[__pyx_v_n])])) != 0)) != 0);
+    if (__pyx_t_1) {
 
-  /* "pyfftw/pyfftw.pyx":705
- * 
- *         self.__axes = NULL
- *         self.__not_axes = NULL             # <<<<<<<<<<<<<<
+      /* "pyfftw/pyfftw.pyx":359
+ *     for n in range(axes_length - 1):
+ *         if not out_shape[axes[n]] == in_shape[axes[n]]:
+ *             return False             # <<<<<<<<<<<<<<
  * 
- *         flags = list(flags)
+ *     # The critical axis is the last of those over which the
  */
-  __pyx_v_self->__pyx___not_axes = NULL;
+      __pyx_r = 0;
+      goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":707
- *         self.__not_axes = NULL
+      /* "pyfftw/pyfftw.pyx":358
  * 
- *         flags = list(flags)             # <<<<<<<<<<<<<<
+ *     for n in range(axes_length - 1):
+ *         if not out_shape[axes[n]] == in_shape[axes[n]]:             # <<<<<<<<<<<<<<
+ *             return False
  * 
- *         cdef double _planning_timelimit
  */
-  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_INCREF(__pyx_v_flags);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_flags);
-  __Pyx_GIVEREF(__pyx_v_flags);
-  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)(&PyList_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_v_flags);
-  __pyx_v_flags = __pyx_t_2;
-  __pyx_t_2 = 0;
+    }
+  }
 
-  /* "pyfftw/pyfftw.pyx":710
+  /* "pyfftw/pyfftw.pyx":363
+ *     # The critical axis is the last of those over which the
+ *     # FFT is taken.
+ *     if not (out_shape[axes[axes_length-1]]             # <<<<<<<<<<<<<<
+ *             == in_shape[axes[axes_length-1]]//2 + 1):
+ *         return False
+ */
+  __pyx_t_1 = ((!(((__pyx_v_out_shape[(__pyx_v_axes[(__pyx_v_axes_length - 1)])]) == (__Pyx_div_long((__pyx_v_in_shape[(__pyx_v_axes[(__pyx_v_axes_length - 1)])]), 2) + 1)) != 0)) != 0);
+  if (__pyx_t_1) {
+
+    /* "pyfftw/pyfftw.pyx":365
+ *     if not (out_shape[axes[axes_length-1]]
+ *             == in_shape[axes[axes_length-1]]//2 + 1):
+ *         return False             # <<<<<<<<<<<<<<
  * 
- *         cdef double _planning_timelimit
- *         if planning_timelimit is None:             # <<<<<<<<<<<<<<
- *             _planning_timelimit = FFTW_NO_TIMELIMIT
- *         else:
+ *     for n in range(input_array.ndim - axes_length):
  */
-  __pyx_t_3 = (__pyx_v_planning_timelimit == Py_None);
-  if (__pyx_t_3) {
+    __pyx_r = 0;
+    goto __pyx_L0;
 
-    /* "pyfftw/pyfftw.pyx":711
- *         cdef double _planning_timelimit
- *         if planning_timelimit is None:
- *             _planning_timelimit = FFTW_NO_TIMELIMIT             # <<<<<<<<<<<<<<
- *         else:
- *             try:
+    /* "pyfftw/pyfftw.pyx":363
+ *     # The critical axis is the last of those over which the
+ *     # FFT is taken.
+ *     if not (out_shape[axes[axes_length-1]]             # <<<<<<<<<<<<<<
+ *             == in_shape[axes[axes_length-1]]//2 + 1):
+ *         return False
  */
-    __pyx_v__planning_timelimit = FFTW_NO_TIMELIMIT;
-    goto __pyx_L3;
   }
-  /*else*/ {
 
-    /* "pyfftw/pyfftw.pyx":713
- *             _planning_timelimit = FFTW_NO_TIMELIMIT
- *         else:
- *             try:             # <<<<<<<<<<<<<<
- *                 _planning_timelimit = planning_timelimit
- *             except TypeError:
+  /* "pyfftw/pyfftw.pyx":367
+ *         return False
+ * 
+ *     for n in range(input_array.ndim - axes_length):             # <<<<<<<<<<<<<<
+ *         if not out_shape[not_axes[n]] == in_shape[not_axes[n]]:
+ *             return False
  */
-    {
-      __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
-      __Pyx_XGOTREF(__pyx_t_4);
-      __Pyx_XGOTREF(__pyx_t_5);
-      __Pyx_XGOTREF(__pyx_t_6);
-      /*try:*/ {
+  __pyx_t_3 = (__pyx_v_input_array->nd - __pyx_v_axes_length);
+  for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+    __pyx_v_n = __pyx_t_4;
 
-        /* "pyfftw/pyfftw.pyx":714
- *         else:
- *             try:
- *                 _planning_timelimit = planning_timelimit             # <<<<<<<<<<<<<<
- *             except TypeError:
- *                 raise TypeError('Invalid planning timelimit: '
+    /* "pyfftw/pyfftw.pyx":368
+ * 
+ *     for n in range(input_array.ndim - axes_length):
+ *         if not out_shape[not_axes[n]] == in_shape[not_axes[n]]:             # <<<<<<<<<<<<<<
+ *             return False
+ * 
  */
-        __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_v_planning_timelimit); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 714; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
-        __pyx_v__planning_timelimit = __pyx_t_7;
-      }
-      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-      goto __pyx_L11_try_end;
-      __pyx_L4_error:;
-      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_1 = ((!(((__pyx_v_out_shape[(__pyx_v_not_axes[__pyx_v_n])]) == (__pyx_v_in_shape[(__pyx_v_not_axes[__pyx_v_n])])) != 0)) != 0);
+    if (__pyx_t_1) {
 
-      /* "pyfftw/pyfftw.pyx":715
- *             try:
- *                 _planning_timelimit = planning_timelimit
- *             except TypeError:             # <<<<<<<<<<<<<<
- *                 raise TypeError('Invalid planning timelimit: '
- *                         'The planning timelimit needs to be a float.')
+      /* "pyfftw/pyfftw.pyx":369
+ *     for n in range(input_array.ndim - axes_length):
+ *         if not out_shape[not_axes[n]] == in_shape[not_axes[n]]:
+ *             return False             # <<<<<<<<<<<<<<
+ * 
+ *     return True
  */
-      __pyx_t_8 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
-      if (__pyx_t_8) {
-        __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-        if (__Pyx_GetException(&__pyx_t_2, &__pyx_t_1, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 715; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
-        __Pyx_GOTREF(__pyx_t_2);
-        __Pyx_GOTREF(__pyx_t_1);
-        __Pyx_GOTREF(__pyx_t_9);
+      __pyx_r = 0;
+      goto __pyx_L0;
 
-        /* "pyfftw/pyfftw.pyx":716
- *                 _planning_timelimit = planning_timelimit
- *             except TypeError:
- *                 raise TypeError('Invalid planning timelimit: '             # <<<<<<<<<<<<<<
- *                         'The planning timelimit needs to be a float.')
+      /* "pyfftw/pyfftw.pyx":368
+ * 
+ *     for n in range(input_array.ndim - axes_length):
+ *         if not out_shape[not_axes[n]] == in_shape[not_axes[n]]:             # <<<<<<<<<<<<<<
+ *             return False
  * 
  */
-        __pyx_t_10 = PyObject_Call(__pyx_builtin_TypeError, ((PyObject *)__pyx_k_tuple_8), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
-        __Pyx_GOTREF(__pyx_t_10);
-        __Pyx_Raise(__pyx_t_10, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
-        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-        goto __pyx_L5_exception_handled;
-      }
-      __pyx_L6_except_error:;
-      __Pyx_XGIVEREF(__pyx_t_4);
-      __Pyx_XGIVEREF(__pyx_t_5);
-      __Pyx_XGIVEREF(__pyx_t_6);
-      __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
-      goto __pyx_L1_error;
-      __pyx_L5_exception_handled:;
-      __Pyx_XGIVEREF(__pyx_t_4);
-      __Pyx_XGIVEREF(__pyx_t_5);
-      __Pyx_XGIVEREF(__pyx_t_6);
-      __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
-      __pyx_L11_try_end:;
     }
   }
-  __pyx_L3:;
 
-  /* "pyfftw/pyfftw.pyx":719
- *                         'The planning timelimit needs to be a float.')
+  /* "pyfftw/pyfftw.pyx":371
+ *             return False
+ * 
+ *     return True             # <<<<<<<<<<<<<<
+ * 
  * 
- *         if not isinstance(input_array, np.ndarray):             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid input array: '
- *                     'The input array needs to be an instance '
  */
-  __pyx_t_9 = ((PyObject *)((PyObject*)__pyx_ptype_5numpy_ndarray));
-  __Pyx_INCREF(__pyx_t_9);
-  __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_input_array, __pyx_t_9); 
-  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-  __pyx_t_11 = (!__pyx_t_3);
-  if (__pyx_t_11) {
+  __pyx_r = 1;
+  goto __pyx_L0;
+
+  /* "pyfftw/pyfftw.pyx":343
+ * # Validator functions
+ * # ===================
+ * cdef bint _validate_r2c_arrays(np.ndarray input_array,             # <<<<<<<<<<<<<<
+ *         np.ndarray output_array, int64_t *axes, int64_t *not_axes,
+ *         int64_t axes_length):
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-    /* "pyfftw/pyfftw.pyx":720
+/* "pyfftw/pyfftw.pyx":374
  * 
- *         if not isinstance(input_array, np.ndarray):
- *             raise ValueError('Invalid input array: '             # <<<<<<<<<<<<<<
- *                     'The input array needs to be an instance '
- *                     'of numpy.ndarray')
+ * 
+ * cdef bint _validate_c2r_arrays(np.ndarray input_array,             # <<<<<<<<<<<<<<
+ *         np.ndarray output_array, int64_t *axes, int64_t *not_axes,
+ *         int64_t axes_length):
  */
-    __pyx_t_9 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_10), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    __Pyx_Raise(__pyx_t_9, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L14;
-  }
-  __pyx_L14:;
 
-  /* "pyfftw/pyfftw.pyx":724
- *                     'of numpy.ndarray')
+static int __pyx_f_6pyfftw_6pyfftw__validate_c2r_arrays(PyArrayObject *__pyx_v_input_array, PyArrayObject *__pyx_v_output_array, int64_t *__pyx_v_axes, int64_t *__pyx_v_not_axes, int64_t __pyx_v_axes_length) {
+  npy_intp *__pyx_v_in_shape;
+  npy_intp *__pyx_v_out_shape;
+  int64_t __pyx_v_n;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  npy_intp *__pyx_t_2;
+  int64_t __pyx_t_3;
+  int64_t __pyx_t_4;
+  __Pyx_RefNannySetupContext("_validate_c2r_arrays", 0);
+
+  /* "pyfftw/pyfftw.pyx":383
+ *     # We firstly need to confirm that the dimenions of the arrays
+ *     # are the same
+ *     if not (input_array.ndim == output_array.ndim):             # <<<<<<<<<<<<<<
+ *         return False
  * 
- *         if not isinstance(output_array, np.ndarray):             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid output array: '
- *                     'The output array needs to be an instance '
  */
-  __pyx_t_9 = ((PyObject *)((PyObject*)__pyx_ptype_5numpy_ndarray));
-  __Pyx_INCREF(__pyx_t_9);
-  __pyx_t_11 = __Pyx_TypeCheck(__pyx_v_output_array, __pyx_t_9); 
-  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-  __pyx_t_3 = (!__pyx_t_11);
-  if (__pyx_t_3) {
+  __pyx_t_1 = ((!((__pyx_v_input_array->nd == __pyx_v_output_array->nd) != 0)) != 0);
+  if (__pyx_t_1) {
 
-    /* "pyfftw/pyfftw.pyx":725
+    /* "pyfftw/pyfftw.pyx":384
+ *     # are the same
+ *     if not (input_array.ndim == output_array.ndim):
+ *         return False             # <<<<<<<<<<<<<<
+ * 
+ *     in_shape = input_array.shape
+ */
+    __pyx_r = 0;
+    goto __pyx_L0;
+
+    /* "pyfftw/pyfftw.pyx":383
+ *     # We firstly need to confirm that the dimenions of the arrays
+ *     # are the same
+ *     if not (input_array.ndim == output_array.ndim):             # <<<<<<<<<<<<<<
+ *         return False
  * 
- *         if not isinstance(output_array, np.ndarray):
- *             raise ValueError('Invalid output array: '             # <<<<<<<<<<<<<<
- *                     'The output array needs to be an instance '
- *                     'of numpy.ndarray')
  */
-    __pyx_t_9 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_12), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    __Pyx_Raise(__pyx_t_9, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L15;
   }
-  __pyx_L15:;
 
-  /* "pyfftw/pyfftw.pyx":729
- *                     'of numpy.ndarray')
+  /* "pyfftw/pyfftw.pyx":386
+ *         return False
+ * 
+ *     in_shape = input_array.shape             # <<<<<<<<<<<<<<
+ *     out_shape = output_array.shape
  * 
- *         try:             # <<<<<<<<<<<<<<
- *             input_dtype = input_array.dtype
- *             output_dtype = output_array.dtype
  */
-  {
-    __Pyx_ExceptionSave(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
-    __Pyx_XGOTREF(__pyx_t_6);
-    __Pyx_XGOTREF(__pyx_t_5);
-    __Pyx_XGOTREF(__pyx_t_4);
-    /*try:*/ {
+  __pyx_t_2 = __pyx_v_input_array->dimensions;
+  __pyx_v_in_shape = __pyx_t_2;
 
-      /* "pyfftw/pyfftw.pyx":730
+  /* "pyfftw/pyfftw.pyx":387
  * 
- *         try:
- *             input_dtype = input_array.dtype             # <<<<<<<<<<<<<<
- *             output_dtype = output_array.dtype
- *             scheme = fftw_schemes[(input_dtype, output_dtype)]
+ *     in_shape = input_array.shape
+ *     out_shape = output_array.shape             # <<<<<<<<<<<<<<
+ * 
+ *     for n in range(axes_length - 1):
  */
-      __pyx_t_9 = PyObject_GetAttr(__pyx_v_input_array, __pyx_n_s__dtype); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 730; __pyx_clineno = __LINE__; goto __pyx_L16_error;}
-      __Pyx_GOTREF(__pyx_t_9);
-      __pyx_v_input_dtype = __pyx_t_9;
-      __pyx_t_9 = 0;
+  __pyx_t_2 = __pyx_v_output_array->dimensions;
+  __pyx_v_out_shape = __pyx_t_2;
 
-      /* "pyfftw/pyfftw.pyx":731
- *         try:
- *             input_dtype = input_array.dtype
- *             output_dtype = output_array.dtype             # <<<<<<<<<<<<<<
- *             scheme = fftw_schemes[(input_dtype, output_dtype)]
- *         except KeyError:
+  /* "pyfftw/pyfftw.pyx":389
+ *     out_shape = output_array.shape
+ * 
+ *     for n in range(axes_length - 1):             # <<<<<<<<<<<<<<
+ *         if not in_shape[axes[n]] == out_shape[axes[n]]:
+ *             return False
  */
-      __pyx_t_9 = PyObject_GetAttr(__pyx_v_output_array, __pyx_n_s__dtype); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; __pyx_clineno = __LINE__; goto __pyx_L16_error;}
-      __Pyx_GOTREF(__pyx_t_9);
-      __pyx_v_output_dtype = __pyx_t_9;
-      __pyx_t_9 = 0;
+  __pyx_t_3 = (__pyx_v_axes_length - 1);
+  for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+    __pyx_v_n = __pyx_t_4;
 
-      /* "pyfftw/pyfftw.pyx":732
- *             input_dtype = input_array.dtype
- *             output_dtype = output_array.dtype
- *             scheme = fftw_schemes[(input_dtype, output_dtype)]             # <<<<<<<<<<<<<<
- *         except KeyError:
- *             raise ValueError('Invalid scheme: '
+    /* "pyfftw/pyfftw.pyx":390
+ * 
+ *     for n in range(axes_length - 1):
+ *         if not in_shape[axes[n]] == out_shape[axes[n]]:             # <<<<<<<<<<<<<<
+ *             return False
+ * 
  */
-      __pyx_t_9 = PyTuple_New(2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 732; __pyx_clineno = __LINE__; goto __pyx_L16_error;}
-      __Pyx_GOTREF(__pyx_t_9);
-      __Pyx_INCREF(__pyx_v_input_dtype);
-      PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_v_input_dtype);
-      __Pyx_GIVEREF(__pyx_v_input_dtype);
-      __Pyx_INCREF(__pyx_v_output_dtype);
-      PyTuple_SET_ITEM(__pyx_t_9, 1, __pyx_v_output_dtype);
-      __Pyx_GIVEREF(__pyx_v_output_dtype);
-      __pyx_t_1 = PyObject_GetItem(__pyx_v_6pyfftw_6pyfftw_fftw_schemes, ((PyObject *)__pyx_t_9)); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 732; __pyx_clineno = __LINE__; goto __pyx_L16_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
-      __pyx_v_scheme = __pyx_t_1;
-      __pyx_t_1 = 0;
-    }
-    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-    goto __pyx_L23_try_end;
-    __pyx_L16_error:;
-    __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
-    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
-    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_1 = ((!(((__pyx_v_in_shape[(__pyx_v_axes[__pyx_v_n])]) == (__pyx_v_out_shape[(__pyx_v_axes[__pyx_v_n])])) != 0)) != 0);
+    if (__pyx_t_1) {
 
-    /* "pyfftw/pyfftw.pyx":733
- *             output_dtype = output_array.dtype
- *             scheme = fftw_schemes[(input_dtype, output_dtype)]
- *         except KeyError:             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid scheme: '
- *                     'The output array and input array dtypes '
+      /* "pyfftw/pyfftw.pyx":391
+ *     for n in range(axes_length - 1):
+ *         if not in_shape[axes[n]] == out_shape[axes[n]]:
+ *             return False             # <<<<<<<<<<<<<<
+ * 
+ *     # The critical axis is the last of those over which the
  */
-    __pyx_t_8 = PyErr_ExceptionMatches(__pyx_builtin_KeyError);
-    if (__pyx_t_8) {
-      __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-      if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_9, &__pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 733; __pyx_clineno = __LINE__; goto __pyx_L18_except_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_GOTREF(__pyx_t_9);
-      __Pyx_GOTREF(__pyx_t_2);
+      __pyx_r = 0;
+      goto __pyx_L0;
 
-      /* "pyfftw/pyfftw.pyx":734
- *             scheme = fftw_schemes[(input_dtype, output_dtype)]
- *         except KeyError:
- *             raise ValueError('Invalid scheme: '             # <<<<<<<<<<<<<<
- *                     'The output array and input array dtypes '
- *                     'do not correspond to a valid fftw scheme.')
+      /* "pyfftw/pyfftw.pyx":390
+ * 
+ *     for n in range(axes_length - 1):
+ *         if not in_shape[axes[n]] == out_shape[axes[n]]:             # <<<<<<<<<<<<<<
+ *             return False
+ * 
  */
-      __pyx_t_10 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_14), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L18_except_error;}
-      __Pyx_GOTREF(__pyx_t_10);
-      __Pyx_Raise(__pyx_t_10, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L18_except_error;}
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      goto __pyx_L17_exception_handled;
     }
-    __pyx_L18_except_error:;
-    __Pyx_XGIVEREF(__pyx_t_6);
-    __Pyx_XGIVEREF(__pyx_t_5);
-    __Pyx_XGIVEREF(__pyx_t_4);
-    __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_5, __pyx_t_4);
-    goto __pyx_L1_error;
-    __pyx_L17_exception_handled:;
-    __Pyx_XGIVEREF(__pyx_t_6);
-    __Pyx_XGIVEREF(__pyx_t_5);
-    __Pyx_XGIVEREF(__pyx_t_4);
-    __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_5, __pyx_t_4);
-    __pyx_L23_try_end:;
   }
 
-  /* "pyfftw/pyfftw.pyx":738
- *                     'do not correspond to a valid fftw scheme.')
- * 
- *         self.__input_dtype = input_dtype             # <<<<<<<<<<<<<<
- *         self.__output_dtype = output_dtype
- * 
+  /* "pyfftw/pyfftw.pyx":395
+ *     # The critical axis is the last of those over which the
+ *     # FFT is taken.
+ *     if not (in_shape[axes[axes_length-1]]             # <<<<<<<<<<<<<<
+ *             == out_shape[axes[axes_length-1]]//2 + 1):
+ *         return False
  */
-  __Pyx_INCREF(__pyx_v_input_dtype);
-  __Pyx_GIVEREF(__pyx_v_input_dtype);
-  __Pyx_GOTREF(__pyx_v_self->__pyx___input_dtype);
-  __Pyx_DECREF(__pyx_v_self->__pyx___input_dtype);
-  __pyx_v_self->__pyx___input_dtype = __pyx_v_input_dtype;
+  __pyx_t_1 = ((!(((__pyx_v_in_shape[(__pyx_v_axes[(__pyx_v_axes_length - 1)])]) == (__Pyx_div_long((__pyx_v_out_shape[(__pyx_v_axes[(__pyx_v_axes_length - 1)])]), 2) + 1)) != 0)) != 0);
+  if (__pyx_t_1) {
 
-  /* "pyfftw/pyfftw.pyx":739
- * 
- *         self.__input_dtype = input_dtype
- *         self.__output_dtype = output_dtype             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":397
+ *     if not (in_shape[axes[axes_length-1]]
+ *             == out_shape[axes[axes_length-1]]//2 + 1):
+ *         return False             # <<<<<<<<<<<<<<
  * 
- *         functions = scheme_functions[scheme]
+ *     for n in range(input_array.ndim - axes_length):
  */
-  __Pyx_INCREF(__pyx_v_output_dtype);
-  __Pyx_GIVEREF(__pyx_v_output_dtype);
-  __Pyx_GOTREF(__pyx_v_self->__pyx___output_dtype);
-  __Pyx_DECREF(__pyx_v_self->__pyx___output_dtype);
-  __pyx_v_self->__pyx___output_dtype = __pyx_v_output_dtype;
+    __pyx_r = 0;
+    goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":741
- *         self.__output_dtype = output_dtype
- * 
- *         functions = scheme_functions[scheme]             # <<<<<<<<<<<<<<
- * 
- *         self.__fftw_planner = planners[functions['planner']]
+    /* "pyfftw/pyfftw.pyx":395
+ *     # The critical axis is the last of those over which the
+ *     # FFT is taken.
+ *     if not (in_shape[axes[axes_length-1]]             # <<<<<<<<<<<<<<
+ *             == out_shape[axes[axes_length-1]]//2 + 1):
+ *         return False
  */
-  __pyx_t_2 = PyObject_GetItem(__pyx_v_6pyfftw_6pyfftw_scheme_functions, __pyx_v_scheme); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 741; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_v_functions = __pyx_t_2;
-  __pyx_t_2 = 0;
+  }
 
-  /* "pyfftw/pyfftw.pyx":743
- *         functions = scheme_functions[scheme]
+  /* "pyfftw/pyfftw.pyx":399
+ *         return False
  * 
- *         self.__fftw_planner = planners[functions['planner']]             # <<<<<<<<<<<<<<
- *         self.__fftw_execute = executors[functions['executor']]
- *         self.__fftw_destroy = destroyers[functions['generic_precision']]
+ *     for n in range(input_array.ndim - axes_length):             # <<<<<<<<<<<<<<
+ *         if not in_shape[not_axes[n]] == out_shape[not_axes[n]]:
+ *             return False
  */
-  __pyx_t_2 = PyObject_GetItem(__pyx_v_functions, ((PyObject *)__pyx_n_s__planner)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_2); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 743; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_v_self->__pyx___fftw_planner = (__pyx_v_6pyfftw_6pyfftw_planners[__pyx_t_12]);
+  __pyx_t_3 = (__pyx_v_input_array->nd - __pyx_v_axes_length);
+  for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_3; __pyx_t_4+=1) {
+    __pyx_v_n = __pyx_t_4;
 
-  /* "pyfftw/pyfftw.pyx":744
+    /* "pyfftw/pyfftw.pyx":400
  * 
- *         self.__fftw_planner = planners[functions['planner']]
- *         self.__fftw_execute = executors[functions['executor']]             # <<<<<<<<<<<<<<
- *         self.__fftw_destroy = destroyers[functions['generic_precision']]
+ *     for n in range(input_array.ndim - axes_length):
+ *         if not in_shape[not_axes[n]] == out_shape[not_axes[n]]:             # <<<<<<<<<<<<<<
+ *             return False
  * 
  */
-  __pyx_t_2 = PyObject_GetItem(__pyx_v_functions, ((PyObject *)__pyx_n_s__executor)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_2); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 744; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_v_self->__pyx___fftw_execute = (__pyx_v_6pyfftw_6pyfftw_executors[__pyx_t_12]);
+    __pyx_t_1 = ((!(((__pyx_v_in_shape[(__pyx_v_not_axes[__pyx_v_n])]) == (__pyx_v_out_shape[(__pyx_v_not_axes[__pyx_v_n])])) != 0)) != 0);
+    if (__pyx_t_1) {
 
-  /* "pyfftw/pyfftw.pyx":745
- *         self.__fftw_planner = planners[functions['planner']]
- *         self.__fftw_execute = executors[functions['executor']]
- *         self.__fftw_destroy = destroyers[functions['generic_precision']]             # <<<<<<<<<<<<<<
+      /* "pyfftw/pyfftw.pyx":401
+ *     for n in range(input_array.ndim - axes_length):
+ *         if not in_shape[not_axes[n]] == out_shape[not_axes[n]]:
+ *             return False             # <<<<<<<<<<<<<<
  * 
- *         self.__nthreads_plan_setter = (
+ *     return True
  */
-  __pyx_t_2 = PyObject_GetItem(__pyx_v_functions, ((PyObject *)__pyx_n_s__generic_precision)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 745; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_2); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 745; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_v_self->__pyx___fftw_destroy = (__pyx_v_6pyfftw_6pyfftw_destroyers[__pyx_t_12]);
+      __pyx_r = 0;
+      goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":748
+      /* "pyfftw/pyfftw.pyx":400
  * 
- *         self.__nthreads_plan_setter = (
- *                 nthreads_plan_setters[functions['generic_precision']])             # <<<<<<<<<<<<<<
+ *     for n in range(input_array.ndim - axes_length):
+ *         if not in_shape[not_axes[n]] == out_shape[not_axes[n]]:             # <<<<<<<<<<<<<<
+ *             return False
  * 
- *         cdef fftw_generic_set_timelimit set_timelimit_func = (
  */
-  __pyx_t_2 = PyObject_GetItem(__pyx_v_functions, ((PyObject *)__pyx_n_s__generic_precision)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_2); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 748; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    }
+  }
 
-  /* "pyfftw/pyfftw.pyx":747
- *         self.__fftw_destroy = destroyers[functions['generic_precision']]
+  /* "pyfftw/pyfftw.pyx":403
+ *             return False
+ * 
+ *     return True             # <<<<<<<<<<<<<<
  * 
- *         self.__nthreads_plan_setter = (             # <<<<<<<<<<<<<<
- *                 nthreads_plan_setters[functions['generic_precision']])
  * 
  */
-  __pyx_v_self->__pyx___nthreads_plan_setter = (__pyx_v_6pyfftw_6pyfftw_nthreads_plan_setters[__pyx_t_12]);
+  __pyx_r = 1;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":751
+  /* "pyfftw/pyfftw.pyx":374
  * 
- *         cdef fftw_generic_set_timelimit set_timelimit_func = (
- *                 set_timelimit_funcs[functions['generic_precision']])             # <<<<<<<<<<<<<<
  * 
- *         # If either of the arrays is not aligned on a 16-byte boundary,
- */
-  __pyx_t_2 = PyObject_GetItem(__pyx_v_functions, ((PyObject *)__pyx_n_s__generic_precision)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_2); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 751; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_v_set_timelimit_func = (__pyx_v_6pyfftw_6pyfftw_set_timelimit_funcs[__pyx_t_12]);
-
-  /* "pyfftw/pyfftw.pyx":756
- *         # we set the FFTW_UNALIGNED flag. This disables SIMD.
- *         # (16 bytes is assumed to be the minimal alignment)
- *         if 'FFTW_UNALIGNED' in flags:             # <<<<<<<<<<<<<<
- *             self.__simd_allowed = False
- *             self.__input_array_alignment = self.__input_dtype.alignment
+ * cdef bint _validate_c2r_arrays(np.ndarray input_array,             # <<<<<<<<<<<<<<
+ *         np.ndarray output_array, int64_t *axes, int64_t *not_axes,
+ *         int64_t axes_length):
  */
-  __pyx_t_3 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_n_s__FFTW_UNALIGNED), __pyx_v_flags, Py_EQ)); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 756; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__pyx_t_3) {
 
-    /* "pyfftw/pyfftw.pyx":757
- *         # (16 bytes is assumed to be the minimal alignment)
- *         if 'FFTW_UNALIGNED' in flags:
- *             self.__simd_allowed = False             # <<<<<<<<<<<<<<
- *             self.__input_array_alignment = self.__input_dtype.alignment
- *             self.__output_array_alignment = self.__output_dtype.alignment
- */
-    __pyx_v_self->__pyx___simd_allowed = 0;
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-    /* "pyfftw/pyfftw.pyx":758
- *         if 'FFTW_UNALIGNED' in flags:
- *             self.__simd_allowed = False
- *             self.__input_array_alignment = self.__input_dtype.alignment             # <<<<<<<<<<<<<<
- *             self.__output_array_alignment = self.__output_dtype.alignment
+/* "pyfftw/pyfftw.pyx":408
+ * # Shape lookup functions
+ * # ======================
+ * def _lookup_shape_r2c_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
+ *     return input_array.shape
  * 
  */
-    __pyx_t_2 = PyObject_GetAttr(__pyx_v_self->__pyx___input_dtype, __pyx_n_s__alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 758; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_v_self->__pyx___input_array_alignment = __pyx_t_8;
 
-    /* "pyfftw/pyfftw.pyx":759
- *             self.__simd_allowed = False
- *             self.__input_array_alignment = self.__input_dtype.alignment
- *             self.__output_array_alignment = self.__output_dtype.alignment             # <<<<<<<<<<<<<<
- * 
- *         else:
- */
-    __pyx_t_2 = PyObject_GetAttr(__pyx_v_self->__pyx___output_dtype, __pyx_n_s__alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_2); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 759; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_v_self->__pyx___output_array_alignment = __pyx_t_8;
-    goto __pyx_L26;
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_17_lookup_shape_r2c_arrays(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_6pyfftw_6pyfftw_17_lookup_shape_r2c_arrays = {"_lookup_shape_r2c_arrays", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_17_lookup_shape_r2c_arrays, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_17_lookup_shape_r2c_arrays(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_input_array = 0;
+  CYTHON_UNUSED PyObject *__pyx_v_output_array = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_lookup_shape_r2c_arrays (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_array,&__pyx_n_s_output_array,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_array)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_array)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_lookup_shape_r2c_arrays", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_lookup_shape_r2c_arrays") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_input_array = values[0];
+    __pyx_v_output_array = values[1];
   }
-  /*else*/ {
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("_lookup_shape_r2c_arrays", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pyfftw.pyfftw._lookup_shape_r2c_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_16_lookup_shape_r2c_arrays(__pyx_self, __pyx_v_input_array, __pyx_v_output_array);
 
-    /* "pyfftw/pyfftw.pyx":763
- *         else:
- * 
- *             self.__input_array_alignment = -1             # <<<<<<<<<<<<<<
- *             self.__output_array_alignment = -1
- * 
- */
-    __pyx_v_self->__pyx___input_array_alignment = -1;
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-    /* "pyfftw/pyfftw.pyx":764
- * 
- *             self.__input_array_alignment = -1
- *             self.__output_array_alignment = -1             # <<<<<<<<<<<<<<
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_16_lookup_shape_r2c_arrays(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_input_array, CYTHON_UNUSED PyObject *__pyx_v_output_array) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_lookup_shape_r2c_arrays", 0);
+
+  /* "pyfftw/pyfftw.pyx":409
+ * # ======================
+ * def _lookup_shape_r2c_arrays(input_array, output_array):
+ *     return input_array.shape             # <<<<<<<<<<<<<<
  * 
- *             for each_alignment in _valid_simd_alignments:
+ * def _lookup_shape_c2r_arrays(input_array, output_array):
  */
-    __pyx_v_self->__pyx___output_array_alignment = -1;
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_array, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-    /* "pyfftw/pyfftw.pyx":766
- *             self.__output_array_alignment = -1
+  /* "pyfftw/pyfftw.pyx":408
+ * # Shape lookup functions
+ * # ======================
+ * def _lookup_shape_r2c_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
+ *     return input_array.shape
  * 
- *             for each_alignment in _valid_simd_alignments:             # <<<<<<<<<<<<<<
- *                 if (<intptr_t>np.PyArray_DATA(input_array) %
- *                         each_alignment == 0 and
  */
-    __pyx_t_2 = __Pyx_GetName(__pyx_m, __pyx_n_s_15); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 766; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    if (PyList_CheckExact(__pyx_t_2) || PyTuple_CheckExact(__pyx_t_2)) {
-      __pyx_t_9 = __pyx_t_2; __Pyx_INCREF(__pyx_t_9); __pyx_t_12 = 0;
-      __pyx_t_13 = NULL;
-    } else {
-      __pyx_t_12 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 766; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_13 = Py_TYPE(__pyx_t_9)->tp_iternext;
-    }
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    for (;;) {
-      if (!__pyx_t_13 && PyList_CheckExact(__pyx_t_9)) {
-        if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_9)) break;
-        #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_2 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_12); __Pyx_INCREF(__pyx_t_2); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 766; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #else
-        __pyx_t_2 = PySequence_ITEM(__pyx_t_9, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 766; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #endif
-      } else if (!__pyx_t_13 && PyTuple_CheckExact(__pyx_t_9)) {
-        if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_9)) break;
-        #if CYTHON_COMPILING_IN_CPYTHON
-        __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_12); __Pyx_INCREF(__pyx_t_2); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 766; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #else
-        __pyx_t_2 = PySequence_ITEM(__pyx_t_9, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 766; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        #endif
-      } else {
-        __pyx_t_2 = __pyx_t_13(__pyx_t_9);
-        if (unlikely(!__pyx_t_2)) {
-          if (PyErr_Occurred()) {
-            if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 766; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-          }
-          break;
-        }
-        __Pyx_GOTREF(__pyx_t_2);
-      }
-      __Pyx_XDECREF(__pyx_v_each_alignment);
-      __pyx_v_each_alignment = __pyx_t_2;
-      __pyx_t_2 = 0;
 
-      /* "pyfftw/pyfftw.pyx":767
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw._lookup_shape_r2c_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":411
+ *     return input_array.shape
+ * 
+ * def _lookup_shape_c2r_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
+ *     return output_array.shape
  * 
- *             for each_alignment in _valid_simd_alignments:
- *                 if (<intptr_t>np.PyArray_DATA(input_array) %             # <<<<<<<<<<<<<<
- *                         each_alignment == 0 and
- *                         <intptr_t>np.PyArray_DATA(output_array) %
  */
-      if (!(likely(((__pyx_v_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_2 = __pyx_v_input_array;
-      __Pyx_INCREF(__pyx_t_2);
-      __pyx_t_1 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_t_2)))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-      /* "pyfftw/pyfftw.pyx":768
- *             for each_alignment in _valid_simd_alignments:
- *                 if (<intptr_t>np.PyArray_DATA(input_array) %
- *                         each_alignment == 0 and             # <<<<<<<<<<<<<<
- *                         <intptr_t>np.PyArray_DATA(output_array) %
- *                         each_alignment == 0):
- */
-      __pyx_t_2 = PyNumber_Remainder(__pyx_t_1, __pyx_v_each_alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 767; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 768; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      if (__pyx_t_3) {
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_19_lookup_shape_c2r_arrays(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyMethodDef __pyx_mdef_6pyfftw_6pyfftw_19_lookup_shape_c2r_arrays = {"_lookup_shape_c2r_arrays", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_19_lookup_shape_c2r_arrays, METH_VARARGS|METH_KEYWORDS, 0};
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_19_lookup_shape_c2r_arrays(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  CYTHON_UNUSED PyObject *__pyx_v_input_array = 0;
+  PyObject *__pyx_v_output_array = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_lookup_shape_c2r_arrays (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_array,&__pyx_n_s_output_array,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_array)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_array)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("_lookup_shape_c2r_arrays", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_lookup_shape_c2r_arrays") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_input_array = values[0];
+    __pyx_v_output_array = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("_lookup_shape_c2r_arrays", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pyfftw.pyfftw._lookup_shape_c2r_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_18_lookup_shape_c2r_arrays(__pyx_self, __pyx_v_input_array, __pyx_v_output_array);
 
-        /* "pyfftw/pyfftw.pyx":769
- *                 if (<intptr_t>np.PyArray_DATA(input_array) %
- *                         each_alignment == 0 and
- *                         <intptr_t>np.PyArray_DATA(output_array) %             # <<<<<<<<<<<<<<
- *                         each_alignment == 0):
- * 
- */
-        if (!(likely(((__pyx_v_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_t_1 = __pyx_v_output_array;
-        __Pyx_INCREF(__pyx_t_1);
-        __pyx_t_2 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_t_1)))); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_2);
-        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-        /* "pyfftw/pyfftw.pyx":770
- *                         each_alignment == 0 and
- *                         <intptr_t>np.PyArray_DATA(output_array) %
- *                         each_alignment == 0):             # <<<<<<<<<<<<<<
- * 
- *                     self.__simd_allowed = True
- */
-        __pyx_t_1 = PyNumber_Remainder(__pyx_t_2, __pyx_v_each_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_1);
-        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-        __pyx_t_14 = __pyx_t_11;
-      } else {
-        __pyx_t_14 = __pyx_t_3;
-      }
-      if (__pyx_t_14) {
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_18_lookup_shape_c2r_arrays(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_lookup_shape_c2r_arrays", 0);
 
-        /* "pyfftw/pyfftw.pyx":772
- *                         each_alignment == 0):
+  /* "pyfftw/pyfftw.pyx":412
  * 
- *                     self.__simd_allowed = True             # <<<<<<<<<<<<<<
+ * def _lookup_shape_c2r_arrays(input_array, output_array):
+ *     return output_array.shape             # <<<<<<<<<<<<<<
  * 
- *                     self.__input_array_alignment = each_alignment
+ * # fftw_schemes is a dictionary with a mapping from a keys,
  */
-        __pyx_v_self->__pyx___simd_allowed = 1;
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_array, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-        /* "pyfftw/pyfftw.pyx":774
- *                     self.__simd_allowed = True
+  /* "pyfftw/pyfftw.pyx":411
+ *     return input_array.shape
  * 
- *                     self.__input_array_alignment = each_alignment             # <<<<<<<<<<<<<<
- *                     self.__output_array_alignment = each_alignment
+ * def _lookup_shape_c2r_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
+ *     return output_array.shape
  * 
  */
-        __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_v_each_alignment); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 774; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_v_self->__pyx___input_array_alignment = __pyx_t_8;
 
-        /* "pyfftw/pyfftw.pyx":775
- * 
- *                     self.__input_array_alignment = each_alignment
- *                     self.__output_array_alignment = each_alignment             # <<<<<<<<<<<<<<
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw._lookup_shape_c2r_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":518
  * 
- *                     break
+ * # Set the cleanup routine
+ * cdef void _cleanup():             # <<<<<<<<<<<<<<
+ *     fftw_cleanup()
+ *     fftwf_cleanup()
  */
-        __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_v_each_alignment); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __pyx_v_self->__pyx___output_array_alignment = __pyx_t_8;
 
-        /* "pyfftw/pyfftw.pyx":777
- *                     self.__output_array_alignment = each_alignment
- * 
- *                     break             # <<<<<<<<<<<<<<
- * 
- *             if (self.__input_array_alignment == -1 or
+static void __pyx_f_6pyfftw_6pyfftw__cleanup(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_cleanup", 0);
+
+  /* "pyfftw/pyfftw.pyx":519
+ * # Set the cleanup routine
+ * cdef void _cleanup():
+ *     fftw_cleanup()             # <<<<<<<<<<<<<<
+ *     fftwf_cleanup()
+ *     fftwl_cleanup()
  */
-        goto __pyx_L28_break;
-        goto __pyx_L29;
-      }
-      __pyx_L29:;
-    }
-    __pyx_L28_break:;
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  fftw_cleanup();
 
-    /* "pyfftw/pyfftw.pyx":779
- *                     break
- * 
- *             if (self.__input_array_alignment == -1 or             # <<<<<<<<<<<<<<
- *                     self.__output_array_alignment == -1):
- * 
+  /* "pyfftw/pyfftw.pyx":520
+ * cdef void _cleanup():
+ *     fftw_cleanup()
+ *     fftwf_cleanup()             # <<<<<<<<<<<<<<
+ *     fftwl_cleanup()
+ *     fftw_cleanup_threads()
  */
-    __pyx_t_14 = (__pyx_v_self->__pyx___input_array_alignment == -1);
-    if (!__pyx_t_14) {
+  fftwf_cleanup();
 
-      /* "pyfftw/pyfftw.pyx":780
- * 
- *             if (self.__input_array_alignment == -1 or
- *                     self.__output_array_alignment == -1):             # <<<<<<<<<<<<<<
- * 
- *                 self.__simd_allowed = False
+  /* "pyfftw/pyfftw.pyx":521
+ *     fftw_cleanup()
+ *     fftwf_cleanup()
+ *     fftwl_cleanup()             # <<<<<<<<<<<<<<
+ *     fftw_cleanup_threads()
+ *     fftwf_cleanup_threads()
  */
-      __pyx_t_3 = (__pyx_v_self->__pyx___output_array_alignment == -1);
-      __pyx_t_11 = __pyx_t_3;
-    } else {
-      __pyx_t_11 = __pyx_t_14;
-    }
-    if (__pyx_t_11) {
+  fftwl_cleanup();
 
-      /* "pyfftw/pyfftw.pyx":782
- *                     self.__output_array_alignment == -1):
- * 
- *                 self.__simd_allowed = False             # <<<<<<<<<<<<<<
- * 
- *                 self.__input_array_alignment = (
+  /* "pyfftw/pyfftw.pyx":522
+ *     fftwf_cleanup()
+ *     fftwl_cleanup()
+ *     fftw_cleanup_threads()             # <<<<<<<<<<<<<<
+ *     fftwf_cleanup_threads()
+ *     fftwl_cleanup_threads()
  */
-      __pyx_v_self->__pyx___simd_allowed = 0;
+  fftw_cleanup_threads();
 
-      /* "pyfftw/pyfftw.pyx":785
+  /* "pyfftw/pyfftw.pyx":523
+ *     fftwl_cleanup()
+ *     fftw_cleanup_threads()
+ *     fftwf_cleanup_threads()             # <<<<<<<<<<<<<<
+ *     fftwl_cleanup_threads()
  * 
- *                 self.__input_array_alignment = (
- *                         self.__input_dtype.alignment)             # <<<<<<<<<<<<<<
- *                 self.__output_array_alignment = (
- *                         self.__output_dtype.alignment)
  */
-      __pyx_t_9 = PyObject_GetAttr(__pyx_v_self->__pyx___input_dtype, __pyx_n_s__alignment); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 785; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 785; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  fftwf_cleanup_threads();
 
-      /* "pyfftw/pyfftw.pyx":784
- *                 self.__simd_allowed = False
+  /* "pyfftw/pyfftw.pyx":524
+ *     fftw_cleanup_threads()
+ *     fftwf_cleanup_threads()
+ *     fftwl_cleanup_threads()             # <<<<<<<<<<<<<<
  * 
- *                 self.__input_array_alignment = (             # <<<<<<<<<<<<<<
- *                         self.__input_dtype.alignment)
- *                 self.__output_array_alignment = (
+ * Py_AtExit(_cleanup)
  */
-      __pyx_v_self->__pyx___input_array_alignment = __pyx_t_8;
+  fftwl_cleanup_threads();
 
-      /* "pyfftw/pyfftw.pyx":787
- *                         self.__input_dtype.alignment)
- *                 self.__output_array_alignment = (
- *                         self.__output_dtype.alignment)             # <<<<<<<<<<<<<<
- *                 flags.append('FFTW_UNALIGNED')
+  /* "pyfftw/pyfftw.pyx":518
  * 
+ * # Set the cleanup routine
+ * cdef void _cleanup():             # <<<<<<<<<<<<<<
+ *     fftw_cleanup()
+ *     fftwf_cleanup()
  */
-      __pyx_t_9 = PyObject_GetAttr(__pyx_v_self->__pyx___output_dtype, __pyx_n_s__alignment); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 787; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 787; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-      /* "pyfftw/pyfftw.pyx":786
- *                 self.__input_array_alignment = (
- *                         self.__input_dtype.alignment)
- *                 self.__output_array_alignment = (             # <<<<<<<<<<<<<<
- *                         self.__output_dtype.alignment)
- *                 flags.append('FFTW_UNALIGNED')
- */
-      __pyx_v_self->__pyx___output_array_alignment = __pyx_t_8;
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
 
-      /* "pyfftw/pyfftw.pyx":788
- *                 self.__output_array_alignment = (
- *                         self.__output_dtype.alignment)
- *                 flags.append('FFTW_UNALIGNED')             # <<<<<<<<<<<<<<
+/* "pyfftw/pyfftw.pyx":529
  * 
- *         if (not (<intptr_t>np.PyArray_DATA(input_array)
+ * # Helper functions
+ * cdef void make_axes_unique(int64_t *axes, int64_t axes_length,             # <<<<<<<<<<<<<<
+ *         int64_t **unique_axes, int64_t **not_axes, int64_t dimensions,
+ *         int64_t *unique_axes_length):
  */
-      __pyx_t_9 = __Pyx_PyObject_Append(__pyx_v_flags, ((PyObject *)__pyx_n_s__FFTW_UNALIGNED)); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 788; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_9);
-      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-      goto __pyx_L30;
-    }
-    __pyx_L30:;
-  }
-  __pyx_L26:;
 
-  /* "pyfftw/pyfftw.pyx":790
- *                 flags.append('FFTW_UNALIGNED')
+static void __pyx_f_6pyfftw_6pyfftw_make_axes_unique(int64_t *__pyx_v_axes, int64_t __pyx_v_axes_length, int64_t **__pyx_v_unique_axes, int64_t **__pyx_v_not_axes, int64_t __pyx_v_dimensions, int64_t *__pyx_v_unique_axes_length) {
+  int64_t __pyx_v_unique_axes_count;
+  int64_t __pyx_v_holding_offset;
+  int64_t *__pyx_v_axes_holding;
+  int64_t *__pyx_v_axes_holding_offset;
+  int64_t __pyx_v_n;
+  int64_t __pyx_v_not_axes_count;
+  __Pyx_RefNannyDeclarations
+  int64_t __pyx_t_1;
+  int64_t __pyx_t_2;
+  int __pyx_t_3;
+  __Pyx_RefNannySetupContext("make_axes_unique", 0);
+
+  /* "pyfftw/pyfftw.pyx":544
+ *     '''
+ * 
+ *     cdef int64_t unique_axes_count = 0             # <<<<<<<<<<<<<<
+ *     cdef int64_t holding_offset = 0
  * 
- *         if (not (<intptr_t>np.PyArray_DATA(input_array)             # <<<<<<<<<<<<<<
- *             % self.__input_array_alignment == 0)):
- *             raise ValueError('Invalid input alignment: '
  */
-  if (!(likely(((__pyx_v_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 790; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_9 = __pyx_v_input_array;
-  __Pyx_INCREF(__pyx_t_9);
-  __pyx_t_15 = ((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_t_9)));
-  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  __pyx_v_unique_axes_count = 0;
 
-  /* "pyfftw/pyfftw.pyx":791
+  /* "pyfftw/pyfftw.pyx":545
  * 
- *         if (not (<intptr_t>np.PyArray_DATA(input_array)
- *             % self.__input_array_alignment == 0)):             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid input alignment: '
- *                     'The input array is expected to lie on a %d '
+ *     cdef int64_t unique_axes_count = 0
+ *     cdef int64_t holding_offset = 0             # <<<<<<<<<<<<<<
+ * 
+ *     cdef int64_t *axes_holding = (
  */
-  if (unlikely(__pyx_v_self->__pyx___input_array_alignment == 0)) {
-    PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_t_11 = (!(__Pyx_mod_intptr_t(__pyx_t_15, __pyx_v_self->__pyx___input_array_alignment) == 0));
-  if (__pyx_t_11) {
+  __pyx_v_holding_offset = 0;
 
-    /* "pyfftw/pyfftw.pyx":794
- *             raise ValueError('Invalid input alignment: '
- *                     'The input array is expected to lie on a %d '
- *                     'byte boundary.' % self.__input_array_alignment)             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":548
  * 
- *         if (not (<intptr_t>np.PyArray_DATA(output_array)
+ *     cdef int64_t *axes_holding = (
+ *             <int64_t *>calloc(dimensions, sizeof(int64_t)))             # <<<<<<<<<<<<<<
+ *     cdef int64_t *axes_holding_offset = (
+ *             <int64_t *>calloc(dimensions, sizeof(int64_t)))
  */
-    __pyx_t_9 = PyInt_FromLong(__pyx_v_self->__pyx___input_array_alignment); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_16), __pyx_t_9); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 792; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    PyTuple_SET_ITEM(__pyx_t_9, 0, ((PyObject *)__pyx_t_2));
-    __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
-    __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 792; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
-    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 792; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L31;
-  }
-  __pyx_L31:;
+  __pyx_v_axes_holding = ((int64_t *)calloc(__pyx_v_dimensions, (sizeof(int64_t))));
 
-  /* "pyfftw/pyfftw.pyx":796
- *                     'byte boundary.' % self.__input_array_alignment)
+  /* "pyfftw/pyfftw.pyx":550
+ *             <int64_t *>calloc(dimensions, sizeof(int64_t)))
+ *     cdef int64_t *axes_holding_offset = (
+ *             <int64_t *>calloc(dimensions, sizeof(int64_t)))             # <<<<<<<<<<<<<<
  * 
- *         if (not (<intptr_t>np.PyArray_DATA(output_array)             # <<<<<<<<<<<<<<
- *             % self.__output_array_alignment == 0)):
- *             raise ValueError('Invalid output alignment: '
+ *     for n in range(dimensions):
  */
-  if (!(likely(((__pyx_v_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = __pyx_v_output_array;
-  __Pyx_INCREF(__pyx_t_2);
-  __pyx_t_15 = ((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_t_2)));
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_axes_holding_offset = ((int64_t *)calloc(__pyx_v_dimensions, (sizeof(int64_t))));
 
-  /* "pyfftw/pyfftw.pyx":797
+  /* "pyfftw/pyfftw.pyx":552
+ *             <int64_t *>calloc(dimensions, sizeof(int64_t)))
+ * 
+ *     for n in range(dimensions):             # <<<<<<<<<<<<<<
+ *         axes_holding[n] = -1
  * 
- *         if (not (<intptr_t>np.PyArray_DATA(output_array)
- *             % self.__output_array_alignment == 0)):             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid output alignment: '
- *                     'The output array is expected to lie on a %d '
  */
-  if (unlikely(__pyx_v_self->__pyx___output_array_alignment == 0)) {
-    PyErr_Format(PyExc_ZeroDivisionError, "integer division or modulo by zero");
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 797; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_t_11 = (!(__Pyx_mod_intptr_t(__pyx_t_15, __pyx_v_self->__pyx___output_array_alignment) == 0));
-  if (__pyx_t_11) {
+  __pyx_t_1 = __pyx_v_dimensions;
+  for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+    __pyx_v_n = __pyx_t_2;
 
-    /* "pyfftw/pyfftw.pyx":800
- *             raise ValueError('Invalid output alignment: '
- *                     'The output array is expected to lie on a %d '
- *                     'byte boundary.' % self.__output_array_alignment)             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":553
  * 
- *         if not direction in scheme_directions[scheme]:
+ *     for n in range(dimensions):
+ *         axes_holding[n] = -1             # <<<<<<<<<<<<<<
+ * 
+ *     # Iterate over all the axes and store each index if it hasn't already
  */
-    __pyx_t_2 = PyInt_FromLong(__pyx_v_self->__pyx___output_array_alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_9 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_17), __pyx_t_2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 800; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(((PyObject *)__pyx_t_9));
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_t_9));
-    __Pyx_GIVEREF(((PyObject *)__pyx_t_9));
-    __pyx_t_9 = 0;
-    __pyx_t_9 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-    __Pyx_Raise(__pyx_t_9, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L32;
+    (__pyx_v_axes_holding[__pyx_v_n]) = -1L;
   }
-  __pyx_L32:;
 
-  /* "pyfftw/pyfftw.pyx":802
- *                     'byte boundary.' % self.__output_array_alignment)
- * 
- *         if not direction in scheme_directions[scheme]:             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid direction: '
- *                     'The direction is not valid for the scheme. '
+  /* "pyfftw/pyfftw.pyx":560
+ *     #
+ *     # axes_holding_offset holds the shift due to repeated axes
+ *     for n in range(axes_length):             # <<<<<<<<<<<<<<
+ *         if axes_holding[axes[n]] == -1:
+ *             axes_holding[axes[n]] = n
  */
-  __pyx_t_9 = PyObject_GetItem(__pyx_v_6pyfftw_6pyfftw_scheme_directions, __pyx_v_scheme); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
-  __pyx_t_11 = (__Pyx_PySequence_Contains(__pyx_v_direction, __pyx_t_9, Py_EQ)); if (unlikely(__pyx_t_11 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-  __pyx_t_14 = (!__pyx_t_11);
-  if (__pyx_t_14) {
+  __pyx_t_1 = __pyx_v_axes_length;
+  for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+    __pyx_v_n = __pyx_t_2;
 
-    /* "pyfftw/pyfftw.pyx":803
- * 
- *         if not direction in scheme_directions[scheme]:
- *             raise ValueError('Invalid direction: '             # <<<<<<<<<<<<<<
- *                     'The direction is not valid for the scheme. '
- *                     'Try setting it explicitly if it is not already.')
+    /* "pyfftw/pyfftw.pyx":561
+ *     # axes_holding_offset holds the shift due to repeated axes
+ *     for n in range(axes_length):
+ *         if axes_holding[axes[n]] == -1:             # <<<<<<<<<<<<<<
+ *             axes_holding[axes[n]] = n
+ *             axes_holding_offset[axes[n]] = holding_offset
  */
-    __pyx_t_9 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_19), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    __Pyx_Raise(__pyx_t_9, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L33;
-  }
-  __pyx_L33:;
+    __pyx_t_3 = (((__pyx_v_axes_holding[(__pyx_v_axes[__pyx_v_n])]) == -1L) != 0);
+    if (__pyx_t_3) {
 
-  /* "pyfftw/pyfftw.pyx":807
- *                     'Try setting it explicitly if it is not already.')
- * 
- *         self.__direction = directions[direction]             # <<<<<<<<<<<<<<
- *         self.__input_shape = input_array.shape
- *         self.__output_shape = output_array.shape
+      /* "pyfftw/pyfftw.pyx":562
+ *     for n in range(axes_length):
+ *         if axes_holding[axes[n]] == -1:
+ *             axes_holding[axes[n]] = n             # <<<<<<<<<<<<<<
+ *             axes_holding_offset[axes[n]] = holding_offset
+ *             unique_axes_count += 1
  */
-  __pyx_t_9 = PyObject_GetItem(__pyx_v_6pyfftw_6pyfftw_directions, __pyx_v_direction); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
-  __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_9); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-  __pyx_v_self->__pyx___direction = __pyx_t_8;
+      (__pyx_v_axes_holding[(__pyx_v_axes[__pyx_v_n])]) = __pyx_v_n;
 
-  /* "pyfftw/pyfftw.pyx":808
- * 
- *         self.__direction = directions[direction]
- *         self.__input_shape = input_array.shape             # <<<<<<<<<<<<<<
- *         self.__output_shape = output_array.shape
- * 
+      /* "pyfftw/pyfftw.pyx":563
+ *         if axes_holding[axes[n]] == -1:
+ *             axes_holding[axes[n]] = n
+ *             axes_holding_offset[axes[n]] = holding_offset             # <<<<<<<<<<<<<<
+ *             unique_axes_count += 1
+ *         else:
  */
-  __pyx_t_9 = PyObject_GetAttr(__pyx_v_input_array, __pyx_n_s__shape); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 808; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
-  __Pyx_GIVEREF(__pyx_t_9);
-  __Pyx_GOTREF(__pyx_v_self->__pyx___input_shape);
-  __Pyx_DECREF(__pyx_v_self->__pyx___input_shape);
-  __pyx_v_self->__pyx___input_shape = __pyx_t_9;
-  __pyx_t_9 = 0;
+      (__pyx_v_axes_holding_offset[(__pyx_v_axes[__pyx_v_n])]) = __pyx_v_holding_offset;
 
-  /* "pyfftw/pyfftw.pyx":809
- *         self.__direction = directions[direction]
- *         self.__input_shape = input_array.shape
- *         self.__output_shape = output_array.shape             # <<<<<<<<<<<<<<
+      /* "pyfftw/pyfftw.pyx":564
+ *             axes_holding[axes[n]] = n
+ *             axes_holding_offset[axes[n]] = holding_offset
+ *             unique_axes_count += 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             holding_offset += 1
+ */
+      __pyx_v_unique_axes_count = (__pyx_v_unique_axes_count + 1);
+
+      /* "pyfftw/pyfftw.pyx":561
+ *     # axes_holding_offset holds the shift due to repeated axes
+ *     for n in range(axes_length):
+ *         if axes_holding[axes[n]] == -1:             # <<<<<<<<<<<<<<
+ *             axes_holding[axes[n]] = n
+ *             axes_holding_offset[axes[n]] = holding_offset
+ */
+      goto __pyx_L7;
+    }
+
+    /* "pyfftw/pyfftw.pyx":566
+ *             unique_axes_count += 1
+ *         else:
+ *             holding_offset += 1             # <<<<<<<<<<<<<<
  * 
- *         self.__input_array = input_array
+ *     unique_axes[0] = <int64_t *>malloc(
  */
-  __pyx_t_9 = PyObject_GetAttr(__pyx_v_output_array, __pyx_n_s__shape); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
-  __Pyx_GIVEREF(__pyx_t_9);
-  __Pyx_GOTREF(__pyx_v_self->__pyx___output_shape);
-  __Pyx_DECREF(__pyx_v_self->__pyx___output_shape);
-  __pyx_v_self->__pyx___output_shape = __pyx_t_9;
-  __pyx_t_9 = 0;
+    /*else*/ {
+      __pyx_v_holding_offset = (__pyx_v_holding_offset + 1);
+    }
+    __pyx_L7:;
+  }
 
-  /* "pyfftw/pyfftw.pyx":811
- *         self.__output_shape = output_array.shape
+  /* "pyfftw/pyfftw.pyx":568
+ *             holding_offset += 1
  * 
- *         self.__input_array = input_array             # <<<<<<<<<<<<<<
- *         self.__output_array = output_array
+ *     unique_axes[0] = <int64_t *>malloc(             # <<<<<<<<<<<<<<
+ *             unique_axes_count * sizeof(int64_t))
  * 
  */
-  if (!(likely(((__pyx_v_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_INCREF(__pyx_v_input_array);
-  __Pyx_GIVEREF(__pyx_v_input_array);
-  __Pyx_GOTREF(__pyx_v_self->__pyx___input_array);
-  __Pyx_DECREF(((PyObject *)__pyx_v_self->__pyx___input_array));
-  __pyx_v_self->__pyx___input_array = ((PyArrayObject *)__pyx_v_input_array);
+  (__pyx_v_unique_axes[0]) = ((int64_t *)malloc((__pyx_v_unique_axes_count * (sizeof(int64_t)))));
 
-  /* "pyfftw/pyfftw.pyx":812
+  /* "pyfftw/pyfftw.pyx":571
+ *             unique_axes_count * sizeof(int64_t))
  * 
- *         self.__input_array = input_array
- *         self.__output_array = output_array             # <<<<<<<<<<<<<<
+ *     not_axes[0] = <int64_t *>malloc(             # <<<<<<<<<<<<<<
+ *             (dimensions - unique_axes_count) * sizeof(int64_t))
  * 
- *         self.__axes = <int64_t *>malloc(len(axes)*sizeof(int64_t))
  */
-  if (!(likely(((__pyx_v_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 812; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_INCREF(__pyx_v_output_array);
-  __Pyx_GIVEREF(__pyx_v_output_array);
-  __Pyx_GOTREF(__pyx_v_self->__pyx___output_array);
-  __Pyx_DECREF(((PyObject *)__pyx_v_self->__pyx___output_array));
-  __pyx_v_self->__pyx___output_array = ((PyArrayObject *)__pyx_v_output_array);
+  (__pyx_v_not_axes[0]) = ((int64_t *)malloc(((__pyx_v_dimensions - __pyx_v_unique_axes_count) * (sizeof(int64_t)))));
 
-  /* "pyfftw/pyfftw.pyx":814
- *         self.__output_array = output_array
+  /* "pyfftw/pyfftw.pyx":575
  * 
- *         self.__axes = <int64_t *>malloc(len(axes)*sizeof(int64_t))             # <<<<<<<<<<<<<<
- *         for n in range(len(axes)):
- *             self.__axes[n] = axes[n]
+ *     # Now we need to write back the unique axes to a tmp axes
+ *     cdef int64_t not_axes_count = 0             # <<<<<<<<<<<<<<
+ * 
+ *     for n in range(dimensions):
  */
-  __pyx_t_12 = PyObject_Length(__pyx_v_axes); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 814; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_self->__pyx___axes = ((int64_t *)malloc((__pyx_t_12 * (sizeof(int64_t)))));
+  __pyx_v_not_axes_count = 0;
 
-  /* "pyfftw/pyfftw.pyx":815
- * 
- *         self.__axes = <int64_t *>malloc(len(axes)*sizeof(int64_t))
- *         for n in range(len(axes)):             # <<<<<<<<<<<<<<
- *             self.__axes[n] = axes[n]
+  /* "pyfftw/pyfftw.pyx":577
+ *     cdef int64_t not_axes_count = 0
  * 
+ *     for n in range(dimensions):             # <<<<<<<<<<<<<<
+ *         if axes_holding[n] != -1:
+ *             unique_axes[0][axes_holding[n] - axes_holding_offset[n]] = (
  */
-  __pyx_t_12 = PyObject_Length(__pyx_v_axes); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_9 = PyInt_FromSsize_t(__pyx_t_12); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_9);
-  __Pyx_GIVEREF(__pyx_t_9);
-  __pyx_t_9 = 0;
-  __pyx_t_9 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
-  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-  if (PyList_CheckExact(__pyx_t_9) || PyTuple_CheckExact(__pyx_t_9)) {
-    __pyx_t_2 = __pyx_t_9; __Pyx_INCREF(__pyx_t_2); __pyx_t_12 = 0;
-    __pyx_t_13 = NULL;
-  } else {
-    __pyx_t_12 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_13 = Py_TYPE(__pyx_t_2)->tp_iternext;
-  }
-  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-  for (;;) {
-    if (!__pyx_t_13 && PyList_CheckExact(__pyx_t_2)) {
-      if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_2)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_9 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_12); __Pyx_INCREF(__pyx_t_9); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_9 = PySequence_ITEM(__pyx_t_2, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else if (!__pyx_t_13 && PyTuple_CheckExact(__pyx_t_2)) {
-      if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_12); __Pyx_INCREF(__pyx_t_9); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_9 = PySequence_ITEM(__pyx_t_2, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else {
-      __pyx_t_9 = __pyx_t_13(__pyx_t_2);
-      if (unlikely(!__pyx_t_9)) {
-        if (PyErr_Occurred()) {
-          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 815; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        }
-        break;
-      }
-      __Pyx_GOTREF(__pyx_t_9);
-    }
-    __Pyx_XDECREF(__pyx_v_n);
-    __pyx_v_n = __pyx_t_9;
-    __pyx_t_9 = 0;
+  __pyx_t_1 = __pyx_v_dimensions;
+  for (__pyx_t_2 = 0; __pyx_t_2 < __pyx_t_1; __pyx_t_2+=1) {
+    __pyx_v_n = __pyx_t_2;
 
-    /* "pyfftw/pyfftw.pyx":816
- *         self.__axes = <int64_t *>malloc(len(axes)*sizeof(int64_t))
- *         for n in range(len(axes)):
- *             self.__axes[n] = axes[n]             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":578
  * 
- *         # Set the negative entries to their actual index (use the size
+ *     for n in range(dimensions):
+ *         if axes_holding[n] != -1:             # <<<<<<<<<<<<<<
+ *             unique_axes[0][axes_holding[n] - axes_holding_offset[n]] = (
+ *                     axes[axes_holding[n]])
  */
-    __pyx_t_9 = PyObject_GetItem(__pyx_v_axes, __pyx_v_n); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    __pyx_t_16 = __Pyx_PyInt_from_py_int64_t(__pyx_t_9); if (unlikely((__pyx_t_16 == (int64_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    __pyx_t_17 = __Pyx_PyIndex_AsSsize_t(__pyx_v_n); if (unlikely((__pyx_t_17 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    (__pyx_v_self->__pyx___axes[__pyx_t_17]) = __pyx_t_16;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __pyx_t_3 = (((__pyx_v_axes_holding[__pyx_v_n]) != -1L) != 0);
+    if (__pyx_t_3) {
 
-  /* "pyfftw/pyfftw.pyx":820
- *         # Set the negative entries to their actual index (use the size
- *         # of the shape array for this)
- *         cdef int64_t array_dimension = len(self.__input_shape)             # <<<<<<<<<<<<<<
+      /* "pyfftw/pyfftw.pyx":579
+ *     for n in range(dimensions):
+ *         if axes_holding[n] != -1:
+ *             unique_axes[0][axes_holding[n] - axes_holding_offset[n]] = (             # <<<<<<<<<<<<<<
+ *                     axes[axes_holding[n]])
  * 
- *         for n in range(len(axes)):
  */
-  __pyx_t_2 = __pyx_v_self->__pyx___input_shape;
-  __Pyx_INCREF(__pyx_t_2);
-  __pyx_t_12 = PyObject_Length(__pyx_t_2); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 820; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_v_array_dimension = __pyx_t_12;
+      ((__pyx_v_unique_axes[0])[((__pyx_v_axes_holding[__pyx_v_n]) - (__pyx_v_axes_holding_offset[__pyx_v_n]))]) = (__pyx_v_axes[(__pyx_v_axes_holding[__pyx_v_n])]);
 
-  /* "pyfftw/pyfftw.pyx":822
- *         cdef int64_t array_dimension = len(self.__input_shape)
+      /* "pyfftw/pyfftw.pyx":578
  * 
- *         for n in range(len(axes)):             # <<<<<<<<<<<<<<
- *             if self.__axes[n] < 0:
- *                 self.__axes[n] = self.__axes[n] + array_dimension
+ *     for n in range(dimensions):
+ *         if axes_holding[n] != -1:             # <<<<<<<<<<<<<<
+ *             unique_axes[0][axes_holding[n] - axes_holding_offset[n]] = (
+ *                     axes[axes_holding[n]])
  */
-  __pyx_t_12 = PyObject_Length(__pyx_v_axes); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = PyInt_FromSsize_t(__pyx_t_12); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_9 = PyTuple_New(1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
-  PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_2);
-  __Pyx_GIVEREF(__pyx_t_2);
-  __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_9), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
-  if (PyList_CheckExact(__pyx_t_2) || PyTuple_CheckExact(__pyx_t_2)) {
-    __pyx_t_9 = __pyx_t_2; __Pyx_INCREF(__pyx_t_9); __pyx_t_12 = 0;
-    __pyx_t_13 = NULL;
-  } else {
-    __pyx_t_12 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    __pyx_t_13 = Py_TYPE(__pyx_t_9)->tp_iternext;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  for (;;) {
-    if (!__pyx_t_13 && PyList_CheckExact(__pyx_t_9)) {
-      if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_9)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_12); __Pyx_INCREF(__pyx_t_2); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_9, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else if (!__pyx_t_13 && PyTuple_CheckExact(__pyx_t_9)) {
-      if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_9)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_12); __Pyx_INCREF(__pyx_t_2); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_9, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else {
-      __pyx_t_2 = __pyx_t_13(__pyx_t_9);
-      if (unlikely(!__pyx_t_2)) {
-        if (PyErr_Occurred()) {
-          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 822; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        }
-        break;
-      }
-      __Pyx_GOTREF(__pyx_t_2);
+      goto __pyx_L10;
     }
-    __Pyx_XDECREF(__pyx_v_n);
-    __pyx_v_n = __pyx_t_2;
-    __pyx_t_2 = 0;
 
-    /* "pyfftw/pyfftw.pyx":823
+    /* "pyfftw/pyfftw.pyx":583
  * 
- *         for n in range(len(axes)):
- *             if self.__axes[n] < 0:             # <<<<<<<<<<<<<<
- *                 self.__axes[n] = self.__axes[n] + array_dimension
+ *         else:
+ *             not_axes[0][not_axes_count] = n             # <<<<<<<<<<<<<<
+ *             not_axes_count += 1
  * 
  */
-    __pyx_t_17 = __Pyx_PyIndex_AsSsize_t(__pyx_v_n); if (unlikely((__pyx_t_17 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_14 = ((__pyx_v_self->__pyx___axes[__pyx_t_17]) < 0);
-    if (__pyx_t_14) {
+    /*else*/ {
+      ((__pyx_v_not_axes[0])[__pyx_v_not_axes_count]) = __pyx_v_n;
 
-      /* "pyfftw/pyfftw.pyx":824
- *         for n in range(len(axes)):
- *             if self.__axes[n] < 0:
- *                 self.__axes[n] = self.__axes[n] + array_dimension             # <<<<<<<<<<<<<<
+      /* "pyfftw/pyfftw.pyx":584
+ *         else:
+ *             not_axes[0][not_axes_count] = n
+ *             not_axes_count += 1             # <<<<<<<<<<<<<<
  * 
- *             if self.__axes[n] >= array_dimension or self.__axes[n] < 0:
+ *     free(axes_holding)
  */
-      __pyx_t_17 = __Pyx_PyIndex_AsSsize_t(__pyx_v_n); if (unlikely((__pyx_t_17 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 824; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_18 = __Pyx_PyIndex_AsSsize_t(__pyx_v_n); if (unlikely((__pyx_t_18 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 824; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      (__pyx_v_self->__pyx___axes[__pyx_t_18]) = ((__pyx_v_self->__pyx___axes[__pyx_t_17]) + __pyx_v_array_dimension);
-      goto __pyx_L38;
+      __pyx_v_not_axes_count = (__pyx_v_not_axes_count + 1);
     }
-    __pyx_L38:;
+    __pyx_L10:;
+  }
 
-    /* "pyfftw/pyfftw.pyx":826
- *                 self.__axes[n] = self.__axes[n] + array_dimension
+  /* "pyfftw/pyfftw.pyx":586
+ *             not_axes_count += 1
+ * 
+ *     free(axes_holding)             # <<<<<<<<<<<<<<
+ *     free(axes_holding_offset)
  * 
- *             if self.__axes[n] >= array_dimension or self.__axes[n] < 0:             # <<<<<<<<<<<<<<
- *                 raise IndexError('Invalid axes: '
- *                     'The axes list cannot contain invalid axes.')
  */
-    __pyx_t_17 = __Pyx_PyIndex_AsSsize_t(__pyx_v_n); if (unlikely((__pyx_t_17 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_14 = ((__pyx_v_self->__pyx___axes[__pyx_t_17]) >= __pyx_v_array_dimension);
-    if (!__pyx_t_14) {
-      __pyx_t_17 = __Pyx_PyIndex_AsSsize_t(__pyx_v_n); if (unlikely((__pyx_t_17 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_11 = ((__pyx_v_self->__pyx___axes[__pyx_t_17]) < 0);
-      __pyx_t_3 = __pyx_t_11;
-    } else {
-      __pyx_t_3 = __pyx_t_14;
-    }
-    if (__pyx_t_3) {
+  free(__pyx_v_axes_holding);
 
-      /* "pyfftw/pyfftw.pyx":827
+  /* "pyfftw/pyfftw.pyx":587
  * 
- *             if self.__axes[n] >= array_dimension or self.__axes[n] < 0:
- *                 raise IndexError('Invalid axes: '             # <<<<<<<<<<<<<<
- *                     'The axes list cannot contain invalid axes.')
+ *     free(axes_holding)
+ *     free(axes_holding_offset)             # <<<<<<<<<<<<<<
  * 
+ *     unique_axes_length[0] = unique_axes_count
  */
-      __pyx_t_2 = PyObject_Call(__pyx_builtin_IndexError, ((PyObject *)__pyx_k_tuple_21), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      __Pyx_Raise(__pyx_t_2, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      goto __pyx_L39;
-    }
-    __pyx_L39:;
-  }
-  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  free(__pyx_v_axes_holding_offset);
 
-  /* "pyfftw/pyfftw.pyx":834
- *         cdef int64_t *not_axes
+  /* "pyfftw/pyfftw.pyx":589
+ *     free(axes_holding_offset)
  * 
- *         make_axes_unique(self.__axes, len(axes), &unique_axes,             # <<<<<<<<<<<<<<
- *                 &not_axes, array_dimension, &unique_axes_length)
+ *     unique_axes_length[0] = unique_axes_count             # <<<<<<<<<<<<<<
  * 
+ *     return
  */
-  __pyx_t_12 = PyObject_Length(__pyx_v_axes); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  (__pyx_v_unique_axes_length[0]) = __pyx_v_unique_axes_count;
 
-  /* "pyfftw/pyfftw.pyx":835
+  /* "pyfftw/pyfftw.pyx":591
+ *     unique_axes_length[0] = unique_axes_count
  * 
- *         make_axes_unique(self.__axes, len(axes), &unique_axes,
- *                 &not_axes, array_dimension, &unique_axes_length)             # <<<<<<<<<<<<<<
+ *     return             # <<<<<<<<<<<<<<
  * 
- *         # and assign axes and not_axes to the filled arrays
- */
-  __pyx_f_6pyfftw_6pyfftw_make_axes_unique(__pyx_v_self->__pyx___axes, __pyx_t_12, (&__pyx_v_unique_axes), (&__pyx_v_not_axes), __pyx_v_array_dimension, (&__pyx_v_unique_axes_length));
-
-  /* "pyfftw/pyfftw.pyx":838
  * 
- *         # and assign axes and not_axes to the filled arrays
- *         free(self.__axes)             # <<<<<<<<<<<<<<
- *         self.__axes = unique_axes
- *         self.__not_axes = not_axes
  */
-  free(__pyx_v_self->__pyx___axes);
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":839
- *         # and assign axes and not_axes to the filled arrays
- *         free(self.__axes)
- *         self.__axes = unique_axes             # <<<<<<<<<<<<<<
- *         self.__not_axes = not_axes
+  /* "pyfftw/pyfftw.pyx":529
  * 
+ * # Helper functions
+ * cdef void make_axes_unique(int64_t *axes, int64_t axes_length,             # <<<<<<<<<<<<<<
+ *         int64_t **unique_axes, int64_t **not_axes, int64_t dimensions,
+ *         int64_t *unique_axes_length):
  */
-  __pyx_v_self->__pyx___axes = __pyx_v_unique_axes;
 
-  /* "pyfftw/pyfftw.pyx":840
- *         free(self.__axes)
- *         self.__axes = unique_axes
- *         self.__not_axes = not_axes             # <<<<<<<<<<<<<<
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "pyfftw/pyfftw.pyx":667
  * 
- *         total_N = 1
+ *     cdef int64_t _N
+ *     def _get_N(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         The product of the lengths of the DFT over all DFT axes.
  */
-  __pyx_v_self->__pyx___not_axes = __pyx_v_not_axes;
 
-  /* "pyfftw/pyfftw.pyx":842
- *         self.__not_axes = not_axes
- * 
- *         total_N = 1             # <<<<<<<<<<<<<<
- *         for n in range(unique_axes_length):
- *             if self.__input_shape[self.__axes[n]] == 0:
- */
-  __Pyx_INCREF(__pyx_int_1);
-  __pyx_v_total_N = __pyx_int_1;
-
-  /* "pyfftw/pyfftw.pyx":843
- * 
- *         total_N = 1
- *         for n in range(unique_axes_length):             # <<<<<<<<<<<<<<
- *             if self.__input_shape[self.__axes[n]] == 0:
- *                 raise ValueError('Zero length array: '
- */
-  __pyx_t_9 = __Pyx_PyInt_to_py_int64_t(__pyx_v_unique_axes_length); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
-  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_9);
-  __Pyx_GIVEREF(__pyx_t_9);
-  __pyx_t_9 = 0;
-  __pyx_t_9 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
-  __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-  if (PyList_CheckExact(__pyx_t_9) || PyTuple_CheckExact(__pyx_t_9)) {
-    __pyx_t_2 = __pyx_t_9; __Pyx_INCREF(__pyx_t_2); __pyx_t_12 = 0;
-    __pyx_t_13 = NULL;
-  } else {
-    __pyx_t_12 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_13 = Py_TYPE(__pyx_t_2)->tp_iternext;
-  }
-  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-  for (;;) {
-    if (!__pyx_t_13 && PyList_CheckExact(__pyx_t_2)) {
-      if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_2)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_9 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_12); __Pyx_INCREF(__pyx_t_9); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_9 = PySequence_ITEM(__pyx_t_2, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else if (!__pyx_t_13 && PyTuple_CheckExact(__pyx_t_2)) {
-      if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_12); __Pyx_INCREF(__pyx_t_9); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_9 = PySequence_ITEM(__pyx_t_2, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else {
-      __pyx_t_9 = __pyx_t_13(__pyx_t_2);
-      if (unlikely(!__pyx_t_9)) {
-        if (PyErr_Occurred()) {
-          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 843; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        }
-        break;
-      }
-      __Pyx_GOTREF(__pyx_t_9);
-    }
-    __Pyx_XDECREF(__pyx_v_n);
-    __pyx_v_n = __pyx_t_9;
-    __pyx_t_9 = 0;
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_1_get_N(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW__get_N[] = "\n        The product of the lengths of the DFT over all DFT axes.\n        1/N is the normalisation constant. For any input array A, \n        and for any set of axes, 1/N * ifft(fft(A)) = A\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_1_get_N(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_N (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW__get_N(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
 
-    /* "pyfftw/pyfftw.pyx":844
- *         total_N = 1
- *         for n in range(unique_axes_length):
- *             if self.__input_shape[self.__axes[n]] == 0:             # <<<<<<<<<<<<<<
- *                 raise ValueError('Zero length array: '
- *                     'The input array should have no zero length'
- */
-    __pyx_t_17 = __Pyx_PyIndex_AsSsize_t(__pyx_v_n); if (unlikely((__pyx_t_17 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_self->__pyx___input_shape, (__pyx_v_self->__pyx___axes[__pyx_t_17]), sizeof(int64_t), __Pyx_PyInt_to_py_int64_t); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    __pyx_t_1 = PyObject_RichCompare(__pyx_t_9, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    if (__pyx_t_3) {
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-      /* "pyfftw/pyfftw.pyx":845
- *         for n in range(unique_axes_length):
- *             if self.__input_shape[self.__axes[n]] == 0:
- *                 raise ValueError('Zero length array: '             # <<<<<<<<<<<<<<
- *                     'The input array should have no zero length'
- *                     'axes over which the FFT is to be taken')
- */
-      __pyx_t_1 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_23), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_Raise(__pyx_t_1, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      goto __pyx_L42;
-    }
-    __pyx_L42:;
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW__get_N(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_N", 0);
 
-    /* "pyfftw/pyfftw.pyx":849
- *                     'axes over which the FFT is to be taken')
+  /* "pyfftw/pyfftw.pyx":673
+ *         and for any set of axes, 1/N * ifft(fft(A)) = A
+ *         '''
+ *         return self._N             # <<<<<<<<<<<<<<
  * 
- *             if self.__direction == FFTW_FORWARD:             # <<<<<<<<<<<<<<
- *                 total_N *= self.__input_shape[self.__axes[n]]
- *             else:
+ *     N = property(_get_N)
  */
-    __pyx_t_3 = (__pyx_v_self->__pyx___direction == __pyx_e_6pyfftw_6pyfftw_FFTW_FORWARD);
-    if (__pyx_t_3) {
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_int64_t(__pyx_v_self->_N); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-      /* "pyfftw/pyfftw.pyx":850
+  /* "pyfftw/pyfftw.pyx":667
  * 
- *             if self.__direction == FFTW_FORWARD:
- *                 total_N *= self.__input_shape[self.__axes[n]]             # <<<<<<<<<<<<<<
- *             else:
- *                 total_N *= self.__output_shape[self.__axes[n]]
+ *     cdef int64_t _N
+ *     def _get_N(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         The product of the lengths of the DFT over all DFT axes.
  */
-      __pyx_t_17 = __Pyx_PyIndex_AsSsize_t(__pyx_v_n); if (unlikely((__pyx_t_17 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 850; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_self->__pyx___input_shape, (__pyx_v_self->__pyx___axes[__pyx_t_17]), sizeof(int64_t), __Pyx_PyInt_to_py_int64_t); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 850; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_9 = PyNumber_InPlaceMultiply(__pyx_v_total_N, __pyx_t_1); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 850; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_9);
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __Pyx_DECREF(__pyx_v_total_N);
-      __pyx_v_total_N = __pyx_t_9;
-      __pyx_t_9 = 0;
-      goto __pyx_L43;
-    }
-    /*else*/ {
 
-      /* "pyfftw/pyfftw.pyx":852
- *                 total_N *= self.__input_shape[self.__axes[n]]
- *             else:
- *                 total_N *= self.__output_shape[self.__axes[n]]             # <<<<<<<<<<<<<<
- * 
- *         self.__N = total_N
- */
-      __pyx_t_17 = __Pyx_PyIndex_AsSsize_t(__pyx_v_n); if (unlikely((__pyx_t_17 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_self->__pyx___output_shape, (__pyx_v_self->__pyx___axes[__pyx_t_17]), sizeof(int64_t), __Pyx_PyInt_to_py_int64_t); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_9);
-      __pyx_t_1 = PyNumber_InPlaceMultiply(__pyx_v_total_N, __pyx_t_9); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 852; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-      __Pyx_DECREF(__pyx_v_total_N);
-      __pyx_v_total_N = __pyx_t_1;
-      __pyx_t_1 = 0;
-    }
-    __pyx_L43:;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW._get_N", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":854
- *                 total_N *= self.__output_shape[self.__axes[n]]
- * 
- *         self.__N = total_N             # <<<<<<<<<<<<<<
- *         self.__normalisation_scaling = 1/float(self.N)
+/* "pyfftw/pyfftw.pyx":677
+ *     N = property(_get_N)
  * 
+ *     def _get_simd_aligned(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return whether or not this FFTW object requires simd aligned
  */
-  __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_v_total_N); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 854; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_v_self->__pyx___N = __pyx_t_8;
 
-  /* "pyfftw/pyfftw.pyx":855
- * 
- *         self.__N = total_N
- *         self.__normalisation_scaling = 1/float(self.N)             # <<<<<<<<<<<<<<
- * 
- *         # Now we can validate the array shapes
- */
-  __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__N); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_7 = __Pyx_PyObject_AsDouble(__pyx_t_2); if (unlikely(__pyx_t_7 == ((double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  if (unlikely(__pyx_t_7 == 0)) {
-    PyErr_Format(PyExc_ZeroDivisionError, "float division");
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 855; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  }
-  __pyx_v_self->__pyx___normalisation_scaling = (1.0 / __pyx_t_7);
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_3_get_simd_aligned(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_2_get_simd_aligned[] = "\n        Return whether or not this FFTW object requires simd aligned\n        input and output data.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_3_get_simd_aligned(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_simd_aligned (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_2_get_simd_aligned(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
 
-  /* "pyfftw/pyfftw.pyx":860
- *         cdef validator _validator
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_2_get_simd_aligned(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_simd_aligned", 0);
+
+  /* "pyfftw/pyfftw.pyx":682
+ *         input and output data.
+ *         '''
+ *         return self._simd_allowed             # <<<<<<<<<<<<<<
  * 
- *         if functions['validator'] == -1:             # <<<<<<<<<<<<<<
- *             if not (output_array.shape == input_array.shape):
- *                 raise ValueError('Invalid shapes: '
+ *     simd_aligned = property(_get_simd_aligned)
  */
-  __pyx_t_2 = PyObject_GetItem(__pyx_v_functions, ((PyObject *)__pyx_n_s__validator)); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (__pyx_t_3) {
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_self->_simd_allowed); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-    /* "pyfftw/pyfftw.pyx":861
+  /* "pyfftw/pyfftw.pyx":677
+ *     N = property(_get_N)
  * 
- *         if functions['validator'] == -1:
- *             if not (output_array.shape == input_array.shape):             # <<<<<<<<<<<<<<
- *                 raise ValueError('Invalid shapes: '
- *                         'The output array should be the same shape as the '
+ *     def _get_simd_aligned(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return whether or not this FFTW object requires simd aligned
  */
-    __pyx_t_1 = PyObject_GetAttr(__pyx_v_output_array, __pyx_n_s__shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyObject_GetAttr(__pyx_v_input_array, __pyx_n_s__shape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_9 = PyObject_RichCompare(__pyx_t_1, __pyx_t_2, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    __pyx_t_14 = (!__pyx_t_3);
-    if (__pyx_t_14) {
 
-      /* "pyfftw/pyfftw.pyx":862
- *         if functions['validator'] == -1:
- *             if not (output_array.shape == input_array.shape):
- *                 raise ValueError('Invalid shapes: '             # <<<<<<<<<<<<<<
- *                         'The output array should be the same shape as the '
- *                         'input array for the given array dtypes.')
- */
-      __pyx_t_9 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_25), NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 862; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_9);
-      __Pyx_Raise(__pyx_t_9, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 862; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      goto __pyx_L45;
-    }
-    __pyx_L45:;
-    goto __pyx_L44;
-  }
-  /*else*/ {
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW._get_simd_aligned", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-    /* "pyfftw/pyfftw.pyx":866
- *                         'input array for the given array dtypes.')
- *         else:
- *             _validator = validators[functions['validator']]             # <<<<<<<<<<<<<<
- *             if not _validator(input_array, output_array,
- *                     self.__axes, self.__not_axes, unique_axes_length):
+/* "pyfftw/pyfftw.pyx":686
+ *     simd_aligned = property(_get_simd_aligned)
+ * 
+ *     def _get_input_alignment(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Returns the byte alignment of the input arrays for which the
  */
-    __pyx_t_9 = PyObject_GetItem(__pyx_v_functions, ((PyObject *)__pyx_n_s__validator)); if (!__pyx_t_9) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 866; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 866; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    __pyx_v__validator = (__pyx_v_6pyfftw_6pyfftw_validators[__pyx_t_12]);
 
-    /* "pyfftw/pyfftw.pyx":867
- *         else:
- *             _validator = validators[functions['validator']]
- *             if not _validator(input_array, output_array,             # <<<<<<<<<<<<<<
- *                     self.__axes, self.__not_axes, unique_axes_length):
- *                 raise ValueError('Invalid shapes: '
- */
-    if (!(likely(((__pyx_v_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 867; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_9 = __pyx_v_input_array;
-    __Pyx_INCREF(__pyx_t_9);
-    if (!(likely(((__pyx_v_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 867; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = __pyx_v_output_array;
-    __Pyx_INCREF(__pyx_t_2);
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_5_get_input_alignment(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_4_get_input_alignment[] = "\n        Returns the byte alignment of the input arrays for which the\n        :class:`~pyfftw.FFTW` object was created.\n\n        Input array updates with arrays that are not aligned on this\n        byte boundary will result in a ValueError being raised, or\n        a copy being made if the :meth:`~pyfftw.FFTW.__call__` \n        interface is used.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_5_get_input_alignment(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_input_alignment (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_4_get_input_alignment(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
 
-    /* "pyfftw/pyfftw.pyx":868
- *             _validator = validators[functions['validator']]
- *             if not _validator(input_array, output_array,
- *                     self.__axes, self.__not_axes, unique_axes_length):             # <<<<<<<<<<<<<<
- *                 raise ValueError('Invalid shapes: '
- *                         'The input array and output array are invalid '
- */
-    __pyx_t_14 = (!__pyx_v__validator(((PyArrayObject *)__pyx_t_9), ((PyArrayObject *)__pyx_t_2), __pyx_v_self->__pyx___axes, __pyx_v_self->__pyx___not_axes, __pyx_v_unique_axes_length));
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (__pyx_t_14) {
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-      /* "pyfftw/pyfftw.pyx":869
- *             if not _validator(input_array, output_array,
- *                     self.__axes, self.__not_axes, unique_axes_length):
- *                 raise ValueError('Invalid shapes: '             # <<<<<<<<<<<<<<
- *                         'The input array and output array are invalid '
- *                         'complementary shapes for their dtypes.')
- */
-      __pyx_t_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_27), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 869; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      __Pyx_Raise(__pyx_t_2, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 869; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      goto __pyx_L46;
-    }
-    __pyx_L46:;
-  }
-  __pyx_L44:;
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_4_get_input_alignment(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_input_alignment", 0);
 
-  /* "pyfftw/pyfftw.pyx":873
- *                         'complementary shapes for their dtypes.')
- * 
- *         self.__rank = unique_axes_length             # <<<<<<<<<<<<<<
- *         self.__howmany_rank = self.__input_array.ndim - unique_axes_length
+  /* "pyfftw/pyfftw.pyx":696
+ *         interface is used.
+ *         '''
+ *         return self._input_array_alignment             # <<<<<<<<<<<<<<
  * 
+ *     input_alignment = property(_get_input_alignment)
  */
-  __pyx_v_self->__pyx___rank = __pyx_v_unique_axes_length;
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->_input_array_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 696; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":874
- * 
- *         self.__rank = unique_axes_length
- *         self.__howmany_rank = self.__input_array.ndim - unique_axes_length             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":686
+ *     simd_aligned = property(_get_simd_aligned)
  * 
- *         self.__flags = 0
+ *     def _get_input_alignment(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Returns the byte alignment of the input arrays for which the
  */
-  __pyx_v_self->__pyx___howmany_rank = (__pyx_v_self->__pyx___input_array->nd - __pyx_v_unique_axes_length);
 
-  /* "pyfftw/pyfftw.pyx":876
- *         self.__howmany_rank = self.__input_array.ndim - unique_axes_length
- * 
- *         self.__flags = 0             # <<<<<<<<<<<<<<
- *         self.__flags_used = []
- *         for each_flag in flags:
- */
-  __pyx_v_self->__pyx___flags = 0;
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW._get_input_alignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":877
+/* "pyfftw/pyfftw.pyx":700
+ *     input_alignment = property(_get_input_alignment)
  * 
- *         self.__flags = 0
- *         self.__flags_used = []             # <<<<<<<<<<<<<<
- *         for each_flag in flags:
- *             try:
+ *     def _get_output_alignment(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Returns the byte alignment of the output arrays for which the
  */
-  __pyx_t_2 = PyList_New(0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 877; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
-  __Pyx_GOTREF(__pyx_v_self->__pyx___flags_used);
-  __Pyx_DECREF(__pyx_v_self->__pyx___flags_used);
-  __pyx_v_self->__pyx___flags_used = ((PyObject *)__pyx_t_2);
-  __pyx_t_2 = 0;
 
-  /* "pyfftw/pyfftw.pyx":878
- *         self.__flags = 0
- *         self.__flags_used = []
- *         for each_flag in flags:             # <<<<<<<<<<<<<<
- *             try:
- *                 self.__flags |= flag_dict[each_flag]
- */
-  if (PyList_CheckExact(__pyx_v_flags) || PyTuple_CheckExact(__pyx_v_flags)) {
-    __pyx_t_2 = __pyx_v_flags; __Pyx_INCREF(__pyx_t_2); __pyx_t_12 = 0;
-    __pyx_t_13 = NULL;
-  } else {
-    __pyx_t_12 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_v_flags); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_13 = Py_TYPE(__pyx_t_2)->tp_iternext;
-  }
-  for (;;) {
-    if (!__pyx_t_13 && PyList_CheckExact(__pyx_t_2)) {
-      if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_2)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_9 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_12); __Pyx_INCREF(__pyx_t_9); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_9 = PySequence_ITEM(__pyx_t_2, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else if (!__pyx_t_13 && PyTuple_CheckExact(__pyx_t_2)) {
-      if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_12); __Pyx_INCREF(__pyx_t_9); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_9 = PySequence_ITEM(__pyx_t_2, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else {
-      __pyx_t_9 = __pyx_t_13(__pyx_t_2);
-      if (unlikely(!__pyx_t_9)) {
-        if (PyErr_Occurred()) {
-          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 878; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        }
-        break;
-      }
-      __Pyx_GOTREF(__pyx_t_9);
-    }
-    __Pyx_XDECREF(__pyx_v_each_flag);
-    __pyx_v_each_flag = __pyx_t_9;
-    __pyx_t_9 = 0;
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_7_get_output_alignment(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_6_get_output_alignment[] = "\n        Returns the byte alignment of the output arrays for which the\n        :class:`~pyfftw.FFTW` object was created.\n\n        Output array updates with arrays that are not aligned on this\n        byte boundary will result in a ValueError being raised.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_7_get_output_alignment(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_output_alignment (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_6_get_output_alignment(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
 
-    /* "pyfftw/pyfftw.pyx":879
- *         self.__flags_used = []
- *         for each_flag in flags:
- *             try:             # <<<<<<<<<<<<<<
- *                 self.__flags |= flag_dict[each_flag]
- *                 self.__flags_used.append(each_flag)
- */
-    {
-      __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
-      __Pyx_XGOTREF(__pyx_t_4);
-      __Pyx_XGOTREF(__pyx_t_5);
-      __Pyx_XGOTREF(__pyx_t_6);
-      /*try:*/ {
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-        /* "pyfftw/pyfftw.pyx":880
- *         for each_flag in flags:
- *             try:
- *                 self.__flags |= flag_dict[each_flag]             # <<<<<<<<<<<<<<
- *                 self.__flags_used.append(each_flag)
- *             except KeyError:
- */
-        __pyx_t_9 = PyInt_FromLong(__pyx_v_self->__pyx___flags); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L49_error;}
-        __Pyx_GOTREF(__pyx_t_9);
-        __pyx_t_1 = PyObject_GetItem(__pyx_v_6pyfftw_6pyfftw_flag_dict, __pyx_v_each_flag); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L49_error;}
-        __Pyx_GOTREF(__pyx_t_1);
-        __pyx_t_10 = PyNumber_InPlaceOr(__pyx_t_9, __pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L49_error;}
-        __Pyx_GOTREF(__pyx_t_10);
-        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __pyx_t_8 = __Pyx_PyInt_AsInt(__pyx_t_10); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L49_error;}
-        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-        __pyx_v_self->__pyx___flags = __pyx_t_8;
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_6_get_output_alignment(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_output_alignment", 0);
 
-        /* "pyfftw/pyfftw.pyx":881
- *             try:
- *                 self.__flags |= flag_dict[each_flag]
- *                 self.__flags_used.append(each_flag)             # <<<<<<<<<<<<<<
- *             except KeyError:
- *                 raise ValueError('Invalid flag: ' + '\'' +
+  /* "pyfftw/pyfftw.pyx":708
+ *         byte boundary will result in a ValueError being raised.
+ *         '''
+ *         return self._output_array_alignment             # <<<<<<<<<<<<<<
+ * 
+ *     output_alignment = property(_get_output_alignment)
  */
-        __pyx_t_10 = __Pyx_PyObject_Append(__pyx_v_self->__pyx___flags_used, __pyx_v_each_flag); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L49_error;}
-        __Pyx_GOTREF(__pyx_t_10);
-        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-      }
-      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
-      goto __pyx_L56_try_end;
-      __pyx_L49_error:;
-      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
-      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
-      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->_output_array_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 708; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-      /* "pyfftw/pyfftw.pyx":882
- *                 self.__flags |= flag_dict[each_flag]
- *                 self.__flags_used.append(each_flag)
- *             except KeyError:             # <<<<<<<<<<<<<<
- *                 raise ValueError('Invalid flag: ' + '\'' +
- *                         each_flag + '\' is not a valid planner flag.')
+  /* "pyfftw/pyfftw.pyx":700
+ *     input_alignment = property(_get_input_alignment)
+ * 
+ *     def _get_output_alignment(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Returns the byte alignment of the output arrays for which the
  */
-      __pyx_t_8 = PyErr_ExceptionMatches(__pyx_builtin_KeyError);
-      if (__pyx_t_8) {
-        __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-        if (__Pyx_GetException(&__pyx_t_10, &__pyx_t_1, &__pyx_t_9) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 882; __pyx_clineno = __LINE__; goto __pyx_L51_except_error;}
-        __Pyx_GOTREF(__pyx_t_10);
-        __Pyx_GOTREF(__pyx_t_1);
-        __Pyx_GOTREF(__pyx_t_9);
 
-        /* "pyfftw/pyfftw.pyx":883
- *                 self.__flags_used.append(each_flag)
- *             except KeyError:
- *                 raise ValueError('Invalid flag: ' + '\'' +             # <<<<<<<<<<<<<<
- *                         each_flag + '\' is not a valid planner flag.')
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW._get_output_alignment", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":712
+ *     output_alignment = property(_get_output_alignment)
  * 
+ *     def _get_flags_used(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return which flags were used to construct the FFTW object.
  */
-        __pyx_t_19 = PyNumber_Add(((PyObject *)__pyx_kp_s_28), ((PyObject *)__pyx_kp_s_29)); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L51_except_error;}
-        __Pyx_GOTREF(((PyObject *)__pyx_t_19));
 
-        /* "pyfftw/pyfftw.pyx":884
- *             except KeyError:
- *                 raise ValueError('Invalid flag: ' + '\'' +
- *                         each_flag + '\' is not a valid planner flag.')             # <<<<<<<<<<<<<<
- * 
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_9_get_flags_used(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_8_get_flags_used[] = "\n        Return which flags were used to construct the FFTW object.\n        \n        This includes flags that were added during initialisation.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_9_get_flags_used(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_flags_used (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_8_get_flags_used(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_8_get_flags_used(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_flags_used", 0);
+
+  /* "pyfftw/pyfftw.pyx":718
+ *         This includes flags that were added during initialisation.
+ *         '''
+ *         return tuple(self._flags_used)             # <<<<<<<<<<<<<<
  * 
+ *     flags = property(_get_flags_used)
  */
-        __pyx_t_20 = PyNumber_Add(((PyObject *)__pyx_t_19), __pyx_v_each_flag); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L51_except_error;}
-        __Pyx_GOTREF(__pyx_t_20);
-        __Pyx_DECREF(((PyObject *)__pyx_t_19)); __pyx_t_19 = 0;
-        __pyx_t_19 = PyNumber_Add(__pyx_t_20, ((PyObject *)__pyx_kp_s_30)); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 884; __pyx_clineno = __LINE__; goto __pyx_L51_except_error;}
-        __Pyx_GOTREF(__pyx_t_19);
-        __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
-        __pyx_t_20 = PyTuple_New(1); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L51_except_error;}
-        __Pyx_GOTREF(__pyx_t_20);
-        PyTuple_SET_ITEM(__pyx_t_20, 0, __pyx_t_19);
-        __Pyx_GIVEREF(__pyx_t_19);
-        __pyx_t_19 = 0;
-        __pyx_t_19 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_20), NULL); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L51_except_error;}
-        __Pyx_GOTREF(__pyx_t_19);
-        __Pyx_DECREF(((PyObject *)__pyx_t_20)); __pyx_t_20 = 0;
-        __Pyx_Raise(__pyx_t_19, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
-        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 883; __pyx_clineno = __LINE__; goto __pyx_L51_except_error;}
-        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-        __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-        goto __pyx_L50_exception_handled;
-      }
-      __pyx_L51_except_error:;
-      __Pyx_XGIVEREF(__pyx_t_4);
-      __Pyx_XGIVEREF(__pyx_t_5);
-      __Pyx_XGIVEREF(__pyx_t_6);
-      __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
-      goto __pyx_L1_error;
-      __pyx_L50_exception_handled:;
-      __Pyx_XGIVEREF(__pyx_t_4);
-      __Pyx_XGIVEREF(__pyx_t_5);
-      __Pyx_XGIVEREF(__pyx_t_6);
-      __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
-      __pyx_L56_try_end:;
-    }
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PySequence_Tuple(__pyx_v_self->_flags_used); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 718; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":887
- * 
+  /* "pyfftw/pyfftw.pyx":712
+ *     output_alignment = property(_get_output_alignment)
  * 
- *         if ('FFTW_DESTROY_INPUT' not in flags) and (             # <<<<<<<<<<<<<<
- *                 (scheme[0] != 'c2r') or not self.__rank > 1):
- *             # The default in all possible cases is to preserve the input
+ *     def _get_flags_used(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return which flags were used to construct the FFTW object.
  */
-  __pyx_t_14 = (__Pyx_PySequence_Contains(((PyObject *)__pyx_n_s__FFTW_DESTROY_INPUT), __pyx_v_flags, Py_NE)); if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 887; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__pyx_t_14) {
 
-    /* "pyfftw/pyfftw.pyx":888
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW._get_flags_used", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":722
+ *     flags = property(_get_flags_used)
  * 
- *         if ('FFTW_DESTROY_INPUT' not in flags) and (
- *                 (scheme[0] != 'c2r') or not self.__rank > 1):             # <<<<<<<<<<<<<<
- *             # The default in all possible cases is to preserve the input
- *             # This is not possible for r2c arrays with rank > 1
+ *     def _get_input_array(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the input array that is associated with the FFTW
  */
-    __pyx_t_2 = __Pyx_GetItemInt(__pyx_v_scheme, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_9 = PyObject_RichCompare(__pyx_t_2, ((PyObject *)__pyx_n_s__c2r), Py_NE); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 888; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    if (!__pyx_t_3) {
-      __pyx_t_11 = (!(__pyx_v_self->__pyx___rank > 1));
-      __pyx_t_21 = __pyx_t_11;
-    } else {
-      __pyx_t_21 = __pyx_t_3;
-    }
-    __pyx_t_3 = __pyx_t_21;
-  } else {
-    __pyx_t_3 = __pyx_t_14;
-  }
-  if (__pyx_t_3) {
 
-    /* "pyfftw/pyfftw.pyx":891
- *             # The default in all possible cases is to preserve the input
- *             # This is not possible for r2c arrays with rank > 1
- *             self.__flags |= FFTW_PRESERVE_INPUT             # <<<<<<<<<<<<<<
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_11_get_input_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_10_get_input_array[] = "\n        Return the input array that is associated with the FFTW \n        instance.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_11_get_input_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_input_array (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_10_get_input_array(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_10_get_input_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_input_array", 0);
+
+  /* "pyfftw/pyfftw.pyx":727
+ *         instance.
+ *         '''
+ *         return self._input_array             # <<<<<<<<<<<<<<
  * 
- *         # Set up the arrays of structs for holding the stride shape
+ *     input_array = property(_get_input_array)
  */
-    __pyx_v_self->__pyx___flags = (__pyx_v_self->__pyx___flags | __pyx_e_6pyfftw_6pyfftw_FFTW_PRESERVE_INPUT);
-    goto __pyx_L59;
-  }
-  __pyx_L59:;
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->_input_array));
+  __pyx_r = ((PyObject *)__pyx_v_self->_input_array);
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":895
- *         # Set up the arrays of structs for holding the stride shape
- *         # information
- *         self.__dims = <_fftw_iodim *>malloc(             # <<<<<<<<<<<<<<
- *                 self.__rank * sizeof(_fftw_iodim))
- *         self.__howmany_dims = <_fftw_iodim *>malloc(
+  /* "pyfftw/pyfftw.pyx":722
+ *     flags = property(_get_flags_used)
+ * 
+ *     def _get_input_array(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the input array that is associated with the FFTW
  */
-  __pyx_v_self->__pyx___dims = ((__pyx_t_6pyfftw_6pyfftw__fftw_iodim *)malloc((__pyx_v_self->__pyx___rank * (sizeof(__pyx_t_6pyfftw_6pyfftw__fftw_iodim)))));
 
-  /* "pyfftw/pyfftw.pyx":897
- *         self.__dims = <_fftw_iodim *>malloc(
- *                 self.__rank * sizeof(_fftw_iodim))
- *         self.__howmany_dims = <_fftw_iodim *>malloc(             # <<<<<<<<<<<<<<
- *                 self.__howmany_rank * sizeof(_fftw_iodim))
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":731
+ *     input_array = property(_get_input_array)
  * 
+ *     def _get_output_array(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the output array that is associated with the FFTW
  */
-  __pyx_v_self->__pyx___howmany_dims = ((__pyx_t_6pyfftw_6pyfftw__fftw_iodim *)malloc((__pyx_v_self->__pyx___howmany_rank * (sizeof(__pyx_t_6pyfftw_6pyfftw__fftw_iodim)))));
 
-  /* "pyfftw/pyfftw.pyx":900
- *                 self.__howmany_rank * sizeof(_fftw_iodim))
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_13_get_output_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_12_get_output_array[] = "\n        Return the output array that is associated with the FFTW \n        instance.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_13_get_output_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_output_array (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_12_get_output_array(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_12_get_output_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_output_array", 0);
+
+  /* "pyfftw/pyfftw.pyx":736
+ *         instance.
+ *         '''
+ *         return self._output_array             # <<<<<<<<<<<<<<
  * 
- *         if self.__dims == NULL or self.__howmany_dims == NULL:             # <<<<<<<<<<<<<<
- *             # Not much else to do than raise an exception
- *             raise MemoryError
+ *     output_array = property(_get_output_array)
  */
-  __pyx_t_3 = (__pyx_v_self->__pyx___dims == NULL);
-  if (!__pyx_t_3) {
-    __pyx_t_14 = (__pyx_v_self->__pyx___howmany_dims == NULL);
-    __pyx_t_21 = __pyx_t_14;
-  } else {
-    __pyx_t_21 = __pyx_t_3;
-  }
-  if (__pyx_t_21) {
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->_output_array));
+  __pyx_r = ((PyObject *)__pyx_v_self->_output_array);
+  goto __pyx_L0;
 
-    /* "pyfftw/pyfftw.pyx":902
- *         if self.__dims == NULL or self.__howmany_dims == NULL:
- *             # Not much else to do than raise an exception
- *             raise MemoryError             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":731
+ *     input_array = property(_get_input_array)
  * 
- *         # Find the strides for all the axes of both arrays in terms of the
+ *     def _get_output_array(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the output array that is associated with the FFTW
  */
-    PyErr_NoMemory(); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L60;
-  }
-  __pyx_L60:;
 
-  /* "pyfftw/pyfftw.pyx":906
- *         # Find the strides for all the axes of both arrays in terms of the
- *         # number of elements (as opposed to the number of bytes).
- *         self.__input_byte_strides = input_array.strides             # <<<<<<<<<<<<<<
- *         self.__input_strides = tuple([stride/input_array.itemsize
- *             for stride in input_array.strides])
- */
-  __pyx_t_9 = PyObject_GetAttr(__pyx_v_input_array, __pyx_n_s__strides); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
-  __Pyx_GIVEREF(__pyx_t_9);
-  __Pyx_GOTREF(__pyx_v_self->__pyx___input_byte_strides);
-  __Pyx_DECREF(__pyx_v_self->__pyx___input_byte_strides);
-  __pyx_v_self->__pyx___input_byte_strides = __pyx_t_9;
-  __pyx_t_9 = 0;
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":907
- *         # number of elements (as opposed to the number of bytes).
- *         self.__input_byte_strides = input_array.strides
- *         self.__input_strides = tuple([stride/input_array.itemsize             # <<<<<<<<<<<<<<
- *             for stride in input_array.strides])
- *         self.__output_byte_strides = output_array.strides
+/* "pyfftw/pyfftw.pyx":740
+ *     output_array = property(_get_output_array)
+ * 
+ *     def _get_input_strides(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the strides of the input array for which the FFT is planned.
  */
-  __pyx_t_9 = PyList_New(0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
 
-  /* "pyfftw/pyfftw.pyx":908
- *         self.__input_byte_strides = input_array.strides
- *         self.__input_strides = tuple([stride/input_array.itemsize
- *             for stride in input_array.strides])             # <<<<<<<<<<<<<<
- *         self.__output_byte_strides = output_array.strides
- *         self.__output_strides = tuple([stride/output_array.itemsize
- */
-  __pyx_t_2 = PyObject_GetAttr(__pyx_v_input_array, __pyx_n_s__strides); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyList_CheckExact(__pyx_t_2) || PyTuple_CheckExact(__pyx_t_2)) {
-    __pyx_t_1 = __pyx_t_2; __Pyx_INCREF(__pyx_t_1); __pyx_t_12 = 0;
-    __pyx_t_13 = NULL;
-  } else {
-    __pyx_t_12 = -1; __pyx_t_1 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_13 = Py_TYPE(__pyx_t_1)->tp_iternext;
-  }
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  for (;;) {
-    if (!__pyx_t_13 && PyList_CheckExact(__pyx_t_1)) {
-      if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_1)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyList_GET_ITEM(__pyx_t_1, __pyx_t_12); __Pyx_INCREF(__pyx_t_2); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else if (!__pyx_t_13 && PyTuple_CheckExact(__pyx_t_1)) {
-      if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_12); __Pyx_INCREF(__pyx_t_2); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_2 = PySequence_ITEM(__pyx_t_1, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else {
-      __pyx_t_2 = __pyx_t_13(__pyx_t_1);
-      if (unlikely(!__pyx_t_2)) {
-        if (PyErr_Occurred()) {
-          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        }
-        break;
-      }
-      __Pyx_GOTREF(__pyx_t_2);
-    }
-    __Pyx_XDECREF(__pyx_v_stride);
-    __pyx_v_stride = __pyx_t_2;
-    __pyx_t_2 = 0;
-
-    /* "pyfftw/pyfftw.pyx":907
- *         # number of elements (as opposed to the number of bytes).
- *         self.__input_byte_strides = input_array.strides
- *         self.__input_strides = tuple([stride/input_array.itemsize             # <<<<<<<<<<<<<<
- *             for stride in input_array.strides])
- *         self.__output_byte_strides = output_array.strides
- */
-    __pyx_t_2 = PyObject_GetAttr(__pyx_v_input_array, __pyx_n_s__itemsize); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_10 = __Pyx_PyNumber_Divide(__pyx_v_stride, __pyx_t_2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_10);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (unlikely(__Pyx_PyList_Append(__pyx_t_9, (PyObject*)__pyx_t_10))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  }
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = ((PyObject *)PyList_AsTuple(__pyx_t_9)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __Pyx_DECREF(((PyObject *)__pyx_t_9)); __pyx_t_9 = 0;
-  __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
-  __Pyx_GOTREF(__pyx_v_self->__pyx___input_strides);
-  __Pyx_DECREF(__pyx_v_self->__pyx___input_strides);
-  __pyx_v_self->__pyx___input_strides = ((PyObject *)__pyx_t_1);
-  __pyx_t_1 = 0;
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_15_get_input_strides(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_14_get_input_strides[] = "\n        Return the strides of the input array for which the FFT is planned.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_15_get_input_strides(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_input_strides (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_14_get_input_strides(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
 
-  /* "pyfftw/pyfftw.pyx":909
- *         self.__input_strides = tuple([stride/input_array.itemsize
- *             for stride in input_array.strides])
- *         self.__output_byte_strides = output_array.strides             # <<<<<<<<<<<<<<
- *         self.__output_strides = tuple([stride/output_array.itemsize
- *             for stride in output_array.strides])
- */
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_output_array, __pyx_n_s__strides); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __Pyx_GOTREF(__pyx_v_self->__pyx___output_byte_strides);
-  __Pyx_DECREF(__pyx_v_self->__pyx___output_byte_strides);
-  __pyx_v_self->__pyx___output_byte_strides = __pyx_t_1;
-  __pyx_t_1 = 0;
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":910
- *             for stride in input_array.strides])
- *         self.__output_byte_strides = output_array.strides
- *         self.__output_strides = tuple([stride/output_array.itemsize             # <<<<<<<<<<<<<<
- *             for stride in output_array.strides])
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_14_get_input_strides(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_input_strides", 0);
+
+  /* "pyfftw/pyfftw.pyx":744
+ *         Return the strides of the input array for which the FFT is planned.
+ *         '''
+ *         return self._input_strides             # <<<<<<<<<<<<<<
  * 
+ *     input_strides = property(_get_input_strides)
  */
-  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->_input_strides);
+  __pyx_r = __pyx_v_self->_input_strides;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":911
- *         self.__output_byte_strides = output_array.strides
- *         self.__output_strides = tuple([stride/output_array.itemsize
- *             for stride in output_array.strides])             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":740
+ *     output_array = property(_get_output_array)
  * 
- *         # Make sure that the arrays are not too big for fftw
+ *     def _get_input_strides(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the strides of the input array for which the FFT is planned.
  */
-  __pyx_t_9 = PyObject_GetAttr(__pyx_v_output_array, __pyx_n_s__strides); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_9);
-  if (PyList_CheckExact(__pyx_t_9) || PyTuple_CheckExact(__pyx_t_9)) {
-    __pyx_t_10 = __pyx_t_9; __Pyx_INCREF(__pyx_t_10); __pyx_t_12 = 0;
-    __pyx_t_13 = NULL;
-  } else {
-    __pyx_t_12 = -1; __pyx_t_10 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_10);
-    __pyx_t_13 = Py_TYPE(__pyx_t_10)->tp_iternext;
-  }
-  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-  for (;;) {
-    if (!__pyx_t_13 && PyList_CheckExact(__pyx_t_10)) {
-      if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_10)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_9 = PyList_GET_ITEM(__pyx_t_10, __pyx_t_12); __Pyx_INCREF(__pyx_t_9); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_9 = PySequence_ITEM(__pyx_t_10, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else if (!__pyx_t_13 && PyTuple_CheckExact(__pyx_t_10)) {
-      if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_10)) break;
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_10, __pyx_t_12); __Pyx_INCREF(__pyx_t_9); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #else
-      __pyx_t_9 = PySequence_ITEM(__pyx_t_10, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else {
-      __pyx_t_9 = __pyx_t_13(__pyx_t_10);
-      if (unlikely(!__pyx_t_9)) {
-        if (PyErr_Occurred()) {
-          if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) PyErr_Clear();
-          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 911; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        }
-        break;
-      }
-      __Pyx_GOTREF(__pyx_t_9);
-    }
-    __Pyx_XDECREF(__pyx_v_stride);
-    __pyx_v_stride = __pyx_t_9;
-    __pyx_t_9 = 0;
 
-    /* "pyfftw/pyfftw.pyx":910
- *             for stride in input_array.strides])
- *         self.__output_byte_strides = output_array.strides
- *         self.__output_strides = tuple([stride/output_array.itemsize             # <<<<<<<<<<<<<<
- *             for stride in output_array.strides])
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":748
+ *     input_strides = property(_get_input_strides)
  * 
+ *     def _get_output_strides(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the strides of the output array for which the FFT is planned.
  */
-    __pyx_t_9 = PyObject_GetAttr(__pyx_v_output_array, __pyx_n_s__itemsize); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_9);
-    __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_v_stride, __pyx_t_9); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
-    if (unlikely(__Pyx_PyList_Append(__pyx_t_1, (PyObject*)__pyx_t_2))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  }
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  __pyx_t_10 = ((PyObject *)PyList_AsTuple(__pyx_t_1)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 910; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_10));
-  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __Pyx_GIVEREF(((PyObject *)__pyx_t_10));
-  __Pyx_GOTREF(__pyx_v_self->__pyx___output_strides);
-  __Pyx_DECREF(__pyx_v_self->__pyx___output_strides);
-  __pyx_v_self->__pyx___output_strides = ((PyObject *)__pyx_t_10);
-  __pyx_t_10 = 0;
 
-  /* "pyfftw/pyfftw.pyx":917
- *         # best (any suggestions, please get in touch).
- *         cdef int i
- *         for i in range(0, len(self.__input_shape)):             # <<<<<<<<<<<<<<
- *             if self.__input_shape[i] >= <Py_ssize_t> limits.INT_MAX:
- *                 raise ValueError('Dimensions of the input array must be ' +
- */
-  __pyx_t_10 = __pyx_v_self->__pyx___input_shape;
-  __Pyx_INCREF(__pyx_t_10);
-  __pyx_t_12 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 917; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_12; __pyx_t_8+=1) {
-    __pyx_v_i = __pyx_t_8;
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_17_get_output_strides(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_16_get_output_strides[] = "\n        Return the strides of the output array for which the FFT is planned.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_17_get_output_strides(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_output_strides (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_16_get_output_strides(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
 
-    /* "pyfftw/pyfftw.pyx":918
- *         cdef int i
- *         for i in range(0, len(self.__input_shape)):
- *             if self.__input_shape[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
- *                 raise ValueError('Dimensions of the input array must be ' +
- *                         'less than ', str(limits.INT_MAX))
- */
-    __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_self->__pyx___input_shape, __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_10);
-    __pyx_t_1 = PyInt_FromSsize_t(((Py_ssize_t)INT_MAX)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyObject_RichCompare(__pyx_t_10, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_21 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_21 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (__pyx_t_21) {
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-      /* "pyfftw/pyfftw.pyx":919
- *         for i in range(0, len(self.__input_shape)):
- *             if self.__input_shape[i] >= <Py_ssize_t> limits.INT_MAX:
- *                 raise ValueError('Dimensions of the input array must be ' +             # <<<<<<<<<<<<<<
- *                         'less than ', str(limits.INT_MAX))
- * 
- */
-      __pyx_t_2 = PyNumber_Add(((PyObject *)__pyx_kp_s_31), ((PyObject *)__pyx_kp_s_32)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_16_get_output_strides(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_output_strides", 0);
 
-      /* "pyfftw/pyfftw.pyx":920
- *             if self.__input_shape[i] >= <Py_ssize_t> limits.INT_MAX:
- *                 raise ValueError('Dimensions of the input array must be ' +
- *                         'less than ', str(limits.INT_MAX))             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":752
+ *         Return the strides of the output array for which the FFT is planned.
+ *         '''
+ *         return self._output_strides             # <<<<<<<<<<<<<<
  * 
- *             if self.__input_strides[i] >= <Py_ssize_t> limits.INT_MAX:
+ *     output_strides = property(_get_output_strides)
  */
-      __pyx_t_1 = PyInt_FromLong(INT_MAX); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_10);
-      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1);
-      __Pyx_GIVEREF(__pyx_t_1);
-      __pyx_t_1 = 0;
-      __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
-      __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_10);
-      PyTuple_SET_ITEM(__pyx_t_10, 0, ((PyObject *)__pyx_t_2));
-      __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
-      PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_1);
-      __Pyx_GIVEREF(__pyx_t_1);
-      __pyx_t_2 = 0;
-      __pyx_t_1 = 0;
-      __pyx_t_1 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
-      __Pyx_Raise(__pyx_t_1, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      goto __pyx_L67;
-    }
-    __pyx_L67:;
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->_output_strides);
+  __pyx_r = __pyx_v_self->_output_strides;
+  goto __pyx_L0;
 
-    /* "pyfftw/pyfftw.pyx":922
- *                         'less than ', str(limits.INT_MAX))
+  /* "pyfftw/pyfftw.pyx":748
+ *     input_strides = property(_get_input_strides)
  * 
- *             if self.__input_strides[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
- *                 raise ValueError('Strides of the input array must be ' +
- *                         'less than ', str(limits.INT_MAX))
+ *     def _get_output_strides(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the strides of the output array for which the FFT is planned.
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_self->__pyx___input_strides, __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_10 = PyInt_FromSsize_t(((Py_ssize_t)INT_MAX)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_10);
-    __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_t_10, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-    __pyx_t_21 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_21 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (__pyx_t_21) {
 
-      /* "pyfftw/pyfftw.pyx":923
- * 
- *             if self.__input_strides[i] >= <Py_ssize_t> limits.INT_MAX:
- *                 raise ValueError('Strides of the input array must be ' +             # <<<<<<<<<<<<<<
- *                         'less than ', str(limits.INT_MAX))
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":756
+ *     output_strides = property(_get_output_strides)
  * 
+ *     def _get_input_shape(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the shape of the input array for which the FFT is planned.
  */
-      __pyx_t_2 = PyNumber_Add(((PyObject *)__pyx_kp_s_33), ((PyObject *)__pyx_kp_s_32)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(((PyObject *)__pyx_t_2));
 
-      /* "pyfftw/pyfftw.pyx":924
- *             if self.__input_strides[i] >= <Py_ssize_t> limits.INT_MAX:
- *                 raise ValueError('Strides of the input array must be ' +
- *                         'less than ', str(limits.INT_MAX))             # <<<<<<<<<<<<<<
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_19_get_input_shape(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_18_get_input_shape[] = "\n        Return the shape of the input array for which the FFT is planned.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_19_get_input_shape(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_input_shape (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_18_get_input_shape(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_18_get_input_shape(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_input_shape", 0);
+
+  /* "pyfftw/pyfftw.pyx":760
+ *         Return the shape of the input array for which the FFT is planned.
+ *         '''
+ *         return self._input_shape             # <<<<<<<<<<<<<<
  * 
- *         for i in range(0, len(self.__output_shape)):
+ *     input_shape = property(_get_input_shape)
  */
-      __pyx_t_10 = PyInt_FromLong(INT_MAX); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_10);
-      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_10);
-      __Pyx_GIVEREF(__pyx_t_10);
-      __pyx_t_10 = 0;
-      __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_10);
-      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_2));
-      __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
-      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_10);
-      __Pyx_GIVEREF(__pyx_t_10);
-      __pyx_t_2 = 0;
-      __pyx_t_10 = 0;
-      __pyx_t_10 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_10);
-      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __Pyx_Raise(__pyx_t_10, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 923; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      goto __pyx_L68;
-    }
-    __pyx_L68:;
-  }
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->_input_shape);
+  __pyx_r = __pyx_v_self->_input_shape;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":926
- *                         'less than ', str(limits.INT_MAX))
+  /* "pyfftw/pyfftw.pyx":756
+ *     output_strides = property(_get_output_strides)
  * 
- *         for i in range(0, len(self.__output_shape)):             # <<<<<<<<<<<<<<
- *             if self.__output_shape[i] >= <Py_ssize_t> limits.INT_MAX:
- *                 raise ValueError('Dimensions of the output array must be ' +
+ *     def _get_input_shape(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the shape of the input array for which the FFT is planned.
  */
-  __pyx_t_10 = __pyx_v_self->__pyx___output_shape;
-  __Pyx_INCREF(__pyx_t_10);
-  __pyx_t_12 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_12; __pyx_t_8+=1) {
-    __pyx_v_i = __pyx_t_8;
 
-    /* "pyfftw/pyfftw.pyx":927
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":764
+ *     input_shape = property(_get_input_shape)
  * 
- *         for i in range(0, len(self.__output_shape)):
- *             if self.__output_shape[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
- *                 raise ValueError('Dimensions of the output array must be ' +
- *                         'less than ', str(limits.INT_MAX))
+ *     def _get_output_shape(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the shape of the output array for which the FFT is planned.
  */
-    __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_self->__pyx___output_shape, __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_10) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_10);
-    __pyx_t_1 = PyInt_FromSsize_t(((Py_ssize_t)INT_MAX)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyObject_RichCompare(__pyx_t_10, __pyx_t_1, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_21 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_21 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (__pyx_t_21) {
 
-      /* "pyfftw/pyfftw.pyx":928
- *         for i in range(0, len(self.__output_shape)):
- *             if self.__output_shape[i] >= <Py_ssize_t> limits.INT_MAX:
- *                 raise ValueError('Dimensions of the output array must be ' +             # <<<<<<<<<<<<<<
- *                         'less than ', str(limits.INT_MAX))
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_21_get_output_shape(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_20_get_output_shape[] = "\n        Return the shape of the output array for which the FFT is planned.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_21_get_output_shape(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_output_shape (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_20_get_output_shape(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_20_get_output_shape(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_output_shape", 0);
+
+  /* "pyfftw/pyfftw.pyx":768
+ *         Return the shape of the output array for which the FFT is planned.
+ *         '''
+ *         return self._output_shape             # <<<<<<<<<<<<<<
  * 
+ *     output_shape = property(_get_output_shape)
  */
-      __pyx_t_2 = PyNumber_Add(((PyObject *)__pyx_kp_s_34), ((PyObject *)__pyx_kp_s_32)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 928; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->_output_shape);
+  __pyx_r = __pyx_v_self->_output_shape;
+  goto __pyx_L0;
 
-      /* "pyfftw/pyfftw.pyx":929
- *             if self.__output_shape[i] >= <Py_ssize_t> limits.INT_MAX:
- *                 raise ValueError('Dimensions of the output array must be ' +
- *                         'less than ', str(limits.INT_MAX))             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":764
+ *     input_shape = property(_get_input_shape)
  * 
- *             if self.__output_strides[i] >= <Py_ssize_t> limits.INT_MAX:
+ *     def _get_output_shape(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the shape of the output array for which the FFT is planned.
  */
-      __pyx_t_1 = PyInt_FromLong(INT_MAX); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_10);
-      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1);
-      __Pyx_GIVEREF(__pyx_t_1);
-      __pyx_t_1 = 0;
-      __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 929; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
-      __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 928; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_10);
-      PyTuple_SET_ITEM(__pyx_t_10, 0, ((PyObject *)__pyx_t_2));
-      __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
-      PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_1);
-      __Pyx_GIVEREF(__pyx_t_1);
-      __pyx_t_2 = 0;
-      __pyx_t_1 = 0;
-      __pyx_t_1 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 928; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
-      __Pyx_Raise(__pyx_t_1, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 928; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      goto __pyx_L71;
-    }
-    __pyx_L71:;
 
-    /* "pyfftw/pyfftw.pyx":931
- *                         'less than ', str(limits.INT_MAX))
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":772
+ *     output_shape = property(_get_output_shape)
  * 
- *             if self.__output_strides[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
- *                 raise ValueError('Strides of the output array must be ' +
- *                         'less than ', str(limits.INT_MAX))
+ *     def _get_input_dtype(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the dtype of the input array for which the FFT is planned.
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_self->__pyx___output_strides, __pyx_v_i, sizeof(int), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_10 = PyInt_FromSsize_t(((Py_ssize_t)INT_MAX)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_10);
-    __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_t_10, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-    __pyx_t_21 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_21 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    if (__pyx_t_21) {
 
-      /* "pyfftw/pyfftw.pyx":932
- * 
- *             if self.__output_strides[i] >= <Py_ssize_t> limits.INT_MAX:
- *                 raise ValueError('Strides of the output array must be ' +             # <<<<<<<<<<<<<<
- *                         'less than ', str(limits.INT_MAX))
- * 
- */
-      __pyx_t_2 = PyNumber_Add(((PyObject *)__pyx_kp_s_35), ((PyObject *)__pyx_kp_s_32)); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_23_get_input_dtype(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_22_get_input_dtype[] = "\n        Return the dtype of the input array for which the FFT is planned.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_23_get_input_dtype(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_input_dtype (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_22_get_input_dtype(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
 
-      /* "pyfftw/pyfftw.pyx":933
- *             if self.__output_strides[i] >= <Py_ssize_t> limits.INT_MAX:
- *                 raise ValueError('Strides of the output array must be ' +
- *                         'less than ', str(limits.INT_MAX))             # <<<<<<<<<<<<<<
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_22_get_input_dtype(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_input_dtype", 0);
+
+  /* "pyfftw/pyfftw.pyx":776
+ *         Return the dtype of the input array for which the FFT is planned.
+ *         '''
+ *         return self._input_dtype             # <<<<<<<<<<<<<<
  * 
- *         fft_shape_lookup = functions['fft_shape_lookup']
+ *     input_dtype = property(_get_input_dtype)
  */
-      __pyx_t_10 = PyInt_FromLong(INT_MAX); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_10);
-      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_10);
-      __Pyx_GIVEREF(__pyx_t_10);
-      __pyx_t_10 = 0;
-      __pyx_t_10 = PyObject_Call(((PyObject *)((PyObject*)(&PyString_Type))), ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_10);
-      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_1);
-      PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_2));
-      __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
-      PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_10);
-      __Pyx_GIVEREF(__pyx_t_10);
-      __pyx_t_2 = 0;
-      __pyx_t_10 = 0;
-      __pyx_t_10 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_10);
-      __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-      __Pyx_Raise(__pyx_t_10, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      goto __pyx_L72;
-    }
-    __pyx_L72:;
-  }
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->_input_dtype);
+  __pyx_r = __pyx_v_self->_input_dtype;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":935
- *                         'less than ', str(limits.INT_MAX))
+  /* "pyfftw/pyfftw.pyx":772
+ *     output_shape = property(_get_output_shape)
  * 
- *         fft_shape_lookup = functions['fft_shape_lookup']             # <<<<<<<<<<<<<<
- *         if fft_shape_lookup == -1:
- *             fft_shape = self.__input_shape
+ *     def _get_input_dtype(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the dtype of the input array for which the FFT is planned.
  */
-  __pyx_t_10 = PyObject_GetItem(__pyx_v_functions, ((PyObject *)__pyx_n_s__fft_shape_lookup)); if (!__pyx_t_10) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_10);
-  __pyx_v_fft_shape_lookup = __pyx_t_10;
-  __pyx_t_10 = 0;
 
-  /* "pyfftw/pyfftw.pyx":936
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":780
+ *     input_dtype = property(_get_input_dtype)
  * 
- *         fft_shape_lookup = functions['fft_shape_lookup']
- *         if fft_shape_lookup == -1:             # <<<<<<<<<<<<<<
- *             fft_shape = self.__input_shape
- *         else:
+ *     def _get_output_dtype(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the shape of the output array for which the FFT is planned.
  */
-  __pyx_t_10 = PyObject_RichCompare(__pyx_v_fft_shape_lookup, __pyx_int_neg_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_10); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_21 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_21 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-  if (__pyx_t_21) {
 
-    /* "pyfftw/pyfftw.pyx":937
- *         fft_shape_lookup = functions['fft_shape_lookup']
- *         if fft_shape_lookup == -1:
- *             fft_shape = self.__input_shape             # <<<<<<<<<<<<<<
- *         else:
- *             fft_shape = fft_shape_lookup(input_array, output_array)
- */
-    __pyx_t_10 = __pyx_v_self->__pyx___input_shape;
-    __Pyx_INCREF(__pyx_t_10);
-    __pyx_v_fft_shape = __pyx_t_10;
-    __pyx_t_10 = 0;
-    goto __pyx_L73;
-  }
-  /*else*/ {
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_25_get_output_dtype(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_24_get_output_dtype[] = "\n        Return the shape of the output array for which the FFT is planned.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_25_get_output_dtype(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_output_dtype (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_24_get_output_dtype(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
 
-    /* "pyfftw/pyfftw.pyx":939
- *             fft_shape = self.__input_shape
- *         else:
- *             fft_shape = fft_shape_lookup(input_array, output_array)             # <<<<<<<<<<<<<<
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_24_get_output_dtype(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_output_dtype", 0);
+
+  /* "pyfftw/pyfftw.pyx":784
+ *         Return the shape of the output array for which the FFT is planned.
+ *         '''
+ *         return self._output_dtype             # <<<<<<<<<<<<<<
  * 
- *         # Fill in the stride and shape information
+ *     output_dtype = property(_get_output_dtype)
  */
-    __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_10);
-    __Pyx_INCREF(__pyx_v_input_array);
-    PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_input_array);
-    __Pyx_GIVEREF(__pyx_v_input_array);
-    __Pyx_INCREF(__pyx_v_output_array);
-    PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_v_output_array);
-    __Pyx_GIVEREF(__pyx_v_output_array);
-    __pyx_t_1 = PyObject_Call(__pyx_v_fft_shape_lookup, ((PyObject *)__pyx_t_10), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(((PyObject *)__pyx_t_10)); __pyx_t_10 = 0;
-    __pyx_v_fft_shape = __pyx_t_1;
-    __pyx_t_1 = 0;
-  }
-  __pyx_L73:;
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(__pyx_v_self->_output_dtype);
+  __pyx_r = __pyx_v_self->_output_dtype;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":942
+  /* "pyfftw/pyfftw.pyx":780
+ *     input_dtype = property(_get_input_dtype)
  * 
- *         # Fill in the stride and shape information
- *         input_strides_array = self.__input_strides             # <<<<<<<<<<<<<<
- *         output_strides_array = self.__output_strides
- *         for i in range(0, self.__rank):
+ *     def _get_output_dtype(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the shape of the output array for which the FFT is planned.
  */
-  __pyx_t_1 = __pyx_v_self->__pyx___input_strides;
-  __Pyx_INCREF(__pyx_t_1);
-  __pyx_v_input_strides_array = __pyx_t_1;
-  __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":943
- *         # Fill in the stride and shape information
- *         input_strides_array = self.__input_strides
- *         output_strides_array = self.__output_strides             # <<<<<<<<<<<<<<
- *         for i in range(0, self.__rank):
- *             self.__dims[i]._n = fft_shape[self.__axes[i]]
- */
-  __pyx_t_1 = __pyx_v_self->__pyx___output_strides;
-  __Pyx_INCREF(__pyx_t_1);
-  __pyx_v_output_strides_array = __pyx_t_1;
-  __pyx_t_1 = 0;
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":944
- *         input_strides_array = self.__input_strides
- *         output_strides_array = self.__output_strides
- *         for i in range(0, self.__rank):             # <<<<<<<<<<<<<<
- *             self.__dims[i]._n = fft_shape[self.__axes[i]]
- *             self.__dims[i]._is = input_strides_array[self.__axes[i]]
+/* "pyfftw/pyfftw.pyx":788
+ *     output_dtype = property(_get_output_dtype)
+ * 
+ *     def _get_direction(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the planned FFT direction. Either `'FFTW_FORWARD'` or
  */
-  __pyx_t_8 = __pyx_v_self->__pyx___rank;
-  for (__pyx_t_22 = 0; __pyx_t_22 < __pyx_t_8; __pyx_t_22+=1) {
-    __pyx_v_i = __pyx_t_22;
 
-    /* "pyfftw/pyfftw.pyx":945
- *         output_strides_array = self.__output_strides
- *         for i in range(0, self.__rank):
- *             self.__dims[i]._n = fft_shape[self.__axes[i]]             # <<<<<<<<<<<<<<
- *             self.__dims[i]._is = input_strides_array[self.__axes[i]]
- *             self.__dims[i]._os = output_strides_array[self.__axes[i]]
- */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_fft_shape, (__pyx_v_self->__pyx___axes[__pyx_v_i]), sizeof(int64_t), __Pyx_PyInt_to_py_int64_t); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_23 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 945; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    (__pyx_v_self->__pyx___dims[__pyx_v_i])._n = __pyx_t_23;
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_27_get_direction(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_26_get_direction[] = "\n        Return the planned FFT direction. Either `'FFTW_FORWARD'` or \n        `'FFTW_BACKWARD'`.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_27_get_direction(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_direction (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_26_get_direction(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_26_get_direction(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_direction", 0);
 
-    /* "pyfftw/pyfftw.pyx":946
- *         for i in range(0, self.__rank):
- *             self.__dims[i]._n = fft_shape[self.__axes[i]]
- *             self.__dims[i]._is = input_strides_array[self.__axes[i]]             # <<<<<<<<<<<<<<
- *             self.__dims[i]._os = output_strides_array[self.__axes[i]]
+  /* "pyfftw/pyfftw.pyx":793
+ *         `'FFTW_BACKWARD'`.
+ *         '''
+ *         return directions_lookup[self._direction]             # <<<<<<<<<<<<<<
  * 
+ *     direction = property(_get_direction)
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_input_strides_array, (__pyx_v_self->__pyx___axes[__pyx_v_i]), sizeof(int64_t), __Pyx_PyInt_to_py_int64_t); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_23 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    (__pyx_v_self->__pyx___dims[__pyx_v_i])._is = __pyx_t_23;
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_6pyfftw_6pyfftw_directions_lookup, __pyx_v_self->_direction, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 793; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-    /* "pyfftw/pyfftw.pyx":947
- *             self.__dims[i]._n = fft_shape[self.__axes[i]]
- *             self.__dims[i]._is = input_strides_array[self.__axes[i]]
- *             self.__dims[i]._os = output_strides_array[self.__axes[i]]             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":788
+ *     output_dtype = property(_get_output_dtype)
  * 
- *         for i in range(0, self.__howmany_rank):
+ *     def _get_direction(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the planned FFT direction. Either `'FFTW_FORWARD'` or
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_output_strides_array, (__pyx_v_self->__pyx___axes[__pyx_v_i]), sizeof(int64_t), __Pyx_PyInt_to_py_int64_t); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_23 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 947; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    (__pyx_v_self->__pyx___dims[__pyx_v_i])._os = __pyx_t_23;
-  }
 
-  /* "pyfftw/pyfftw.pyx":949
- *             self.__dims[i]._os = output_strides_array[self.__axes[i]]
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW._get_direction", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":797
+ *     direction = property(_get_direction)
  * 
- *         for i in range(0, self.__howmany_rank):             # <<<<<<<<<<<<<<
- *             self.__howmany_dims[i]._n = fft_shape[self.__not_axes[i]]
- *             self.__howmany_dims[i]._is = input_strides_array[self.__not_axes[i]]
+ *     def _get_axes(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the axes for the planned FFT in canonical form. That is, as
  */
-  __pyx_t_8 = __pyx_v_self->__pyx___howmany_rank;
-  for (__pyx_t_22 = 0; __pyx_t_22 < __pyx_t_8; __pyx_t_22+=1) {
-    __pyx_v_i = __pyx_t_22;
 
-    /* "pyfftw/pyfftw.pyx":950
- * 
- *         for i in range(0, self.__howmany_rank):
- *             self.__howmany_dims[i]._n = fft_shape[self.__not_axes[i]]             # <<<<<<<<<<<<<<
- *             self.__howmany_dims[i]._is = input_strides_array[self.__not_axes[i]]
- *             self.__howmany_dims[i]._os = output_strides_array[self.__not_axes[i]]
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_29_get_axes(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_28_get_axes[] = "\n        Return the axes for the planned FFT in canonical form. That is, as\n        a tuple of positive integers. The order in which they were passed\n        is maintained.\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_29_get_axes(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_get_axes (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_28_get_axes(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_28_get_axes(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_v_axes = NULL;
+  int __pyx_v_i;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  int __pyx_t_4;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_get_axes", 0);
+
+  /* "pyfftw/pyfftw.pyx":803
+ *         is maintained.
+ *         '''
+ *         axes = []             # <<<<<<<<<<<<<<
+ *         for i in range(self._rank):
+ *             axes.append(self._axes[i])
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_fft_shape, (__pyx_v_self->__pyx___not_axes[__pyx_v_i]), sizeof(int64_t), __Pyx_PyInt_to_py_int64_t); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_23 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 950; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    (__pyx_v_self->__pyx___howmany_dims[__pyx_v_i])._n = __pyx_t_23;
+  __pyx_t_1 = PyList_New(0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_axes = ((PyObject*)__pyx_t_1);
+  __pyx_t_1 = 0;
 
-    /* "pyfftw/pyfftw.pyx":951
- *         for i in range(0, self.__howmany_rank):
- *             self.__howmany_dims[i]._n = fft_shape[self.__not_axes[i]]
- *             self.__howmany_dims[i]._is = input_strides_array[self.__not_axes[i]]             # <<<<<<<<<<<<<<
- *             self.__howmany_dims[i]._os = output_strides_array[self.__not_axes[i]]
+  /* "pyfftw/pyfftw.pyx":804
+ *         '''
+ *         axes = []
+ *         for i in range(self._rank):             # <<<<<<<<<<<<<<
+ *             axes.append(self._axes[i])
  * 
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_input_strides_array, (__pyx_v_self->__pyx___not_axes[__pyx_v_i]), sizeof(int64_t), __Pyx_PyInt_to_py_int64_t); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_23 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    (__pyx_v_self->__pyx___howmany_dims[__pyx_v_i])._is = __pyx_t_23;
+  __pyx_t_2 = __pyx_v_self->_rank;
+  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
+    __pyx_v_i = __pyx_t_3;
 
-    /* "pyfftw/pyfftw.pyx":952
- *             self.__howmany_dims[i]._n = fft_shape[self.__not_axes[i]]
- *             self.__howmany_dims[i]._is = input_strides_array[self.__not_axes[i]]
- *             self.__howmany_dims[i]._os = output_strides_array[self.__not_axes[i]]             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":805
+ *         axes = []
+ *         for i in range(self._rank):
+ *             axes.append(self._axes[i])             # <<<<<<<<<<<<<<
  * 
- *         ## Point at which FFTW calls are made
+ *         return tuple(axes)
  */
-    __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_output_strides_array, (__pyx_v_self->__pyx___not_axes[__pyx_v_i]), sizeof(int64_t), __Pyx_PyInt_to_py_int64_t); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_1 = __Pyx_PyInt_From_int64_t((__pyx_v_self->_axes[__pyx_v_i])); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 805; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_23 = __Pyx_PyInt_AsInt(__pyx_t_1); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 952; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = __Pyx_PyList_Append(__pyx_v_axes, __pyx_t_1); if (unlikely(__pyx_t_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 805; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    (__pyx_v_self->__pyx___howmany_dims[__pyx_v_i])._os = __pyx_t_23;
   }
 
-  /* "pyfftw/pyfftw.pyx":956
- *         ## Point at which FFTW calls are made
- *         ## (and none should be made before this)
- *         if threads > 1:             # <<<<<<<<<<<<<<
- *             self.__use_threads = True
- *             self.__nthreads_plan_setter(threads)
+  /* "pyfftw/pyfftw.pyx":807
+ *             axes.append(self._axes[i])
+ * 
+ *         return tuple(axes)             # <<<<<<<<<<<<<<
+ * 
+ *     axes = property(_get_axes)
  */
-  __pyx_t_21 = (__pyx_v_threads > 1);
-  if (__pyx_t_21) {
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyList_AsTuple(__pyx_v_axes); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-    /* "pyfftw/pyfftw.pyx":957
- *         ## (and none should be made before this)
- *         if threads > 1:
- *             self.__use_threads = True             # <<<<<<<<<<<<<<
- *             self.__nthreads_plan_setter(threads)
- *         else:
+  /* "pyfftw/pyfftw.pyx":797
+ *     direction = property(_get_direction)
+ * 
+ *     def _get_axes(self):             # <<<<<<<<<<<<<<
+ *         '''
+ *         Return the axes for the planned FFT in canonical form. That is, as
  */
-    __pyx_v_self->__pyx___use_threads = 1;
 
-    /* "pyfftw/pyfftw.pyx":958
- *         if threads > 1:
- *             self.__use_threads = True
- *             self.__nthreads_plan_setter(threads)             # <<<<<<<<<<<<<<
- *         else:
- *             self.__use_threads = False
- */
-    __pyx_v_self->__pyx___nthreads_plan_setter(__pyx_v_threads);
-    goto __pyx_L78;
-  }
-  /*else*/ {
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW._get_axes", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_axes);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-    /* "pyfftw/pyfftw.pyx":960
- *             self.__nthreads_plan_setter(threads)
- *         else:
- *             self.__use_threads = False             # <<<<<<<<<<<<<<
- *             self.__nthreads_plan_setter(1)
+/* "pyfftw/pyfftw.pyx":811
+ *     axes = property(_get_axes)
  * 
+ *     def __cinit__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
+ *                   direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
+ *                   unsigned int threads=1, planning_timelimit=None,
  */
-    __pyx_v_self->__pyx___use_threads = 0;
 
-    /* "pyfftw/pyfftw.pyx":961
- *         else:
- *             self.__use_threads = False
- *             self.__nthreads_plan_setter(1)             # <<<<<<<<<<<<<<
- * 
- *         # Set the timelimit
- */
-    __pyx_v_self->__pyx___nthreads_plan_setter(1);
+/* Python wrapper */
+static int __pyx_pw_6pyfftw_6pyfftw_4FFTW_31__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_pw_6pyfftw_6pyfftw_4FFTW_31__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_input_array = 0;
+  PyObject *__pyx_v_output_array = 0;
+  PyObject *__pyx_v_axes = 0;
+  PyObject *__pyx_v_direction = 0;
+  PyObject *__pyx_v_flags = 0;
+  unsigned int __pyx_v_threads;
+  PyObject *__pyx_v_planning_timelimit = 0;
+  CYTHON_UNUSED PyObject *__pyx_v_args = 0;
+  CYTHON_UNUSED PyObject *__pyx_v_kwargs = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
+  __pyx_v_kwargs = PyDict_New(); if (unlikely(!__pyx_v_kwargs)) return -1;
+  __Pyx_GOTREF(__pyx_v_kwargs);
+  if (PyTuple_GET_SIZE(__pyx_args) > 7) {
+    __pyx_v_args = PyTuple_GetSlice(__pyx_args, 7, PyTuple_GET_SIZE(__pyx_args));
+    if (unlikely(!__pyx_v_args)) {
+      __Pyx_DECREF(__pyx_v_kwargs); __pyx_v_kwargs = 0;
+      __Pyx_RefNannyFinishContext();
+      return -1;
+    }
+    __Pyx_GOTREF(__pyx_v_args);
+  } else {
+    __pyx_v_args = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
   }
-  __pyx_L78:;
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_array,&__pyx_n_s_output_array,&__pyx_n_s_axes,&__pyx_n_s_direction,&__pyx_n_s_flags,&__pyx_n_s_threads,&__pyx_n_s_planning_timelimit,0};
+    PyObject* values[7] = {0,0,0,0,0,0,0};
+    values[2] = ((PyObject *)__pyx_tuple__6);
+    values[3] = ((PyObject *)__pyx_n_s_FFTW_FORWARD);
 
-  /* "pyfftw/pyfftw.pyx":964
- * 
- *         # Set the timelimit
- *         set_timelimit_func(_planning_timelimit)             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":812
  * 
- *         # Finally, construct the plan
- */
-  __pyx_v_set_timelimit_func(__pyx_v__planning_timelimit);
-
-  /* "pyfftw/pyfftw.pyx":970
- *             self.__rank, <fftw_iodim *>self.__dims,
- *             self.__howmany_rank, <fftw_iodim *>self.__howmany_dims,
- *             <void *>np.PyArray_DATA(self.__input_array),             # <<<<<<<<<<<<<<
- *             <void *>np.PyArray_DATA(self.__output_array),
- *             self.__direction, self.__flags)
+ *     def __cinit__(self, input_array, output_array, axes=(-1,),
+ *                   direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),             # <<<<<<<<<<<<<<
+ *                   unsigned int threads=1, planning_timelimit=None,
+ *                   *args, **kwargs):
  */
-  __pyx_t_1 = ((PyObject *)__pyx_v_self->__pyx___input_array);
-  __Pyx_INCREF(__pyx_t_1);
+    values[4] = ((PyObject *)__pyx_tuple__7);
 
-  /* "pyfftw/pyfftw.pyx":971
- *             self.__howmany_rank, <fftw_iodim *>self.__howmany_dims,
- *             <void *>np.PyArray_DATA(self.__input_array),
- *             <void *>np.PyArray_DATA(self.__output_array),             # <<<<<<<<<<<<<<
- *             self.__direction, self.__flags)
+    /* "pyfftw/pyfftw.pyx":813
+ *     def __cinit__(self, input_array, output_array, axes=(-1,),
+ *                   direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
+ *                   unsigned int threads=1, planning_timelimit=None,             # <<<<<<<<<<<<<<
+ *                   *args, **kwargs):
  * 
  */
-  __pyx_t_10 = ((PyObject *)__pyx_v_self->__pyx___output_array);
-  __Pyx_INCREF(__pyx_t_10);
-
-  /* "pyfftw/pyfftw.pyx":967
- * 
- *         # Finally, construct the plan
- *         self.__plan = self.__fftw_planner(             # <<<<<<<<<<<<<<
- *             self.__rank, <fftw_iodim *>self.__dims,
- *             self.__howmany_rank, <fftw_iodim *>self.__howmany_dims,
- */
-  __pyx_v_self->__pyx___plan = __pyx_v_self->__pyx___fftw_planner(__pyx_v_self->__pyx___rank, ((fftw_iodim *)__pyx_v_self->__pyx___dims), __pyx_v_self->__pyx___howmany_rank, ((fftw_iodim *)__pyx_v_self->__pyx___howmany_dims), ((void *)PyArray_DATA(((PyArrayObject *)__pyx_t_1))), ((void *)PyArray_DATA(((PyArrayObject *)__pyx_t_10))), __pyx_v_self->__pyx___direction, __pyx_v_self->__pyx___flags);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-
-  /* "pyfftw/pyfftw.pyx":974
- *             self.__direction, self.__flags)
- * 
- *         if self.__plan == NULL:             # <<<<<<<<<<<<<<
- *             raise RuntimeError('The data has an uncaught error that led '+
- *                     'to the planner returning NULL. This is a bug.')
- */
-  __pyx_t_21 = (__pyx_v_self->__pyx___plan == NULL);
-  if (__pyx_t_21) {
-
-    /* "pyfftw/pyfftw.pyx":975
- * 
- *         if self.__plan == NULL:
- *             raise RuntimeError('The data has an uncaught error that led '+             # <<<<<<<<<<<<<<
- *                     'to the planner returning NULL. This is a bug.')
- * 
- */
-    __pyx_t_10 = PyNumber_Add(((PyObject *)__pyx_kp_s_36), ((PyObject *)__pyx_kp_s_37)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(((PyObject *)__pyx_t_10));
-    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_10));
-    __Pyx_GIVEREF(((PyObject *)__pyx_t_10));
-    __pyx_t_10 = 0;
-    __pyx_t_10 = PyObject_Call(__pyx_builtin_RuntimeError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_10);
-    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-    __Pyx_Raise(__pyx_t_10, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L79;
-  }
-  __pyx_L79:;
-
-  __pyx_r = 0;
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_9);
-  __Pyx_XDECREF(__pyx_t_10);
-  __Pyx_XDECREF(__pyx_t_19);
-  __Pyx_XDECREF(__pyx_t_20);
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = -1;
-  __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_input_dtype);
-  __Pyx_XDECREF(__pyx_v_output_dtype);
-  __Pyx_XDECREF(__pyx_v_scheme);
-  __Pyx_XDECREF(__pyx_v_functions);
-  __Pyx_XDECREF(__pyx_v_each_alignment);
-  __Pyx_XDECREF(__pyx_v_n);
-  __Pyx_XDECREF(__pyx_v_total_N);
-  __Pyx_XDECREF(__pyx_v_each_flag);
-  __Pyx_XDECREF(__pyx_v_fft_shape_lookup);
-  __Pyx_XDECREF(__pyx_v_fft_shape);
-  __Pyx_XDECREF(__pyx_v_input_strides_array);
-  __Pyx_XDECREF(__pyx_v_output_strides_array);
-  __Pyx_XDECREF(__pyx_v_stride);
-  __Pyx_XDECREF(__pyx_v_flags);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* Python wrapper */
-static int __pyx_pw_6pyfftw_6pyfftw_4FFTW_13__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_12__init__[] = "\n        **Arguments**:\n\n        * ``input_array`` and ``output_array`` should be numpy arrays.\n          The contents of these arrays will be destroyed by the planning \n          process during initialisation. Information on supported \n          dtypes for the arrays is :ref:`given below <scheme_table>`.\n        \n        * ``axes`` describes along which axes the DFT should be taken.\n          This should be a valid lis [...]
-#if CYTHON_COMPILING_IN_CPYTHON
-struct wrapperbase __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_12__init__;
-#endif
-static int __pyx_pw_6pyfftw_6pyfftw_4FFTW_13__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  CYTHON_UNUSED PyObject *__pyx_v_input_array = 0;
-  CYTHON_UNUSED PyObject *__pyx_v_output_array = 0;
-  CYTHON_UNUSED PyObject *__pyx_v_axes = 0;
-  CYTHON_UNUSED PyObject *__pyx_v_direction = 0;
-  CYTHON_UNUSED PyObject *__pyx_v_flags = 0;
-  CYTHON_UNUSED int __pyx_v_threads;
-  CYTHON_UNUSED PyObject *__pyx_v_planning_timelimit = 0;
-  CYTHON_UNUSED PyObject *__pyx_v_args = 0;
-  CYTHON_UNUSED PyObject *__pyx_v_kwargs = 0;
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
-  __pyx_v_kwargs = PyDict_New(); if (unlikely(!__pyx_v_kwargs)) return -1;
-  __Pyx_GOTREF(__pyx_v_kwargs);
-  if (PyTuple_GET_SIZE(__pyx_args) > 7) {
-    __pyx_v_args = PyTuple_GetSlice(__pyx_args, 7, PyTuple_GET_SIZE(__pyx_args));
-    if (unlikely(!__pyx_v_args)) {
-      __Pyx_DECREF(__pyx_v_kwargs); __pyx_v_kwargs = 0;
-      __Pyx_RefNannyFinishContext();
-      return -1;
-    }
-    __Pyx_GOTREF(__pyx_v_args);
-  } else {
-    __pyx_v_args = __pyx_empty_tuple; __Pyx_INCREF(__pyx_empty_tuple);
-  }
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__input_array,&__pyx_n_s__output_array,&__pyx_n_s__axes,&__pyx_n_s__direction,&__pyx_n_s__flags,&__pyx_n_s__threads,&__pyx_n_s__planning_timelimit,0};
-    PyObject* values[7] = {0,0,0,0,0,0,0};
-
-    /* "pyfftw/pyfftw.pyx":978
- *                     'to the planner returning NULL. This is a bug.')
- * 
- *     def __init__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
- *             int threads=1, planning_timelimit=None,
- */
-    values[2] = ((PyObject *)__pyx_k_tuple_38);
-    values[3] = ((PyObject *)__pyx_n_s__FFTW_FORWARD);
-
-    /* "pyfftw/pyfftw.pyx":979
- * 
- *     def __init__(self, input_array, output_array, axes=(-1,),
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),             # <<<<<<<<<<<<<<
- *             int threads=1, planning_timelimit=None,
- *             *args, **kwargs):
- */
-    values[4] = ((PyObject *)__pyx_k_tuple_39);
-
-    /* "pyfftw/pyfftw.pyx":980
- *     def __init__(self, input_array, output_array, axes=(-1,),
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
- *             int threads=1, planning_timelimit=None,             # <<<<<<<<<<<<<<
- *             *args, **kwargs):
- *         '''
- */
     values[6] = ((PyObject *)Py_None);
     if (unlikely(__pyx_kwds)) {
       Py_ssize_t kw_args;
@@ -7725,42 +7412,42 @@ static int __pyx_pw_6pyfftw_6pyfftw_4FFTW_13__init__(PyObject *__pyx_v_self, PyO
       kw_args = PyDict_Size(__pyx_kwds);
       switch (pos_args) {
         case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__input_array)) != 0)) kw_args--;
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_array)) != 0)) kw_args--;
         else goto __pyx_L5_argtuple_error;
         case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__output_array)) != 0)) kw_args--;
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_array)) != 0)) kw_args--;
         else {
-          __Pyx_RaiseArgtupleInvalid("__init__", 0, 2, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 978; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+          __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
         }
         case  2:
         if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__axes);
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_axes);
           if (value) { values[2] = value; kw_args--; }
         }
         case  3:
         if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__direction);
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_direction);
           if (value) { values[3] = value; kw_args--; }
         }
         case  4:
         if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__flags);
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags);
           if (value) { values[4] = value; kw_args--; }
         }
         case  5:
         if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__threads);
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_threads);
           if (value) { values[5] = value; kw_args--; }
         }
         case  6:
         if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__planning_timelimit);
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_planning_timelimit);
           if (value) { values[6] = value; kw_args--; }
         }
       }
       if (unlikely(kw_args > 0)) {
         const Py_ssize_t used_pos_args = (pos_args < 7) ? pos_args : 7;
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, __pyx_v_kwargs, values, used_pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 978; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, __pyx_v_kwargs, values, used_pos_args, "__cinit__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
       }
     } else {
       switch (PyTuple_GET_SIZE(__pyx_args)) {
@@ -7784,7283 +7471,11614 @@ static int __pyx_pw_6pyfftw_6pyfftw_4FFTW_13__init__(PyObject *__pyx_v_self, PyO
     __pyx_v_direction = values[3];
     __pyx_v_flags = values[4];
     if (values[5]) {
-      __pyx_v_threads = __Pyx_PyInt_AsInt(values[5]); if (unlikely((__pyx_v_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 980; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      __pyx_v_threads = __Pyx_PyInt_As_unsigned_int(values[5]); if (unlikely((__pyx_v_threads == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
     } else {
-      __pyx_v_threads = ((int)1);
+      __pyx_v_threads = ((unsigned int)1);
     }
     __pyx_v_planning_timelimit = values[6];
   }
   goto __pyx_L4_argument_unpacking_done;
   __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__init__", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 978; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
   __pyx_L3_error:;
   __Pyx_DECREF(__pyx_v_args); __pyx_v_args = 0;
   __Pyx_DECREF(__pyx_v_kwargs); __pyx_v_kwargs = 0;
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __Pyx_RefNannyFinishContext();
   return -1;
   __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_12__init__(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self), __pyx_v_input_array, __pyx_v_output_array, __pyx_v_axes, __pyx_v_direction, __pyx_v_flags, __pyx_v_threads, __pyx_v_planning_timelimit, __pyx_v_args, __pyx_v_kwargs);
-  __Pyx_XDECREF(__pyx_v_args);
-  __Pyx_XDECREF(__pyx_v_kwargs);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_30__cinit__(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self), __pyx_v_input_array, __pyx_v_output_array, __pyx_v_axes, __pyx_v_direction, __pyx_v_flags, __pyx_v_threads, __pyx_v_planning_timelimit, __pyx_v_args, __pyx_v_kwargs);
 
-/* "pyfftw/pyfftw.pyx":978
- *                     'to the planner returning NULL. This is a bug.')
+  /* "pyfftw/pyfftw.pyx":811
+ *     axes = property(_get_axes)
  * 
- *     def __init__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
- *             int threads=1, planning_timelimit=None,
+ *     def __cinit__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
+ *                   direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
+ *                   unsigned int threads=1, planning_timelimit=None,
  */
 
-static int __pyx_pf_6pyfftw_6pyfftw_4FFTW_12__init__(CYTHON_UNUSED struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_input_array, CYTHON_UNUSED PyObject *__pyx_v_output_array, CYTHON_UNUSED PyObject *__pyx_v_axes, CYTHON_UNUSED PyObject *__pyx_v_direction, CYTHON_UNUSED PyObject *__pyx_v_flags, CYTHON_UNUSED int __pyx_v_threads, CYTHON_UNUSED PyObject *__pyx_v_planning_timelimit, CYTHON_UNUSED PyObject *__pyx_v_args, CYTHON_UNUSED PyObject *__pyx_v_kwargs) {
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__init__", 0);
-
-  __pyx_r = 0;
+  /* function exit code */
+  __Pyx_XDECREF(__pyx_v_args);
+  __Pyx_XDECREF(__pyx_v_kwargs);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* Python wrapper */
-static void __pyx_pw_6pyfftw_6pyfftw_4FFTW_15__dealloc__(PyObject *__pyx_v_self); /*proto*/
-static void __pyx_pw_6pyfftw_6pyfftw_4FFTW_15__dealloc__(PyObject *__pyx_v_self) {
+static int __pyx_pf_6pyfftw_6pyfftw_4FFTW_30__cinit__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array, PyObject *__pyx_v_axes, PyObject *__pyx_v_direction, PyObject *__pyx_v_flags, unsigned int __pyx_v_threads, PyObject *__pyx_v_planning_timelimit, CYTHON_UNUSED PyObject *__pyx_v_args, CYTHON_UNUSED PyObject *__pyx_v_kwargs) {
+  double __pyx_v__planning_timelimit;
+  PyObject *__pyx_v_input_dtype = NULL;
+  PyObject *__pyx_v_output_dtype = NULL;
+  PyObject *__pyx_v_scheme = NULL;
+  PyObject *__pyx_v_functions = NULL;
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_set_timelimit __pyx_v_set_timelimit_func;
+  int __pyx_v_natural_input_alignment;
+  int __pyx_v_natural_output_alignment;
+  PyObject *__pyx_v_each_alignment = NULL;
+  Py_ssize_t __pyx_v_n;
+  int64_t __pyx_v_array_dimension;
+  int64_t __pyx_v_unique_axes_length;
+  int64_t *__pyx_v_unique_axes;
+  int64_t *__pyx_v_not_axes;
+  PyObject *__pyx_v_total_N = NULL;
+  __pyx_t_6pyfftw_6pyfftw_validator __pyx_v__validator;
+  PyObject *__pyx_v_each_flag = NULL;
+  int __pyx_v_i;
+  PyObject *__pyx_v_fft_shape_lookup = NULL;
+  PyObject *__pyx_v_fft_shape = NULL;
+  PyObject *__pyx_v_input_strides_array = NULL;
+  PyObject *__pyx_v_output_strides_array = NULL;
+  void *__pyx_v_plan;
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru __pyx_v_fftw_planner;
+  int __pyx_v_rank;
+  fftw_iodim *__pyx_v_dims;
+  int __pyx_v_howmany_rank;
+  fftw_iodim *__pyx_v_howmany_dims;
+  void *__pyx_v__in;
+  void *__pyx_v__out;
+  int __pyx_v_sign;
+  unsigned int __pyx_v_c_flags;
+  PyObject *__pyx_v_stride = NULL;
+  int __pyx_r;
   __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
-  __pyx_pf_6pyfftw_6pyfftw_4FFTW_14__dealloc__(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
-  __Pyx_RefNannyFinishContext();
-}
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  double __pyx_t_7;
+  int __pyx_t_8;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *__pyx_t_11 = NULL;
+  Py_ssize_t __pyx_t_12;
+  PyObject *(*__pyx_t_13)(PyObject *);
+  int __pyx_t_14;
+  intptr_t __pyx_t_15;
+  Py_ssize_t __pyx_t_16;
+  int64_t __pyx_t_17;
+  unsigned int __pyx_t_18;
+  PyObject *__pyx_t_19 = NULL;
+  PyObject *__pyx_t_20 = NULL;
+  int __pyx_t_21;
+  int __pyx_t_22;
+  int __pyx_t_23;
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_plan_guru __pyx_t_24;
+  PyObject *__pyx_t_25 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__cinit__", 0);
+  __Pyx_INCREF(__pyx_v_flags);
 
-/* "pyfftw/pyfftw.pyx":1176
- *         pass
+  /* "pyfftw/pyfftw.pyx":817
  * 
- *     def __dealloc__(self):             # <<<<<<<<<<<<<<
- * 
- *         if not self.__axes == NULL:
+ *         # Initialise the pointers that need to be freed
+ *         self._plan = NULL             # <<<<<<<<<<<<<<
+ *         self._dims = NULL
+ *         self._howmany_dims = NULL
  */
+  __pyx_v_self->_plan = NULL;
 
-static void __pyx_pf_6pyfftw_6pyfftw_4FFTW_14__dealloc__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  __Pyx_RefNannySetupContext("__dealloc__", 0);
-
-  /* "pyfftw/pyfftw.pyx":1178
- *     def __dealloc__(self):
- * 
- *         if not self.__axes == NULL:             # <<<<<<<<<<<<<<
- *             free(self.__axes)
+  /* "pyfftw/pyfftw.pyx":818
+ *         # Initialise the pointers that need to be freed
+ *         self._plan = NULL
+ *         self._dims = NULL             # <<<<<<<<<<<<<<
+ *         self._howmany_dims = NULL
  * 
  */
-  __pyx_t_1 = (!(__pyx_v_self->__pyx___axes == NULL));
-  if (__pyx_t_1) {
+  __pyx_v_self->_dims = NULL;
 
-    /* "pyfftw/pyfftw.pyx":1179
- * 
- *         if not self.__axes == NULL:
- *             free(self.__axes)             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":819
+ *         self._plan = NULL
+ *         self._dims = NULL
+ *         self._howmany_dims = NULL             # <<<<<<<<<<<<<<
  * 
- *         if not self.__not_axes == NULL:
+ *         self._axes = NULL
  */
-    free(__pyx_v_self->__pyx___axes);
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
+  __pyx_v_self->_howmany_dims = NULL;
 
-  /* "pyfftw/pyfftw.pyx":1181
- *             free(self.__axes)
+  /* "pyfftw/pyfftw.pyx":821
+ *         self._howmany_dims = NULL
  * 
- *         if not self.__not_axes == NULL:             # <<<<<<<<<<<<<<
- *             free(self.__not_axes)
+ *         self._axes = NULL             # <<<<<<<<<<<<<<
+ *         self._not_axes = NULL
  * 
  */
-  __pyx_t_1 = (!(__pyx_v_self->__pyx___not_axes == NULL));
-  if (__pyx_t_1) {
+  __pyx_v_self->_axes = NULL;
 
-    /* "pyfftw/pyfftw.pyx":1182
+  /* "pyfftw/pyfftw.pyx":822
  * 
- *         if not self.__not_axes == NULL:
- *             free(self.__not_axes)             # <<<<<<<<<<<<<<
+ *         self._axes = NULL
+ *         self._not_axes = NULL             # <<<<<<<<<<<<<<
  * 
- *         if not self.__plan == NULL:
+ *         flags = list(flags)
  */
-    free(__pyx_v_self->__pyx___not_axes);
-    goto __pyx_L4;
-  }
-  __pyx_L4:;
+  __pyx_v_self->_not_axes = NULL;
 
-  /* "pyfftw/pyfftw.pyx":1184
- *             free(self.__not_axes)
+  /* "pyfftw/pyfftw.pyx":824
+ *         self._not_axes = NULL
  * 
- *         if not self.__plan == NULL:             # <<<<<<<<<<<<<<
- *             self.__fftw_destroy(self.__plan)
+ *         flags = list(flags)             # <<<<<<<<<<<<<<
  * 
+ *         cdef double _planning_timelimit
  */
-  __pyx_t_1 = (!(__pyx_v_self->__pyx___plan == NULL));
-  if (__pyx_t_1) {
+  __pyx_t_1 = PySequence_List(__pyx_v_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 824; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF_SET(__pyx_v_flags, __pyx_t_1);
+  __pyx_t_1 = 0;
 
-    /* "pyfftw/pyfftw.pyx":1185
- * 
- *         if not self.__plan == NULL:
- *             self.__fftw_destroy(self.__plan)             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":827
  * 
- *         if not self.__dims == NULL:
+ *         cdef double _planning_timelimit
+ *         if planning_timelimit is None:             # <<<<<<<<<<<<<<
+ *             _planning_timelimit = FFTW_NO_TIMELIMIT
+ *         else:
  */
-    __pyx_v_self->__pyx___fftw_destroy(__pyx_v_self->__pyx___plan);
-    goto __pyx_L5;
-  }
-  __pyx_L5:;
+  __pyx_t_2 = (__pyx_v_planning_timelimit == Py_None);
+  __pyx_t_3 = (__pyx_t_2 != 0);
+  if (__pyx_t_3) {
 
-  /* "pyfftw/pyfftw.pyx":1187
- *             self.__fftw_destroy(self.__plan)
- * 
- *         if not self.__dims == NULL:             # <<<<<<<<<<<<<<
- *             free(self.__dims)
- * 
+    /* "pyfftw/pyfftw.pyx":828
+ *         cdef double _planning_timelimit
+ *         if planning_timelimit is None:
+ *             _planning_timelimit = FFTW_NO_TIMELIMIT             # <<<<<<<<<<<<<<
+ *         else:
+ *             try:
  */
-  __pyx_t_1 = (!(__pyx_v_self->__pyx___dims == NULL));
-  if (__pyx_t_1) {
+    __pyx_v__planning_timelimit = FFTW_NO_TIMELIMIT;
 
-    /* "pyfftw/pyfftw.pyx":1188
- * 
- *         if not self.__dims == NULL:
- *             free(self.__dims)             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":827
  * 
- *         if not self.__howmany_dims == NULL:
+ *         cdef double _planning_timelimit
+ *         if planning_timelimit is None:             # <<<<<<<<<<<<<<
+ *             _planning_timelimit = FFTW_NO_TIMELIMIT
+ *         else:
  */
-    free(__pyx_v_self->__pyx___dims);
-    goto __pyx_L6;
+    goto __pyx_L3;
   }
-  __pyx_L6:;
 
-  /* "pyfftw/pyfftw.pyx":1190
- *             free(self.__dims)
- * 
- *         if not self.__howmany_dims == NULL:             # <<<<<<<<<<<<<<
- *             free(self.__howmany_dims)
- * 
+  /* "pyfftw/pyfftw.pyx":830
+ *             _planning_timelimit = FFTW_NO_TIMELIMIT
+ *         else:
+ *             try:             # <<<<<<<<<<<<<<
+ *                 _planning_timelimit = planning_timelimit
+ *             except TypeError:
  */
-  __pyx_t_1 = (!(__pyx_v_self->__pyx___howmany_dims == NULL));
-  if (__pyx_t_1) {
+  /*else*/ {
+    {
+      __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
+      __Pyx_XGOTREF(__pyx_t_4);
+      __Pyx_XGOTREF(__pyx_t_5);
+      __Pyx_XGOTREF(__pyx_t_6);
+      /*try:*/ {
 
-    /* "pyfftw/pyfftw.pyx":1191
- * 
- *         if not self.__howmany_dims == NULL:
- *             free(self.__howmany_dims)             # <<<<<<<<<<<<<<
- * 
- *     def __call__(self, input_array=None, output_array=None,
+        /* "pyfftw/pyfftw.pyx":831
+ *         else:
+ *             try:
+ *                 _planning_timelimit = planning_timelimit             # <<<<<<<<<<<<<<
+ *             except TypeError:
+ *                 raise TypeError('Invalid planning timelimit: '
  */
-    free(__pyx_v_self->__pyx___howmany_dims);
-    goto __pyx_L7;
-  }
-  __pyx_L7:;
-
-  __Pyx_RefNannyFinishContext();
-}
+        __pyx_t_7 = __pyx_PyFloat_AsDouble(__pyx_v_planning_timelimit); if (unlikely((__pyx_t_7 == (double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L4_error;}
+        __pyx_v__planning_timelimit = __pyx_t_7;
 
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_17__call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_16__call__[] = "__call__(input_array=None, output_array=None, normalise_idft=True)\n\n        Calling the class instance (optionally) updates the arrays, then\n        calls :meth:`~pyfftw.FFTW.execute`, before optionally normalising \n        the output and returning the output array.\n\n        It has some built-in helpers to make life simpler for the calling\n        functions (as distinct from manually updating the arrays and\n        calli [...]
-#if CYTHON_COMPILING_IN_CPYTHON
-struct wrapperbase __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_16__call__;
-#endif
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_17__call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_input_array = 0;
-  PyObject *__pyx_v_output_array = 0;
-  PyObject *__pyx_v_normalise_idft = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__call__ (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__input_array,&__pyx_n_s__output_array,&__pyx_n_s__normalise_idft,0};
-    PyObject* values[3] = {0,0,0};
+        /* "pyfftw/pyfftw.pyx":830
+ *             _planning_timelimit = FFTW_NO_TIMELIMIT
+ *         else:
+ *             try:             # <<<<<<<<<<<<<<
+ *                 _planning_timelimit = planning_timelimit
+ *             except TypeError:
+ */
+      }
+      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+      goto __pyx_L11_try_end;
+      __pyx_L4_error:;
+      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+      /* "pyfftw/pyfftw.pyx":832
+ *             try:
+ *                 _planning_timelimit = planning_timelimit
+ *             except TypeError:             # <<<<<<<<<<<<<<
+ *                 raise TypeError('Invalid planning timelimit: '
+ *                         'The planning timelimit needs to be a float.')
+ */
+      __pyx_t_8 = PyErr_ExceptionMatches(__pyx_builtin_TypeError);
+      if (__pyx_t_8) {
+        __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+        if (__Pyx_GetException(&__pyx_t_1, &__pyx_t_9, &__pyx_t_10) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __Pyx_GOTREF(__pyx_t_9);
+        __Pyx_GOTREF(__pyx_t_10);
 
-    /* "pyfftw/pyfftw.pyx":1193
- *             free(self.__howmany_dims)
+        /* "pyfftw/pyfftw.pyx":833
+ *                 _planning_timelimit = planning_timelimit
+ *             except TypeError:
+ *                 raise TypeError('Invalid planning timelimit: '             # <<<<<<<<<<<<<<
+ *                         'The planning timelimit needs to be a float.')
  * 
- *     def __call__(self, input_array=None, output_array=None,             # <<<<<<<<<<<<<<
- *             normalise_idft=True):
- *         '''__call__(input_array=None, output_array=None, normalise_idft=True)
  */
-    values[0] = ((PyObject *)Py_None);
-    values[1] = ((PyObject *)Py_None);
-    values[2] = __pyx_k_40;
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__input_array);
-          if (value) { values[0] = value; kw_args--; }
-        }
-        case  1:
-        if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__output_array);
-          if (value) { values[1] = value; kw_args--; }
-        }
-        case  2:
-        if (kw_args > 0) {
-          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s__normalise_idft);
-          if (value) { values[2] = value; kw_args--; }
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__call__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else {
-      switch (PyTuple_GET_SIZE(__pyx_args)) {
-        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
+        __pyx_t_11 = __Pyx_PyObject_Call(__pyx_builtin_TypeError, __pyx_tuple__8, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __Pyx_Raise(__pyx_t_11, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L6_except_error;}
       }
+      goto __pyx_L6_except_error;
+      __pyx_L6_except_error:;
+
+      /* "pyfftw/pyfftw.pyx":830
+ *             _planning_timelimit = FFTW_NO_TIMELIMIT
+ *         else:
+ *             try:             # <<<<<<<<<<<<<<
+ *                 _planning_timelimit = planning_timelimit
+ *             except TypeError:
+ */
+      __Pyx_XGIVEREF(__pyx_t_4);
+      __Pyx_XGIVEREF(__pyx_t_5);
+      __Pyx_XGIVEREF(__pyx_t_6);
+      __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
+      goto __pyx_L1_error;
+      __pyx_L11_try_end:;
     }
-    __pyx_v_input_array = values[0];
-    __pyx_v_output_array = values[1];
-    __pyx_v_normalise_idft = values[2];
   }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("__call__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__call__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_16__call__(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self), __pyx_v_input_array, __pyx_v_output_array, __pyx_v_normalise_idft);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_16__call__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array, PyObject *__pyx_v_normalise_idft) {
-  int __pyx_v_copy_needed;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  int __pyx_t_2;
-  int __pyx_t_3;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *__pyx_t_6 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("__call__", 0);
-  __Pyx_INCREF(__pyx_v_input_array);
-  __Pyx_INCREF(__pyx_v_output_array);
+  __pyx_L3:;
 
-  /* "pyfftw/pyfftw.pyx":1251
- *         '''
- * 
- *         if input_array is not None or output_array is not None:             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":836
+ *                         'The planning timelimit needs to be a float.')
  * 
- *             if input_array is None:
+ *         if not isinstance(input_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input array: '
+ *                     'The input array needs to be an instance '
  */
-  __pyx_t_1 = (__pyx_v_input_array != Py_None);
-  if (!__pyx_t_1) {
-    __pyx_t_2 = (__pyx_v_output_array != Py_None);
-    __pyx_t_3 = __pyx_t_2;
-  } else {
-    __pyx_t_3 = __pyx_t_1;
-  }
-  if (__pyx_t_3) {
+  __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray); 
+  __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0);
+  if (__pyx_t_2) {
 
-    /* "pyfftw/pyfftw.pyx":1253
- *         if input_array is not None or output_array is not None:
- * 
- *             if input_array is None:             # <<<<<<<<<<<<<<
- *                 input_array = self.__input_array
+    /* "pyfftw/pyfftw.pyx":837
  * 
+ *         if not isinstance(input_array, np.ndarray):
+ *             raise ValueError('Invalid input array: '             # <<<<<<<<<<<<<<
+ *                     'The input array needs to be an instance '
+ *                     'of numpy.ndarray')
  */
-    __pyx_t_3 = (__pyx_v_input_array == Py_None);
-    if (__pyx_t_3) {
+    __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__9, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-      /* "pyfftw/pyfftw.pyx":1254
- * 
- *             if input_array is None:
- *                 input_array = self.__input_array             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":836
+ *                         'The planning timelimit needs to be a float.')
  * 
- *             if output_array is None:
+ *         if not isinstance(input_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input array: '
+ *                     'The input array needs to be an instance '
  */
-      __pyx_t_4 = ((PyObject *)__pyx_v_self->__pyx___input_array);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_DECREF(__pyx_v_input_array);
-      __pyx_v_input_array = __pyx_t_4;
-      __pyx_t_4 = 0;
-      goto __pyx_L4;
-    }
-    __pyx_L4:;
+  }
 
-    /* "pyfftw/pyfftw.pyx":1256
- *                 input_array = self.__input_array
- * 
- *             if output_array is None:             # <<<<<<<<<<<<<<
- *                 output_array = self.__output_array
+  /* "pyfftw/pyfftw.pyx":841
+ *                     'of numpy.ndarray')
  * 
+ *         if not isinstance(output_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output array: '
+ *                     'The output array needs to be an instance '
  */
-    __pyx_t_3 = (__pyx_v_output_array == Py_None);
-    if (__pyx_t_3) {
+  __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_output_array, __pyx_ptype_5numpy_ndarray); 
+  __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0);
+  if (__pyx_t_3) {
 
-      /* "pyfftw/pyfftw.pyx":1257
- * 
- *             if output_array is None:
- *                 output_array = self.__output_array             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":842
  * 
- *             if not isinstance(input_array, np.ndarray):
+ *         if not isinstance(output_array, np.ndarray):
+ *             raise ValueError('Invalid output array: '             # <<<<<<<<<<<<<<
+ *                     'The output array needs to be an instance '
+ *                     'of numpy.ndarray')
  */
-      __pyx_t_4 = ((PyObject *)__pyx_v_self->__pyx___output_array);
-      __Pyx_INCREF(__pyx_t_4);
-      __Pyx_DECREF(__pyx_v_output_array);
-      __pyx_v_output_array = __pyx_t_4;
-      __pyx_t_4 = 0;
-      goto __pyx_L5;
-    }
-    __pyx_L5:;
+    __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__10, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-    /* "pyfftw/pyfftw.pyx":1259
- *                 output_array = self.__output_array
+    /* "pyfftw/pyfftw.pyx":841
+ *                     'of numpy.ndarray')
  * 
- *             if not isinstance(input_array, np.ndarray):             # <<<<<<<<<<<<<<
- *                 copy_needed = True
- *             elif (not input_array.dtype == self.__input_dtype):
+ *         if not isinstance(output_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output array: '
+ *                     'The output array needs to be an instance '
  */
-    __pyx_t_4 = ((PyObject *)((PyObject*)__pyx_ptype_5numpy_ndarray));
-    __Pyx_INCREF(__pyx_t_4);
-    __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_input_array, __pyx_t_4); 
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_1 = (!__pyx_t_3);
-    if (__pyx_t_1) {
+  }
 
-      /* "pyfftw/pyfftw.pyx":1260
+  /* "pyfftw/pyfftw.pyx":846
+ *                     'of numpy.ndarray')
  * 
- *             if not isinstance(input_array, np.ndarray):
- *                 copy_needed = True             # <<<<<<<<<<<<<<
- *             elif (not input_array.dtype == self.__input_dtype):
- *                 copy_needed = True
+ *         try:             # <<<<<<<<<<<<<<
+ *             input_dtype = input_array.dtype
+ *             output_dtype = output_array.dtype
  */
-      __pyx_v_copy_needed = 1;
-      goto __pyx_L6;
-    }
+  {
+    __Pyx_ExceptionSave(&__pyx_t_6, &__pyx_t_5, &__pyx_t_4);
+    __Pyx_XGOTREF(__pyx_t_6);
+    __Pyx_XGOTREF(__pyx_t_5);
+    __Pyx_XGOTREF(__pyx_t_4);
+    /*try:*/ {
 
-    /* "pyfftw/pyfftw.pyx":1261
- *             if not isinstance(input_array, np.ndarray):
- *                 copy_needed = True
- *             elif (not input_array.dtype == self.__input_dtype):             # <<<<<<<<<<<<<<
- *                 copy_needed = True
- *             elif (not input_array.strides == self.__input_byte_strides):
+      /* "pyfftw/pyfftw.pyx":847
+ * 
+ *         try:
+ *             input_dtype = input_array.dtype             # <<<<<<<<<<<<<<
+ *             output_dtype = output_array.dtype
+ *             scheme = fftw_schemes[(input_dtype, output_dtype)]
  */
-    __pyx_t_4 = PyObject_GetAttr(__pyx_v_input_array, __pyx_n_s__dtype); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = PyObject_RichCompare(__pyx_t_4, __pyx_v_self->__pyx___input_dtype, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_3 = (!__pyx_t_1);
-    if (__pyx_t_3) {
+      __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_array, __pyx_n_s_dtype); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 847; __pyx_clineno = __LINE__; goto __pyx_L16_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_v_input_dtype = __pyx_t_10;
+      __pyx_t_10 = 0;
 
-      /* "pyfftw/pyfftw.pyx":1262
- *                 copy_needed = True
- *             elif (not input_array.dtype == self.__input_dtype):
- *                 copy_needed = True             # <<<<<<<<<<<<<<
- *             elif (not input_array.strides == self.__input_byte_strides):
- *                 copy_needed = True
+      /* "pyfftw/pyfftw.pyx":848
+ *         try:
+ *             input_dtype = input_array.dtype
+ *             output_dtype = output_array.dtype             # <<<<<<<<<<<<<<
+ *             scheme = fftw_schemes[(input_dtype, output_dtype)]
+ *         except KeyError:
  */
-      __pyx_v_copy_needed = 1;
-      goto __pyx_L6;
-    }
+      __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_array, __pyx_n_s_dtype); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 848; __pyx_clineno = __LINE__; goto __pyx_L16_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_v_output_dtype = __pyx_t_10;
+      __pyx_t_10 = 0;
 
-    /* "pyfftw/pyfftw.pyx":1263
- *             elif (not input_array.dtype == self.__input_dtype):
- *                 copy_needed = True
- *             elif (not input_array.strides == self.__input_byte_strides):             # <<<<<<<<<<<<<<
- *                 copy_needed = True
- *             elif not (<intptr_t>np.PyArray_DATA(input_array)
+      /* "pyfftw/pyfftw.pyx":849
+ *             input_dtype = input_array.dtype
+ *             output_dtype = output_array.dtype
+ *             scheme = fftw_schemes[(input_dtype, output_dtype)]             # <<<<<<<<<<<<<<
+ *         except KeyError:
+ *             raise ValueError('Invalid scheme: '
  */
-    __pyx_t_5 = PyObject_GetAttr(__pyx_v_input_array, __pyx_n_s__strides); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_v_self->__pyx___input_byte_strides, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1263; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_1 = (!__pyx_t_3);
-    if (__pyx_t_1) {
+      __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L16_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_INCREF(__pyx_v_input_dtype);
+      __Pyx_GIVEREF(__pyx_v_input_dtype);
+      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_v_input_dtype);
+      __Pyx_INCREF(__pyx_v_output_dtype);
+      __Pyx_GIVEREF(__pyx_v_output_dtype);
+      PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_v_output_dtype);
+      __pyx_t_9 = PyObject_GetItem(__pyx_v_6pyfftw_6pyfftw_fftw_schemes, __pyx_t_10); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L16_error;};
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __pyx_v_scheme = __pyx_t_9;
+      __pyx_t_9 = 0;
 
-      /* "pyfftw/pyfftw.pyx":1264
- *                 copy_needed = True
- *             elif (not input_array.strides == self.__input_byte_strides):
- *                 copy_needed = True             # <<<<<<<<<<<<<<
- *             elif not (<intptr_t>np.PyArray_DATA(input_array)
- *                     % self.input_alignment == 0):
+      /* "pyfftw/pyfftw.pyx":846
+ *                     'of numpy.ndarray')
+ * 
+ *         try:             # <<<<<<<<<<<<<<
+ *             input_dtype = input_array.dtype
+ *             output_dtype = output_array.dtype
  */
-      __pyx_v_copy_needed = 1;
-      goto __pyx_L6;
     }
+    __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+    goto __pyx_L23_try_end;
+    __pyx_L16_error:;
+    __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
+    __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-    /* "pyfftw/pyfftw.pyx":1265
- *             elif (not input_array.strides == self.__input_byte_strides):
- *                 copy_needed = True
- *             elif not (<intptr_t>np.PyArray_DATA(input_array)             # <<<<<<<<<<<<<<
- *                     % self.input_alignment == 0):
- *                 copy_needed = True
- */
-    if (!(likely(((__pyx_v_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_4 = __pyx_v_input_array;
-    __Pyx_INCREF(__pyx_t_4);
-    __pyx_t_5 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_t_4)))); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-
-    /* "pyfftw/pyfftw.pyx":1266
- *                 copy_needed = True
- *             elif not (<intptr_t>np.PyArray_DATA(input_array)
- *                     % self.input_alignment == 0):             # <<<<<<<<<<<<<<
- *                 copy_needed = True
- *             else:
+    /* "pyfftw/pyfftw.pyx":850
+ *             output_dtype = output_array.dtype
+ *             scheme = fftw_schemes[(input_dtype, output_dtype)]
+ *         except KeyError:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid scheme: '
+ *                     'The output array and input array dtypes '
  */
-    __pyx_t_4 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__input_alignment); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = PyNumber_Remainder(__pyx_t_5, __pyx_t_4); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_4 = PyObject_RichCompare(__pyx_t_6, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-    __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1266; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __pyx_t_3 = (!__pyx_t_1);
-    if (__pyx_t_3) {
+    __pyx_t_8 = PyErr_ExceptionMatches(__pyx_builtin_KeyError);
+    if (__pyx_t_8) {
+      __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+      if (__Pyx_GetException(&__pyx_t_9, &__pyx_t_10, &__pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 850; __pyx_clineno = __LINE__; goto __pyx_L18_except_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_GOTREF(__pyx_t_1);
 
-      /* "pyfftw/pyfftw.pyx":1267
- *             elif not (<intptr_t>np.PyArray_DATA(input_array)
- *                     % self.input_alignment == 0):
- *                 copy_needed = True             # <<<<<<<<<<<<<<
- *             else:
- *                 copy_needed = False
+      /* "pyfftw/pyfftw.pyx":851
+ *             scheme = fftw_schemes[(input_dtype, output_dtype)]
+ *         except KeyError:
+ *             raise ValueError('Invalid scheme: '             # <<<<<<<<<<<<<<
+ *                     'The output array and input array dtypes '
+ *                     'do not correspond to a valid fftw scheme.')
  */
-      __pyx_v_copy_needed = 1;
-      goto __pyx_L6;
+      __pyx_t_11 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__11, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; __pyx_clineno = __LINE__; goto __pyx_L18_except_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_Raise(__pyx_t_11, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; __pyx_clineno = __LINE__; goto __pyx_L18_except_error;}
     }
-    /*else*/ {
+    goto __pyx_L18_except_error;
+    __pyx_L18_except_error:;
 
-      /* "pyfftw/pyfftw.pyx":1269
- *                 copy_needed = True
- *             else:
- *                 copy_needed = False             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":846
+ *                     'of numpy.ndarray')
  * 
- *             if copy_needed:
+ *         try:             # <<<<<<<<<<<<<<
+ *             input_dtype = input_array.dtype
+ *             output_dtype = output_array.dtype
  */
-      __pyx_v_copy_needed = 0;
-    }
-    __pyx_L6:;
+    __Pyx_XGIVEREF(__pyx_t_6);
+    __Pyx_XGIVEREF(__pyx_t_5);
+    __Pyx_XGIVEREF(__pyx_t_4);
+    __Pyx_ExceptionReset(__pyx_t_6, __pyx_t_5, __pyx_t_4);
+    goto __pyx_L1_error;
+    __pyx_L23_try_end:;
+  }
 
-    /* "pyfftw/pyfftw.pyx":1271
- *                 copy_needed = False
+  /* "pyfftw/pyfftw.pyx":855
+ *                     'do not correspond to a valid fftw scheme.')
  * 
- *             if copy_needed:             # <<<<<<<<<<<<<<
+ *         self._input_dtype = input_dtype             # <<<<<<<<<<<<<<
+ *         self._output_dtype = output_dtype
  * 
- *                 if not isinstance(input_array, np.ndarray):
  */
-    if (__pyx_v_copy_needed) {
+  __Pyx_INCREF(__pyx_v_input_dtype);
+  __Pyx_GIVEREF(__pyx_v_input_dtype);
+  __Pyx_GOTREF(__pyx_v_self->_input_dtype);
+  __Pyx_DECREF(__pyx_v_self->_input_dtype);
+  __pyx_v_self->_input_dtype = __pyx_v_input_dtype;
 
-      /* "pyfftw/pyfftw.pyx":1273
- *             if copy_needed:
+  /* "pyfftw/pyfftw.pyx":856
  * 
- *                 if not isinstance(input_array, np.ndarray):             # <<<<<<<<<<<<<<
- *                     input_array = np.asanyarray(input_array)
+ *         self._input_dtype = input_dtype
+ *         self._output_dtype = output_dtype             # <<<<<<<<<<<<<<
  * 
+ *         functions = scheme_functions[scheme]
  */
-      __pyx_t_4 = ((PyObject *)((PyObject*)__pyx_ptype_5numpy_ndarray));
-      __Pyx_INCREF(__pyx_t_4);
-      __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_input_array, __pyx_t_4); 
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_1 = (!__pyx_t_3);
-      if (__pyx_t_1) {
+  __Pyx_INCREF(__pyx_v_output_dtype);
+  __Pyx_GIVEREF(__pyx_v_output_dtype);
+  __Pyx_GOTREF(__pyx_v_self->_output_dtype);
+  __Pyx_DECREF(__pyx_v_self->_output_dtype);
+  __pyx_v_self->_output_dtype = __pyx_v_output_dtype;
 
-        /* "pyfftw/pyfftw.pyx":1274
+  /* "pyfftw/pyfftw.pyx":858
+ *         self._output_dtype = output_dtype
  * 
- *                 if not isinstance(input_array, np.ndarray):
- *                     input_array = np.asanyarray(input_array)             # <<<<<<<<<<<<<<
- * 
- *                 if not input_array.shape == self.__input_shape:
- */
-        __pyx_t_4 = __Pyx_GetName(__pyx_m, __pyx_n_s__np); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_4);
-        __pyx_t_6 = PyObject_GetAttr(__pyx_t_4, __pyx_n_s__asanyarray); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_6);
-        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_4);
-        __Pyx_INCREF(__pyx_v_input_array);
-        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_v_input_array);
-        __Pyx_GIVEREF(__pyx_v_input_array);
-        __pyx_t_5 = PyObject_Call(__pyx_t_6, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
-        __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
-        __Pyx_DECREF(__pyx_v_input_array);
-        __pyx_v_input_array = __pyx_t_5;
-        __pyx_t_5 = 0;
-        goto __pyx_L8;
-      }
-      __pyx_L8:;
-
-      /* "pyfftw/pyfftw.pyx":1276
- *                     input_array = np.asanyarray(input_array)
+ *         functions = scheme_functions[scheme]             # <<<<<<<<<<<<<<
  * 
- *                 if not input_array.shape == self.__input_shape:             # <<<<<<<<<<<<<<
- *                     raise ValueError('Invalid input shape: '
- *                             'The new input array should be the same shape '
+ *         self._fftw_planner = planners[functions['planner']]
  */
-      __pyx_t_5 = PyObject_GetAttr(__pyx_v_input_array, __pyx_n_s__shape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_v_self->__pyx___input_shape, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_3 = (!__pyx_t_1);
-      if (__pyx_t_3) {
+  __pyx_t_1 = PyObject_GetItem(__pyx_v_6pyfftw_6pyfftw_scheme_functions, __pyx_v_scheme); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 858; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_functions = __pyx_t_1;
+  __pyx_t_1 = 0;
 
-        /* "pyfftw/pyfftw.pyx":1277
+  /* "pyfftw/pyfftw.pyx":860
+ *         functions = scheme_functions[scheme]
  * 
- *                 if not input_array.shape == self.__input_shape:
- *                     raise ValueError('Invalid input shape: '             # <<<<<<<<<<<<<<
- *                             'The new input array should be the same shape '
- *                             'as the input array used to instantiate the '
+ *         self._fftw_planner = planners[functions['planner']]             # <<<<<<<<<<<<<<
+ *         self._fftw_execute = executors[functions['executor']]
+ *         self._fftw_destroy = destroyers[functions['generic_precision']]
  */
-        __pyx_t_4 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_42), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_4);
-        __Pyx_Raise(__pyx_t_4, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        goto __pyx_L9;
-      }
-      __pyx_L9:;
+  __pyx_t_1 = PyObject_GetItem(__pyx_v_functions, __pyx_n_s_planner); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 860; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_self->_fftw_planner = (__pyx_v_6pyfftw_6pyfftw_planners[__pyx_t_12]);
 
-      /* "pyfftw/pyfftw.pyx":1282
- *                             'object.')
+  /* "pyfftw/pyfftw.pyx":861
  * 
- *                 self.__input_array[:] = input_array             # <<<<<<<<<<<<<<
+ *         self._fftw_planner = planners[functions['planner']]
+ *         self._fftw_execute = executors[functions['executor']]             # <<<<<<<<<<<<<<
+ *         self._fftw_destroy = destroyers[functions['generic_precision']]
  * 
- *                 if output_array is not None:
  */
-      if (__Pyx_PySequence_SetSlice(((PyObject *)__pyx_v_self->__pyx___input_array), 0, PY_SSIZE_T_MAX, __pyx_v_input_array) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyObject_GetItem(__pyx_v_functions, __pyx_n_s_executor); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_self->_fftw_execute = (__pyx_v_6pyfftw_6pyfftw_executors[__pyx_t_12]);
 
-      /* "pyfftw/pyfftw.pyx":1284
- *                 self.__input_array[:] = input_array
+  /* "pyfftw/pyfftw.pyx":862
+ *         self._fftw_planner = planners[functions['planner']]
+ *         self._fftw_execute = executors[functions['executor']]
+ *         self._fftw_destroy = destroyers[functions['generic_precision']]             # <<<<<<<<<<<<<<
  * 
- *                 if output_array is not None:             # <<<<<<<<<<<<<<
- *                     # No point wasting time if no update is necessary
- *                     # (which the copy above may have avoided)
+ *         self._nthreads_plan_setter = (
  */
-      __pyx_t_3 = (__pyx_v_output_array != Py_None);
-      if (__pyx_t_3) {
+  __pyx_t_1 = PyObject_GetItem(__pyx_v_functions, __pyx_n_s_generic_precision); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 862; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 862; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_self->_fftw_destroy = (__pyx_v_6pyfftw_6pyfftw_destroyers[__pyx_t_12]);
 
-        /* "pyfftw/pyfftw.pyx":1287
- *                     # No point wasting time if no update is necessary
- *                     # (which the copy above may have avoided)
- *                     input_array = self.__input_array             # <<<<<<<<<<<<<<
- *                     self.update_arrays(input_array, output_array)
+  /* "pyfftw/pyfftw.pyx":865
  * 
- */
-        __pyx_t_4 = ((PyObject *)__pyx_v_self->__pyx___input_array);
-        __Pyx_INCREF(__pyx_t_4);
-        __Pyx_DECREF(__pyx_v_input_array);
-        __pyx_v_input_array = __pyx_t_4;
-        __pyx_t_4 = 0;
-
-        /* "pyfftw/pyfftw.pyx":1288
- *                     # (which the copy above may have avoided)
- *                     input_array = self.__input_array
- *                     self.update_arrays(input_array, output_array)             # <<<<<<<<<<<<<<
+ *         self._nthreads_plan_setter = (
+ *                 nthreads_plan_setters[functions['generic_precision']])             # <<<<<<<<<<<<<<
  * 
- *             else:
+ *         cdef fftw_generic_set_timelimit set_timelimit_func = (
  */
-        __pyx_t_4 = ((struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *)__pyx_v_self->__pyx_vtab)->update_arrays(__pyx_v_self, __pyx_v_input_array, __pyx_v_output_array, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_4);
-        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-        goto __pyx_L10;
-      }
-      __pyx_L10:;
-      goto __pyx_L7;
-    }
-    /*else*/ {
+  __pyx_t_1 = PyObject_GetItem(__pyx_v_functions, __pyx_n_s_generic_precision); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 865; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 865; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-      /* "pyfftw/pyfftw.pyx":1291
+  /* "pyfftw/pyfftw.pyx":864
+ *         self._fftw_destroy = destroyers[functions['generic_precision']]
  * 
- *             else:
- *                 self.update_arrays(input_array, output_array)             # <<<<<<<<<<<<<<
+ *         self._nthreads_plan_setter = (             # <<<<<<<<<<<<<<
+ *                 nthreads_plan_setters[functions['generic_precision']])
  * 
- *         self.execute()
  */
-      __pyx_t_4 = ((struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *)__pyx_v_self->__pyx_vtab)->update_arrays(__pyx_v_self, __pyx_v_input_array, __pyx_v_output_array, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    }
-    __pyx_L7:;
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
+  __pyx_v_self->_nthreads_plan_setter = (__pyx_v_6pyfftw_6pyfftw_nthreads_plan_setters[__pyx_t_12]);
 
-  /* "pyfftw/pyfftw.pyx":1293
- *                 self.update_arrays(input_array, output_array)
+  /* "pyfftw/pyfftw.pyx":868
  * 
- *         self.execute()             # <<<<<<<<<<<<<<
+ *         cdef fftw_generic_set_timelimit set_timelimit_func = (
+ *                 set_timelimit_funcs[functions['generic_precision']])             # <<<<<<<<<<<<<<
  * 
- *         if self.__direction == FFTW_BACKWARD and normalise_idft:
+ *         # We're interested in the natural alignment on the real type, not
  */
-  __pyx_t_4 = ((struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *)__pyx_v_self->__pyx_vtab)->execute(__pyx_v_self, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+  __pyx_t_1 = PyObject_GetItem(__pyx_v_functions, __pyx_n_s_generic_precision); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 868; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_1); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 868; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_set_timelimit_func = (__pyx_v_6pyfftw_6pyfftw_set_timelimit_funcs[__pyx_t_12]);
 
-  /* "pyfftw/pyfftw.pyx":1295
- *         self.execute()
+  /* "pyfftw/pyfftw.pyx":874
+ *         # numpy reported an alignment on a complex dtype that was different
+ *         # to that on the real type.
+ *         cdef int natural_input_alignment = input_array.real.dtype.alignment             # <<<<<<<<<<<<<<
+ *         cdef int natural_output_alignment = output_array.real.dtype.alignment
  * 
- *         if self.__direction == FFTW_BACKWARD and normalise_idft:             # <<<<<<<<<<<<<<
- *             self.__output_array *= self.__normalisation_scaling
+ */
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_array, __pyx_n_s_real); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_dtype); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __pyx_t_8 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 874; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_natural_input_alignment = __pyx_t_8;
+
+  /* "pyfftw/pyfftw.pyx":875
+ *         # to that on the real type.
+ *         cdef int natural_input_alignment = input_array.real.dtype.alignment
+ *         cdef int natural_output_alignment = output_array.real.dtype.alignment             # <<<<<<<<<<<<<<
  * 
+ *         # If either of the arrays is not aligned on a 16-byte boundary,
  */
-  __pyx_t_3 = (__pyx_v_self->__pyx___direction == __pyx_e_6pyfftw_6pyfftw_FFTW_BACKWARD);
-  if (__pyx_t_3) {
-    __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_normalise_idft); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_t_2 = __pyx_t_1;
-  } else {
-    __pyx_t_2 = __pyx_t_3;
-  }
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_array, __pyx_n_s_real); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_dtype); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_n_s_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __pyx_t_8 = __Pyx_PyInt_As_int(__pyx_t_1); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 875; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_v_natural_output_alignment = __pyx_t_8;
+
+  /* "pyfftw/pyfftw.pyx":880
+ *         # we set the FFTW_UNALIGNED flag. This disables SIMD.
+ *         # (16 bytes is assumed to be the minimal alignment)
+ *         if 'FFTW_UNALIGNED' in flags:             # <<<<<<<<<<<<<<
+ *             self._simd_allowed = False
+ *             self._input_array_alignment = natural_input_alignment
+ */
+  __pyx_t_3 = (__Pyx_PySequence_ContainsTF(__pyx_n_s_FFTW_UNALIGNED, __pyx_v_flags, Py_EQ)); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = (__pyx_t_3 != 0);
   if (__pyx_t_2) {
 
-    /* "pyfftw/pyfftw.pyx":1296
+    /* "pyfftw/pyfftw.pyx":881
+ *         # (16 bytes is assumed to be the minimal alignment)
+ *         if 'FFTW_UNALIGNED' in flags:
+ *             self._simd_allowed = False             # <<<<<<<<<<<<<<
+ *             self._input_array_alignment = natural_input_alignment
+ *             self._output_array_alignment = natural_output_alignment
+ */
+    __pyx_v_self->_simd_allowed = 0;
+
+    /* "pyfftw/pyfftw.pyx":882
+ *         if 'FFTW_UNALIGNED' in flags:
+ *             self._simd_allowed = False
+ *             self._input_array_alignment = natural_input_alignment             # <<<<<<<<<<<<<<
+ *             self._output_array_alignment = natural_output_alignment
  * 
- *         if self.__direction == FFTW_BACKWARD and normalise_idft:
- *             self.__output_array *= self.__normalisation_scaling             # <<<<<<<<<<<<<<
+ */
+    __pyx_v_self->_input_array_alignment = __pyx_v_natural_input_alignment;
+
+    /* "pyfftw/pyfftw.pyx":883
+ *             self._simd_allowed = False
+ *             self._input_array_alignment = natural_input_alignment
+ *             self._output_array_alignment = natural_output_alignment             # <<<<<<<<<<<<<<
  * 
- *         return self.__output_array
+ *         else:
  */
-    __pyx_t_4 = PyFloat_FromDouble(__pyx_v_self->__pyx___normalisation_scaling); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_5 = PyNumber_InPlaceMultiply(((PyObject *)__pyx_v_self->__pyx___output_array), __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GIVEREF(__pyx_t_5);
-    __Pyx_GOTREF(__pyx_v_self->__pyx___output_array);
-    __Pyx_DECREF(((PyObject *)__pyx_v_self->__pyx___output_array));
-    __pyx_v_self->__pyx___output_array = ((PyArrayObject *)__pyx_t_5);
-    __pyx_t_5 = 0;
-    goto __pyx_L11;
+    __pyx_v_self->_output_array_alignment = __pyx_v_natural_output_alignment;
+
+    /* "pyfftw/pyfftw.pyx":880
+ *         # we set the FFTW_UNALIGNED flag. This disables SIMD.
+ *         # (16 bytes is assumed to be the minimal alignment)
+ *         if 'FFTW_UNALIGNED' in flags:             # <<<<<<<<<<<<<<
+ *             self._simd_allowed = False
+ *             self._input_array_alignment = natural_input_alignment
+ */
+    goto __pyx_L26;
   }
-  __pyx_L11:;
 
-  /* "pyfftw/pyfftw.pyx":1298
- *             self.__output_array *= self.__normalisation_scaling
+  /* "pyfftw/pyfftw.pyx":887
+ *         else:
  * 
- *         return self.__output_array             # <<<<<<<<<<<<<<
+ *             self._input_array_alignment = -1             # <<<<<<<<<<<<<<
+ *             self._output_array_alignment = -1
  * 
- *     cpdef update_arrays(self,
  */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_self->__pyx___output_array));
-  __pyx_r = ((PyObject *)__pyx_v_self->__pyx___output_array);
-  goto __pyx_L0;
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_XDECREF(__pyx_t_6);
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__call__", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_input_array);
-  __Pyx_XDECREF(__pyx_v_output_array);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  /*else*/ {
+    __pyx_v_self->_input_array_alignment = -1;
 
-/* "pyfftw/pyfftw.pyx":1300
- *         return self.__output_array
+    /* "pyfftw/pyfftw.pyx":888
  * 
- *     cpdef update_arrays(self,             # <<<<<<<<<<<<<<
- *             new_input_array, new_output_array):
- *         '''update_arrays(new_input_array, new_output_array)
+ *             self._input_array_alignment = -1
+ *             self._output_array_alignment = -1             # <<<<<<<<<<<<<<
+ * 
+ *             for each_alignment in _valid_simd_alignments:
  */
+    __pyx_v_self->_output_array_alignment = -1;
 
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_19update_arrays(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static PyObject *__pyx_f_6pyfftw_6pyfftw_4FFTW_update_arrays(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_new_input_array, PyObject *__pyx_v_new_output_array, int __pyx_skip_dispatch) {
-  PyObject *__pyx_v_new_input_shape = NULL;
-  PyObject *__pyx_v_new_output_shape = NULL;
-  PyObject *__pyx_v_new_input_strides = NULL;
-  PyObject *__pyx_v_new_output_strides = NULL;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  PyObject *__pyx_t_3 = NULL;
-  int __pyx_t_4;
-  int __pyx_t_5;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("update_arrays", 0);
-  /* Check if called by wrapper */
-  if (unlikely(__pyx_skip_dispatch)) ;
-  /* Check if overriden in Python */
-  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__update_arrays); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1300; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    /* "pyfftw/pyfftw.pyx":890
+ *             self._output_array_alignment = -1
+ * 
+ *             for each_alignment in _valid_simd_alignments:             # <<<<<<<<<<<<<<
+ *                 if (<intptr_t>np.PyArray_DATA(input_array) %
+ *                         each_alignment == 0 and
+ */
+    __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_valid_simd_alignments); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_19update_arrays)) {
-      __Pyx_XDECREF(__pyx_r);
-      __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1300; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      __Pyx_INCREF(__pyx_v_new_input_array);
-      PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_v_new_input_array);
-      __Pyx_GIVEREF(__pyx_v_new_input_array);
-      __Pyx_INCREF(__pyx_v_new_output_array);
-      PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_v_new_output_array);
-      __Pyx_GIVEREF(__pyx_v_new_output_array);
-      __pyx_t_3 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1300; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-      __pyx_r = __pyx_t_3;
-      __pyx_t_3 = 0;
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      goto __pyx_L0;
+    if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+      __pyx_t_10 = __pyx_t_1; __Pyx_INCREF(__pyx_t_10); __pyx_t_12 = 0;
+      __pyx_t_13 = NULL;
+    } else {
+      __pyx_t_12 = -1; __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_t_13 = Py_TYPE(__pyx_t_10)->tp_iternext; if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
     }
     __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  }
+    for (;;) {
+      if (likely(!__pyx_t_13)) {
+        if (likely(PyList_CheckExact(__pyx_t_10))) {
+          if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_10)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_1 = PyList_GET_ITEM(__pyx_t_10, __pyx_t_12); __Pyx_INCREF(__pyx_t_1); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_1 = PySequence_ITEM(__pyx_t_10, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+          #endif
+        } else {
+          if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_10)) break;
+          #if CYTHON_COMPILING_IN_CPYTHON
+          __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_10, __pyx_t_12); __Pyx_INCREF(__pyx_t_1); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          #else
+          __pyx_t_1 = PySequence_ITEM(__pyx_t_10, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_1);
+          #endif
+        }
+      } else {
+        __pyx_t_1 = __pyx_t_13(__pyx_t_10);
+        if (unlikely(!__pyx_t_1)) {
+          PyObject* exc_type = PyErr_Occurred();
+          if (exc_type) {
+            if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+            else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 890; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          }
+          break;
+        }
+        __Pyx_GOTREF(__pyx_t_1);
+      }
+      __Pyx_XDECREF_SET(__pyx_v_each_alignment, __pyx_t_1);
+      __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1323
- *         object will still be in a sane state).
- *         '''
- *         if not isinstance(new_input_array, np.ndarray):             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid input array: '
- *                     'The new input array needs to be an instance '
+      /* "pyfftw/pyfftw.pyx":891
+ * 
+ *             for each_alignment in _valid_simd_alignments:
+ *                 if (<intptr_t>np.PyArray_DATA(input_array) %             # <<<<<<<<<<<<<<
+ *                         each_alignment == 0 and
+ *                         <intptr_t>np.PyArray_DATA(output_array) %
  */
-  __pyx_t_1 = ((PyObject *)((PyObject*)__pyx_ptype_5numpy_ndarray));
-  __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_4 = __Pyx_TypeCheck(__pyx_v_new_input_array, __pyx_t_1); 
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_5 = (!__pyx_t_4);
-  if (__pyx_t_5) {
+      if (!(likely(((__pyx_v_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_v_input_array)))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
 
-    /* "pyfftw/pyfftw.pyx":1324
- *         '''
- *         if not isinstance(new_input_array, np.ndarray):
- *             raise ValueError('Invalid input array: '             # <<<<<<<<<<<<<<
- *                     'The new input array needs to be an instance '
- *                     'of numpy.ndarray')
+      /* "pyfftw/pyfftw.pyx":892
+ *             for each_alignment in _valid_simd_alignments:
+ *                 if (<intptr_t>np.PyArray_DATA(input_array) %
+ *                         each_alignment == 0 and             # <<<<<<<<<<<<<<
+ *                         <intptr_t>np.PyArray_DATA(output_array) %
+ *                         each_alignment == 0):
  */
-    __pyx_t_1 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_44), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1324; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1324; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
+      __pyx_t_9 = PyNumber_Remainder(__pyx_t_1, __pyx_v_each_alignment); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 891; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_t_9, __pyx_int_0, 0, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 892; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      if (__pyx_t_3) {
+      } else {
+        __pyx_t_2 = __pyx_t_3;
+        goto __pyx_L30_bool_binop_done;
+      }
 
-  /* "pyfftw/pyfftw.pyx":1328
- *                     'of numpy.ndarray')
+      /* "pyfftw/pyfftw.pyx":893
+ *                 if (<intptr_t>np.PyArray_DATA(input_array) %
+ *                         each_alignment == 0 and
+ *                         <intptr_t>np.PyArray_DATA(output_array) %             # <<<<<<<<<<<<<<
+ *                         each_alignment == 0):
  * 
- *         if not isinstance(new_output_array, np.ndarray):             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid output array '
- *                     'The new output array needs to be an instance '
  */
-  __pyx_t_1 = ((PyObject *)((PyObject*)__pyx_ptype_5numpy_ndarray));
-  __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_5 = __Pyx_TypeCheck(__pyx_v_new_output_array, __pyx_t_1); 
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_4 = (!__pyx_t_5);
-  if (__pyx_t_4) {
+      if (!(likely(((__pyx_v_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_1 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_v_output_array)))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
 
-    /* "pyfftw/pyfftw.pyx":1329
+      /* "pyfftw/pyfftw.pyx":894
+ *                         each_alignment == 0 and
+ *                         <intptr_t>np.PyArray_DATA(output_array) %
+ *                         each_alignment == 0):             # <<<<<<<<<<<<<<
  * 
- *         if not isinstance(new_output_array, np.ndarray):
- *             raise ValueError('Invalid output array '             # <<<<<<<<<<<<<<
- *                     'The new output array needs to be an instance '
- *                     'of numpy.ndarray')
+ *                     self._simd_allowed = True
  */
-    __pyx_t_1 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_46), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1329; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1329; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L4;
-  }
-  __pyx_L4:;
+      __pyx_t_9 = PyNumber_Remainder(__pyx_t_1, __pyx_v_each_alignment); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 893; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_t_9, __pyx_int_0, 0, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 894; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __pyx_t_2 = __pyx_t_3;
+      __pyx_L30_bool_binop_done:;
 
-  /* "pyfftw/pyfftw.pyx":1333
- *                     'of numpy.ndarray')
+      /* "pyfftw/pyfftw.pyx":891
  * 
- *         if not (<intptr_t>np.PyArray_DATA(new_input_array) %             # <<<<<<<<<<<<<<
- *                 self.input_alignment == 0):
- *             raise ValueError('Invalid input alignment: '
+ *             for each_alignment in _valid_simd_alignments:
+ *                 if (<intptr_t>np.PyArray_DATA(input_array) %             # <<<<<<<<<<<<<<
+ *                         each_alignment == 0 and
+ *                         <intptr_t>np.PyArray_DATA(output_array) %
  */
-  if (!(likely(((__pyx_v_new_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_new_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_1 = __pyx_v_new_input_array;
-  __Pyx_INCREF(__pyx_t_1);
-  __pyx_t_3 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_t_1)))); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      if (__pyx_t_2) {
 
-  /* "pyfftw/pyfftw.pyx":1334
+        /* "pyfftw/pyfftw.pyx":896
+ *                         each_alignment == 0):
  * 
- *         if not (<intptr_t>np.PyArray_DATA(new_input_array) %
- *                 self.input_alignment == 0):             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid input alignment: '
- *                     'The original arrays were %d-byte aligned. It is '
- */
-  __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__input_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyNumber_Remainder(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1333; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1334; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_5 = (!__pyx_t_4);
-  if (__pyx_t_5) {
-
-    /* "pyfftw/pyfftw.pyx":1338
- *                     'The original arrays were %d-byte aligned. It is '
- *                     'necessary that the update input array is similarly '
- *                     'aligned.' % self.input_alignment)             # <<<<<<<<<<<<<<
+ *                     self._simd_allowed = True             # <<<<<<<<<<<<<<
  * 
- *         if not (<intptr_t>np.PyArray_DATA(new_output_array) %
+ *                     self._input_array_alignment = each_alignment
  */
-    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__input_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __pyx_t_2 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_47), __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1338; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(((PyObject *)__pyx_t_2));
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    PyTuple_SET_ITEM(__pyx_t_1, 0, ((PyObject *)__pyx_t_2));
-    __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
-    __pyx_t_2 = 0;
-    __pyx_t_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_1), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L5;
-  }
-  __pyx_L5:;
+        __pyx_v_self->_simd_allowed = 1;
 
-  /* "pyfftw/pyfftw.pyx":1340
- *                     'aligned.' % self.input_alignment)
+        /* "pyfftw/pyfftw.pyx":898
+ *                     self._simd_allowed = True
  * 
- *         if not (<intptr_t>np.PyArray_DATA(new_output_array) %             # <<<<<<<<<<<<<<
- *                 self.output_alignment == 0):
- *             raise ValueError('Invalid output alignment: '
- */
-  if (!(likely(((__pyx_v_new_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_new_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1340; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = __pyx_v_new_output_array;
-  __Pyx_INCREF(__pyx_t_2);
-  __pyx_t_1 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_t_2)))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1340; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-
-  /* "pyfftw/pyfftw.pyx":1341
+ *                     self._input_array_alignment = each_alignment             # <<<<<<<<<<<<<<
+ *                     self._output_array_alignment = each_alignment
  * 
- *         if not (<intptr_t>np.PyArray_DATA(new_output_array) %
- *                 self.output_alignment == 0):             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid output alignment: '
- *                     'The original arrays were %d-byte aligned. It is '
  */
-  __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__output_alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyNumber_Remainder(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1340; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_int_0, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_4 = (!__pyx_t_5);
-  if (__pyx_t_4) {
+        __pyx_t_8 = __Pyx_PyInt_As_int(__pyx_v_each_alignment); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_v_self->_input_array_alignment = __pyx_t_8;
 
-    /* "pyfftw/pyfftw.pyx":1345
- *                     'The original arrays were %d-byte aligned. It is '
- *                     'necessary that the update output array is similarly '
- *                     'aligned.' % self.output_alignment)             # <<<<<<<<<<<<<<
+        /* "pyfftw/pyfftw.pyx":899
  * 
- *         if not new_input_array.dtype == self.__input_dtype:
- */
-    __pyx_t_2 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__output_alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1345; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_3 = PyNumber_Remainder(((PyObject *)__pyx_kp_s_48), __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1345; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(((PyObject *)__pyx_t_3));
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1342; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    PyTuple_SET_ITEM(__pyx_t_2, 0, ((PyObject *)__pyx_t_3));
-    __Pyx_GIVEREF(((PyObject *)__pyx_t_3));
-    __pyx_t_3 = 0;
-    __pyx_t_3 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_2), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1342; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1342; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L6;
-  }
-  __pyx_L6:;
-
-  /* "pyfftw/pyfftw.pyx":1347
- *                     'aligned.' % self.output_alignment)
+ *                     self._input_array_alignment = each_alignment
+ *                     self._output_array_alignment = each_alignment             # <<<<<<<<<<<<<<
  * 
- *         if not new_input_array.dtype == self.__input_dtype:             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid input dtype: '
- *                     'The new input array is not of the same '
+ *                     break
  */
-  __pyx_t_3 = PyObject_GetAttr(__pyx_v_new_input_array, __pyx_n_s__dtype); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_2 = PyObject_RichCompare(__pyx_t_3, __pyx_v_self->__pyx___input_dtype, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_5 = (!__pyx_t_4);
-  if (__pyx_t_5) {
+        __pyx_t_8 = __Pyx_PyInt_As_int(__pyx_v_each_alignment); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __pyx_v_self->_output_array_alignment = __pyx_t_8;
 
-    /* "pyfftw/pyfftw.pyx":1348
+        /* "pyfftw/pyfftw.pyx":901
+ *                     self._output_array_alignment = each_alignment
  * 
- *         if not new_input_array.dtype == self.__input_dtype:
- *             raise ValueError('Invalid input dtype: '             # <<<<<<<<<<<<<<
- *                     'The new input array is not of the same '
- *                     'dtype as was originally planned for.')
+ *                     break             # <<<<<<<<<<<<<<
+ * 
+ *             if (self._input_array_alignment == -1 or
  */
-    __pyx_t_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_50), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1348; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1348; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L7;
-  }
-  __pyx_L7:;
+        goto __pyx_L28_break;
 
-  /* "pyfftw/pyfftw.pyx":1352
- *                     'dtype as was originally planned for.')
+        /* "pyfftw/pyfftw.pyx":891
  * 
- *         if not new_output_array.dtype == self.__output_dtype:             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid output dtype: '
- *                     'The new output array is not of the same '
+ *             for each_alignment in _valid_simd_alignments:
+ *                 if (<intptr_t>np.PyArray_DATA(input_array) %             # <<<<<<<<<<<<<<
+ *                         each_alignment == 0 and
+ *                         <intptr_t>np.PyArray_DATA(output_array) %
  */
-  __pyx_t_2 = PyObject_GetAttr(__pyx_v_new_output_array, __pyx_n_s__dtype); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_v_self->__pyx___output_dtype, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_4 = (!__pyx_t_5);
-  if (__pyx_t_4) {
+      }
 
-    /* "pyfftw/pyfftw.pyx":1353
+      /* "pyfftw/pyfftw.pyx":890
+ *             self._output_array_alignment = -1
  * 
- *         if not new_output_array.dtype == self.__output_dtype:
- *             raise ValueError('Invalid output dtype: '             # <<<<<<<<<<<<<<
- *                     'The new output array is not of the same '
- *                     'dtype as was originally planned for.')
+ *             for each_alignment in _valid_simd_alignments:             # <<<<<<<<<<<<<<
+ *                 if (<intptr_t>np.PyArray_DATA(input_array) %
+ *                         each_alignment == 0 and
  */
-    __pyx_t_3 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_52), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L8;
-  }
-  __pyx_L8:;
+    }
+    __pyx_L28_break:;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1357
- *                     'dtype as was originally planned for.')
+    /* "pyfftw/pyfftw.pyx":903
+ *                     break
  * 
- *         new_input_shape = new_input_array.shape             # <<<<<<<<<<<<<<
- *         new_output_shape = new_output_array.shape
+ *             if (self._input_array_alignment == -1 or             # <<<<<<<<<<<<<<
+ *                     self._output_array_alignment == -1):
  * 
  */
-  __pyx_t_3 = PyObject_GetAttr(__pyx_v_new_input_array, __pyx_n_s__shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_v_new_input_shape = __pyx_t_3;
-  __pyx_t_3 = 0;
+    __pyx_t_3 = ((__pyx_v_self->_input_array_alignment == -1L) != 0);
+    if (!__pyx_t_3) {
+    } else {
+      __pyx_t_2 = __pyx_t_3;
+      goto __pyx_L33_bool_binop_done;
+    }
 
-  /* "pyfftw/pyfftw.pyx":1358
+    /* "pyfftw/pyfftw.pyx":904
  * 
- *         new_input_shape = new_input_array.shape
- *         new_output_shape = new_output_array.shape             # <<<<<<<<<<<<<<
+ *             if (self._input_array_alignment == -1 or
+ *                     self._output_array_alignment == -1):             # <<<<<<<<<<<<<<
  * 
- *         new_input_strides = new_input_array.strides
+ *                 self._simd_allowed = False
  */
-  __pyx_t_3 = PyObject_GetAttr(__pyx_v_new_output_array, __pyx_n_s__shape); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1358; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_v_new_output_shape = __pyx_t_3;
-  __pyx_t_3 = 0;
+    __pyx_t_3 = ((__pyx_v_self->_output_array_alignment == -1L) != 0);
+    __pyx_t_2 = __pyx_t_3;
+    __pyx_L33_bool_binop_done:;
 
-  /* "pyfftw/pyfftw.pyx":1360
- *         new_output_shape = new_output_array.shape
+    /* "pyfftw/pyfftw.pyx":903
+ *                     break
  * 
- *         new_input_strides = new_input_array.strides             # <<<<<<<<<<<<<<
- *         new_output_strides = new_output_array.strides
+ *             if (self._input_array_alignment == -1 or             # <<<<<<<<<<<<<<
+ *                     self._output_array_alignment == -1):
  * 
  */
-  __pyx_t_3 = PyObject_GetAttr(__pyx_v_new_input_array, __pyx_n_s__strides); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1360; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_v_new_input_strides = __pyx_t_3;
-  __pyx_t_3 = 0;
+    if (__pyx_t_2) {
 
-  /* "pyfftw/pyfftw.pyx":1361
+      /* "pyfftw/pyfftw.pyx":906
+ *                     self._output_array_alignment == -1):
  * 
- *         new_input_strides = new_input_array.strides
- *         new_output_strides = new_output_array.strides             # <<<<<<<<<<<<<<
+ *                 self._simd_allowed = False             # <<<<<<<<<<<<<<
  * 
- *         if not new_input_shape == self.__input_shape:
+ *                 self._input_array_alignment = (
  */
-  __pyx_t_3 = PyObject_GetAttr(__pyx_v_new_output_array, __pyx_n_s__strides); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1361; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_v_new_output_strides = __pyx_t_3;
-  __pyx_t_3 = 0;
+      __pyx_v_self->_simd_allowed = 0;
 
-  /* "pyfftw/pyfftw.pyx":1363
- *         new_output_strides = new_output_array.strides
+      /* "pyfftw/pyfftw.pyx":908
+ *                 self._simd_allowed = False
  * 
- *         if not new_input_shape == self.__input_shape:             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid input shape: '
- *                     'The new input array should be the same shape as '
+ *                 self._input_array_alignment = (             # <<<<<<<<<<<<<<
+ *                         natural_input_alignment)
+ *                 self._output_array_alignment = (
  */
-  __pyx_t_3 = PyObject_RichCompare(__pyx_v_new_input_shape, __pyx_v_self->__pyx___input_shape, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1363; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_5 = (!__pyx_t_4);
-  if (__pyx_t_5) {
+      __pyx_v_self->_input_array_alignment = __pyx_v_natural_input_alignment;
 
-    /* "pyfftw/pyfftw.pyx":1364
- * 
- *         if not new_input_shape == self.__input_shape:
- *             raise ValueError('Invalid input shape: '             # <<<<<<<<<<<<<<
- *                     'The new input array should be the same shape as '
- *                     'the input array used to instantiate the object.')
+      /* "pyfftw/pyfftw.pyx":910
+ *                 self._input_array_alignment = (
+ *                         natural_input_alignment)
+ *                 self._output_array_alignment = (             # <<<<<<<<<<<<<<
+ *                         natural_output_alignment)
+ *                 flags.append('FFTW_UNALIGNED')
  */
-    __pyx_t_3 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_53), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L9;
-  }
-  __pyx_L9:;
+      __pyx_v_self->_output_array_alignment = __pyx_v_natural_output_alignment;
 
-  /* "pyfftw/pyfftw.pyx":1368
- *                     'the input array used to instantiate the object.')
+      /* "pyfftw/pyfftw.pyx":912
+ *                 self._output_array_alignment = (
+ *                         natural_output_alignment)
+ *                 flags.append('FFTW_UNALIGNED')             # <<<<<<<<<<<<<<
  * 
- *         if not new_output_shape == self.__output_shape:             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid output shape: '
- *                     'The new output array should be the same shape as '
+ *         if (not (<intptr_t>np.PyArray_DATA(input_array)
  */
-  __pyx_t_3 = PyObject_RichCompare(__pyx_v_new_output_shape, __pyx_v_self->__pyx___output_shape, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1368; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_4 = (!__pyx_t_5);
-  if (__pyx_t_4) {
+      __pyx_t_14 = __Pyx_PyObject_Append(__pyx_v_flags, __pyx_n_s_FFTW_UNALIGNED); if (unlikely(__pyx_t_14 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-    /* "pyfftw/pyfftw.pyx":1369
+      /* "pyfftw/pyfftw.pyx":903
+ *                     break
+ * 
+ *             if (self._input_array_alignment == -1 or             # <<<<<<<<<<<<<<
+ *                     self._output_array_alignment == -1):
  * 
- *         if not new_output_shape == self.__output_shape:
- *             raise ValueError('Invalid output shape: '             # <<<<<<<<<<<<<<
- *                     'The new output array should be the same shape as '
- *                     'the output array used to instantiate the object.')
  */
-    __pyx_t_3 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_55), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L10;
+    }
   }
-  __pyx_L10:;
+  __pyx_L26:;
 
-  /* "pyfftw/pyfftw.pyx":1373
- *                     'the output array used to instantiate the object.')
+  /* "pyfftw/pyfftw.pyx":914
+ *                 flags.append('FFTW_UNALIGNED')
  * 
- *         if not new_input_strides == self.__input_byte_strides:             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid input striding: '
- *                     'The strides should be identical for the new '
+ *         if (not (<intptr_t>np.PyArray_DATA(input_array)             # <<<<<<<<<<<<<<
+ *             % self._input_array_alignment == 0)):
+ *             raise ValueError('Invalid input alignment: '
  */
-  __pyx_t_3 = PyObject_RichCompare(__pyx_v_new_input_strides, __pyx_v_self->__pyx___input_byte_strides, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_4 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1373; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_5 = (!__pyx_t_4);
-  if (__pyx_t_5) {
+  if (!(likely(((__pyx_v_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_15 = ((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_v_input_array)));
 
-    /* "pyfftw/pyfftw.pyx":1374
+  /* "pyfftw/pyfftw.pyx":915
  * 
- *         if not new_input_strides == self.__input_byte_strides:
- *             raise ValueError('Invalid input striding: '             # <<<<<<<<<<<<<<
- *                     'The strides should be identical for the new '
- *                     'input array as for the old.')
+ *         if (not (<intptr_t>np.PyArray_DATA(input_array)
+ *             % self._input_array_alignment == 0)):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input alignment: '
+ *                     'The input array is expected to lie on a %d '
  */
-    __pyx_t_3 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_57), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L11;
+  if (unlikely(__pyx_v_self->_input_array_alignment == 0)) {
+    PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
-  __pyx_L11:;
 
-  /* "pyfftw/pyfftw.pyx":1378
- *                     'input array as for the old.')
+  /* "pyfftw/pyfftw.pyx":914
+ *                 flags.append('FFTW_UNALIGNED')
  * 
- *         if not new_output_strides == self.__output_byte_strides:             # <<<<<<<<<<<<<<
- *             raise ValueError('Invalid output striding: '
- *                     'The strides should be identical for the new '
+ *         if (not (<intptr_t>np.PyArray_DATA(input_array)             # <<<<<<<<<<<<<<
+ *             % self._input_array_alignment == 0)):
+ *             raise ValueError('Invalid input alignment: '
  */
-  __pyx_t_3 = PyObject_RichCompare(__pyx_v_new_output_strides, __pyx_v_self->__pyx___output_byte_strides, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1378; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1378; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __pyx_t_4 = (!__pyx_t_5);
-  if (__pyx_t_4) {
+  __pyx_t_2 = ((!((__Pyx_mod_intptr_t(__pyx_t_15, __pyx_v_self->_input_array_alignment) == 0) != 0)) != 0);
+  if (__pyx_t_2) {
 
-    /* "pyfftw/pyfftw.pyx":1379
+    /* "pyfftw/pyfftw.pyx":918
+ *             raise ValueError('Invalid input alignment: '
+ *                     'The input array is expected to lie on a %d '
+ *                     'byte boundary.' % self._input_array_alignment)             # <<<<<<<<<<<<<<
  * 
- *         if not new_output_strides == self.__output_byte_strides:
- *             raise ValueError('Invalid output striding: '             # <<<<<<<<<<<<<<
- *                     'The strides should be identical for the new '
- *                     'output array as for the old.')
+ *         if (not (<intptr_t>np.PyArray_DATA(output_array)
  */
-    __pyx_t_3 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_59), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L12;
-  }
-  __pyx_L12:;
+    __pyx_t_10 = __Pyx_PyInt_From_int(__pyx_v_self->_input_array_alignment); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_input_alignment_The_inpu, __pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1383
- *                     'output array as for the old.')
- * 
- *         self._update_arrays(new_input_array, new_output_array)             # <<<<<<<<<<<<<<
- * 
- *     cdef _update_arrays(self,
+    /* "pyfftw/pyfftw.pyx":916
+ *         if (not (<intptr_t>np.PyArray_DATA(input_array)
+ *             % self._input_array_alignment == 0)):
+ *             raise ValueError('Invalid input alignment: '             # <<<<<<<<<<<<<<
+ *                     'The input array is expected to lie on a %d '
+ *                     'byte boundary.' % self._input_array_alignment)
  */
-  if (!(likely(((__pyx_v_new_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_new_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_3 = __pyx_v_new_input_array;
-  __Pyx_INCREF(__pyx_t_3);
-  if (!(likely(((__pyx_v_new_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_new_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_t_2 = __pyx_v_new_output_array;
-  __Pyx_INCREF(__pyx_t_2);
-  __pyx_t_1 = ((struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *)__pyx_v_self->__pyx_vtab)->_update_arrays(__pyx_v_self, ((PyArrayObject *)__pyx_t_3), ((PyArrayObject *)__pyx_t_2)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.update_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_new_input_shape);
-  __Pyx_XDECREF(__pyx_v_new_output_shape);
-  __Pyx_XDECREF(__pyx_v_new_input_strides);
-  __Pyx_XDECREF(__pyx_v_new_output_strides);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+    __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __Pyx_GIVEREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1);
+    __pyx_t_1 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 916; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_19update_arrays(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_18update_arrays[] = "update_arrays(new_input_array, new_output_array)\n\n        Update the arrays upon which the DFT is taken.\n\n        The new arrays should be of the same dtypes as the originals, the same\n        shapes as the originals and should have the same strides between axes.\n        If the original data was aligned so as to allow SIMD instructions\n        (e.g. by being aligned on a 16-byte boundary), then the new array must\n   [...]
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_19update_arrays(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
-  PyObject *__pyx_v_new_input_array = 0;
-  PyObject *__pyx_v_new_output_array = 0;
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("update_arrays (wrapper)", 0);
-  {
-    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s__new_input_array,&__pyx_n_s__new_output_array,0};
-    PyObject* values[2] = {0,0};
-    if (unlikely(__pyx_kwds)) {
-      Py_ssize_t kw_args;
-      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
-      switch (pos_args) {
-        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-        case  0: break;
-        default: goto __pyx_L5_argtuple_error;
-      }
-      kw_args = PyDict_Size(__pyx_kwds);
-      switch (pos_args) {
-        case  0:
-        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__new_input_array)) != 0)) kw_args--;
-        else goto __pyx_L5_argtuple_error;
-        case  1:
-        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s__new_output_array)) != 0)) kw_args--;
-        else {
-          __Pyx_RaiseArgtupleInvalid("update_arrays", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1300; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-        }
-      }
-      if (unlikely(kw_args > 0)) {
-        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "update_arrays") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1300; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-      }
-    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
-      goto __pyx_L5_argtuple_error;
-    } else {
-      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
-      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
-    }
-    __pyx_v_new_input_array = values[0];
-    __pyx_v_new_output_array = values[1];
+    /* "pyfftw/pyfftw.pyx":914
+ *                 flags.append('FFTW_UNALIGNED')
+ * 
+ *         if (not (<intptr_t>np.PyArray_DATA(input_array)             # <<<<<<<<<<<<<<
+ *             % self._input_array_alignment == 0)):
+ *             raise ValueError('Invalid input alignment: '
+ */
   }
-  goto __pyx_L4_argument_unpacking_done;
-  __pyx_L5_argtuple_error:;
-  __Pyx_RaiseArgtupleInvalid("update_arrays", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1300; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
-  __pyx_L3_error:;
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.update_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __Pyx_RefNannyFinishContext();
-  return NULL;
-  __pyx_L4_argument_unpacking_done:;
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_18update_arrays(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self), __pyx_v_new_input_array, __pyx_v_new_output_array);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
 
-/* "pyfftw/pyfftw.pyx":1300
- *         return self.__output_array
+  /* "pyfftw/pyfftw.pyx":920
+ *                     'byte boundary.' % self._input_array_alignment)
  * 
- *     cpdef update_arrays(self,             # <<<<<<<<<<<<<<
- *             new_input_array, new_output_array):
- *         '''update_arrays(new_input_array, new_output_array)
+ *         if (not (<intptr_t>np.PyArray_DATA(output_array)             # <<<<<<<<<<<<<<
+ *             % self._output_array_alignment == 0)):
+ *             raise ValueError('Invalid output alignment: '
  */
+  if (!(likely(((__pyx_v_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_15 = ((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_v_output_array)));
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_18update_arrays(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_new_input_array, PyObject *__pyx_v_new_output_array) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("update_arrays", 0);
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *)__pyx_v_self->__pyx_vtab)->update_arrays(__pyx_v_self, __pyx_v_new_input_array, __pyx_v_new_output_array, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1300; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.update_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pyfftw/pyfftw.pyx":1385
- *         self._update_arrays(new_input_array, new_output_array)
+  /* "pyfftw/pyfftw.pyx":921
  * 
- *     cdef _update_arrays(self,             # <<<<<<<<<<<<<<
- *             np.ndarray new_input_array, np.ndarray new_output_array):
- *         ''' A C interface to the update_arrays method that does not
+ *         if (not (<intptr_t>np.PyArray_DATA(output_array)
+ *             % self._output_array_alignment == 0)):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output alignment: '
+ *                     'The output array is expected to lie on a %d '
  */
+  if (unlikely(__pyx_v_self->_output_array_alignment == 0)) {
+    PyErr_SetString(PyExc_ZeroDivisionError, "integer division or modulo by zero");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
 
-static PyObject *__pyx_f_6pyfftw_6pyfftw_4FFTW__update_arrays(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyArrayObject *__pyx_v_new_input_array, PyArrayObject *__pyx_v_new_output_array) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("_update_arrays", 0);
-
-  /* "pyfftw/pyfftw.pyx":1390
- *         perform any checks on strides being correct and so on.
- *         '''
- *         self.__input_array = new_input_array             # <<<<<<<<<<<<<<
- *         self.__output_array = new_output_array
+  /* "pyfftw/pyfftw.pyx":920
+ *                     'byte boundary.' % self._input_array_alignment)
  * 
+ *         if (not (<intptr_t>np.PyArray_DATA(output_array)             # <<<<<<<<<<<<<<
+ *             % self._output_array_alignment == 0)):
+ *             raise ValueError('Invalid output alignment: '
  */
-  __Pyx_INCREF(((PyObject *)__pyx_v_new_input_array));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_new_input_array));
-  __Pyx_GOTREF(__pyx_v_self->__pyx___input_array);
-  __Pyx_DECREF(((PyObject *)__pyx_v_self->__pyx___input_array));
-  __pyx_v_self->__pyx___input_array = __pyx_v_new_input_array;
+  __pyx_t_2 = ((!((__Pyx_mod_intptr_t(__pyx_t_15, __pyx_v_self->_output_array_alignment) == 0) != 0)) != 0);
+  if (__pyx_t_2) {
 
-  /* "pyfftw/pyfftw.pyx":1391
- *         '''
- *         self.__input_array = new_input_array
- *         self.__output_array = new_output_array             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":924
+ *             raise ValueError('Invalid output alignment: '
+ *                     'The output array is expected to lie on a %d '
+ *                     'byte boundary.' % self._output_array_alignment)             # <<<<<<<<<<<<<<
  * 
- *     def get_input_array(self):
+ *         if not direction in scheme_directions[scheme]:
  */
-  __Pyx_INCREF(((PyObject *)__pyx_v_new_output_array));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_new_output_array));
-  __Pyx_GOTREF(__pyx_v_self->__pyx___output_array);
-  __Pyx_DECREF(((PyObject *)__pyx_v_self->__pyx___output_array));
-  __pyx_v_self->__pyx___output_array = __pyx_v_new_output_array;
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+    __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_self->_output_array_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_10 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_output_alignment_The_out, __pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 924; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_21get_input_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_20get_input_array[] = "get_input_array()\n\n        Return the input array that is associated with the FFTW \n        instance.\n        ";
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_21get_input_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("get_input_array (wrapper)", 0);
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_20get_input_array(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+    /* "pyfftw/pyfftw.pyx":922
+ *         if (not (<intptr_t>np.PyArray_DATA(output_array)
+ *             % self._output_array_alignment == 0)):
+ *             raise ValueError('Invalid output alignment: '             # <<<<<<<<<<<<<<
+ *                     'The output array is expected to lie on a %d '
+ *                     'byte boundary.' % self._output_array_alignment)
+ */
+    __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_GIVEREF(__pyx_t_10);
+    PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_10);
+    __pyx_t_10 = 0;
+    __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_1, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 922; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-/* "pyfftw/pyfftw.pyx":1393
- *         self.__output_array = new_output_array
- * 
- *     def get_input_array(self):             # <<<<<<<<<<<<<<
- *         '''get_input_array()
+    /* "pyfftw/pyfftw.pyx":920
+ *                     'byte boundary.' % self._input_array_alignment)
  * 
+ *         if (not (<intptr_t>np.PyArray_DATA(output_array)             # <<<<<<<<<<<<<<
+ *             % self._output_array_alignment == 0)):
+ *             raise ValueError('Invalid output alignment: '
  */
+  }
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_20get_input_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("get_input_array", 0);
-
-  /* "pyfftw/pyfftw.pyx":1399
- *         instance.
- *         '''
- *         return self.__input_array             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":926
+ *                     'byte boundary.' % self._output_array_alignment)
  * 
- *     def get_output_array(self):
+ *         if not direction in scheme_directions[scheme]:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid direction: '
+ *                     'The direction is not valid for the scheme. '
  */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_self->__pyx___input_array));
-  __pyx_r = ((PyObject *)__pyx_v_self->__pyx___input_array);
-  goto __pyx_L0;
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  __pyx_t_10 = PyObject_GetItem(__pyx_v_6pyfftw_6pyfftw_scheme_directions, __pyx_v_scheme); if (unlikely(__pyx_t_10 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_10);
+  __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_v_direction, __pyx_t_10, Py_NE)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 926; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __pyx_t_3 = (__pyx_t_2 != 0);
+  if (__pyx_t_3) {
 
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_23get_output_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_22get_output_array[] = "get_output_array()\n\n        Return the output array that is associated with the FFTW\n        instance.\n        ";
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_23get_output_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("get_output_array (wrapper)", 0);
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_22get_output_array(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pyfftw/pyfftw.pyx":1401
- *         return self.__input_array
+    /* "pyfftw/pyfftw.pyx":927
  * 
- *     def get_output_array(self):             # <<<<<<<<<<<<<<
- *         '''get_output_array()
+ *         if not direction in scheme_directions[scheme]:
+ *             raise ValueError('Invalid direction: '             # <<<<<<<<<<<<<<
+ *                     'The direction is not valid for the scheme. '
+ *                     'Try setting it explicitly if it is not already.')
+ */
+    __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__12, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "pyfftw/pyfftw.pyx":926
+ *                     'byte boundary.' % self._output_array_alignment)
  * 
+ *         if not direction in scheme_directions[scheme]:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid direction: '
+ *                     'The direction is not valid for the scheme. '
  */
+  }
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_22get_output_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("get_output_array", 0);
+  /* "pyfftw/pyfftw.pyx":931
+ *                     'Try setting it explicitly if it is not already.')
+ * 
+ *         self._direction = directions[direction]             # <<<<<<<<<<<<<<
+ *         self._input_shape = input_array.shape
+ *         self._output_shape = output_array.shape
+ */
+  __pyx_t_10 = PyObject_GetItem(__pyx_v_6pyfftw_6pyfftw_directions, __pyx_v_direction); if (unlikely(__pyx_t_10 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_10);
+  __pyx_t_8 = __Pyx_PyInt_As_int(__pyx_t_10); if (unlikely((__pyx_t_8 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 931; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __pyx_v_self->_direction = __pyx_t_8;
 
-  /* "pyfftw/pyfftw.pyx":1407
- *         instance.
- *         '''
- *         return self.__output_array             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":932
+ * 
+ *         self._direction = directions[direction]
+ *         self._input_shape = input_array.shape             # <<<<<<<<<<<<<<
+ *         self._output_shape = output_array.shape
  * 
- *     cpdef execute(self):
  */
-  __Pyx_XDECREF(__pyx_r);
-  __Pyx_INCREF(((PyObject *)__pyx_v_self->__pyx___output_array));
-  __pyx_r = ((PyObject *)__pyx_v_self->__pyx___output_array);
-  goto __pyx_L0;
+  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_array, __pyx_n_s_shape); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 932; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_GIVEREF(__pyx_t_10);
+  __Pyx_GOTREF(__pyx_v_self->_input_shape);
+  __Pyx_DECREF(__pyx_v_self->_input_shape);
+  __pyx_v_self->_input_shape = __pyx_t_10;
+  __pyx_t_10 = 0;
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  /* "pyfftw/pyfftw.pyx":933
+ *         self._direction = directions[direction]
+ *         self._input_shape = input_array.shape
+ *         self._output_shape = output_array.shape             # <<<<<<<<<<<<<<
+ * 
+ *         self._input_array = input_array
+ */
+  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_array, __pyx_n_s_shape); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 933; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_GIVEREF(__pyx_t_10);
+  __Pyx_GOTREF(__pyx_v_self->_output_shape);
+  __Pyx_DECREF(__pyx_v_self->_output_shape);
+  __pyx_v_self->_output_shape = __pyx_t_10;
+  __pyx_t_10 = 0;
 
-/* "pyfftw/pyfftw.pyx":1409
- *         return self.__output_array
+  /* "pyfftw/pyfftw.pyx":935
+ *         self._output_shape = output_array.shape
  * 
- *     cpdef execute(self):             # <<<<<<<<<<<<<<
- *         '''execute()
+ *         self._input_array = input_array             # <<<<<<<<<<<<<<
+ *         self._output_array = output_array
  * 
  */
+  if (!(likely(((__pyx_v_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 935; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_10 = __pyx_v_input_array;
+  __Pyx_INCREF(__pyx_t_10);
+  __Pyx_GIVEREF(__pyx_t_10);
+  __Pyx_GOTREF(__pyx_v_self->_input_array);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->_input_array));
+  __pyx_v_self->_input_array = ((PyArrayObject *)__pyx_t_10);
+  __pyx_t_10 = 0;
 
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_25execute(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static PyObject *__pyx_f_6pyfftw_6pyfftw_4FFTW_execute(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, int __pyx_skip_dispatch) {
-  void *__pyx_v_input_pointer;
-  void *__pyx_v_output_pointer;
-  void *__pyx_v_plan;
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_execute __pyx_v_fftw_execute;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  PyObject *__pyx_t_2 = NULL;
-  void *__pyx_t_3;
-  __pyx_t_6pyfftw_6pyfftw_fftw_generic_execute __pyx_t_4;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("execute", 0);
-  /* Check if called by wrapper */
-  if (unlikely(__pyx_skip_dispatch)) ;
-  /* Check if overriden in Python */
-  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
-    __pyx_t_1 = PyObject_GetAttr(((PyObject *)__pyx_v_self), __pyx_n_s__execute); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_25execute)) {
-      __Pyx_XDECREF(__pyx_r);
-      __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_2);
-      __pyx_r = __pyx_t_2;
-      __pyx_t_2 = 0;
-      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-      goto __pyx_L0;
-    }
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  }
-
-  /* "pyfftw/pyfftw.pyx":1418
- *         '''
- *         cdef void *input_pointer = (
- *                 <void *>np.PyArray_DATA(self.__input_array))             # <<<<<<<<<<<<<<
- *         cdef void *output_pointer = (
- *                 <void *>np.PyArray_DATA(self.__output_array))
+  /* "pyfftw/pyfftw.pyx":936
+ * 
+ *         self._input_array = input_array
+ *         self._output_array = output_array             # <<<<<<<<<<<<<<
+ * 
+ *         self._axes = <int64_t *>malloc(len(axes)*sizeof(int64_t))
  */
-  __pyx_t_1 = ((PyObject *)__pyx_v_self->__pyx___input_array);
-  __Pyx_INCREF(__pyx_t_1);
-  __pyx_v_input_pointer = ((void *)PyArray_DATA(((PyArrayObject *)__pyx_t_1)));
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (!(likely(((__pyx_v_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 936; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_10 = __pyx_v_output_array;
+  __Pyx_INCREF(__pyx_t_10);
+  __Pyx_GIVEREF(__pyx_t_10);
+  __Pyx_GOTREF(__pyx_v_self->_output_array);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->_output_array));
+  __pyx_v_self->_output_array = ((PyArrayObject *)__pyx_t_10);
+  __pyx_t_10 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1420
- *                 <void *>np.PyArray_DATA(self.__input_array))
- *         cdef void *output_pointer = (
- *                 <void *>np.PyArray_DATA(self.__output_array))             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":938
+ *         self._output_array = output_array
  * 
- *         cdef void *plan = self.__plan
+ *         self._axes = <int64_t *>malloc(len(axes)*sizeof(int64_t))             # <<<<<<<<<<<<<<
+ *         for n in range(len(axes)):
+ *             self._axes[n] = axes[n]
  */
-  __pyx_t_1 = ((PyObject *)__pyx_v_self->__pyx___output_array);
-  __Pyx_INCREF(__pyx_t_1);
-  __pyx_v_output_pointer = ((void *)PyArray_DATA(((PyArrayObject *)__pyx_t_1)));
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_12 = PyObject_Length(__pyx_v_axes); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 938; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->_axes = ((int64_t *)malloc((__pyx_t_12 * (sizeof(int64_t)))));
 
-  /* "pyfftw/pyfftw.pyx":1422
- *                 <void *>np.PyArray_DATA(self.__output_array))
+  /* "pyfftw/pyfftw.pyx":939
  * 
- *         cdef void *plan = self.__plan             # <<<<<<<<<<<<<<
- *         cdef fftw_generic_execute fftw_execute = self.__fftw_execute
+ *         self._axes = <int64_t *>malloc(len(axes)*sizeof(int64_t))
+ *         for n in range(len(axes)):             # <<<<<<<<<<<<<<
+ *             self._axes[n] = axes[n]
  * 
  */
-  __pyx_t_3 = __pyx_v_self->__pyx___plan;
-  __pyx_v_plan = __pyx_t_3;
+  __pyx_t_12 = PyObject_Length(__pyx_v_axes); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 939; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  for (__pyx_t_16 = 0; __pyx_t_16 < __pyx_t_12; __pyx_t_16+=1) {
+    __pyx_v_n = __pyx_t_16;
 
-  /* "pyfftw/pyfftw.pyx":1423
+    /* "pyfftw/pyfftw.pyx":940
+ *         self._axes = <int64_t *>malloc(len(axes)*sizeof(int64_t))
+ *         for n in range(len(axes)):
+ *             self._axes[n] = axes[n]             # <<<<<<<<<<<<<<
  * 
- *         cdef void *plan = self.__plan
- *         cdef fftw_generic_execute fftw_execute = self.__fftw_execute             # <<<<<<<<<<<<<<
+ *         # Set the negative entries to their actual index (use the size
+ */
+    __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_axes, __pyx_v_n, Py_ssize_t, 1, PyInt_FromSsize_t, 0, 1, 1); if (unlikely(__pyx_t_10 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_17 = __Pyx_PyInt_As_int64_t(__pyx_t_10); if (unlikely((__pyx_t_17 == (int64_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 940; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    (__pyx_v_self->_axes[__pyx_v_n]) = __pyx_t_17;
+  }
+
+  /* "pyfftw/pyfftw.pyx":944
+ *         # Set the negative entries to their actual index (use the size
+ *         # of the shape array for this)
+ *         cdef int64_t array_dimension = len(self._input_shape)             # <<<<<<<<<<<<<<
  * 
- *         if self.__use_threads:
+ *         for n in range(len(axes)):
  */
-  __pyx_t_4 = __pyx_v_self->__pyx___fftw_execute;
-  __pyx_v_fftw_execute = __pyx_t_4;
+  __pyx_t_10 = __pyx_v_self->_input_shape;
+  __Pyx_INCREF(__pyx_t_10);
+  __pyx_t_12 = PyObject_Length(__pyx_t_10); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 944; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __pyx_v_array_dimension = __pyx_t_12;
 
-  /* "pyfftw/pyfftw.pyx":1425
- *         cdef fftw_generic_execute fftw_execute = self.__fftw_execute
+  /* "pyfftw/pyfftw.pyx":946
+ *         cdef int64_t array_dimension = len(self._input_shape)
  * 
- *         if self.__use_threads:             # <<<<<<<<<<<<<<
- *             with nogil:
- *                 fftw_execute(plan, input_pointer, output_pointer)
+ *         for n in range(len(axes)):             # <<<<<<<<<<<<<<
+ *             if self._axes[n] < 0:
+ *                 self._axes[n] = self._axes[n] + array_dimension
  */
-  if (__pyx_v_self->__pyx___use_threads) {
+  __pyx_t_12 = PyObject_Length(__pyx_v_axes); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 946; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  for (__pyx_t_16 = 0; __pyx_t_16 < __pyx_t_12; __pyx_t_16+=1) {
+    __pyx_v_n = __pyx_t_16;
 
-    /* "pyfftw/pyfftw.pyx":1426
+    /* "pyfftw/pyfftw.pyx":947
+ * 
+ *         for n in range(len(axes)):
+ *             if self._axes[n] < 0:             # <<<<<<<<<<<<<<
+ *                 self._axes[n] = self._axes[n] + array_dimension
  * 
- *         if self.__use_threads:
- *             with nogil:             # <<<<<<<<<<<<<<
- *                 fftw_execute(plan, input_pointer, output_pointer)
- *         else:
  */
-    {
-        #ifdef WITH_THREAD
-        PyThreadState *_save = NULL;
-        #endif
-        Py_UNBLOCK_THREADS
-        /*try:*/ {
+    __pyx_t_3 = (((__pyx_v_self->_axes[__pyx_v_n]) < 0) != 0);
+    if (__pyx_t_3) {
 
-          /* "pyfftw/pyfftw.pyx":1427
- *         if self.__use_threads:
- *             with nogil:
- *                 fftw_execute(plan, input_pointer, output_pointer)             # <<<<<<<<<<<<<<
- *         else:
- *             fftw_execute(self.__plan, input_pointer, output_pointer)
+      /* "pyfftw/pyfftw.pyx":948
+ *         for n in range(len(axes)):
+ *             if self._axes[n] < 0:
+ *                 self._axes[n] = self._axes[n] + array_dimension             # <<<<<<<<<<<<<<
+ * 
+ *             if self._axes[n] >= array_dimension or self._axes[n] < 0:
  */
-          __pyx_v_fftw_execute(__pyx_v_plan, __pyx_v_input_pointer, __pyx_v_output_pointer);
-        }
+      (__pyx_v_self->_axes[__pyx_v_n]) = ((__pyx_v_self->_axes[__pyx_v_n]) + __pyx_v_array_dimension);
 
-        /* "pyfftw/pyfftw.pyx":1426
+      /* "pyfftw/pyfftw.pyx":947
+ * 
+ *         for n in range(len(axes)):
+ *             if self._axes[n] < 0:             # <<<<<<<<<<<<<<
+ *                 self._axes[n] = self._axes[n] + array_dimension
  * 
- *         if self.__use_threads:
- *             with nogil:             # <<<<<<<<<<<<<<
- *                 fftw_execute(plan, input_pointer, output_pointer)
- *         else:
  */
-        /*finally:*/ {
-          Py_BLOCK_THREADS
-        }
     }
-    goto __pyx_L3;
-  }
-  /*else*/ {
 
-    /* "pyfftw/pyfftw.pyx":1429
- *                 fftw_execute(plan, input_pointer, output_pointer)
- *         else:
- *             fftw_execute(self.__plan, input_pointer, output_pointer)             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":950
+ *                 self._axes[n] = self._axes[n] + array_dimension
  * 
- * cdef void count_char(char c, void *counter_ptr):
+ *             if self._axes[n] >= array_dimension or self._axes[n] < 0:             # <<<<<<<<<<<<<<
+ *                 raise IndexError('Invalid axes: '
+ *                     'The axes list cannot contain invalid axes.')
  */
-    __pyx_v_fftw_execute(__pyx_v_self->__pyx___plan, __pyx_v_input_pointer, __pyx_v_output_pointer);
-  }
-  __pyx_L3:;
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.execute", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_25execute(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_24execute[] = "execute()\n\n        Execute the planned operation, taking the correct kind of FFT of\n        the input array (what is returned by :meth:`get_input_array`), \n        and putting the result in the output array (what is returned by\n        :meth:`get_output_array`).\n        ";
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_25execute(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("execute (wrapper)", 0);
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_24execute(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+    __pyx_t_2 = (((__pyx_v_self->_axes[__pyx_v_n]) >= __pyx_v_array_dimension) != 0);
+    if (!__pyx_t_2) {
+    } else {
+      __pyx_t_3 = __pyx_t_2;
+      goto __pyx_L44_bool_binop_done;
+    }
+    __pyx_t_2 = (((__pyx_v_self->_axes[__pyx_v_n]) < 0) != 0);
+    __pyx_t_3 = __pyx_t_2;
+    __pyx_L44_bool_binop_done:;
+    if (__pyx_t_3) {
 
-/* "pyfftw/pyfftw.pyx":1409
- *         return self.__output_array
+      /* "pyfftw/pyfftw.pyx":951
  * 
- *     cpdef execute(self):             # <<<<<<<<<<<<<<
- *         '''execute()
+ *             if self._axes[n] >= array_dimension or self._axes[n] < 0:
+ *                 raise IndexError('Invalid axes: '             # <<<<<<<<<<<<<<
+ *                     'The axes list cannot contain invalid axes.')
  * 
  */
+      __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_IndexError, __pyx_tuple__13, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_24execute(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("execute", 0);
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = ((struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *)__pyx_v_self->__pyx_vtab)->execute(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.execute", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pyfftw/pyfftw.pyx":1431
- *             fftw_execute(self.__plan, input_pointer, output_pointer)
+      /* "pyfftw/pyfftw.pyx":950
+ *                 self._axes[n] = self._axes[n] + array_dimension
  * 
- * cdef void count_char(char c, void *counter_ptr):             # <<<<<<<<<<<<<<
- *     '''
- *     On every call, increment the derefenced counter_ptr.
+ *             if self._axes[n] >= array_dimension or self._axes[n] < 0:             # <<<<<<<<<<<<<<
+ *                 raise IndexError('Invalid axes: '
+ *                     'The axes list cannot contain invalid axes.')
  */
+    }
+  }
 
-static void __pyx_f_6pyfftw_6pyfftw_count_char(CYTHON_UNUSED char __pyx_v_c, void *__pyx_v_counter_ptr) {
-  __Pyx_RefNannyDeclarations
-  int *__pyx_t_1;
-  long __pyx_t_2;
-  __Pyx_RefNannySetupContext("count_char", 0);
-
-  /* "pyfftw/pyfftw.pyx":1435
- *     On every call, increment the derefenced counter_ptr.
- *     '''
- *     (<int *>counter_ptr)[0] += 1             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":958
+ *         cdef int64_t *not_axes
  * 
+ *         make_axes_unique(self._axes, len(axes), &unique_axes,             # <<<<<<<<<<<<<<
+ *                 &not_axes, array_dimension, &unique_axes_length)
  * 
  */
-  __pyx_t_1 = ((int *)__pyx_v_counter_ptr);
-  __pyx_t_2 = 0;
-  (__pyx_t_1[__pyx_t_2]) = ((__pyx_t_1[__pyx_t_2]) + 1);
+  __pyx_t_12 = PyObject_Length(__pyx_v_axes); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 958; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  __Pyx_RefNannyFinishContext();
-}
-
-/* "pyfftw/pyfftw.pyx":1438
+  /* "pyfftw/pyfftw.pyx":959
  * 
+ *         make_axes_unique(self._axes, len(axes), &unique_axes,
+ *                 &not_axes, array_dimension, &unique_axes_length)             # <<<<<<<<<<<<<<
  * 
- * cdef void write_char_to_string(char c, void *string_location_ptr):             # <<<<<<<<<<<<<<
- *     '''
- *     Write the passed character c to the memory location
+ *         # and assign axes and not_axes to the filled arrays
  */
+  __pyx_f_6pyfftw_6pyfftw_make_axes_unique(__pyx_v_self->_axes, __pyx_t_12, (&__pyx_v_unique_axes), (&__pyx_v_not_axes), __pyx_v_array_dimension, (&__pyx_v_unique_axes_length));
 
-static void __pyx_f_6pyfftw_6pyfftw_write_char_to_string(char __pyx_v_c, void *__pyx_v_string_location_ptr) {
-  char *__pyx_v_write_location;
-  __Pyx_RefNannyDeclarations
-  intptr_t *__pyx_t_1;
-  long __pyx_t_2;
-  __Pyx_RefNannySetupContext("write_char_to_string", 0);
-
-  /* "pyfftw/pyfftw.pyx":1452
- *     unallocated piece of memory, a segfault will likely occur.
- *     '''
- *     cdef char *write_location = <char *>((<intptr_t *>string_location_ptr)[0])             # <<<<<<<<<<<<<<
- *     write_location[0] = c
+  /* "pyfftw/pyfftw.pyx":962
  * 
+ *         # and assign axes and not_axes to the filled arrays
+ *         free(self._axes)             # <<<<<<<<<<<<<<
+ *         self._axes = unique_axes
+ *         self._not_axes = not_axes
  */
-  __pyx_v_write_location = ((char *)(((intptr_t *)__pyx_v_string_location_ptr)[0]));
+  free(__pyx_v_self->_axes);
 
-  /* "pyfftw/pyfftw.pyx":1453
- *     '''
- *     cdef char *write_location = <char *>((<intptr_t *>string_location_ptr)[0])
- *     write_location[0] = c             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":963
+ *         # and assign axes and not_axes to the filled arrays
+ *         free(self._axes)
+ *         self._axes = unique_axes             # <<<<<<<<<<<<<<
+ *         self._not_axes = not_axes
  * 
- *     (<intptr_t *>string_location_ptr)[0] += 1
  */
-  (__pyx_v_write_location[0]) = __pyx_v_c;
+  __pyx_v_self->_axes = __pyx_v_unique_axes;
 
-  /* "pyfftw/pyfftw.pyx":1455
- *     write_location[0] = c
- * 
- *     (<intptr_t *>string_location_ptr)[0] += 1             # <<<<<<<<<<<<<<
- * 
+  /* "pyfftw/pyfftw.pyx":964
+ *         free(self._axes)
+ *         self._axes = unique_axes
+ *         self._not_axes = not_axes             # <<<<<<<<<<<<<<
  * 
+ *         total_N = 1
  */
-  __pyx_t_1 = ((intptr_t *)__pyx_v_string_location_ptr);
-  __pyx_t_2 = 0;
-  (__pyx_t_1[__pyx_t_2]) = ((__pyx_t_1[__pyx_t_2]) + 1);
+  __pyx_v_self->_not_axes = __pyx_v_not_axes;
 
-  __Pyx_RefNannyFinishContext();
-}
-
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_11export_wisdom(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_10export_wisdom[] = "export_wisdom()\n\n    Return the FFTW wisdom as a tuple of strings.\n\n    The first string in the tuple is the string for the double\n    precision wisdom. The second string in the tuple is the string \n    for the single precision wisdom. The third string in the tuple \n    is the string for the long double precision wisdom.\n\n    The tuple that is returned from this function can be used as the\n    argument to :func:`~pyfftw [...]
-static PyMethodDef __pyx_mdef_6pyfftw_6pyfftw_11export_wisdom = {__Pyx_NAMESTR("export_wisdom"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_11export_wisdom, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_10export_wisdom)};
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_11export_wisdom(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("export_wisdom (wrapper)", 0);
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_10export_wisdom(__pyx_self);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pyfftw/pyfftw.pyx":1458
- * 
- * 
- * def export_wisdom():             # <<<<<<<<<<<<<<
- *     '''export_wisdom()
+  /* "pyfftw/pyfftw.pyx":966
+ *         self._not_axes = not_axes
  * 
+ *         total_N = 1             # <<<<<<<<<<<<<<
+ *         for n in range(unique_axes_length):
+ *             if self._input_shape[self._axes[n]] == 0:
  */
+  __Pyx_INCREF(__pyx_int_1);
+  __pyx_v_total_N = __pyx_int_1;
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_10export_wisdom(CYTHON_UNUSED PyObject *__pyx_self) {
-  PyObject *__pyx_v_py_wisdom = 0;
-  PyObject *__pyx_v_py_wisdomf = 0;
-  PyObject *__pyx_v_py_wisdoml = 0;
-  int __pyx_v_counter;
-  int __pyx_v_counterf;
-  int __pyx_v_counterl;
-  char *__pyx_v_c_wisdom;
-  char *__pyx_v_c_wisdomf;
-  char *__pyx_v_c_wisdoml;
-  intptr_t __pyx_v_c_wisdom_ptr;
-  intptr_t __pyx_v_c_wisdomf_ptr;
-  intptr_t __pyx_v_c_wisdoml_ptr;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  int __pyx_t_2;
-  int __pyx_t_3;
-  int __pyx_t_4;
-  PyObject *__pyx_t_5 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("export_wisdom", 0);
-
-  /* "pyfftw/pyfftw.pyx":1476
- *     cdef bytes py_wisdoml
+  /* "pyfftw/pyfftw.pyx":967
  * 
- *     cdef int counter = 0             # <<<<<<<<<<<<<<
- *     cdef int counterf = 0
- *     cdef int counterl = 0
+ *         total_N = 1
+ *         for n in range(unique_axes_length):             # <<<<<<<<<<<<<<
+ *             if self._input_shape[self._axes[n]] == 0:
+ *                 raise ValueError('Zero length array: '
  */
-  __pyx_v_counter = 0;
+  __pyx_t_17 = __pyx_v_unique_axes_length;
+  for (__pyx_t_12 = 0; __pyx_t_12 < __pyx_t_17; __pyx_t_12+=1) {
+    __pyx_v_n = __pyx_t_12;
 
-  /* "pyfftw/pyfftw.pyx":1477
- * 
- *     cdef int counter = 0
- *     cdef int counterf = 0             # <<<<<<<<<<<<<<
- *     cdef int counterl = 0
- * 
+    /* "pyfftw/pyfftw.pyx":968
+ *         total_N = 1
+ *         for n in range(unique_axes_length):
+ *             if self._input_shape[self._axes[n]] == 0:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Zero length array: '
+ *                     'The input array should have no zero length'
  */
-  __pyx_v_counterf = 0;
+    __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_self->_input_shape, (__pyx_v_self->_axes[__pyx_v_n]), int64_t, 1, __Pyx_PyInt_From_int64_t, 0, 1, 1); if (unlikely(__pyx_t_10 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_1 = __Pyx_PyInt_EqObjC(__pyx_t_10, __pyx_int_0, 0, 0); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 968; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_3) {
 
-  /* "pyfftw/pyfftw.pyx":1478
- *     cdef int counter = 0
- *     cdef int counterf = 0
- *     cdef int counterl = 0             # <<<<<<<<<<<<<<
- * 
- *     fftw_export_wisdom(&count_char, <void *>&counter)
+      /* "pyfftw/pyfftw.pyx":969
+ *         for n in range(unique_axes_length):
+ *             if self._input_shape[self._axes[n]] == 0:
+ *                 raise ValueError('Zero length array: '             # <<<<<<<<<<<<<<
+ *                     'The input array should have no zero length'
+ *                     'axes over which the FFT is to be taken')
  */
-  __pyx_v_counterl = 0;
+      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__14, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "pyfftw/pyfftw.pyx":1480
- *     cdef int counterl = 0
- * 
- *     fftw_export_wisdom(&count_char, <void *>&counter)             # <<<<<<<<<<<<<<
- *     fftwf_export_wisdom(&count_char, <void *>&counterf)
- *     fftwl_export_wisdom(&count_char, <void *>&counterl)
+      /* "pyfftw/pyfftw.pyx":968
+ *         total_N = 1
+ *         for n in range(unique_axes_length):
+ *             if self._input_shape[self._axes[n]] == 0:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Zero length array: '
+ *                     'The input array should have no zero length'
  */
-  fftw_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_count_char), ((void *)(&__pyx_v_counter)));
+    }
 
-  /* "pyfftw/pyfftw.pyx":1481
- * 
- *     fftw_export_wisdom(&count_char, <void *>&counter)
- *     fftwf_export_wisdom(&count_char, <void *>&counterf)             # <<<<<<<<<<<<<<
- *     fftwl_export_wisdom(&count_char, <void *>&counterl)
+    /* "pyfftw/pyfftw.pyx":973
+ *                     'axes over which the FFT is to be taken')
  * 
+ *             if self._direction == FFTW_FORWARD:             # <<<<<<<<<<<<<<
+ *                 total_N *= self._input_shape[self._axes[n]]
+ *             else:
  */
-  fftwf_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_count_char), ((void *)(&__pyx_v_counterf)));
+    __pyx_t_3 = ((__pyx_v_self->_direction == __pyx_e_6pyfftw_6pyfftw_FFTW_FORWARD) != 0);
+    if (__pyx_t_3) {
 
-  /* "pyfftw/pyfftw.pyx":1482
- *     fftw_export_wisdom(&count_char, <void *>&counter)
- *     fftwf_export_wisdom(&count_char, <void *>&counterf)
- *     fftwl_export_wisdom(&count_char, <void *>&counterl)             # <<<<<<<<<<<<<<
+      /* "pyfftw/pyfftw.pyx":974
  * 
- *     cdef char* c_wisdom = <char *>malloc(sizeof(char)*(counter + 1))
+ *             if self._direction == FFTW_FORWARD:
+ *                 total_N *= self._input_shape[self._axes[n]]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 total_N *= self._output_shape[self._axes[n]]
  */
-  fftwl_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_count_char), ((void *)(&__pyx_v_counterl)));
+      __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_self->_input_shape, (__pyx_v_self->_axes[__pyx_v_n]), int64_t, 1, __Pyx_PyInt_From_int64_t, 0, 1, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 974; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_1);
+      __pyx_t_10 = PyNumber_InPlaceMultiply(__pyx_v_total_N, __pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 974; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_DECREF_SET(__pyx_v_total_N, __pyx_t_10);
+      __pyx_t_10 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1484
- *     fftwl_export_wisdom(&count_char, <void *>&counterl)
+      /* "pyfftw/pyfftw.pyx":973
+ *                     'axes over which the FFT is to be taken')
  * 
- *     cdef char* c_wisdom = <char *>malloc(sizeof(char)*(counter + 1))             # <<<<<<<<<<<<<<
- *     cdef char* c_wisdomf = <char *>malloc(sizeof(char)*(counterf + 1))
- *     cdef char* c_wisdoml = <char *>malloc(sizeof(char)*(counterl + 1))
+ *             if self._direction == FFTW_FORWARD:             # <<<<<<<<<<<<<<
+ *                 total_N *= self._input_shape[self._axes[n]]
+ *             else:
  */
-  __pyx_v_c_wisdom = ((char *)malloc(((sizeof(char)) * (__pyx_v_counter + 1))));
+      goto __pyx_L49;
+    }
 
-  /* "pyfftw/pyfftw.pyx":1485
- * 
- *     cdef char* c_wisdom = <char *>malloc(sizeof(char)*(counter + 1))
- *     cdef char* c_wisdomf = <char *>malloc(sizeof(char)*(counterf + 1))             # <<<<<<<<<<<<<<
- *     cdef char* c_wisdoml = <char *>malloc(sizeof(char)*(counterl + 1))
+    /* "pyfftw/pyfftw.pyx":976
+ *                 total_N *= self._input_shape[self._axes[n]]
+ *             else:
+ *                 total_N *= self._output_shape[self._axes[n]]             # <<<<<<<<<<<<<<
  * 
+ *         self._N = total_N
  */
-  __pyx_v_c_wisdomf = ((char *)malloc(((sizeof(char)) * (__pyx_v_counterf + 1))));
+    /*else*/ {
+      __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_self->_output_shape, (__pyx_v_self->_axes[__pyx_v_n]), int64_t, 1, __Pyx_PyInt_From_int64_t, 0, 1, 1); if (unlikely(__pyx_t_10 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 976; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_t_1 = PyNumber_InPlaceMultiply(__pyx_v_total_N, __pyx_t_10); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 976; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_DECREF_SET(__pyx_v_total_N, __pyx_t_1);
+      __pyx_t_1 = 0;
+    }
+    __pyx_L49:;
+  }
 
-  /* "pyfftw/pyfftw.pyx":1486
- *     cdef char* c_wisdom = <char *>malloc(sizeof(char)*(counter + 1))
- *     cdef char* c_wisdomf = <char *>malloc(sizeof(char)*(counterf + 1))
- *     cdef char* c_wisdoml = <char *>malloc(sizeof(char)*(counterl + 1))             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":978
+ *                 total_N *= self._output_shape[self._axes[n]]
+ * 
+ *         self._N = total_N             # <<<<<<<<<<<<<<
+ *         self._normalisation_scaling = 1/float(self.N)
  * 
- *     if c_wisdom == NULL or c_wisdomf == NULL or c_wisdoml == NULL:
  */
-  __pyx_v_c_wisdoml = ((char *)malloc(((sizeof(char)) * (__pyx_v_counterl + 1))));
+  __pyx_t_17 = __Pyx_PyInt_As_int64_t(__pyx_v_total_N); if (unlikely((__pyx_t_17 == (int64_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->_N = __pyx_t_17;
 
-  /* "pyfftw/pyfftw.pyx":1488
- *     cdef char* c_wisdoml = <char *>malloc(sizeof(char)*(counterl + 1))
+  /* "pyfftw/pyfftw.pyx":979
  * 
- *     if c_wisdom == NULL or c_wisdomf == NULL or c_wisdoml == NULL:             # <<<<<<<<<<<<<<
- *         raise MemoryError
+ *         self._N = total_N
+ *         self._normalisation_scaling = 1/float(self.N)             # <<<<<<<<<<<<<<
  * 
+ *         # Now we can validate the array shapes
  */
-  __pyx_t_1 = (__pyx_v_c_wisdom == NULL);
-  if (!__pyx_t_1) {
-    __pyx_t_2 = (__pyx_v_c_wisdomf == NULL);
-    if (!__pyx_t_2) {
-      __pyx_t_3 = (__pyx_v_c_wisdoml == NULL);
-      __pyx_t_4 = __pyx_t_3;
-    } else {
-      __pyx_t_4 = __pyx_t_2;
-    }
-    __pyx_t_2 = __pyx_t_4;
-  } else {
-    __pyx_t_2 = __pyx_t_1;
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_N); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_7 = __Pyx_PyObject_AsDouble(__pyx_t_1); if (unlikely(__pyx_t_7 == ((double)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  if (unlikely(__pyx_t_7 == 0)) {
+    PyErr_SetString(PyExc_ZeroDivisionError, "float division");
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
-  if (__pyx_t_2) {
+  __pyx_v_self->_normalisation_scaling = (1.0 / __pyx_t_7);
 
-    /* "pyfftw/pyfftw.pyx":1489
- * 
- *     if c_wisdom == NULL or c_wisdomf == NULL or c_wisdoml == NULL:
- *         raise MemoryError             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":984
+ *         cdef validator _validator
  * 
- *     # Set the pointers to the string pointers
+ *         if functions['validator'] == -1:             # <<<<<<<<<<<<<<
+ *             if not (output_array.shape == input_array.shape):
+ *                 raise ValueError('Invalid shapes: '
  */
-    PyErr_NoMemory(); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
+  __pyx_t_1 = PyObject_GetItem(__pyx_v_functions, __pyx_n_s_validator); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_10 = __Pyx_PyInt_EqObjC(__pyx_t_1, __pyx_int_neg_1, -1L, 0); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_10); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 984; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  if (__pyx_t_3) {
 
-  /* "pyfftw/pyfftw.pyx":1492
+    /* "pyfftw/pyfftw.pyx":985
  * 
- *     # Set the pointers to the string pointers
- *     cdef intptr_t c_wisdom_ptr = <intptr_t>c_wisdom             # <<<<<<<<<<<<<<
- *     cdef intptr_t c_wisdomf_ptr = <intptr_t>c_wisdomf
- *     cdef intptr_t c_wisdoml_ptr = <intptr_t>c_wisdoml
+ *         if functions['validator'] == -1:
+ *             if not (output_array.shape == input_array.shape):             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Invalid shapes: '
+ *                         'The output array should be the same shape as the '
  */
-  __pyx_v_c_wisdom_ptr = ((intptr_t)__pyx_v_c_wisdom);
+    __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_array, __pyx_n_s_shape); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_array, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_9 = PyObject_RichCompare(__pyx_t_10, __pyx_t_1, Py_EQ); __Pyx_XGOTREF(__pyx_t_9); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    __pyx_t_3 = __Pyx_PyObject_IsTrue(__pyx_t_9); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 985; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_t_2 = ((!__pyx_t_3) != 0);
+    if (__pyx_t_2) {
 
-  /* "pyfftw/pyfftw.pyx":1493
- *     # Set the pointers to the string pointers
- *     cdef intptr_t c_wisdom_ptr = <intptr_t>c_wisdom
- *     cdef intptr_t c_wisdomf_ptr = <intptr_t>c_wisdomf             # <<<<<<<<<<<<<<
- *     cdef intptr_t c_wisdoml_ptr = <intptr_t>c_wisdoml
- * 
+      /* "pyfftw/pyfftw.pyx":986
+ *         if functions['validator'] == -1:
+ *             if not (output_array.shape == input_array.shape):
+ *                 raise ValueError('Invalid shapes: '             # <<<<<<<<<<<<<<
+ *                         'The output array should be the same shape as the '
+ *                         'input array for the given array dtypes.')
  */
-  __pyx_v_c_wisdomf_ptr = ((intptr_t)__pyx_v_c_wisdomf);
+      __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__15, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "pyfftw/pyfftw.pyx":1494
- *     cdef intptr_t c_wisdom_ptr = <intptr_t>c_wisdom
- *     cdef intptr_t c_wisdomf_ptr = <intptr_t>c_wisdomf
- *     cdef intptr_t c_wisdoml_ptr = <intptr_t>c_wisdoml             # <<<<<<<<<<<<<<
+      /* "pyfftw/pyfftw.pyx":985
  * 
- *     fftw_export_wisdom(&write_char_to_string, <void *>&c_wisdom_ptr)
+ *         if functions['validator'] == -1:
+ *             if not (output_array.shape == input_array.shape):             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Invalid shapes: '
+ *                         'The output array should be the same shape as the '
  */
-  __pyx_v_c_wisdoml_ptr = ((intptr_t)__pyx_v_c_wisdoml);
+    }
 
-  /* "pyfftw/pyfftw.pyx":1496
- *     cdef intptr_t c_wisdoml_ptr = <intptr_t>c_wisdoml
+    /* "pyfftw/pyfftw.pyx":984
+ *         cdef validator _validator
  * 
- *     fftw_export_wisdom(&write_char_to_string, <void *>&c_wisdom_ptr)             # <<<<<<<<<<<<<<
- *     fftwf_export_wisdom(&write_char_to_string, <void *>&c_wisdomf_ptr)
- *     fftwl_export_wisdom(&write_char_to_string, <void *>&c_wisdoml_ptr)
+ *         if functions['validator'] == -1:             # <<<<<<<<<<<<<<
+ *             if not (output_array.shape == input_array.shape):
+ *                 raise ValueError('Invalid shapes: '
  */
-  fftw_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_write_char_to_string), ((void *)(&__pyx_v_c_wisdom_ptr)));
+    goto __pyx_L50;
+  }
 
-  /* "pyfftw/pyfftw.pyx":1497
- * 
- *     fftw_export_wisdom(&write_char_to_string, <void *>&c_wisdom_ptr)
- *     fftwf_export_wisdom(&write_char_to_string, <void *>&c_wisdomf_ptr)             # <<<<<<<<<<<<<<
- *     fftwl_export_wisdom(&write_char_to_string, <void *>&c_wisdoml_ptr)
- * 
+  /* "pyfftw/pyfftw.pyx":990
+ *                         'input array for the given array dtypes.')
+ *         else:
+ *             _validator = validators[functions['validator']]             # <<<<<<<<<<<<<<
+ *             if not _validator(input_array, output_array,
+ *                     self._axes, self._not_axes, unique_axes_length):
  */
-  fftwf_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_write_char_to_string), ((void *)(&__pyx_v_c_wisdomf_ptr)));
+  /*else*/ {
+    __pyx_t_9 = PyObject_GetItem(__pyx_v_functions, __pyx_n_s_validator); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 990; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_12 = __Pyx_PyIndex_AsSsize_t(__pyx_t_9); if (unlikely((__pyx_t_12 == (Py_ssize_t)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __pyx_v__validator = (__pyx_v_6pyfftw_6pyfftw_validators[__pyx_t_12]);
 
-  /* "pyfftw/pyfftw.pyx":1498
- *     fftw_export_wisdom(&write_char_to_string, <void *>&c_wisdom_ptr)
- *     fftwf_export_wisdom(&write_char_to_string, <void *>&c_wisdomf_ptr)
- *     fftwl_export_wisdom(&write_char_to_string, <void *>&c_wisdoml_ptr)             # <<<<<<<<<<<<<<
- * 
- *     # Write the last byte as the null byte
+    /* "pyfftw/pyfftw.pyx":991
+ *         else:
+ *             _validator = validators[functions['validator']]
+ *             if not _validator(input_array, output_array,             # <<<<<<<<<<<<<<
+ *                     self._axes, self._not_axes, unique_axes_length):
+ *                 raise ValueError('Invalid shapes: '
  */
-  fftwl_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_write_char_to_string), ((void *)(&__pyx_v_c_wisdoml_ptr)));
+    if (!(likely(((__pyx_v_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!(likely(((__pyx_v_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 991; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "pyfftw/pyfftw.pyx":1501
- * 
- *     # Write the last byte as the null byte
- *     c_wisdom[counter] = 0             # <<<<<<<<<<<<<<
- *     c_wisdomf[counterf] = 0
- *     c_wisdoml[counterl] = 0
+    /* "pyfftw/pyfftw.pyx":992
+ *             _validator = validators[functions['validator']]
+ *             if not _validator(input_array, output_array,
+ *                     self._axes, self._not_axes, unique_axes_length):             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Invalid shapes: '
+ *                         'The input array and output array are invalid '
  */
-  (__pyx_v_c_wisdom[__pyx_v_counter]) = 0;
+    __pyx_t_2 = ((!(__pyx_v__validator(((PyArrayObject *)__pyx_v_input_array), ((PyArrayObject *)__pyx_v_output_array), __pyx_v_self->_axes, __pyx_v_self->_not_axes, __pyx_v_unique_axes_length) != 0)) != 0);
 
-  /* "pyfftw/pyfftw.pyx":1502
- *     # Write the last byte as the null byte
- *     c_wisdom[counter] = 0
- *     c_wisdomf[counterf] = 0             # <<<<<<<<<<<<<<
- *     c_wisdoml[counterl] = 0
- * 
+    /* "pyfftw/pyfftw.pyx":991
+ *         else:
+ *             _validator = validators[functions['validator']]
+ *             if not _validator(input_array, output_array,             # <<<<<<<<<<<<<<
+ *                     self._axes, self._not_axes, unique_axes_length):
+ *                 raise ValueError('Invalid shapes: '
  */
-  (__pyx_v_c_wisdomf[__pyx_v_counterf]) = 0;
+    if (__pyx_t_2) {
 
-  /* "pyfftw/pyfftw.pyx":1503
- *     c_wisdom[counter] = 0
- *     c_wisdomf[counterf] = 0
- *     c_wisdoml[counterl] = 0             # <<<<<<<<<<<<<<
- * 
- *     try:
+      /* "pyfftw/pyfftw.pyx":993
+ *             if not _validator(input_array, output_array,
+ *                     self._axes, self._not_axes, unique_axes_length):
+ *                 raise ValueError('Invalid shapes: '             # <<<<<<<<<<<<<<
+ *                         'The input array and output array are invalid '
+ *                         'complementary shapes for their dtypes.')
  */
-  (__pyx_v_c_wisdoml[__pyx_v_counterl]) = 0;
+      __pyx_t_9 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__16, NULL); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_9);
+      __Pyx_Raise(__pyx_t_9, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "pyfftw/pyfftw.pyx":1505
- *     c_wisdoml[counterl] = 0
- * 
- *     try:             # <<<<<<<<<<<<<<
- *         py_wisdom = c_wisdom
- *         py_wisdomf = c_wisdomf
+      /* "pyfftw/pyfftw.pyx":991
+ *         else:
+ *             _validator = validators[functions['validator']]
+ *             if not _validator(input_array, output_array,             # <<<<<<<<<<<<<<
+ *                     self._axes, self._not_axes, unique_axes_length):
+ *                 raise ValueError('Invalid shapes: '
  */
-  /*try:*/ {
+    }
+  }
+  __pyx_L50:;
 
-    /* "pyfftw/pyfftw.pyx":1506
+  /* "pyfftw/pyfftw.pyx":997
+ *                         'complementary shapes for their dtypes.')
  * 
- *     try:
- *         py_wisdom = c_wisdom             # <<<<<<<<<<<<<<
- *         py_wisdomf = c_wisdomf
- *         py_wisdoml = c_wisdoml
- */
-    __pyx_t_5 = PyBytes_FromString(__pyx_v_c_wisdom); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1506; __pyx_clineno = __LINE__; goto __pyx_L5;}
-    __Pyx_GOTREF(((PyObject *)__pyx_t_5));
-    __pyx_v_py_wisdom = __pyx_t_5;
-    __pyx_t_5 = 0;
-
-    /* "pyfftw/pyfftw.pyx":1507
- *     try:
- *         py_wisdom = c_wisdom
- *         py_wisdomf = c_wisdomf             # <<<<<<<<<<<<<<
- *         py_wisdoml = c_wisdoml
+ *         self._rank = unique_axes_length             # <<<<<<<<<<<<<<
+ *         self._howmany_rank = self._input_array.ndim - unique_axes_length
  * 
  */
-    __pyx_t_5 = PyBytes_FromString(__pyx_v_c_wisdomf); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1507; __pyx_clineno = __LINE__; goto __pyx_L5;}
-    __Pyx_GOTREF(((PyObject *)__pyx_t_5));
-    __pyx_v_py_wisdomf = __pyx_t_5;
-    __pyx_t_5 = 0;
+  __pyx_v_self->_rank = __pyx_v_unique_axes_length;
 
-    /* "pyfftw/pyfftw.pyx":1508
- *         py_wisdom = c_wisdom
- *         py_wisdomf = c_wisdomf
- *         py_wisdoml = c_wisdoml             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":998
  * 
- *     finally:
+ *         self._rank = unique_axes_length
+ *         self._howmany_rank = self._input_array.ndim - unique_axes_length             # <<<<<<<<<<<<<<
+ * 
+ *         self._flags = 0
  */
-    __pyx_t_5 = PyBytes_FromString(__pyx_v_c_wisdoml); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1508; __pyx_clineno = __LINE__; goto __pyx_L5;}
-    __Pyx_GOTREF(((PyObject *)__pyx_t_5));
-    __pyx_v_py_wisdoml = __pyx_t_5;
-    __pyx_t_5 = 0;
-  }
+  __pyx_v_self->_howmany_rank = (__pyx_v_self->_input_array->nd - __pyx_v_unique_axes_length);
 
-  /* "pyfftw/pyfftw.pyx":1511
+  /* "pyfftw/pyfftw.pyx":1000
+ *         self._howmany_rank = self._input_array.ndim - unique_axes_length
  * 
- *     finally:
- *         free(c_wisdom)             # <<<<<<<<<<<<<<
- *         free(c_wisdomf)
- *         free(c_wisdoml)
+ *         self._flags = 0             # <<<<<<<<<<<<<<
+ *         self._flags_used = []
+ *         for each_flag in flags:
  */
-  /*finally:*/ {
-    int __pyx_why;
-    PyObject *__pyx_exc_type, *__pyx_exc_value, *__pyx_exc_tb;
-    int __pyx_exc_lineno;
-    __pyx_exc_type = 0; __pyx_exc_value = 0; __pyx_exc_tb = 0; __pyx_exc_lineno = 0;
-    __pyx_why = 0; goto __pyx_L6;
-    __pyx_L5: {
-      __pyx_why = 4;
-      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __Pyx_ErrFetch(&__pyx_exc_type, &__pyx_exc_value, &__pyx_exc_tb);
-      __pyx_exc_lineno = __pyx_lineno;
-      goto __pyx_L6;
-    }
-    __pyx_L6:;
-    free(__pyx_v_c_wisdom);
+  __pyx_v_self->_flags = 0;
 
-    /* "pyfftw/pyfftw.pyx":1512
- *     finally:
- *         free(c_wisdom)
- *         free(c_wisdomf)             # <<<<<<<<<<<<<<
- *         free(c_wisdoml)
+  /* "pyfftw/pyfftw.pyx":1001
  * 
+ *         self._flags = 0
+ *         self._flags_used = []             # <<<<<<<<<<<<<<
+ *         for each_flag in flags:
+ *             try:
  */
-    free(__pyx_v_c_wisdomf);
+  __pyx_t_9 = PyList_New(0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1001; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __Pyx_GIVEREF(__pyx_t_9);
+  __Pyx_GOTREF(__pyx_v_self->_flags_used);
+  __Pyx_DECREF(__pyx_v_self->_flags_used);
+  __pyx_v_self->_flags_used = __pyx_t_9;
+  __pyx_t_9 = 0;
 
-    /* "pyfftw/pyfftw.pyx":1513
- *         free(c_wisdom)
- *         free(c_wisdomf)
- *         free(c_wisdoml)             # <<<<<<<<<<<<<<
- * 
- *     return (py_wisdom, py_wisdomf, py_wisdoml)
+  /* "pyfftw/pyfftw.pyx":1002
+ *         self._flags = 0
+ *         self._flags_used = []
+ *         for each_flag in flags:             # <<<<<<<<<<<<<<
+ *             try:
+ *                 self._flags |= flag_dict[each_flag]
  */
-    free(__pyx_v_c_wisdoml);
-    switch (__pyx_why) {
-      case 4: {
-        __Pyx_ErrRestore(__pyx_exc_type, __pyx_exc_value, __pyx_exc_tb);
-        __pyx_lineno = __pyx_exc_lineno;
-        __pyx_exc_type = 0;
-        __pyx_exc_value = 0;
-        __pyx_exc_tb = 0;
-        goto __pyx_L1_error;
+  if (likely(PyList_CheckExact(__pyx_v_flags)) || PyTuple_CheckExact(__pyx_v_flags)) {
+    __pyx_t_9 = __pyx_v_flags; __Pyx_INCREF(__pyx_t_9); __pyx_t_12 = 0;
+    __pyx_t_13 = NULL;
+  } else {
+    __pyx_t_12 = -1; __pyx_t_9 = PyObject_GetIter(__pyx_v_flags); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_13 = Py_TYPE(__pyx_t_9)->tp_iternext; if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  for (;;) {
+    if (likely(!__pyx_t_13)) {
+      if (likely(PyList_CheckExact(__pyx_t_9))) {
+        if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_9)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_9, __pyx_t_12); __Pyx_INCREF(__pyx_t_1); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_9, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        #endif
+      } else {
+        if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_9)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_9, __pyx_t_12); __Pyx_INCREF(__pyx_t_1); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_9, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        #endif
       }
+    } else {
+      __pyx_t_1 = __pyx_t_13(__pyx_t_9);
+      if (unlikely(!__pyx_t_1)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1002; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_1);
     }
-  }
+    __Pyx_XDECREF_SET(__pyx_v_each_flag, __pyx_t_1);
+    __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1515
- *         free(c_wisdoml)
- * 
- *     return (py_wisdom, py_wisdomf, py_wisdoml)             # <<<<<<<<<<<<<<
- * 
- * def import_wisdom(wisdom):
+    /* "pyfftw/pyfftw.pyx":1003
+ *         self._flags_used = []
+ *         for each_flag in flags:
+ *             try:             # <<<<<<<<<<<<<<
+ *                 self._flags |= flag_dict[each_flag]
+ *                 self._flags_used.append(each_flag)
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  __Pyx_INCREF(((PyObject *)__pyx_v_py_wisdom));
-  PyTuple_SET_ITEM(__pyx_t_5, 0, ((PyObject *)__pyx_v_py_wisdom));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_py_wisdom));
-  __Pyx_INCREF(((PyObject *)__pyx_v_py_wisdomf));
-  PyTuple_SET_ITEM(__pyx_t_5, 1, ((PyObject *)__pyx_v_py_wisdomf));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_py_wisdomf));
-  __Pyx_INCREF(((PyObject *)__pyx_v_py_wisdoml));
-  PyTuple_SET_ITEM(__pyx_t_5, 2, ((PyObject *)__pyx_v_py_wisdoml));
-  __Pyx_GIVEREF(((PyObject *)__pyx_v_py_wisdoml));
-  __pyx_r = ((PyObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-  goto __pyx_L0;
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pyfftw.pyfftw.export_wisdom", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XDECREF(__pyx_v_py_wisdom);
-  __Pyx_XDECREF(__pyx_v_py_wisdomf);
-  __Pyx_XDECREF(__pyx_v_py_wisdoml);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_13import_wisdom(PyObject *__pyx_self, PyObject *__pyx_v_wisdom); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_12import_wisdom[] = "import_wisdom(wisdom)\n\n    Function that imports wisdom from the passed tuple\n    of strings.\n\n    The first string in the tuple is the string for the double\n    precision wisdom. The second string in the tuple is the string \n    for the single precision wisdom. The third string in the tuple \n    is the string for the long double precision wisdom.\n\n    The tuple that is returned from :func:`~pyfftw.export_wisdom`\n    c [...]
-static PyMethodDef __pyx_mdef_6pyfftw_6pyfftw_13import_wisdom = {__Pyx_NAMESTR("import_wisdom"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_13import_wisdom, METH_O, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_12import_wisdom)};
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_13import_wisdom(PyObject *__pyx_self, PyObject *__pyx_v_wisdom) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("import_wisdom (wrapper)", 0);
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_12import_wisdom(__pyx_self, ((PyObject *)__pyx_v_wisdom));
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+    {
+      __Pyx_ExceptionSave(&__pyx_t_4, &__pyx_t_5, &__pyx_t_6);
+      __Pyx_XGOTREF(__pyx_t_4);
+      __Pyx_XGOTREF(__pyx_t_5);
+      __Pyx_XGOTREF(__pyx_t_6);
+      /*try:*/ {
 
-/* "pyfftw/pyfftw.pyx":1517
- *     return (py_wisdom, py_wisdomf, py_wisdoml)
- * 
- * def import_wisdom(wisdom):             # <<<<<<<<<<<<<<
- *     '''import_wisdom(wisdom)
- * 
+        /* "pyfftw/pyfftw.pyx":1004
+ *         for each_flag in flags:
+ *             try:
+ *                 self._flags |= flag_dict[each_flag]             # <<<<<<<<<<<<<<
+ *                 self._flags_used.append(each_flag)
+ *             except KeyError:
  */
+        __pyx_t_1 = __Pyx_PyInt_From_unsigned_int(__pyx_v_self->_flags); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L55_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        __pyx_t_10 = PyObject_GetItem(__pyx_v_6pyfftw_6pyfftw_flag_dict, __pyx_v_each_flag); if (unlikely(__pyx_t_10 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L55_error;};
+        __Pyx_GOTREF(__pyx_t_10);
+        __pyx_t_11 = PyNumber_InPlaceOr(__pyx_t_1, __pyx_t_10); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L55_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+        __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+        __pyx_t_18 = __Pyx_PyInt_As_unsigned_int(__pyx_t_11); if (unlikely((__pyx_t_18 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1004; __pyx_clineno = __LINE__; goto __pyx_L55_error;}
+        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+        __pyx_v_self->_flags = __pyx_t_18;
 
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_12import_wisdom(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_wisdom) {
-  char *__pyx_v_c_wisdom;
-  char *__pyx_v_c_wisdomf;
-  char *__pyx_v_c_wisdoml;
-  int __pyx_v_success;
-  int __pyx_v_successf;
-  int __pyx_v_successl;
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  char *__pyx_t_2;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("import_wisdom", 0);
-
-  /* "pyfftw/pyfftw.pyx":1536
- *     '''
- * 
- *     cdef char* c_wisdom = wisdom[0]             # <<<<<<<<<<<<<<
- *     cdef char* c_wisdomf = wisdom[1]
- *     cdef char* c_wisdoml = wisdom[2]
+        /* "pyfftw/pyfftw.pyx":1005
+ *             try:
+ *                 self._flags |= flag_dict[each_flag]
+ *                 self._flags_used.append(each_flag)             # <<<<<<<<<<<<<<
+ *             except KeyError:
+ *                 raise ValueError('Invalid flag: ' + '\'' +
  */
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_wisdom, 0, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyBytes_AsString(__pyx_t_1); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_v_c_wisdom = __pyx_t_2;
+        __pyx_t_14 = __Pyx_PyObject_Append(__pyx_v_self->_flags_used, __pyx_v_each_flag); if (unlikely(__pyx_t_14 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L55_error;}
 
-  /* "pyfftw/pyfftw.pyx":1537
- * 
- *     cdef char* c_wisdom = wisdom[0]
- *     cdef char* c_wisdomf = wisdom[1]             # <<<<<<<<<<<<<<
- *     cdef char* c_wisdoml = wisdom[2]
- * 
+        /* "pyfftw/pyfftw.pyx":1003
+ *         self._flags_used = []
+ *         for each_flag in flags:
+ *             try:             # <<<<<<<<<<<<<<
+ *                 self._flags |= flag_dict[each_flag]
+ *                 self._flags_used.append(each_flag)
  */
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_wisdom, 1, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1537; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyBytes_AsString(__pyx_t_1); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1537; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_v_c_wisdomf = __pyx_t_2;
+      }
+      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
+      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
+      goto __pyx_L62_try_end;
+      __pyx_L55_error:;
+      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1538
- *     cdef char* c_wisdom = wisdom[0]
- *     cdef char* c_wisdomf = wisdom[1]
- *     cdef char* c_wisdoml = wisdom[2]             # <<<<<<<<<<<<<<
- * 
- *     cdef bint success = fftw_import_wisdom_from_string(c_wisdom)
+      /* "pyfftw/pyfftw.pyx":1006
+ *                 self._flags |= flag_dict[each_flag]
+ *                 self._flags_used.append(each_flag)
+ *             except KeyError:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Invalid flag: ' + '\'' +
+ *                         each_flag + '\' is not a valid planner flag.')
  */
-  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_wisdom, 2, sizeof(long), PyInt_FromLong); if (!__pyx_t_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyBytes_AsString(__pyx_t_1); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1538; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_v_c_wisdoml = __pyx_t_2;
+      __pyx_t_8 = PyErr_ExceptionMatches(__pyx_builtin_KeyError);
+      if (__pyx_t_8) {
+        __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+        if (__Pyx_GetException(&__pyx_t_11, &__pyx_t_10, &__pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L57_except_error;}
+        __Pyx_GOTREF(__pyx_t_11);
+        __Pyx_GOTREF(__pyx_t_10);
+        __Pyx_GOTREF(__pyx_t_1);
 
-  /* "pyfftw/pyfftw.pyx":1540
- *     cdef char* c_wisdoml = wisdom[2]
+        /* "pyfftw/pyfftw.pyx":1007
+ *                 self._flags_used.append(each_flag)
+ *             except KeyError:
+ *                 raise ValueError('Invalid flag: ' + '\'' +             # <<<<<<<<<<<<<<
+ *                         each_flag + '\' is not a valid planner flag.')
  * 
- *     cdef bint success = fftw_import_wisdom_from_string(c_wisdom)             # <<<<<<<<<<<<<<
- *     cdef bint successf = fftwf_import_wisdom_from_string(c_wisdomf)
- *     cdef bint successl = fftwl_import_wisdom_from_string(c_wisdoml)
  */
-  __pyx_v_success = fftw_import_wisdom_from_string(__pyx_v_c_wisdom);
+        __pyx_t_19 = PyNumber_Add(__pyx_kp_s_Invalid_flag, __pyx_kp_s__17); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L57_except_error;}
+        __Pyx_GOTREF(__pyx_t_19);
 
-  /* "pyfftw/pyfftw.pyx":1541
+        /* "pyfftw/pyfftw.pyx":1008
+ *             except KeyError:
+ *                 raise ValueError('Invalid flag: ' + '\'' +
+ *                         each_flag + '\' is not a valid planner flag.')             # <<<<<<<<<<<<<<
  * 
- *     cdef bint success = fftw_import_wisdom_from_string(c_wisdom)
- *     cdef bint successf = fftwf_import_wisdom_from_string(c_wisdomf)             # <<<<<<<<<<<<<<
- *     cdef bint successl = fftwl_import_wisdom_from_string(c_wisdoml)
  * 
  */
-  __pyx_v_successf = fftwf_import_wisdom_from_string(__pyx_v_c_wisdomf);
+        __pyx_t_20 = PyNumber_Add(__pyx_t_19, __pyx_v_each_flag); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L57_except_error;}
+        __Pyx_GOTREF(__pyx_t_20);
+        __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+        __pyx_t_19 = PyNumber_Add(__pyx_t_20, __pyx_kp_s_is_not_a_valid_planner_flag); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L57_except_error;}
+        __Pyx_GOTREF(__pyx_t_19);
+        __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1542
- *     cdef bint success = fftw_import_wisdom_from_string(c_wisdom)
- *     cdef bint successf = fftwf_import_wisdom_from_string(c_wisdomf)
- *     cdef bint successl = fftwl_import_wisdom_from_string(c_wisdoml)             # <<<<<<<<<<<<<<
+        /* "pyfftw/pyfftw.pyx":1007
+ *                 self._flags_used.append(each_flag)
+ *             except KeyError:
+ *                 raise ValueError('Invalid flag: ' + '\'' +             # <<<<<<<<<<<<<<
+ *                         each_flag + '\' is not a valid planner flag.')
  * 
- *     return (success, successf, successl)
  */
-  __pyx_v_successl = fftwl_import_wisdom_from_string(__pyx_v_c_wisdoml);
+        __pyx_t_20 = PyTuple_New(1); if (unlikely(!__pyx_t_20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L57_except_error;}
+        __Pyx_GOTREF(__pyx_t_20);
+        __Pyx_GIVEREF(__pyx_t_19);
+        PyTuple_SET_ITEM(__pyx_t_20, 0, __pyx_t_19);
+        __pyx_t_19 = 0;
+        __pyx_t_19 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_20, NULL); if (unlikely(!__pyx_t_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L57_except_error;}
+        __Pyx_GOTREF(__pyx_t_19);
+        __Pyx_DECREF(__pyx_t_20); __pyx_t_20 = 0;
+        __Pyx_Raise(__pyx_t_19, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_19); __pyx_t_19 = 0;
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L57_except_error;}
+      }
+      goto __pyx_L57_except_error;
+      __pyx_L57_except_error:;
 
-  /* "pyfftw/pyfftw.pyx":1544
- *     cdef bint successl = fftwl_import_wisdom_from_string(c_wisdoml)
- * 
- *     return (success, successf, successl)             # <<<<<<<<<<<<<<
- * 
- * #def export_wisdom_to_files(
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_success); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_successf); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_successl); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_5);
-  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_3);
-  __Pyx_GIVEREF(__pyx_t_3);
-  PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_4);
-  __Pyx_GIVEREF(__pyx_t_4);
-  __pyx_t_1 = 0;
-  __pyx_t_3 = 0;
-  __pyx_t_4 = 0;
-  __pyx_r = ((PyObject *)__pyx_t_5);
-  __pyx_t_5 = 0;
-  goto __pyx_L0;
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("pyfftw.pyfftw.import_wisdom", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = NULL;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* Python wrapper */
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_15forget_wisdom(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused); /*proto*/
-static char __pyx_doc_6pyfftw_6pyfftw_14forget_wisdom[] = "forget_wisdom()\n\n    Forget all the accumulated wisdom.\n    ";
-static PyMethodDef __pyx_mdef_6pyfftw_6pyfftw_15forget_wisdom = {__Pyx_NAMESTR("forget_wisdom"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_15forget_wisdom, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_14forget_wisdom)};
-static PyObject *__pyx_pw_6pyfftw_6pyfftw_15forget_wisdom(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused) {
-  PyObject *__pyx_r = 0;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("forget_wisdom (wrapper)", 0);
-  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_14forget_wisdom(__pyx_self);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "pyfftw/pyfftw.pyx":1633
- * #    return (success, successf, successl)
- * 
- * def forget_wisdom():             # <<<<<<<<<<<<<<
- *     '''forget_wisdom()
- * 
- */
-
-static PyObject *__pyx_pf_6pyfftw_6pyfftw_14forget_wisdom(CYTHON_UNUSED PyObject *__pyx_self) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("forget_wisdom", 0);
-
-  /* "pyfftw/pyfftw.pyx":1638
- *     Forget all the accumulated wisdom.
- *     '''
- *     fftw_forget_wisdom()             # <<<<<<<<<<<<<<
- *     fftwf_forget_wisdom()
- *     fftwl_forget_wisdom()
+      /* "pyfftw/pyfftw.pyx":1003
+ *         self._flags_used = []
+ *         for each_flag in flags:
+ *             try:             # <<<<<<<<<<<<<<
+ *                 self._flags |= flag_dict[each_flag]
+ *                 self._flags_used.append(each_flag)
  */
-  fftw_forget_wisdom();
+      __Pyx_XGIVEREF(__pyx_t_4);
+      __Pyx_XGIVEREF(__pyx_t_5);
+      __Pyx_XGIVEREF(__pyx_t_6);
+      __Pyx_ExceptionReset(__pyx_t_4, __pyx_t_5, __pyx_t_6);
+      goto __pyx_L1_error;
+      __pyx_L62_try_end:;
+    }
 
-  /* "pyfftw/pyfftw.pyx":1639
- *     '''
- *     fftw_forget_wisdom()
- *     fftwf_forget_wisdom()             # <<<<<<<<<<<<<<
- *     fftwl_forget_wisdom()
- * 
+    /* "pyfftw/pyfftw.pyx":1002
+ *         self._flags = 0
+ *         self._flags_used = []
+ *         for each_flag in flags:             # <<<<<<<<<<<<<<
+ *             try:
+ *                 self._flags |= flag_dict[each_flag]
  */
-  fftwf_forget_wisdom();
+  }
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1640
- *     fftw_forget_wisdom()
- *     fftwf_forget_wisdom()
- *     fftwl_forget_wisdom()             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1011
  * 
  * 
+ *         if ('FFTW_DESTROY_INPUT' not in flags) and (             # <<<<<<<<<<<<<<
+ *                 (scheme[0] != 'c2r') or not self._rank > 1):
+ *             # The default in all possible cases is to preserve the input
  */
-  fftwl_forget_wisdom();
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* Python wrapper */
-static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
-static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
-  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-
-/* "numpy.pxd":194
- *         # experimental exception made for __getbuffer__ and __releasebuffer__
- *         # -- the details of this may change.
- *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
- *             # This implementation of getbuffer is geared towards Cython
- *             # requirements, and does not yet fullfill the PEP.
- */
-
-static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
-  int __pyx_v_copy_shape;
-  int __pyx_v_i;
-  int __pyx_v_ndim;
-  int __pyx_v_endian_detector;
-  int __pyx_v_little_endian;
-  int __pyx_v_t;
-  char *__pyx_v_f;
-  PyArray_Descr *__pyx_v_descr = 0;
-  int __pyx_v_offset;
-  int __pyx_v_hasfields;
-  int __pyx_r;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  int __pyx_t_2;
-  int __pyx_t_3;
-  PyObject *__pyx_t_4 = NULL;
-  int __pyx_t_5;
-  int __pyx_t_6;
-  int __pyx_t_7;
-  PyObject *__pyx_t_8 = NULL;
-  char *__pyx_t_9;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("__getbuffer__", 0);
-  if (__pyx_v_info != NULL) {
-    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
-    __Pyx_GIVEREF(__pyx_v_info->obj);
+  __pyx_t_3 = (__Pyx_PySequence_ContainsTF(__pyx_n_s_FFTW_DESTROY_INPUT, __pyx_v_flags, Py_NE)); if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_21 = (__pyx_t_3 != 0);
+  if (__pyx_t_21) {
+  } else {
+    __pyx_t_2 = __pyx_t_21;
+    goto __pyx_L66_bool_binop_done;
   }
 
-  /* "numpy.pxd":200
- *             # of flags
- * 
- *             if info == NULL: return             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1012
  * 
- *             cdef int copy_shape, i, ndim
+ *         if ('FFTW_DESTROY_INPUT' not in flags) and (
+ *                 (scheme[0] != 'c2r') or not self._rank > 1):             # <<<<<<<<<<<<<<
+ *             # The default in all possible cases is to preserve the input
+ *             # This is not possible for r2c arrays with rank > 1
  */
-  __pyx_t_1 = (__pyx_v_info == NULL);
-  if (__pyx_t_1) {
-    __pyx_r = 0;
-    goto __pyx_L0;
-    goto __pyx_L3;
+  __pyx_t_9 = __Pyx_GetItemInt(__pyx_v_scheme, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_9);
+  __pyx_t_21 = (__Pyx_PyString_Equals(__pyx_t_9, __pyx_n_s_c2r, Py_NE)); if (unlikely(__pyx_t_21 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  if (!__pyx_t_21) {
+  } else {
+    __pyx_t_2 = __pyx_t_21;
+    goto __pyx_L66_bool_binop_done;
   }
-  __pyx_L3:;
+  __pyx_t_21 = ((!((__pyx_v_self->_rank > 1) != 0)) != 0);
+  __pyx_t_2 = __pyx_t_21;
+  __pyx_L66_bool_binop_done:;
 
-  /* "numpy.pxd":203
+  /* "pyfftw/pyfftw.pyx":1011
  * 
- *             cdef int copy_shape, i, ndim
- *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
- *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
  * 
+ *         if ('FFTW_DESTROY_INPUT' not in flags) and (             # <<<<<<<<<<<<<<
+ *                 (scheme[0] != 'c2r') or not self._rank > 1):
+ *             # The default in all possible cases is to preserve the input
  */
-  __pyx_v_endian_detector = 1;
+  if (__pyx_t_2) {
 
-  /* "numpy.pxd":204
- *             cdef int copy_shape, i, ndim
- *             cdef int endian_detector = 1
- *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":1015
+ *             # The default in all possible cases is to preserve the input
+ *             # This is not possible for r2c arrays with rank > 1
+ *             self._flags |= FFTW_PRESERVE_INPUT             # <<<<<<<<<<<<<<
  * 
- *             ndim = PyArray_NDIM(self)
+ *         # Set up the arrays of structs for holding the stride shape
  */
-  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+    __pyx_v_self->_flags = (__pyx_v_self->_flags | __pyx_e_6pyfftw_6pyfftw_FFTW_PRESERVE_INPUT);
 
-  /* "numpy.pxd":206
- *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+    /* "pyfftw/pyfftw.pyx":1011
  * 
- *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
  * 
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *         if ('FFTW_DESTROY_INPUT' not in flags) and (             # <<<<<<<<<<<<<<
+ *                 (scheme[0] != 'c2r') or not self._rank > 1):
+ *             # The default in all possible cases is to preserve the input
  */
-  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+  }
 
-  /* "numpy.pxd":208
- *             ndim = PyArray_NDIM(self)
- * 
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
- *                 copy_shape = 1
- *             else:
+  /* "pyfftw/pyfftw.pyx":1019
+ *         # Set up the arrays of structs for holding the stride shape
+ *         # information
+ *         self._dims = <_fftw_iodim *>malloc(             # <<<<<<<<<<<<<<
+ *                 self._rank * sizeof(_fftw_iodim))
+ *         self._howmany_dims = <_fftw_iodim *>malloc(
  */
-  __pyx_t_1 = ((sizeof(npy_intp)) != (sizeof(Py_ssize_t)));
-  if (__pyx_t_1) {
+  __pyx_v_self->_dims = ((__pyx_t_6pyfftw_6pyfftw__fftw_iodim *)malloc((__pyx_v_self->_rank * (sizeof(__pyx_t_6pyfftw_6pyfftw__fftw_iodim)))));
 
-    /* "numpy.pxd":209
+  /* "pyfftw/pyfftw.pyx":1021
+ *         self._dims = <_fftw_iodim *>malloc(
+ *                 self._rank * sizeof(_fftw_iodim))
+ *         self._howmany_dims = <_fftw_iodim *>malloc(             # <<<<<<<<<<<<<<
+ *                 self._howmany_rank * sizeof(_fftw_iodim))
  * 
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
- *                 copy_shape = 1             # <<<<<<<<<<<<<<
- *             else:
- *                 copy_shape = 0
  */
-    __pyx_v_copy_shape = 1;
-    goto __pyx_L4;
-  }
-  /*else*/ {
+  __pyx_v_self->_howmany_dims = ((__pyx_t_6pyfftw_6pyfftw__fftw_iodim *)malloc((__pyx_v_self->_howmany_rank * (sizeof(__pyx_t_6pyfftw_6pyfftw__fftw_iodim)))));
 
-    /* "numpy.pxd":211
- *                 copy_shape = 1
- *             else:
- *                 copy_shape = 0             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1024
+ *                 self._howmany_rank * sizeof(_fftw_iodim))
  * 
- *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *         if self._dims == NULL or self._howmany_dims == NULL:             # <<<<<<<<<<<<<<
+ *             # Not much else to do than raise an exception
+ *             raise MemoryError
  */
-    __pyx_v_copy_shape = 0;
+  __pyx_t_21 = ((__pyx_v_self->_dims == NULL) != 0);
+  if (!__pyx_t_21) {
+  } else {
+    __pyx_t_2 = __pyx_t_21;
+    goto __pyx_L70_bool_binop_done;
   }
-  __pyx_L4:;
+  __pyx_t_21 = ((__pyx_v_self->_howmany_dims == NULL) != 0);
+  __pyx_t_2 = __pyx_t_21;
+  __pyx_L70_bool_binop_done:;
+  if (__pyx_t_2) {
 
-  /* "numpy.pxd":213
- *                 copy_shape = 0
+    /* "pyfftw/pyfftw.pyx":1026
+ *         if self._dims == NULL or self._howmany_dims == NULL:
+ *             # Not much else to do than raise an exception
+ *             raise MemoryError             # <<<<<<<<<<<<<<
  * 
- *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
- *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not C contiguous")
+ *         # Find the strides for all the axes of both arrays in terms of the
  */
-  __pyx_t_1 = ((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS);
-  if (__pyx_t_1) {
+    PyErr_NoMemory(); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-    /* "numpy.pxd":214
- * 
- *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
- *                 raise ValueError(u"ndarray is not C contiguous")
+    /* "pyfftw/pyfftw.pyx":1024
+ *                 self._howmany_rank * sizeof(_fftw_iodim))
  * 
+ *         if self._dims == NULL or self._howmany_dims == NULL:             # <<<<<<<<<<<<<<
+ *             # Not much else to do than raise an exception
+ *             raise MemoryError
  */
-    __pyx_t_2 = (!PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS));
-    __pyx_t_3 = __pyx_t_2;
-  } else {
-    __pyx_t_3 = __pyx_t_1;
   }
-  if (__pyx_t_3) {
 
-    /* "numpy.pxd":215
- *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
- * 
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+  /* "pyfftw/pyfftw.pyx":1030
+ *         # Find the strides for all the axes of both arrays in terms of the
+ *         # number of items (as opposed to the number of bytes).
+ *         self._input_strides = input_array.strides             # <<<<<<<<<<<<<<
+ *         self._input_item_strides = tuple([stride/input_array.itemsize
+ *             for stride in input_array.strides])
  */
-    __pyx_t_4 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_61), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    {__pyx_filename = __pyx_f[2]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L5;
-  }
-  __pyx_L5:;
+  __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_array, __pyx_n_s_strides); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  __Pyx_GIVEREF(__pyx_t_9);
+  __Pyx_GOTREF(__pyx_v_self->_input_strides);
+  __Pyx_DECREF(__pyx_v_self->_input_strides);
+  __pyx_v_self->_input_strides = __pyx_t_9;
+  __pyx_t_9 = 0;
 
-  /* "numpy.pxd":217
- *                 raise ValueError(u"ndarray is not C contiguous")
- * 
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
- *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not Fortran contiguous")
+  /* "pyfftw/pyfftw.pyx":1031
+ *         # number of items (as opposed to the number of bytes).
+ *         self._input_strides = input_array.strides
+ *         self._input_item_strides = tuple([stride/input_array.itemsize             # <<<<<<<<<<<<<<
+ *             for stride in input_array.strides])
+ *         self._output_strides = output_array.strides
  */
-  __pyx_t_3 = ((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS);
-  if (__pyx_t_3) {
+  __pyx_t_9 = PyList_New(0); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
 
-    /* "numpy.pxd":218
- * 
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
- *                 raise ValueError(u"ndarray is not Fortran contiguous")
- * 
+  /* "pyfftw/pyfftw.pyx":1032
+ *         self._input_strides = input_array.strides
+ *         self._input_item_strides = tuple([stride/input_array.itemsize
+ *             for stride in input_array.strides])             # <<<<<<<<<<<<<<
+ *         self._output_strides = output_array.strides
+ *         self._output_item_strides = tuple([stride/output_array.itemsize
  */
-    __pyx_t_1 = (!PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS));
-    __pyx_t_2 = __pyx_t_1;
-  } else {
-    __pyx_t_2 = __pyx_t_3;
-  }
-  if (__pyx_t_2) {
-
-    /* "numpy.pxd":219
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
- * 
- *             info.buf = PyArray_DATA(self)
- */
-    __pyx_t_4 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_63), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __Pyx_Raise(__pyx_t_4, 0, 0, 0);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    {__pyx_filename = __pyx_f[2]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    goto __pyx_L6;
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_array, __pyx_n_s_strides); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
+    __pyx_t_10 = __pyx_t_1; __Pyx_INCREF(__pyx_t_10); __pyx_t_12 = 0;
+    __pyx_t_13 = NULL;
+  } else {
+    __pyx_t_12 = -1; __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_13 = Py_TYPE(__pyx_t_10)->tp_iternext; if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   }
-  __pyx_L6:;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_13)) {
+      if (likely(PyList_CheckExact(__pyx_t_10))) {
+        if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_10)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_10, __pyx_t_12); __Pyx_INCREF(__pyx_t_1); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_10, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        #endif
+      } else {
+        if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_10)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_10, __pyx_t_12); __Pyx_INCREF(__pyx_t_1); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_1 = PySequence_ITEM(__pyx_t_10, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_1);
+        #endif
+      }
+    } else {
+      __pyx_t_1 = __pyx_t_13(__pyx_t_10);
+      if (unlikely(!__pyx_t_1)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1032; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_1);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_stride, __pyx_t_1);
+    __pyx_t_1 = 0;
 
-  /* "numpy.pxd":221
- *                 raise ValueError(u"ndarray is not Fortran contiguous")
- * 
- *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
- *             info.ndim = ndim
- *             if copy_shape:
+    /* "pyfftw/pyfftw.pyx":1031
+ *         # number of items (as opposed to the number of bytes).
+ *         self._input_strides = input_array.strides
+ *         self._input_item_strides = tuple([stride/input_array.itemsize             # <<<<<<<<<<<<<<
+ *             for stride in input_array.strides])
+ *         self._output_strides = output_array.strides
  */
-  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_array, __pyx_n_s_itemsize); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_11 = __Pyx_PyNumber_Divide(__pyx_v_stride, __pyx_t_1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_11);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (unlikely(__Pyx_ListComp_Append(__pyx_t_9, (PyObject*)__pyx_t_11))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-  /* "numpy.pxd":222
- * 
- *             info.buf = PyArray_DATA(self)
- *             info.ndim = ndim             # <<<<<<<<<<<<<<
- *             if copy_shape:
- *                 # Allocate new buffer for strides and shape info.
+    /* "pyfftw/pyfftw.pyx":1032
+ *         self._input_strides = input_array.strides
+ *         self._input_item_strides = tuple([stride/input_array.itemsize
+ *             for stride in input_array.strides])             # <<<<<<<<<<<<<<
+ *         self._output_strides = output_array.strides
+ *         self._output_item_strides = tuple([stride/output_array.itemsize
  */
-  __pyx_v_info->ndim = __pyx_v_ndim;
+  }
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-  /* "numpy.pxd":223
- *             info.buf = PyArray_DATA(self)
- *             info.ndim = ndim
- *             if copy_shape:             # <<<<<<<<<<<<<<
- *                 # Allocate new buffer for strides and shape info.
- *                 # This is allocated as one block, strides first.
+  /* "pyfftw/pyfftw.pyx":1031
+ *         # number of items (as opposed to the number of bytes).
+ *         self._input_strides = input_array.strides
+ *         self._input_item_strides = tuple([stride/input_array.itemsize             # <<<<<<<<<<<<<<
+ *             for stride in input_array.strides])
+ *         self._output_strides = output_array.strides
  */
-  if (__pyx_v_copy_shape) {
+  __pyx_t_10 = PyList_AsTuple(((PyObject*)__pyx_t_9)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1031; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  __Pyx_GIVEREF(__pyx_t_10);
+  __Pyx_GOTREF(__pyx_v_self->_input_item_strides);
+  __Pyx_DECREF(__pyx_v_self->_input_item_strides);
+  __pyx_v_self->_input_item_strides = __pyx_t_10;
+  __pyx_t_10 = 0;
 
-    /* "numpy.pxd":226
- *                 # Allocate new buffer for strides and shape info.
- *                 # This is allocated as one block, strides first.
- *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
- *                 info.shape = info.strides + ndim
- *                 for i in range(ndim):
+  /* "pyfftw/pyfftw.pyx":1033
+ *         self._input_item_strides = tuple([stride/input_array.itemsize
+ *             for stride in input_array.strides])
+ *         self._output_strides = output_array.strides             # <<<<<<<<<<<<<<
+ *         self._output_item_strides = tuple([stride/output_array.itemsize
+ *             for stride in output_array.strides])
  */
-    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+  __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_array, __pyx_n_s_strides); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
+  __Pyx_GIVEREF(__pyx_t_10);
+  __Pyx_GOTREF(__pyx_v_self->_output_strides);
+  __Pyx_DECREF(__pyx_v_self->_output_strides);
+  __pyx_v_self->_output_strides = __pyx_t_10;
+  __pyx_t_10 = 0;
 
-    /* "numpy.pxd":227
- *                 # This is allocated as one block, strides first.
- *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
- *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
- *                 for i in range(ndim):
- *                     info.strides[i] = PyArray_STRIDES(self)[i]
+  /* "pyfftw/pyfftw.pyx":1034
+ *             for stride in input_array.strides])
+ *         self._output_strides = output_array.strides
+ *         self._output_item_strides = tuple([stride/output_array.itemsize             # <<<<<<<<<<<<<<
+ *             for stride in output_array.strides])
+ * 
  */
-    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+  __pyx_t_10 = PyList_New(0); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_10);
 
-    /* "numpy.pxd":228
- *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
- *                 info.shape = info.strides + ndim
- *                 for i in range(ndim):             # <<<<<<<<<<<<<<
- *                     info.strides[i] = PyArray_STRIDES(self)[i]
- *                     info.shape[i] = PyArray_DIMS(self)[i]
+  /* "pyfftw/pyfftw.pyx":1035
+ *         self._output_strides = output_array.strides
+ *         self._output_item_strides = tuple([stride/output_array.itemsize
+ *             for stride in output_array.strides])             # <<<<<<<<<<<<<<
+ * 
+ *         # Make sure that the arrays are not too big for fftw
  */
-    __pyx_t_5 = __pyx_v_ndim;
-    for (__pyx_t_6 = 0; __pyx_t_6 < __pyx_t_5; __pyx_t_6+=1) {
-      __pyx_v_i = __pyx_t_6;
+  __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_array, __pyx_n_s_strides); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_9);
+  if (likely(PyList_CheckExact(__pyx_t_9)) || PyTuple_CheckExact(__pyx_t_9)) {
+    __pyx_t_11 = __pyx_t_9; __Pyx_INCREF(__pyx_t_11); __pyx_t_12 = 0;
+    __pyx_t_13 = NULL;
+  } else {
+    __pyx_t_12 = -1; __pyx_t_11 = PyObject_GetIter(__pyx_t_9); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_13 = Py_TYPE(__pyx_t_11)->tp_iternext; if (unlikely(!__pyx_t_13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+  for (;;) {
+    if (likely(!__pyx_t_13)) {
+      if (likely(PyList_CheckExact(__pyx_t_11))) {
+        if (__pyx_t_12 >= PyList_GET_SIZE(__pyx_t_11)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_9 = PyList_GET_ITEM(__pyx_t_11, __pyx_t_12); __Pyx_INCREF(__pyx_t_9); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_9 = PySequence_ITEM(__pyx_t_11, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        #endif
+      } else {
+        if (__pyx_t_12 >= PyTuple_GET_SIZE(__pyx_t_11)) break;
+        #if CYTHON_COMPILING_IN_CPYTHON
+        __pyx_t_9 = PyTuple_GET_ITEM(__pyx_t_11, __pyx_t_12); __Pyx_INCREF(__pyx_t_9); __pyx_t_12++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        #else
+        __pyx_t_9 = PySequence_ITEM(__pyx_t_11, __pyx_t_12); __pyx_t_12++; if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_9);
+        #endif
+      }
+    } else {
+      __pyx_t_9 = __pyx_t_13(__pyx_t_11);
+      if (unlikely(!__pyx_t_9)) {
+        PyObject* exc_type = PyErr_Occurred();
+        if (exc_type) {
+          if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
+          else {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1035; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        }
+        break;
+      }
+      __Pyx_GOTREF(__pyx_t_9);
+    }
+    __Pyx_XDECREF_SET(__pyx_v_stride, __pyx_t_9);
+    __pyx_t_9 = 0;
 
-      /* "numpy.pxd":229
- *                 info.shape = info.strides + ndim
- *                 for i in range(ndim):
- *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
- *                     info.shape[i] = PyArray_DIMS(self)[i]
- *             else:
+    /* "pyfftw/pyfftw.pyx":1034
+ *             for stride in input_array.strides])
+ *         self._output_strides = output_array.strides
+ *         self._output_item_strides = tuple([stride/output_array.itemsize             # <<<<<<<<<<<<<<
+ *             for stride in output_array.strides])
+ * 
  */
-      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+    __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_output_array, __pyx_n_s_itemsize); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
+    __pyx_t_1 = __Pyx_PyNumber_Divide(__pyx_v_stride, __pyx_t_9); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    if (unlikely(__Pyx_ListComp_Append(__pyx_t_10, (PyObject*)__pyx_t_1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-      /* "numpy.pxd":230
- *                 for i in range(ndim):
- *                     info.strides[i] = PyArray_STRIDES(self)[i]
- *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
- *             else:
- *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+    /* "pyfftw/pyfftw.pyx":1035
+ *         self._output_strides = output_array.strides
+ *         self._output_item_strides = tuple([stride/output_array.itemsize
+ *             for stride in output_array.strides])             # <<<<<<<<<<<<<<
+ * 
+ *         # Make sure that the arrays are not too big for fftw
  */
-      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
-    }
-    goto __pyx_L7;
   }
-  /*else*/ {
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-    /* "numpy.pxd":232
- *                     info.shape[i] = PyArray_DIMS(self)[i]
- *             else:
- *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
- *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
- *             info.suboffsets = NULL
+  /* "pyfftw/pyfftw.pyx":1034
+ *             for stride in input_array.strides])
+ *         self._output_strides = output_array.strides
+ *         self._output_item_strides = tuple([stride/output_array.itemsize             # <<<<<<<<<<<<<<
+ *             for stride in output_array.strides])
+ * 
  */
-    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+  __pyx_t_11 = PyList_AsTuple(((PyObject*)__pyx_t_10)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1034; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
+  __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+  __Pyx_GIVEREF(__pyx_t_11);
+  __Pyx_GOTREF(__pyx_v_self->_output_item_strides);
+  __Pyx_DECREF(__pyx_v_self->_output_item_strides);
+  __pyx_v_self->_output_item_strides = __pyx_t_11;
+  __pyx_t_11 = 0;
 
-    /* "numpy.pxd":233
- *             else:
- *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
- *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
- *             info.suboffsets = NULL
- *             info.itemsize = PyArray_ITEMSIZE(self)
+  /* "pyfftw/pyfftw.pyx":1041
+ *         # best (any suggestions, please get in touch).
+ *         cdef int i
+ *         for i in range(0, len(self._input_shape)):             # <<<<<<<<<<<<<<
+ *             if self._input_shape[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Dimensions of the input array must be ' +
  */
-    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
-  }
-  __pyx_L7:;
+  __pyx_t_11 = __pyx_v_self->_input_shape;
+  __Pyx_INCREF(__pyx_t_11);
+  __pyx_t_12 = PyObject_Length(__pyx_t_11); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1041; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_12; __pyx_t_8+=1) {
+    __pyx_v_i = __pyx_t_8;
 
-  /* "numpy.pxd":234
- *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
- *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
- *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
- *             info.itemsize = PyArray_ITEMSIZE(self)
- *             info.readonly = not PyArray_ISWRITEABLE(self)
+    /* "pyfftw/pyfftw.pyx":1042
+ *         cdef int i
+ *         for i in range(0, len(self._input_shape)):
+ *             if self._input_shape[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Dimensions of the input array must be ' +
+ *                         'less than ', str(limits.INT_MAX))
  */
-  __pyx_v_info->suboffsets = NULL;
+    __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_self->_input_shape, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_10 = PyInt_FromSsize_t(((Py_ssize_t)INT_MAX)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_11, __pyx_t_10, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1042; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_2) {
 
-  /* "numpy.pxd":235
- *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
- *             info.suboffsets = NULL
- *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
- *             info.readonly = not PyArray_ISWRITEABLE(self)
+      /* "pyfftw/pyfftw.pyx":1043
+ *         for i in range(0, len(self._input_shape)):
+ *             if self._input_shape[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Dimensions of the input array must be ' +             # <<<<<<<<<<<<<<
+ *                         'less than ', str(limits.INT_MAX))
  * 
  */
-  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+      __pyx_t_1 = PyNumber_Add(__pyx_kp_s_Dimensions_of_the_input_array_mu, __pyx_kp_s_less_than); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
 
-  /* "numpy.pxd":236
- *             info.suboffsets = NULL
- *             info.itemsize = PyArray_ITEMSIZE(self)
- *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
+      /* "pyfftw/pyfftw.pyx":1044
+ *             if self._input_shape[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Dimensions of the input array must be ' +
+ *                         'less than ', str(limits.INT_MAX))             # <<<<<<<<<<<<<<
  * 
- *             cdef int t
+ *             if self._input_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:
  */
-  __pyx_v_info->readonly = (!PyArray_ISWRITEABLE(__pyx_v_self));
+      __pyx_t_10 = __Pyx_PyInt_From_int(INT_MAX); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_GIVEREF(__pyx_t_10);
+      PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_10);
+      __pyx_t_10 = 0;
+      __pyx_t_10 = __Pyx_PyObject_Call(((PyObject *)(&PyString_Type)), __pyx_t_11, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1044; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-  /* "numpy.pxd":239
+      /* "pyfftw/pyfftw.pyx":1043
+ *         for i in range(0, len(self._input_shape)):
+ *             if self._input_shape[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Dimensions of the input array must be ' +             # <<<<<<<<<<<<<<
+ *                         'less than ', str(limits.INT_MAX))
  * 
- *             cdef int t
- *             cdef char* f = NULL             # <<<<<<<<<<<<<<
- *             cdef dtype descr = self.descr
- *             cdef list stack
  */
-  __pyx_v_f = NULL;
+      __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_GIVEREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_10);
+      PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_10);
+      __pyx_t_1 = 0;
+      __pyx_t_10 = 0;
+      __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+      __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1043; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "numpy.pxd":240
- *             cdef int t
- *             cdef char* f = NULL
- *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
- *             cdef list stack
- *             cdef int offset
+      /* "pyfftw/pyfftw.pyx":1042
+ *         cdef int i
+ *         for i in range(0, len(self._input_shape)):
+ *             if self._input_shape[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Dimensions of the input array must be ' +
+ *                         'less than ', str(limits.INT_MAX))
  */
-  __pyx_t_4 = ((PyObject *)__pyx_v_self->descr);
-  __Pyx_INCREF(__pyx_t_4);
-  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_4);
-  __pyx_t_4 = 0;
+    }
 
-  /* "numpy.pxd":244
- *             cdef int offset
+    /* "pyfftw/pyfftw.pyx":1046
+ *                         'less than ', str(limits.INT_MAX))
  * 
- *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
+ *             if self._input_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Strides of the input array must be ' +
+ *                         'less than ', str(limits.INT_MAX))
+ */
+    __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_self->_input_item_strides, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_10 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_11 = PyInt_FromSsize_t(((Py_ssize_t)INT_MAX)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_10, __pyx_t_11, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1046; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_2) {
+
+      /* "pyfftw/pyfftw.pyx":1047
+ * 
+ *             if self._input_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Strides of the input array must be ' +             # <<<<<<<<<<<<<<
+ *                         'less than ', str(limits.INT_MAX))
  * 
- *             if not hasfields and not copy_shape:
  */
-  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+      __pyx_t_1 = PyNumber_Add(__pyx_kp_s_Strides_of_the_input_array_must, __pyx_kp_s_less_than); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1047; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
 
-  /* "numpy.pxd":246
- *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
+      /* "pyfftw/pyfftw.pyx":1048
+ *             if self._input_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Strides of the input array must be ' +
+ *                         'less than ', str(limits.INT_MAX))             # <<<<<<<<<<<<<<
  * 
- *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
- *                 # do not call releasebuffer
- *                 info.obj = None
+ *         for i in range(0, len(self._output_shape)):
  */
-  __pyx_t_2 = (!__pyx_v_hasfields);
-  if (__pyx_t_2) {
-    __pyx_t_3 = (!__pyx_v_copy_shape);
-    __pyx_t_1 = __pyx_t_3;
-  } else {
-    __pyx_t_1 = __pyx_t_2;
-  }
-  if (__pyx_t_1) {
+      __pyx_t_11 = __Pyx_PyInt_From_int(INT_MAX); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1048; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1048; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_GIVEREF(__pyx_t_11);
+      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_11);
+      __pyx_t_11 = 0;
+      __pyx_t_11 = __Pyx_PyObject_Call(((PyObject *)(&PyString_Type)), __pyx_t_10, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1048; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-    /* "numpy.pxd":248
- *             if not hasfields and not copy_shape:
- *                 # do not call releasebuffer
- *                 info.obj = None             # <<<<<<<<<<<<<<
- *             else:
- *                 # need to call releasebuffer
+      /* "pyfftw/pyfftw.pyx":1047
+ * 
+ *             if self._input_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Strides of the input array must be ' +             # <<<<<<<<<<<<<<
+ *                         'less than ', str(limits.INT_MAX))
+ * 
  */
-    __Pyx_INCREF(Py_None);
-    __Pyx_GIVEREF(Py_None);
-    __Pyx_GOTREF(__pyx_v_info->obj);
-    __Pyx_DECREF(__pyx_v_info->obj);
-    __pyx_v_info->obj = Py_None;
-    goto __pyx_L10;
-  }
-  /*else*/ {
+      __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1047; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_GIVEREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_11);
+      PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_11);
+      __pyx_t_1 = 0;
+      __pyx_t_11 = 0;
+      __pyx_t_11 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1047; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_Raise(__pyx_t_11, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1047; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-    /* "numpy.pxd":251
- *             else:
- *                 # need to call releasebuffer
- *                 info.obj = self             # <<<<<<<<<<<<<<
+      /* "pyfftw/pyfftw.pyx":1046
+ *                         'less than ', str(limits.INT_MAX))
  * 
- *             if not hasfields:
+ *             if self._input_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Strides of the input array must be ' +
+ *                         'less than ', str(limits.INT_MAX))
  */
-    __Pyx_INCREF(((PyObject *)__pyx_v_self));
-    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
-    __Pyx_GOTREF(__pyx_v_info->obj);
-    __Pyx_DECREF(__pyx_v_info->obj);
-    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+    }
   }
-  __pyx_L10:;
 
-  /* "numpy.pxd":253
- *                 info.obj = self
+  /* "pyfftw/pyfftw.pyx":1050
+ *                         'less than ', str(limits.INT_MAX))
  * 
- *             if not hasfields:             # <<<<<<<<<<<<<<
- *                 t = descr.type_num
- *                 if ((descr.byteorder == c'>' and little_endian) or
+ *         for i in range(0, len(self._output_shape)):             # <<<<<<<<<<<<<<
+ *             if self._output_shape[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Dimensions of the output array must be ' +
  */
-  __pyx_t_1 = (!__pyx_v_hasfields);
-  if (__pyx_t_1) {
+  __pyx_t_11 = __pyx_v_self->_output_shape;
+  __Pyx_INCREF(__pyx_t_11);
+  __pyx_t_12 = PyObject_Length(__pyx_t_11); if (unlikely(__pyx_t_12 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  for (__pyx_t_8 = 0; __pyx_t_8 < __pyx_t_12; __pyx_t_8+=1) {
+    __pyx_v_i = __pyx_t_8;
 
-    /* "numpy.pxd":254
+    /* "pyfftw/pyfftw.pyx":1051
  * 
- *             if not hasfields:
- *                 t = descr.type_num             # <<<<<<<<<<<<<<
- *                 if ((descr.byteorder == c'>' and little_endian) or
- *                     (descr.byteorder == c'<' and not little_endian)):
+ *         for i in range(0, len(self._output_shape)):
+ *             if self._output_shape[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Dimensions of the output array must be ' +
+ *                         'less than ', str(limits.INT_MAX))
  */
-    __pyx_t_5 = __pyx_v_descr->type_num;
-    __pyx_v_t = __pyx_t_5;
+    __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_self->_output_shape, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1051; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_10 = PyInt_FromSsize_t(((Py_ssize_t)INT_MAX)); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_11, __pyx_t_10, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1051; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_2) {
 
-    /* "numpy.pxd":255
- *             if not hasfields:
- *                 t = descr.type_num
- *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
- *                     (descr.byteorder == c'<' and not little_endian)):
- *                     raise ValueError(u"Non-native byte order not supported")
+      /* "pyfftw/pyfftw.pyx":1052
+ *         for i in range(0, len(self._output_shape)):
+ *             if self._output_shape[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Dimensions of the output array must be ' +             # <<<<<<<<<<<<<<
+ *                         'less than ', str(limits.INT_MAX))
+ * 
  */
-    __pyx_t_1 = (__pyx_v_descr->byteorder == '>');
-    if (__pyx_t_1) {
-      __pyx_t_2 = __pyx_v_little_endian;
-    } else {
-      __pyx_t_2 = __pyx_t_1;
-    }
-    if (!__pyx_t_2) {
+      __pyx_t_1 = PyNumber_Add(__pyx_kp_s_Dimensions_of_the_output_array_m, __pyx_kp_s_less_than); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
 
-      /* "numpy.pxd":256
- *                 t = descr.type_num
- *                 if ((descr.byteorder == c'>' and little_endian) or
- *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
- *                     raise ValueError(u"Non-native byte order not supported")
- *                 if   t == NPY_BYTE:        f = "b"
+      /* "pyfftw/pyfftw.pyx":1053
+ *             if self._output_shape[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Dimensions of the output array must be ' +
+ *                         'less than ', str(limits.INT_MAX))             # <<<<<<<<<<<<<<
+ * 
+ *             if self._output_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:
  */
-      __pyx_t_1 = (__pyx_v_descr->byteorder == '<');
-      if (__pyx_t_1) {
-        __pyx_t_3 = (!__pyx_v_little_endian);
-        __pyx_t_7 = __pyx_t_3;
-      } else {
-        __pyx_t_7 = __pyx_t_1;
-      }
-      __pyx_t_1 = __pyx_t_7;
-    } else {
-      __pyx_t_1 = __pyx_t_2;
-    }
-    if (__pyx_t_1) {
+      __pyx_t_10 = __Pyx_PyInt_From_int(INT_MAX); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __pyx_t_11 = PyTuple_New(1); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_GIVEREF(__pyx_t_10);
+      PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_10);
+      __pyx_t_10 = 0;
+      __pyx_t_10 = __Pyx_PyObject_Call(((PyObject *)(&PyString_Type)), __pyx_t_11, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1053; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 
-      /* "numpy.pxd":257
- *                 if ((descr.byteorder == c'>' and little_endian) or
- *                     (descr.byteorder == c'<' and not little_endian)):
- *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
- *                 if   t == NPY_BYTE:        f = "b"
- *                 elif t == NPY_UBYTE:       f = "B"
+      /* "pyfftw/pyfftw.pyx":1052
+ *         for i in range(0, len(self._output_shape)):
+ *             if self._output_shape[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Dimensions of the output array must be ' +             # <<<<<<<<<<<<<<
+ *                         'less than ', str(limits.INT_MAX))
+ * 
  */
-      __pyx_t_4 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_65), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __Pyx_Raise(__pyx_t_4, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      goto __pyx_L12;
-    }
-    __pyx_L12:;
+      __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_GIVEREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_10);
+      PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_10);
+      __pyx_t_1 = 0;
+      __pyx_t_10 = 0;
+      __pyx_t_10 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_11, NULL); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+      __Pyx_Raise(__pyx_t_10, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1052; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-    /* "numpy.pxd":258
- *                     (descr.byteorder == c'<' and not little_endian)):
- *                     raise ValueError(u"Non-native byte order not supported")
- *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_UBYTE:       f = "B"
- *                 elif t == NPY_SHORT:       f = "h"
+      /* "pyfftw/pyfftw.pyx":1051
+ * 
+ *         for i in range(0, len(self._output_shape)):
+ *             if self._output_shape[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Dimensions of the output array must be ' +
+ *                         'less than ', str(limits.INT_MAX))
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_BYTE);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__b;
-      goto __pyx_L13;
     }
 
-    /* "numpy.pxd":259
- *                     raise ValueError(u"Non-native byte order not supported")
- *                 if   t == NPY_BYTE:        f = "b"
- *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_SHORT:       f = "h"
- *                 elif t == NPY_USHORT:      f = "H"
+    /* "pyfftw/pyfftw.pyx":1055
+ *                         'less than ', str(limits.INT_MAX))
+ * 
+ *             if self._output_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Strides of the output array must be ' +
+ *                         'less than ', str(limits.INT_MAX))
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_UBYTE);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__B;
-      goto __pyx_L13;
-    }
+    __pyx_t_10 = __Pyx_GetItemInt(__pyx_v_self->_output_item_strides, __pyx_v_i, int, 1, __Pyx_PyInt_From_int, 0, 1, 1); if (unlikely(__pyx_t_10 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_11 = PyInt_FromSsize_t(((Py_ssize_t)INT_MAX)); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_1 = PyObject_RichCompare(__pyx_t_10, __pyx_t_11, Py_GE); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1055; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    if (__pyx_t_2) {
 
-    /* "numpy.pxd":260
- *                 if   t == NPY_BYTE:        f = "b"
- *                 elif t == NPY_UBYTE:       f = "B"
- *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_USHORT:      f = "H"
- *                 elif t == NPY_INT:         f = "i"
+      /* "pyfftw/pyfftw.pyx":1056
+ * 
+ *             if self._output_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Strides of the output array must be ' +             # <<<<<<<<<<<<<<
+ *                         'less than ', str(limits.INT_MAX))
+ * 
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_SHORT);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__h;
-      goto __pyx_L13;
-    }
+      __pyx_t_1 = PyNumber_Add(__pyx_kp_s_Strides_of_the_output_array_must, __pyx_kp_s_less_than); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_1);
 
-    /* "numpy.pxd":261
- *                 elif t == NPY_UBYTE:       f = "B"
- *                 elif t == NPY_SHORT:       f = "h"
- *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_INT:         f = "i"
- *                 elif t == NPY_UINT:        f = "I"
+      /* "pyfftw/pyfftw.pyx":1057
+ *             if self._output_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Strides of the output array must be ' +
+ *                         'less than ', str(limits.INT_MAX))             # <<<<<<<<<<<<<<
+ * 
+ *         fft_shape_lookup = functions['fft_shape_lookup']
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_USHORT);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__H;
-      goto __pyx_L13;
-    }
+      __pyx_t_11 = __Pyx_PyInt_From_int(INT_MAX); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_GIVEREF(__pyx_t_11);
+      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_11);
+      __pyx_t_11 = 0;
+      __pyx_t_11 = __Pyx_PyObject_Call(((PyObject *)(&PyString_Type)), __pyx_t_10, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1057; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 
-    /* "numpy.pxd":262
- *                 elif t == NPY_SHORT:       f = "h"
- *                 elif t == NPY_USHORT:      f = "H"
- *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_UINT:        f = "I"
- *                 elif t == NPY_LONG:        f = "l"
+      /* "pyfftw/pyfftw.pyx":1056
+ * 
+ *             if self._output_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:
+ *                 raise ValueError('Strides of the output array must be ' +             # <<<<<<<<<<<<<<
+ *                         'less than ', str(limits.INT_MAX))
+ * 
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_INT);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__i;
-      goto __pyx_L13;
-    }
+      __pyx_t_10 = PyTuple_New(2); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_GIVEREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_1);
+      __Pyx_GIVEREF(__pyx_t_11);
+      PyTuple_SET_ITEM(__pyx_t_10, 1, __pyx_t_11);
+      __pyx_t_1 = 0;
+      __pyx_t_11 = 0;
+      __pyx_t_11 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_Raise(__pyx_t_11, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1056; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-    /* "numpy.pxd":263
- *                 elif t == NPY_USHORT:      f = "H"
- *                 elif t == NPY_INT:         f = "i"
- *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_LONG:        f = "l"
- *                 elif t == NPY_ULONG:       f = "L"
+      /* "pyfftw/pyfftw.pyx":1055
+ *                         'less than ', str(limits.INT_MAX))
+ * 
+ *             if self._output_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:             # <<<<<<<<<<<<<<
+ *                 raise ValueError('Strides of the output array must be ' +
+ *                         'less than ', str(limits.INT_MAX))
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_UINT);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__I;
-      goto __pyx_L13;
     }
+  }
 
-    /* "numpy.pxd":264
- *                 elif t == NPY_INT:         f = "i"
- *                 elif t == NPY_UINT:        f = "I"
- *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_ULONG:       f = "L"
- *                 elif t == NPY_LONGLONG:    f = "q"
+  /* "pyfftw/pyfftw.pyx":1059
+ *                         'less than ', str(limits.INT_MAX))
+ * 
+ *         fft_shape_lookup = functions['fft_shape_lookup']             # <<<<<<<<<<<<<<
+ *         if fft_shape_lookup == -1:
+ *             fft_shape = self._input_shape
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_LONG);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__l;
-      goto __pyx_L13;
-    }
+  __pyx_t_11 = PyObject_GetItem(__pyx_v_functions, __pyx_n_s_fft_shape_lookup); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1059; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __Pyx_GOTREF(__pyx_t_11);
+  __pyx_v_fft_shape_lookup = __pyx_t_11;
+  __pyx_t_11 = 0;
 
-    /* "numpy.pxd":265
- *                 elif t == NPY_UINT:        f = "I"
- *                 elif t == NPY_LONG:        f = "l"
- *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_LONGLONG:    f = "q"
- *                 elif t == NPY_ULONGLONG:   f = "Q"
+  /* "pyfftw/pyfftw.pyx":1060
+ * 
+ *         fft_shape_lookup = functions['fft_shape_lookup']
+ *         if fft_shape_lookup == -1:             # <<<<<<<<<<<<<<
+ *             fft_shape = self._input_shape
+ *         else:
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_ULONG);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__L;
-      goto __pyx_L13;
-    }
+  __pyx_t_11 = __Pyx_PyInt_EqObjC(__pyx_v_fft_shape_lookup, __pyx_int_neg_1, -1L, 0); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_11);
+  __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_11); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1060; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+  if (__pyx_t_2) {
 
-    /* "numpy.pxd":266
- *                 elif t == NPY_LONG:        f = "l"
- *                 elif t == NPY_ULONG:       f = "L"
- *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_ULONGLONG:   f = "Q"
- *                 elif t == NPY_FLOAT:       f = "f"
+    /* "pyfftw/pyfftw.pyx":1061
+ *         fft_shape_lookup = functions['fft_shape_lookup']
+ *         if fft_shape_lookup == -1:
+ *             fft_shape = self._input_shape             # <<<<<<<<<<<<<<
+ *         else:
+ *             fft_shape = fft_shape_lookup(input_array, output_array)
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_LONGLONG);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__q;
-      goto __pyx_L13;
-    }
+    __pyx_t_11 = __pyx_v_self->_input_shape;
+    __Pyx_INCREF(__pyx_t_11);
+    __pyx_v_fft_shape = __pyx_t_11;
+    __pyx_t_11 = 0;
 
-    /* "numpy.pxd":267
- *                 elif t == NPY_ULONG:       f = "L"
- *                 elif t == NPY_LONGLONG:    f = "q"
- *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_FLOAT:       f = "f"
- *                 elif t == NPY_DOUBLE:      f = "d"
+    /* "pyfftw/pyfftw.pyx":1060
+ * 
+ *         fft_shape_lookup = functions['fft_shape_lookup']
+ *         if fft_shape_lookup == -1:             # <<<<<<<<<<<<<<
+ *             fft_shape = self._input_shape
+ *         else:
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_ULONGLONG);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__Q;
-      goto __pyx_L13;
-    }
+    goto __pyx_L84;
+  }
 
-    /* "numpy.pxd":268
- *                 elif t == NPY_LONGLONG:    f = "q"
- *                 elif t == NPY_ULONGLONG:   f = "Q"
- *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_DOUBLE:      f = "d"
- *                 elif t == NPY_LONGDOUBLE:  f = "g"
+  /* "pyfftw/pyfftw.pyx":1063
+ *             fft_shape = self._input_shape
+ *         else:
+ *             fft_shape = fft_shape_lookup(input_array, output_array)             # <<<<<<<<<<<<<<
+ * 
+ *         # Fill in the stride and shape information
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_FLOAT);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__f;
-      goto __pyx_L13;
+  /*else*/ {
+    __Pyx_INCREF(__pyx_v_fft_shape_lookup);
+    __pyx_t_10 = __pyx_v_fft_shape_lookup; __pyx_t_1 = NULL;
+    __pyx_t_12 = 0;
+    if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_10))) {
+      __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_10);
+      if (likely(__pyx_t_1)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+        __Pyx_INCREF(__pyx_t_1);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_10, function);
+        __pyx_t_12 = 1;
+      }
     }
-
-    /* "numpy.pxd":269
- *                 elif t == NPY_ULONGLONG:   f = "Q"
- *                 elif t == NPY_FLOAT:       f = "f"
- *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_LONGDOUBLE:  f = "g"
- *                 elif t == NPY_CFLOAT:      f = "Zf"
- */
-    __pyx_t_1 = (__pyx_v_t == NPY_DOUBLE);
+    __pyx_t_9 = PyTuple_New(2+__pyx_t_12); if (unlikely(!__pyx_t_9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_9);
     if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__d;
-      goto __pyx_L13;
+      __Pyx_GIVEREF(__pyx_t_1); PyTuple_SET_ITEM(__pyx_t_9, 0, __pyx_t_1); __pyx_t_1 = NULL;
     }
-
-    /* "numpy.pxd":270
- *                 elif t == NPY_FLOAT:       f = "f"
- *                 elif t == NPY_DOUBLE:      f = "d"
- *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_CFLOAT:      f = "Zf"
- *                 elif t == NPY_CDOUBLE:     f = "Zd"
+    __Pyx_INCREF(__pyx_v_input_array);
+    __Pyx_GIVEREF(__pyx_v_input_array);
+    PyTuple_SET_ITEM(__pyx_t_9, 0+__pyx_t_12, __pyx_v_input_array);
+    __Pyx_INCREF(__pyx_v_output_array);
+    __Pyx_GIVEREF(__pyx_v_output_array);
+    PyTuple_SET_ITEM(__pyx_t_9, 1+__pyx_t_12, __pyx_v_output_array);
+    __pyx_t_11 = __Pyx_PyObject_Call(__pyx_t_10, __pyx_t_9, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1063; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_11);
+    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __pyx_v_fft_shape = __pyx_t_11;
+    __pyx_t_11 = 0;
+  }
+  __pyx_L84:;
+
+  /* "pyfftw/pyfftw.pyx":1066
+ * 
+ *         # Fill in the stride and shape information
+ *         input_strides_array = self._input_item_strides             # <<<<<<<<<<<<<<
+ *         output_strides_array = self._output_item_strides
+ *         for i in range(0, self._rank):
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_LONGDOUBLE);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__g;
-      goto __pyx_L13;
-    }
+  __pyx_t_11 = __pyx_v_self->_input_item_strides;
+  __Pyx_INCREF(__pyx_t_11);
+  __pyx_v_input_strides_array = __pyx_t_11;
+  __pyx_t_11 = 0;
 
-    /* "numpy.pxd":271
- *                 elif t == NPY_DOUBLE:      f = "d"
- *                 elif t == NPY_LONGDOUBLE:  f = "g"
- *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_CDOUBLE:     f = "Zd"
- *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+  /* "pyfftw/pyfftw.pyx":1067
+ *         # Fill in the stride and shape information
+ *         input_strides_array = self._input_item_strides
+ *         output_strides_array = self._output_item_strides             # <<<<<<<<<<<<<<
+ *         for i in range(0, self._rank):
+ *             self._dims[i]._n = fft_shape[self._axes[i]]
+ */
+  __pyx_t_11 = __pyx_v_self->_output_item_strides;
+  __Pyx_INCREF(__pyx_t_11);
+  __pyx_v_output_strides_array = __pyx_t_11;
+  __pyx_t_11 = 0;
+
+  /* "pyfftw/pyfftw.pyx":1068
+ *         input_strides_array = self._input_item_strides
+ *         output_strides_array = self._output_item_strides
+ *         for i in range(0, self._rank):             # <<<<<<<<<<<<<<
+ *             self._dims[i]._n = fft_shape[self._axes[i]]
+ *             self._dims[i]._is = input_strides_array[self._axes[i]]
+ */
+  __pyx_t_8 = __pyx_v_self->_rank;
+  for (__pyx_t_22 = 0; __pyx_t_22 < __pyx_t_8; __pyx_t_22+=1) {
+    __pyx_v_i = __pyx_t_22;
+
+    /* "pyfftw/pyfftw.pyx":1069
+ *         output_strides_array = self._output_item_strides
+ *         for i in range(0, self._rank):
+ *             self._dims[i]._n = fft_shape[self._axes[i]]             # <<<<<<<<<<<<<<
+ *             self._dims[i]._is = input_strides_array[self._axes[i]]
+ *             self._dims[i]._os = output_strides_array[self._axes[i]]
+ */
+    __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_fft_shape, (__pyx_v_self->_axes[__pyx_v_i]), int64_t, 1, __Pyx_PyInt_From_int64_t, 0, 1, 1); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1069; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_23 = __Pyx_PyInt_As_int(__pyx_t_11); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1069; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    (__pyx_v_self->_dims[__pyx_v_i])._n = __pyx_t_23;
+
+    /* "pyfftw/pyfftw.pyx":1070
+ *         for i in range(0, self._rank):
+ *             self._dims[i]._n = fft_shape[self._axes[i]]
+ *             self._dims[i]._is = input_strides_array[self._axes[i]]             # <<<<<<<<<<<<<<
+ *             self._dims[i]._os = output_strides_array[self._axes[i]]
+ * 
+ */
+    __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_input_strides_array, (__pyx_v_self->_axes[__pyx_v_i]), int64_t, 1, __Pyx_PyInt_From_int64_t, 0, 1, 1); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1070; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_23 = __Pyx_PyInt_As_int(__pyx_t_11); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1070; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    (__pyx_v_self->_dims[__pyx_v_i])._is = __pyx_t_23;
+
+    /* "pyfftw/pyfftw.pyx":1071
+ *             self._dims[i]._n = fft_shape[self._axes[i]]
+ *             self._dims[i]._is = input_strides_array[self._axes[i]]
+ *             self._dims[i]._os = output_strides_array[self._axes[i]]             # <<<<<<<<<<<<<<
+ * 
+ *         for i in range(0, self._howmany_rank):
+ */
+    __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_output_strides_array, (__pyx_v_self->_axes[__pyx_v_i]), int64_t, 1, __Pyx_PyInt_From_int64_t, 0, 1, 1); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1071; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_23 = __Pyx_PyInt_As_int(__pyx_t_11); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1071; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    (__pyx_v_self->_dims[__pyx_v_i])._os = __pyx_t_23;
+  }
+
+  /* "pyfftw/pyfftw.pyx":1073
+ *             self._dims[i]._os = output_strides_array[self._axes[i]]
+ * 
+ *         for i in range(0, self._howmany_rank):             # <<<<<<<<<<<<<<
+ *             self._howmany_dims[i]._n = fft_shape[self._not_axes[i]]
+ *             self._howmany_dims[i]._is = input_strides_array[self._not_axes[i]]
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_CFLOAT);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__Zf;
-      goto __pyx_L13;
-    }
+  __pyx_t_8 = __pyx_v_self->_howmany_rank;
+  for (__pyx_t_22 = 0; __pyx_t_22 < __pyx_t_8; __pyx_t_22+=1) {
+    __pyx_v_i = __pyx_t_22;
 
-    /* "numpy.pxd":272
- *                 elif t == NPY_LONGDOUBLE:  f = "g"
- *                 elif t == NPY_CFLOAT:      f = "Zf"
- *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
- *                 elif t == NPY_OBJECT:      f = "O"
+    /* "pyfftw/pyfftw.pyx":1074
+ * 
+ *         for i in range(0, self._howmany_rank):
+ *             self._howmany_dims[i]._n = fft_shape[self._not_axes[i]]             # <<<<<<<<<<<<<<
+ *             self._howmany_dims[i]._is = input_strides_array[self._not_axes[i]]
+ *             self._howmany_dims[i]._os = output_strides_array[self._not_axes[i]]
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_CDOUBLE);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__Zd;
-      goto __pyx_L13;
-    }
+    __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_fft_shape, (__pyx_v_self->_not_axes[__pyx_v_i]), int64_t, 1, __Pyx_PyInt_From_int64_t, 0, 1, 1); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1074; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_23 = __Pyx_PyInt_As_int(__pyx_t_11); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1074; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    (__pyx_v_self->_howmany_dims[__pyx_v_i])._n = __pyx_t_23;
 
-    /* "numpy.pxd":273
- *                 elif t == NPY_CFLOAT:      f = "Zf"
- *                 elif t == NPY_CDOUBLE:     f = "Zd"
- *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
- *                 elif t == NPY_OBJECT:      f = "O"
- *                 else:
+    /* "pyfftw/pyfftw.pyx":1075
+ *         for i in range(0, self._howmany_rank):
+ *             self._howmany_dims[i]._n = fft_shape[self._not_axes[i]]
+ *             self._howmany_dims[i]._is = input_strides_array[self._not_axes[i]]             # <<<<<<<<<<<<<<
+ *             self._howmany_dims[i]._os = output_strides_array[self._not_axes[i]]
+ * 
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_CLONGDOUBLE);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__Zg;
-      goto __pyx_L13;
-    }
+    __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_input_strides_array, (__pyx_v_self->_not_axes[__pyx_v_i]), int64_t, 1, __Pyx_PyInt_From_int64_t, 0, 1, 1); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1075; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_23 = __Pyx_PyInt_As_int(__pyx_t_11); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1075; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    (__pyx_v_self->_howmany_dims[__pyx_v_i])._is = __pyx_t_23;
 
-    /* "numpy.pxd":274
- *                 elif t == NPY_CDOUBLE:     f = "Zd"
- *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
- *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
- *                 else:
- *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+    /* "pyfftw/pyfftw.pyx":1076
+ *             self._howmany_dims[i]._n = fft_shape[self._not_axes[i]]
+ *             self._howmany_dims[i]._is = input_strides_array[self._not_axes[i]]
+ *             self._howmany_dims[i]._os = output_strides_array[self._not_axes[i]]             # <<<<<<<<<<<<<<
+ * 
+ *         ## Point at which FFTW calls are made
  */
-    __pyx_t_1 = (__pyx_v_t == NPY_OBJECT);
-    if (__pyx_t_1) {
-      __pyx_v_f = __pyx_k__O;
-      goto __pyx_L13;
-    }
-    /*else*/ {
+    __pyx_t_11 = __Pyx_GetItemInt(__pyx_v_output_strides_array, (__pyx_v_self->_not_axes[__pyx_v_i]), int64_t, 1, __Pyx_PyInt_From_int64_t, 0, 1, 1); if (unlikely(__pyx_t_11 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1076; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_11);
+    __pyx_t_23 = __Pyx_PyInt_As_int(__pyx_t_11); if (unlikely((__pyx_t_23 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1076; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    (__pyx_v_self->_howmany_dims[__pyx_v_i])._os = __pyx_t_23;
+  }
 
-      /* "numpy.pxd":276
- *                 elif t == NPY_OBJECT:      f = "O"
- *                 else:
- *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
- *                 info.format = f
- *                 return
+  /* "pyfftw/pyfftw.pyx":1080
+ *         ## Point at which FFTW calls are made
+ *         ## (and none should be made before this)
+ *         self._nthreads_plan_setter(threads)             # <<<<<<<<<<<<<<
+ * 
+ *         # Set the timelimit
  */
-      __pyx_t_4 = PyInt_FromLong(__pyx_v_t); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      __pyx_t_8 = PyNumber_Remainder(((PyObject *)__pyx_kp_u_66), __pyx_t_4); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(((PyObject *)__pyx_t_8));
-      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-      __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_4);
-      PyTuple_SET_ITEM(__pyx_t_4, 0, ((PyObject *)__pyx_t_8));
-      __Pyx_GIVEREF(((PyObject *)__pyx_t_8));
-      __pyx_t_8 = 0;
-      __pyx_t_8 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_4), NULL); if (unlikely(!__pyx_t_8)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_8);
-      __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
-      __Pyx_Raise(__pyx_t_8, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
-      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 276; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_self->_nthreads_plan_setter(__pyx_v_threads);
+
+  /* "pyfftw/pyfftw.pyx":1083
+ * 
+ *         # Set the timelimit
+ *         set_timelimit_func(_planning_timelimit)             # <<<<<<<<<<<<<<
+ * 
+ *         # Finally, construct the plan, after acquiring the global planner lock
+ */
+  __pyx_v_set_timelimit_func(__pyx_v__planning_timelimit);
+
+  /* "pyfftw/pyfftw.pyx":1091
+ *         # no self-lookups allowed in nogil block, so must grab all these first
+ *         cdef void *plan
+ *         cdef fftw_generic_plan_guru fftw_planner = self._fftw_planner             # <<<<<<<<<<<<<<
+ *         cdef int rank = self._rank
+ *         cdef fftw_iodim *dims = <fftw_iodim *>self._dims
+ */
+  __pyx_t_24 = __pyx_v_self->_fftw_planner;
+  __pyx_v_fftw_planner = __pyx_t_24;
+
+  /* "pyfftw/pyfftw.pyx":1092
+ *         cdef void *plan
+ *         cdef fftw_generic_plan_guru fftw_planner = self._fftw_planner
+ *         cdef int rank = self._rank             # <<<<<<<<<<<<<<
+ *         cdef fftw_iodim *dims = <fftw_iodim *>self._dims
+ *         cdef int howmany_rank = self._howmany_rank
+ */
+  __pyx_t_8 = __pyx_v_self->_rank;
+  __pyx_v_rank = __pyx_t_8;
+
+  /* "pyfftw/pyfftw.pyx":1093
+ *         cdef fftw_generic_plan_guru fftw_planner = self._fftw_planner
+ *         cdef int rank = self._rank
+ *         cdef fftw_iodim *dims = <fftw_iodim *>self._dims             # <<<<<<<<<<<<<<
+ *         cdef int howmany_rank = self._howmany_rank
+ *         cdef fftw_iodim *howmany_dims = <fftw_iodim *>self._howmany_dims
+ */
+  __pyx_v_dims = ((fftw_iodim *)__pyx_v_self->_dims);
+
+  /* "pyfftw/pyfftw.pyx":1094
+ *         cdef int rank = self._rank
+ *         cdef fftw_iodim *dims = <fftw_iodim *>self._dims
+ *         cdef int howmany_rank = self._howmany_rank             # <<<<<<<<<<<<<<
+ *         cdef fftw_iodim *howmany_dims = <fftw_iodim *>self._howmany_dims
+ *         cdef void *_in = <void *>np.PyArray_DATA(self._input_array)
+ */
+  __pyx_t_8 = __pyx_v_self->_howmany_rank;
+  __pyx_v_howmany_rank = __pyx_t_8;
+
+  /* "pyfftw/pyfftw.pyx":1095
+ *         cdef fftw_iodim *dims = <fftw_iodim *>self._dims
+ *         cdef int howmany_rank = self._howmany_rank
+ *         cdef fftw_iodim *howmany_dims = <fftw_iodim *>self._howmany_dims             # <<<<<<<<<<<<<<
+ *         cdef void *_in = <void *>np.PyArray_DATA(self._input_array)
+ *         cdef void *_out = <void *>np.PyArray_DATA(self._output_array)
+ */
+  __pyx_v_howmany_dims = ((fftw_iodim *)__pyx_v_self->_howmany_dims);
+
+  /* "pyfftw/pyfftw.pyx":1096
+ *         cdef int howmany_rank = self._howmany_rank
+ *         cdef fftw_iodim *howmany_dims = <fftw_iodim *>self._howmany_dims
+ *         cdef void *_in = <void *>np.PyArray_DATA(self._input_array)             # <<<<<<<<<<<<<<
+ *         cdef void *_out = <void *>np.PyArray_DATA(self._output_array)
+ *         cdef int sign = self._direction
+ */
+  __pyx_t_11 = ((PyObject *)__pyx_v_self->_input_array);
+  __Pyx_INCREF(__pyx_t_11);
+  __pyx_v__in = ((void *)PyArray_DATA(((PyArrayObject *)__pyx_t_11)));
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+
+  /* "pyfftw/pyfftw.pyx":1097
+ *         cdef fftw_iodim *howmany_dims = <fftw_iodim *>self._howmany_dims
+ *         cdef void *_in = <void *>np.PyArray_DATA(self._input_array)
+ *         cdef void *_out = <void *>np.PyArray_DATA(self._output_array)             # <<<<<<<<<<<<<<
+ *         cdef int sign = self._direction
+ *         cdef unsigned c_flags = self._flags
+ */
+  __pyx_t_11 = ((PyObject *)__pyx_v_self->_output_array);
+  __Pyx_INCREF(__pyx_t_11);
+  __pyx_v__out = ((void *)PyArray_DATA(((PyArrayObject *)__pyx_t_11)));
+  __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+
+  /* "pyfftw/pyfftw.pyx":1098
+ *         cdef void *_in = <void *>np.PyArray_DATA(self._input_array)
+ *         cdef void *_out = <void *>np.PyArray_DATA(self._output_array)
+ *         cdef int sign = self._direction             # <<<<<<<<<<<<<<
+ *         cdef unsigned c_flags = self._flags
+ * 
+ */
+  __pyx_t_8 = __pyx_v_self->_direction;
+  __pyx_v_sign = __pyx_t_8;
+
+  /* "pyfftw/pyfftw.pyx":1099
+ *         cdef void *_out = <void *>np.PyArray_DATA(self._output_array)
+ *         cdef int sign = self._direction
+ *         cdef unsigned c_flags = self._flags             # <<<<<<<<<<<<<<
+ * 
+ *         with plan_lock, nogil:
+ */
+  __pyx_t_18 = __pyx_v_self->_flags;
+  __pyx_v_c_flags = __pyx_t_18;
+
+  /* "pyfftw/pyfftw.pyx":1101
+ *         cdef unsigned c_flags = self._flags
+ * 
+ *         with plan_lock, nogil:             # <<<<<<<<<<<<<<
+ *             plan = fftw_planner(rank, dims, howmany_rank, howmany_dims,
+ *                                 _in, _out, sign, c_flags)
+ */
+  /*with:*/ {
+    __pyx_t_6 = __Pyx_PyObject_LookupSpecial(__pyx_v_6pyfftw_6pyfftw_plan_lock, __pyx_n_s_exit); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_10 = __Pyx_PyObject_LookupSpecial(__pyx_v_6pyfftw_6pyfftw_plan_lock, __pyx_n_s_enter); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1101; __pyx_clineno = __LINE__; goto __pyx_L89_error;}
+    __Pyx_GOTREF(__pyx_t_10);
+    __pyx_t_9 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_10))) {
+      __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_10);
+      if (likely(__pyx_t_9)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
+        __Pyx_INCREF(__pyx_t_9);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_10, function);
+      }
     }
-    __pyx_L13:;
+    if (__pyx_t_9) {
+      __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_9); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1101; __pyx_clineno = __LINE__; goto __pyx_L89_error;}
+      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
+    } else {
+      __pyx_t_11 = __Pyx_PyObject_CallNoArg(__pyx_t_10); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1101; __pyx_clineno = __LINE__; goto __pyx_L89_error;}
+    }
+    __Pyx_GOTREF(__pyx_t_11);
+    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+    /*try:*/ {
+      {
+        if (__pyx_t_5||__pyx_t_4||__pyx_t_25); else {/*mark used*/}
+        /*try:*/ {
+          {
+              #ifdef WITH_THREAD
+              PyThreadState *_save;
+              Py_UNBLOCK_THREADS
+              #endif
+              /*try:*/ {
+
+                /* "pyfftw/pyfftw.pyx":1102
+ * 
+ *         with plan_lock, nogil:
+ *             plan = fftw_planner(rank, dims, howmany_rank, howmany_dims,             # <<<<<<<<<<<<<<
+ *                                 _in, _out, sign, c_flags)
+ *         self._plan = plan
+ */
+                __pyx_v_plan = __pyx_v_fftw_planner(__pyx_v_rank, __pyx_v_dims, __pyx_v_howmany_rank, __pyx_v_howmany_dims, __pyx_v__in, __pyx_v__out, __pyx_v_sign, __pyx_v_c_flags);
+              }
+
+              /* "pyfftw/pyfftw.pyx":1101
+ *         cdef unsigned c_flags = self._flags
+ * 
+ *         with plan_lock, nogil:             # <<<<<<<<<<<<<<
+ *             plan = fftw_planner(rank, dims, howmany_rank, howmany_dims,
+ *                                 _in, _out, sign, c_flags)
+ */
+              /*finally:*/ {
+                /*normal exit:*/{
+                  #ifdef WITH_THREAD
+                  Py_BLOCK_THREADS
+                  #endif
+                  goto __pyx_L105;
+                }
+                __pyx_L105:;
+              }
+          }
+        }
+      }
+    }
+    /*finally:*/ {
+      /*normal exit:*/{
+        if (__pyx_t_6) {
+          __pyx_t_25 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_tuple__18, NULL);
+          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+          if (unlikely(!__pyx_t_25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_25);
+          __Pyx_DECREF(__pyx_t_25); __pyx_t_25 = 0;
+        }
+        goto __pyx_L92;
+      }
+      __pyx_L92:;
+    }
+    goto __pyx_L106;
+    __pyx_L89_error:;
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    goto __pyx_L1_error;
+    __pyx_L106:;
+  }
 
-    /* "numpy.pxd":277
- *                 else:
- *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
- *                 info.format = f             # <<<<<<<<<<<<<<
- *                 return
- *             else:
+  /* "pyfftw/pyfftw.pyx":1104
+ *             plan = fftw_planner(rank, dims, howmany_rank, howmany_dims,
+ *                                 _in, _out, sign, c_flags)
+ *         self._plan = plan             # <<<<<<<<<<<<<<
+ * 
+ *         if self._plan == NULL:
  */
-    __pyx_v_info->format = __pyx_v_f;
+  __pyx_v_self->_plan = __pyx_v_plan;
 
-    /* "numpy.pxd":278
- *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
- *                 info.format = f
- *                 return             # <<<<<<<<<<<<<<
- *             else:
- *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+  /* "pyfftw/pyfftw.pyx":1106
+ *         self._plan = plan
+ * 
+ *         if self._plan == NULL:             # <<<<<<<<<<<<<<
+ *             if 'FFTW_WISDOM_ONLY' in flags:
+ *                 raise RuntimeError('No FFTW wisdom is known for this plan.')
  */
-    __pyx_r = 0;
-    goto __pyx_L0;
-    goto __pyx_L11;
-  }
-  /*else*/ {
+  __pyx_t_2 = ((__pyx_v_self->_plan == NULL) != 0);
+  if (__pyx_t_2) {
 
-    /* "numpy.pxd":280
- *                 return
+    /* "pyfftw/pyfftw.pyx":1107
+ * 
+ *         if self._plan == NULL:
+ *             if 'FFTW_WISDOM_ONLY' in flags:             # <<<<<<<<<<<<<<
+ *                 raise RuntimeError('No FFTW wisdom is known for this plan.')
  *             else:
- *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
- *                 info.format[0] = c'^' # Native data types, manual alignment
- *                 offset = 0
  */
-    __pyx_v_info->format = ((char *)malloc(255));
+    __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_n_s_FFTW_WISDOM_ONLY, __pyx_v_flags, Py_EQ)); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1107; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_21 = (__pyx_t_2 != 0);
+    if (__pyx_t_21) {
 
-    /* "numpy.pxd":281
+      /* "pyfftw/pyfftw.pyx":1108
+ *         if self._plan == NULL:
+ *             if 'FFTW_WISDOM_ONLY' in flags:
+ *                 raise RuntimeError('No FFTW wisdom is known for this plan.')             # <<<<<<<<<<<<<<
  *             else:
- *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
- *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
- *                 offset = 0
- *                 f = _util_dtypestring(descr, info.format + 1,
+ *                 raise RuntimeError('The data has an uncaught error that led '+
  */
-    (__pyx_v_info->format[0]) = '^';
+      __pyx_t_11 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__19, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_Raise(__pyx_t_11, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-    /* "numpy.pxd":282
- *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
- *                 info.format[0] = c'^' # Native data types, manual alignment
- *                 offset = 0             # <<<<<<<<<<<<<<
- *                 f = _util_dtypestring(descr, info.format + 1,
- *                                       info.format + _buffer_format_string_len,
+      /* "pyfftw/pyfftw.pyx":1107
+ * 
+ *         if self._plan == NULL:
+ *             if 'FFTW_WISDOM_ONLY' in flags:             # <<<<<<<<<<<<<<
+ *                 raise RuntimeError('No FFTW wisdom is known for this plan.')
+ *             else:
  */
-    __pyx_v_offset = 0;
+    }
 
-    /* "numpy.pxd":285
- *                 f = _util_dtypestring(descr, info.format + 1,
- *                                       info.format + _buffer_format_string_len,
- *                                       &offset)             # <<<<<<<<<<<<<<
- *                 f[0] = c'\0' # Terminate format string
+    /* "pyfftw/pyfftw.pyx":1110
+ *                 raise RuntimeError('No FFTW wisdom is known for this plan.')
+ *             else:
+ *                 raise RuntimeError('The data has an uncaught error that led '+             # <<<<<<<<<<<<<<
+ *                     'to the planner returning NULL. This is a bug.')
  * 
  */
-    __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 255), (&__pyx_v_offset)); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __pyx_v_f = __pyx_t_9;
+    /*else*/ {
+      __pyx_t_11 = PyNumber_Add(__pyx_kp_s_The_data_has_an_uncaught_error_t, __pyx_kp_s_to_the_planner_returning_NULL_Th); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __pyx_t_10 = PyTuple_New(1); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_10);
+      __Pyx_GIVEREF(__pyx_t_11);
+      PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_11);
+      __pyx_t_11 = 0;
+      __pyx_t_11 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_t_10, NULL); if (unlikely(!__pyx_t_11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_11);
+      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+      __Pyx_Raise(__pyx_t_11, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
 
-    /* "numpy.pxd":286
- *                                       info.format + _buffer_format_string_len,
- *                                       &offset)
- *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":1106
+ *         self._plan = plan
  * 
- *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *         if self._plan == NULL:             # <<<<<<<<<<<<<<
+ *             if 'FFTW_WISDOM_ONLY' in flags:
+ *                 raise RuntimeError('No FFTW wisdom is known for this plan.')
  */
-    (__pyx_v_f[0]) = '\x00';
   }
-  __pyx_L11:;
 
+  /* "pyfftw/pyfftw.pyx":811
+ *     axes = property(_get_axes)
+ * 
+ *     def __cinit__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
+ *                   direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
+ *                   unsigned int threads=1, planning_timelimit=None,
+ */
+
+  /* function exit code */
   __pyx_r = 0;
   goto __pyx_L0;
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_8);
-  __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_9);
+  __Pyx_XDECREF(__pyx_t_10);
+  __Pyx_XDECREF(__pyx_t_11);
+  __Pyx_XDECREF(__pyx_t_19);
+  __Pyx_XDECREF(__pyx_t_20);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = -1;
-  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
-    __Pyx_GOTREF(__pyx_v_info->obj);
-    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
-  }
-  goto __pyx_L2;
   __pyx_L0:;
-  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
-    __Pyx_GOTREF(Py_None);
-    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
-  }
-  __pyx_L2:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+  __Pyx_XDECREF(__pyx_v_input_dtype);
+  __Pyx_XDECREF(__pyx_v_output_dtype);
+  __Pyx_XDECREF(__pyx_v_scheme);
+  __Pyx_XDECREF(__pyx_v_functions);
+  __Pyx_XDECREF(__pyx_v_each_alignment);
+  __Pyx_XDECREF(__pyx_v_total_N);
+  __Pyx_XDECREF(__pyx_v_each_flag);
+  __Pyx_XDECREF(__pyx_v_fft_shape_lookup);
+  __Pyx_XDECREF(__pyx_v_fft_shape);
+  __Pyx_XDECREF(__pyx_v_input_strides_array);
+  __Pyx_XDECREF(__pyx_v_output_strides_array);
+  __Pyx_XDECREF(__pyx_v_stride);
+  __Pyx_XDECREF(__pyx_v_flags);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* Python wrapper */
-static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
-static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
-  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
-  __Pyx_RefNannyFinishContext();
-}
-
-/* "numpy.pxd":288
- *                 f[0] = c'\0' # Terminate format string
+/* "pyfftw/pyfftw.pyx":1113
+ *                     'to the planner returning NULL. This is a bug.')
  * 
- *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
- *             if PyArray_HASFIELDS(self):
- *                 stdlib.free(info.format)
+ *     def __init__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
+ *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
+ *             int threads=1, planning_timelimit=None):
  */
 
-static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+/* Python wrapper */
+static int __pyx_pw_6pyfftw_6pyfftw_4FFTW_33__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_32__init__[] = "\n        **Arguments**:\n\n        * ``input_array`` and ``output_array`` should be numpy arrays.\n          The contents of these arrays will be destroyed by the planning \n          process during initialisation. Information on supported \n          dtypes for the arrays is :ref:`given below <scheme_table>`.\n        \n        * ``axes`` describes along which axes the DFT should be taken.\n          This should be a valid lis [...]
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_32__init__;
+#endif
+static int __pyx_pw_6pyfftw_6pyfftw_4FFTW_33__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  CYTHON_UNUSED PyObject *__pyx_v_input_array = 0;
+  CYTHON_UNUSED PyObject *__pyx_v_output_array = 0;
+  CYTHON_UNUSED PyObject *__pyx_v_axes = 0;
+  CYTHON_UNUSED PyObject *__pyx_v_direction = 0;
+  CYTHON_UNUSED PyObject *__pyx_v_flags = 0;
+  CYTHON_UNUSED int __pyx_v_threads;
+  CYTHON_UNUSED PyObject *__pyx_v_planning_timelimit = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  int __pyx_r;
   __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_array,&__pyx_n_s_output_array,&__pyx_n_s_axes,&__pyx_n_s_direction,&__pyx_n_s_flags,&__pyx_n_s_threads,&__pyx_n_s_planning_timelimit,0};
+    PyObject* values[7] = {0,0,0,0,0,0,0};
+    values[2] = ((PyObject *)__pyx_tuple__20);
+    values[3] = ((PyObject *)__pyx_n_s_FFTW_FORWARD);
 
-  /* "numpy.pxd":289
+    /* "pyfftw/pyfftw.pyx":1114
  * 
- *         def __releasebuffer__(ndarray self, Py_buffer* info):
- *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
- *                 stdlib.free(info.format)
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *     def __init__(self, input_array, output_array, axes=(-1,),
+ *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),             # <<<<<<<<<<<<<<
+ *             int threads=1, planning_timelimit=None):
+ *         '''
  */
-  __pyx_t_1 = PyArray_HASFIELDS(__pyx_v_self);
-  if (__pyx_t_1) {
+    values[4] = ((PyObject *)__pyx_tuple__21);
 
-    /* "numpy.pxd":290
- *         def __releasebuffer__(ndarray self, Py_buffer* info):
- *             if PyArray_HASFIELDS(self):
- *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
- *                 stdlib.free(info.strides)
+    /* "pyfftw/pyfftw.pyx":1115
+ *     def __init__(self, input_array, output_array, axes=(-1,),
+ *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
+ *             int threads=1, planning_timelimit=None):             # <<<<<<<<<<<<<<
+ *         '''
+ *         **Arguments**:
  */
-    free(__pyx_v_info->format);
-    goto __pyx_L3;
-  }
-  __pyx_L3:;
-
-  /* "numpy.pxd":291
- *             if PyArray_HASFIELDS(self):
- *                 stdlib.free(info.format)
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
- *                 stdlib.free(info.strides)
- *                 # info.shape was stored after info.strides in the same block
- */
-  __pyx_t_1 = ((sizeof(npy_intp)) != (sizeof(Py_ssize_t)));
-  if (__pyx_t_1) {
+    values[6] = ((PyObject *)Py_None);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_array)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_array)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("__init__", 0, 2, 7, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_axes);
+          if (value) { values[2] = value; kw_args--; }
+        }
+        case  3:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_direction);
+          if (value) { values[3] = value; kw_args--; }
+        }
+        case  4:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_flags);
+          if (value) { values[4] = value; kw_args--; }
+        }
+        case  5:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_threads);
+          if (value) { values[5] = value; kw_args--; }
+        }
+        case  6:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_planning_timelimit);
+          if (value) { values[6] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
+        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
+        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
+        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_input_array = values[0];
+    __pyx_v_output_array = values[1];
+    __pyx_v_axes = values[2];
+    __pyx_v_direction = values[3];
+    __pyx_v_flags = values[4];
+    if (values[5]) {
+      __pyx_v_threads = __Pyx_PyInt_As_int(values[5]); if (unlikely((__pyx_v_threads == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1115; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+    } else {
+      __pyx_v_threads = ((int)1);
+    }
+    __pyx_v_planning_timelimit = values[6];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__init__", 0, 2, 7, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return -1;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_32__init__(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self), __pyx_v_input_array, __pyx_v_output_array, __pyx_v_axes, __pyx_v_direction, __pyx_v_flags, __pyx_v_threads, __pyx_v_planning_timelimit);
 
-    /* "numpy.pxd":292
- *                 stdlib.free(info.format)
- *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
- *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
- *                 # info.shape was stored after info.strides in the same block
+  /* "pyfftw/pyfftw.pyx":1113
+ *                     'to the planner returning NULL. This is a bug.')
  * 
+ *     def __init__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
+ *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
+ *             int threads=1, planning_timelimit=None):
  */
-    free(__pyx_v_info->strides);
-    goto __pyx_L4;
-  }
-  __pyx_L4:;
 
+  /* function exit code */
   __Pyx_RefNannyFinishContext();
+  return __pyx_r;
 }
 
-/* "numpy.pxd":768
- * ctypedef npy_cdouble     complex_t
- * 
- * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(1, <void*>a)
- * 
- */
-
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
-  PyObject *__pyx_r = NULL;
+static int __pyx_pf_6pyfftw_6pyfftw_4FFTW_32__init__(CYTHON_UNUSED struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, CYTHON_UNUSED PyObject *__pyx_v_input_array, CYTHON_UNUSED PyObject *__pyx_v_output_array, CYTHON_UNUSED PyObject *__pyx_v_axes, CYTHON_UNUSED PyObject *__pyx_v_direction, CYTHON_UNUSED PyObject *__pyx_v_flags, CYTHON_UNUSED int __pyx_v_threads, CYTHON_UNUSED PyObject *__pyx_v_planning_timelimit) {
+  int __pyx_r;
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
-
-  /* "numpy.pxd":769
- * 
- * cdef inline object PyArray_MultiIterNew1(a):
- *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
- * 
- * cdef inline object PyArray_MultiIterNew2(a, b):
- */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 769; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
+  __Pyx_RefNannySetupContext("__init__", 0);
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  /* function exit code */
   __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "numpy.pxd":771
- *     return PyArray_MultiIterNew(1, <void*>a)
+/* "pyfftw/pyfftw.pyx":1322
+ *         pass
  * 
- * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ *     def __dealloc__(self):             # <<<<<<<<<<<<<<
  * 
+ *         if not self._axes == NULL:
  */
 
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
-  PyObject *__pyx_r = NULL;
+/* Python wrapper */
+static void __pyx_pw_6pyfftw_6pyfftw_4FFTW_35__dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_pw_6pyfftw_6pyfftw_4FFTW_35__dealloc__(PyObject *__pyx_v_self) {
   __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+  __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
+  __pyx_pf_6pyfftw_6pyfftw_4FFTW_34__dealloc__(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_6pyfftw_6pyfftw_4FFTW_34__dealloc__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__dealloc__", 0);
 
-  /* "numpy.pxd":772
+  /* "pyfftw/pyfftw.pyx":1324
+ *     def __dealloc__(self):
  * 
- * cdef inline object PyArray_MultiIterNew2(a, b):
- *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
+ *         if not self._axes == NULL:             # <<<<<<<<<<<<<<
+ *             free(self._axes)
  * 
- * cdef inline object PyArray_MultiIterNew3(a, b, c):
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 772; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
-
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+  __pyx_t_1 = ((!((__pyx_v_self->_axes == NULL) != 0)) != 0);
+  if (__pyx_t_1) {
 
-/* "numpy.pxd":774
- *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+    /* "pyfftw/pyfftw.pyx":1325
  * 
- * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ *         if not self._axes == NULL:
+ *             free(self._axes)             # <<<<<<<<<<<<<<
  * 
+ *         if not self._not_axes == NULL:
  */
+    free(__pyx_v_self->_axes);
 
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+    /* "pyfftw/pyfftw.pyx":1324
+ *     def __dealloc__(self):
+ * 
+ *         if not self._axes == NULL:             # <<<<<<<<<<<<<<
+ *             free(self._axes)
+ * 
+ */
+  }
 
-  /* "numpy.pxd":775
+  /* "pyfftw/pyfftw.pyx":1327
+ *             free(self._axes)
  * 
- * cdef inline object PyArray_MultiIterNew3(a, b, c):
- *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
+ *         if not self._not_axes == NULL:             # <<<<<<<<<<<<<<
+ *             free(self._not_axes)
  * 
- * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 775; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
+  __pyx_t_1 = ((!((__pyx_v_self->_not_axes == NULL) != 0)) != 0);
+  if (__pyx_t_1) {
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+    /* "pyfftw/pyfftw.pyx":1328
+ * 
+ *         if not self._not_axes == NULL:
+ *             free(self._not_axes)             # <<<<<<<<<<<<<<
+ * 
+ *         if not self._plan == NULL:
+ */
+    free(__pyx_v_self->_not_axes);
 
-/* "numpy.pxd":777
- *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+    /* "pyfftw/pyfftw.pyx":1327
+ *             free(self._axes)
  * 
- * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ *         if not self._not_axes == NULL:             # <<<<<<<<<<<<<<
+ *             free(self._not_axes)
  * 
  */
+  }
 
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+  /* "pyfftw/pyfftw.pyx":1330
+ *             free(self._not_axes)
+ * 
+ *         if not self._plan == NULL:             # <<<<<<<<<<<<<<
+ *             self._fftw_destroy(self._plan)
+ * 
+ */
+  __pyx_t_1 = ((!((__pyx_v_self->_plan == NULL) != 0)) != 0);
+  if (__pyx_t_1) {
 
-  /* "numpy.pxd":778
+    /* "pyfftw/pyfftw.pyx":1331
  * 
- * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
- *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
+ *         if not self._plan == NULL:
+ *             self._fftw_destroy(self._plan)             # <<<<<<<<<<<<<<
  * 
- * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ *         if not self._dims == NULL:
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
+    __pyx_v_self->_fftw_destroy(__pyx_v_self->_plan);
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
+    /* "pyfftw/pyfftw.pyx":1330
+ *             free(self._not_axes)
+ * 
+ *         if not self._plan == NULL:             # <<<<<<<<<<<<<<
+ *             self._fftw_destroy(self._plan)
+ * 
+ */
+  }
 
-/* "numpy.pxd":780
- *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+  /* "pyfftw/pyfftw.pyx":1333
+ *             self._fftw_destroy(self._plan)
  * 
- * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
- *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ *         if not self._dims == NULL:             # <<<<<<<<<<<<<<
+ *             free(self._dims)
  * 
  */
+  __pyx_t_1 = ((!((__pyx_v_self->_dims == NULL) != 0)) != 0);
+  if (__pyx_t_1) {
 
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  int __pyx_lineno = 0;
-  const char *__pyx_filename = NULL;
-  int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+    /* "pyfftw/pyfftw.pyx":1334
+ * 
+ *         if not self._dims == NULL:
+ *             free(self._dims)             # <<<<<<<<<<<<<<
+ * 
+ *         if not self._howmany_dims == NULL:
+ */
+    free(__pyx_v_self->_dims);
 
-  /* "numpy.pxd":781
+    /* "pyfftw/pyfftw.pyx":1333
+ *             self._fftw_destroy(self._plan)
  * 
- * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
- *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
+ *         if not self._dims == NULL:             # <<<<<<<<<<<<<<
+ *             free(self._dims)
  * 
- * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
  */
-  __Pyx_XDECREF(__pyx_r);
-  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 781; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_r = __pyx_t_1;
-  __pyx_t_1 = 0;
-  goto __pyx_L0;
+  }
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
-  __pyx_r = 0;
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
+  /* "pyfftw/pyfftw.pyx":1336
+ *             free(self._dims)
+ * 
+ *         if not self._howmany_dims == NULL:             # <<<<<<<<<<<<<<
+ *             free(self._howmany_dims)
+ * 
+ */
+  __pyx_t_1 = ((!((__pyx_v_self->_howmany_dims == NULL) != 0)) != 0);
+  if (__pyx_t_1) {
+
+    /* "pyfftw/pyfftw.pyx":1337
+ * 
+ *         if not self._howmany_dims == NULL:
+ *             free(self._howmany_dims)             # <<<<<<<<<<<<<<
+ * 
+ *     def __call__(self, input_array=None, output_array=None,
+ */
+    free(__pyx_v_self->_howmany_dims);
+
+    /* "pyfftw/pyfftw.pyx":1336
+ *             free(self._dims)
+ * 
+ *         if not self._howmany_dims == NULL:             # <<<<<<<<<<<<<<
+ *             free(self._howmany_dims)
+ * 
+ */
+  }
+
+  /* "pyfftw/pyfftw.pyx":1322
+ *         pass
+ * 
+ *     def __dealloc__(self):             # <<<<<<<<<<<<<<
+ * 
+ *         if not self._axes == NULL:
+ */
+
+  /* function exit code */
   __Pyx_RefNannyFinishContext();
-  return __pyx_r;
 }
 
-/* "numpy.pxd":783
- *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+/* "pyfftw/pyfftw.pyx":1339
+ *             free(self._howmany_dims)
  * 
- * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
- *     # Recursive utility function used in __getbuffer__ to get format
- *     # string. The new location in the format string is returned.
+ *     def __call__(self, input_array=None, output_array=None,             # <<<<<<<<<<<<<<
+ *             normalise_idft=True):
+ *         '''__call__(input_array=None, output_array=None, normalise_idft=True)
  */
 
-static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
-  PyArray_Descr *__pyx_v_child = 0;
-  int __pyx_v_endian_detector;
-  int __pyx_v_little_endian;
-  PyObject *__pyx_v_fields = 0;
-  PyObject *__pyx_v_childname = NULL;
-  PyObject *__pyx_v_new_offset = NULL;
-  PyObject *__pyx_v_t = NULL;
-  char *__pyx_r;
-  __Pyx_RefNannyDeclarations
-  PyObject *__pyx_t_1 = NULL;
-  Py_ssize_t __pyx_t_2;
-  PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  PyObject *__pyx_t_5 = NULL;
-  PyObject *(*__pyx_t_6)(PyObject *);
-  int __pyx_t_7;
-  int __pyx_t_8;
-  int __pyx_t_9;
-  int __pyx_t_10;
-  long __pyx_t_11;
-  char *__pyx_t_12;
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_37__call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_36__call__[] = "__call__(input_array=None, output_array=None, normalise_idft=True)\n\n        Calling the class instance (optionally) updates the arrays, then\n        calls :meth:`~pyfftw.FFTW.execute`, before optionally normalising \n        the output and returning the output array.\n\n        It has some built-in helpers to make life simpler for the calling\n        functions (as distinct from manually updating the arrays and\n        calli [...]
+#if CYTHON_COMPILING_IN_CPYTHON
+struct wrapperbase __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_36__call__;
+#endif
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_37__call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_input_array = 0;
+  PyObject *__pyx_v_output_array = 0;
+  PyObject *__pyx_v_normalise_idft = 0;
   int __pyx_lineno = 0;
   const char *__pyx_filename = NULL;
   int __pyx_clineno = 0;
-  __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__call__ (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_input_array,&__pyx_n_s_output_array,&__pyx_n_s_normalise_idft,0};
+    PyObject* values[3] = {0,0,0};
+    values[0] = ((PyObject *)Py_None);
+    values[1] = ((PyObject *)Py_None);
 
-  /* "numpy.pxd":790
- *     cdef int delta_offset
- *     cdef tuple i
- *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
- *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
- *     cdef tuple fields
+    /* "pyfftw/pyfftw.pyx":1340
+ * 
+ *     def __call__(self, input_array=None, output_array=None,
+ *             normalise_idft=True):             # <<<<<<<<<<<<<<
+ *         '''__call__(input_array=None, output_array=None, normalise_idft=True)
+ * 
  */
-  __pyx_v_endian_detector = 1;
+    values[2] = ((PyObject *)Py_True);
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_input_array);
+          if (value) { values[0] = value; kw_args--; }
+        }
+        case  1:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_output_array);
+          if (value) { values[1] = value; kw_args--; }
+        }
+        case  2:
+        if (kw_args > 0) {
+          PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_normalise_idft);
+          if (value) { values[2] = value; kw_args--; }
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__call__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1339; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else {
+      switch (PyTuple_GET_SIZE(__pyx_args)) {
+        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+    }
+    __pyx_v_input_array = values[0];
+    __pyx_v_output_array = values[1];
+    __pyx_v_normalise_idft = values[2];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("__call__", 0, 0, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1339; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__call__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_36__call__(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self), __pyx_v_input_array, __pyx_v_output_array, __pyx_v_normalise_idft);
 
-  /* "numpy.pxd":791
- *     cdef tuple i
- *     cdef int endian_detector = 1
- *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
- *     cdef tuple fields
+  /* "pyfftw/pyfftw.pyx":1339
+ *             free(self._howmany_dims)
  * 
+ *     def __call__(self, input_array=None, output_array=None,             # <<<<<<<<<<<<<<
+ *             normalise_idft=True):
+ *         '''__call__(input_array=None, output_array=None, normalise_idft=True)
  */
-  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
 
-  /* "numpy.pxd":794
- *     cdef tuple fields
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_36__call__(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_input_array, PyObject *__pyx_v_output_array, PyObject *__pyx_v_normalise_idft) {
+  int __pyx_v_copy_needed;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  int __pyx_t_3;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__call__", 0);
+  __Pyx_INCREF(__pyx_v_input_array);
+  __Pyx_INCREF(__pyx_v_output_array);
+
+  /* "pyfftw/pyfftw.pyx":1397
+ *         '''
  * 
- *     for childname in descr.names:             # <<<<<<<<<<<<<<
- *         fields = descr.fields[childname]
- *         child, new_offset = fields
+ *         if input_array is not None or output_array is not None:             # <<<<<<<<<<<<<<
+ * 
+ *             if input_array is None:
  */
-  if (unlikely(((PyObject *)__pyx_v_descr->names) == Py_None)) {
-    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
-    {__pyx_filename = __pyx_f[2]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = (__pyx_v_input_array != Py_None);
+  __pyx_t_3 = (__pyx_t_2 != 0);
+  if (!__pyx_t_3) {
+  } else {
+    __pyx_t_1 = __pyx_t_3;
+    goto __pyx_L4_bool_binop_done;
   }
-  __pyx_t_1 = ((PyObject *)__pyx_v_descr->names); __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
-  for (;;) {
-    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
-    #if CYTHON_COMPILING_IN_CPYTHON
-    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    #else
-    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    #endif
-    __Pyx_XDECREF(__pyx_v_childname);
-    __pyx_v_childname = __pyx_t_3;
-    __pyx_t_3 = 0;
+  __pyx_t_3 = (__pyx_v_output_array != Py_None);
+  __pyx_t_2 = (__pyx_t_3 != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L4_bool_binop_done:;
+  if (__pyx_t_1) {
 
-    /* "numpy.pxd":795
+    /* "pyfftw/pyfftw.pyx":1399
+ *         if input_array is not None or output_array is not None:
  * 
- *     for childname in descr.names:
- *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
- *         child, new_offset = fields
+ *             if input_array is None:             # <<<<<<<<<<<<<<
+ *                 input_array = self._input_array
  * 
  */
-    __pyx_t_3 = PyObject_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (!__pyx_t_3) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected tuple, got %.200s", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_XDECREF(((PyObject *)__pyx_v_fields));
-    __pyx_v_fields = ((PyObject*)__pyx_t_3);
-    __pyx_t_3 = 0;
+    __pyx_t_1 = (__pyx_v_input_array == Py_None);
+    __pyx_t_2 = (__pyx_t_1 != 0);
+    if (__pyx_t_2) {
 
-    /* "numpy.pxd":796
- *     for childname in descr.names:
- *         fields = descr.fields[childname]
- *         child, new_offset = fields             # <<<<<<<<<<<<<<
+      /* "pyfftw/pyfftw.pyx":1400
+ * 
+ *             if input_array is None:
+ *                 input_array = self._input_array             # <<<<<<<<<<<<<<
  * 
- *         if (end - f) - (new_offset - offset[0]) < 15:
+ *             if output_array is None:
  */
-    if (likely(PyTuple_CheckExact(((PyObject *)__pyx_v_fields)))) {
-      PyObject* sequence = ((PyObject *)__pyx_v_fields);
-      #if CYTHON_COMPILING_IN_CPYTHON
-      Py_ssize_t size = Py_SIZE(sequence);
-      #else
-      Py_ssize_t size = PySequence_Size(sequence);
-      #endif
-      if (unlikely(size != 2)) {
-        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
-        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
-        {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      }
-      #if CYTHON_COMPILING_IN_CPYTHON
-      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
-      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
-      __Pyx_INCREF(__pyx_t_3);
+      __pyx_t_4 = ((PyObject *)__pyx_v_self->_input_array);
       __Pyx_INCREF(__pyx_t_4);
-      #else
-      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      #endif
-    } else if (1) {
-      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    } else
-    {
-      Py_ssize_t index = -1;
-      __pyx_t_5 = PyObject_GetIter(((PyObject *)__pyx_v_fields)); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_6 = Py_TYPE(__pyx_t_5)->tp_iternext;
-      index = 0; __pyx_t_3 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_3)) goto __pyx_L5_unpacking_failed;
-      __Pyx_GOTREF(__pyx_t_3);
-      index = 1; __pyx_t_4 = __pyx_t_6(__pyx_t_5); if (unlikely(!__pyx_t_4)) goto __pyx_L5_unpacking_failed;
-      __Pyx_GOTREF(__pyx_t_4);
-      if (__Pyx_IternextUnpackEndCheck(__pyx_t_6(__pyx_t_5), 2) < 0) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_t_6 = NULL;
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      goto __pyx_L6_unpacking_done;
-      __pyx_L5_unpacking_failed:;
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_6 = NULL;
-      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
-      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_L6_unpacking_done:;
-    }
-    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_XDECREF(((PyObject *)__pyx_v_child));
-    __pyx_v_child = ((PyArray_Descr *)__pyx_t_3);
-    __pyx_t_3 = 0;
-    __Pyx_XDECREF(__pyx_v_new_offset);
-    __pyx_v_new_offset = __pyx_t_4;
-    __pyx_t_4 = 0;
+      __Pyx_DECREF_SET(__pyx_v_input_array, __pyx_t_4);
+      __pyx_t_4 = 0;
 
-    /* "numpy.pxd":798
- *         child, new_offset = fields
+      /* "pyfftw/pyfftw.pyx":1399
+ *         if input_array is not None or output_array is not None:
  * 
- *         if (end - f) - (new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
- *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ *             if input_array is None:             # <<<<<<<<<<<<<<
+ *                 input_array = self._input_array
  * 
  */
-    __pyx_t_4 = PyInt_FromLong((__pyx_v_end - __pyx_v_f)); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_3 = PyInt_FromLong((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_5 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_5);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_3 = PyNumber_Subtract(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    __pyx_t_5 = PyObject_RichCompare(__pyx_t_3, __pyx_int_15, Py_LT); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-    if (__pyx_t_7) {
+    }
 
-      /* "numpy.pxd":799
+    /* "pyfftw/pyfftw.pyx":1402
+ *                 input_array = self._input_array
  * 
- *         if (end - f) - (new_offset - offset[0]) < 15:
- *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ *             if output_array is None:             # <<<<<<<<<<<<<<
+ *                 output_array = self._output_array
  * 
- *         if ((child.byteorder == c'>' and little_endian) or
  */
-      __pyx_t_5 = PyObject_Call(__pyx_builtin_RuntimeError, ((PyObject *)__pyx_k_tuple_68), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __Pyx_Raise(__pyx_t_5, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      goto __pyx_L7;
-    }
-    __pyx_L7:;
+    __pyx_t_2 = (__pyx_v_output_array == Py_None);
+    __pyx_t_1 = (__pyx_t_2 != 0);
+    if (__pyx_t_1) {
 
-    /* "numpy.pxd":801
- *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+      /* "pyfftw/pyfftw.pyx":1403
+ * 
+ *             if output_array is None:
+ *                 output_array = self._output_array             # <<<<<<<<<<<<<<
+ * 
+ *             if not isinstance(input_array, np.ndarray):
+ */
+      __pyx_t_4 = ((PyObject *)__pyx_v_self->_output_array);
+      __Pyx_INCREF(__pyx_t_4);
+      __Pyx_DECREF_SET(__pyx_v_output_array, __pyx_t_4);
+      __pyx_t_4 = 0;
+
+      /* "pyfftw/pyfftw.pyx":1402
+ *                 input_array = self._input_array
+ * 
+ *             if output_array is None:             # <<<<<<<<<<<<<<
+ *                 output_array = self._output_array
  * 
- *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
- *             (child.byteorder == c'<' and not little_endian)):
- *             raise ValueError(u"Non-native byte order not supported")
  */
-    __pyx_t_7 = (__pyx_v_child->byteorder == '>');
-    if (__pyx_t_7) {
-      __pyx_t_8 = __pyx_v_little_endian;
-    } else {
-      __pyx_t_8 = __pyx_t_7;
     }
-    if (!__pyx_t_8) {
 
-      /* "numpy.pxd":802
+    /* "pyfftw/pyfftw.pyx":1405
+ *                 output_array = self._output_array
  * 
- *         if ((child.byteorder == c'>' and little_endian) or
- *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
- *             raise ValueError(u"Non-native byte order not supported")
- *             # One could encode it in the format string and have Cython
+ *             if not isinstance(input_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *                 copy_needed = True
+ *             elif (not input_array.dtype == self._input_dtype):
  */
-      __pyx_t_7 = (__pyx_v_child->byteorder == '<');
-      if (__pyx_t_7) {
-        __pyx_t_9 = (!__pyx_v_little_endian);
-        __pyx_t_10 = __pyx_t_9;
-      } else {
-        __pyx_t_10 = __pyx_t_7;
-      }
-      __pyx_t_7 = __pyx_t_10;
-    } else {
-      __pyx_t_7 = __pyx_t_8;
+    __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray); 
+    __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+    if (__pyx_t_2) {
+
+      /* "pyfftw/pyfftw.pyx":1406
+ * 
+ *             if not isinstance(input_array, np.ndarray):
+ *                 copy_needed = True             # <<<<<<<<<<<<<<
+ *             elif (not input_array.dtype == self._input_dtype):
+ *                 copy_needed = True
+ */
+      __pyx_v_copy_needed = 1;
+
+      /* "pyfftw/pyfftw.pyx":1405
+ *                 output_array = self._output_array
+ * 
+ *             if not isinstance(input_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *                 copy_needed = True
+ *             elif (not input_array.dtype == self._input_dtype):
+ */
+      goto __pyx_L8;
     }
-    if (__pyx_t_7) {
 
-      /* "numpy.pxd":803
- *         if ((child.byteorder == c'>' and little_endian) or
- *             (child.byteorder == c'<' and not little_endian)):
- *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
- *             # One could encode it in the format string and have Cython
- *             # complain instead, BUT: < and > in format strings also imply
+    /* "pyfftw/pyfftw.pyx":1407
+ *             if not isinstance(input_array, np.ndarray):
+ *                 copy_needed = True
+ *             elif (not input_array.dtype == self._input_dtype):             # <<<<<<<<<<<<<<
+ *                 copy_needed = True
+ *             elif (not input_array.strides == self._input_strides):
+ */
+    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_array, __pyx_n_s_dtype); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = PyObject_RichCompare(__pyx_t_4, __pyx_v_self->_input_dtype, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1407; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_1 = ((!__pyx_t_2) != 0);
+    if (__pyx_t_1) {
+
+      /* "pyfftw/pyfftw.pyx":1408
+ *                 copy_needed = True
+ *             elif (not input_array.dtype == self._input_dtype):
+ *                 copy_needed = True             # <<<<<<<<<<<<<<
+ *             elif (not input_array.strides == self._input_strides):
+ *                 copy_needed = True
+ */
+      __pyx_v_copy_needed = 1;
+
+      /* "pyfftw/pyfftw.pyx":1407
+ *             if not isinstance(input_array, np.ndarray):
+ *                 copy_needed = True
+ *             elif (not input_array.dtype == self._input_dtype):             # <<<<<<<<<<<<<<
+ *                 copy_needed = True
+ *             elif (not input_array.strides == self._input_strides):
  */
-      __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_k_tuple_69), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __Pyx_Raise(__pyx_t_5, 0, 0, 0);
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       goto __pyx_L8;
     }
-    __pyx_L8:;
 
-    /* "numpy.pxd":813
- * 
- *         # Output padding bytes
- *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
- *             f[0] = 120 # "x"; pad byte
- *             f += 1
+    /* "pyfftw/pyfftw.pyx":1409
+ *             elif (not input_array.dtype == self._input_dtype):
+ *                 copy_needed = True
+ *             elif (not input_array.strides == self._input_strides):             # <<<<<<<<<<<<<<
+ *                 copy_needed = True
+ *             elif not (<intptr_t>np.PyArray_DATA(input_array)
  */
-    while (1) {
-      __pyx_t_5 = PyInt_FromLong((__pyx_v_offset[0])); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_t_5, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (!__pyx_t_7) break;
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_array, __pyx_n_s_strides); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_v_self->_input_strides, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1409; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_2 = ((!__pyx_t_1) != 0);
+    if (__pyx_t_2) {
 
-      /* "numpy.pxd":814
- *         # Output padding bytes
- *         while offset[0] < new_offset:
- *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
- *             f += 1
- *             offset[0] += 1
+      /* "pyfftw/pyfftw.pyx":1410
+ *                 copy_needed = True
+ *             elif (not input_array.strides == self._input_strides):
+ *                 copy_needed = True             # <<<<<<<<<<<<<<
+ *             elif not (<intptr_t>np.PyArray_DATA(input_array)
+ *                     % self.input_alignment == 0):
  */
-      (__pyx_v_f[0]) = 120;
+      __pyx_v_copy_needed = 1;
 
-      /* "numpy.pxd":815
- *         while offset[0] < new_offset:
- *             f[0] = 120 # "x"; pad byte
- *             f += 1             # <<<<<<<<<<<<<<
- *             offset[0] += 1
- * 
+      /* "pyfftw/pyfftw.pyx":1409
+ *             elif (not input_array.dtype == self._input_dtype):
+ *                 copy_needed = True
+ *             elif (not input_array.strides == self._input_strides):             # <<<<<<<<<<<<<<
+ *                 copy_needed = True
+ *             elif not (<intptr_t>np.PyArray_DATA(input_array)
  */
-      __pyx_v_f = (__pyx_v_f + 1);
+      goto __pyx_L8;
+    }
 
-      /* "numpy.pxd":816
- *             f[0] = 120 # "x"; pad byte
- *             f += 1
- *             offset[0] += 1             # <<<<<<<<<<<<<<
- * 
- *         offset[0] += child.itemsize
+    /* "pyfftw/pyfftw.pyx":1411
+ *             elif (not input_array.strides == self._input_strides):
+ *                 copy_needed = True
+ *             elif not (<intptr_t>np.PyArray_DATA(input_array)             # <<<<<<<<<<<<<<
+ *                     % self.input_alignment == 0):
+ *                 copy_needed = True
  */
-      __pyx_t_11 = 0;
-      (__pyx_v_offset[__pyx_t_11]) = ((__pyx_v_offset[__pyx_t_11]) + 1);
+    if (!(likely(((__pyx_v_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_4 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_v_input_array)))); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+
+    /* "pyfftw/pyfftw.pyx":1412
+ *                 copy_needed = True
+ *             elif not (<intptr_t>np.PyArray_DATA(input_array)
+ *                     % self.input_alignment == 0):             # <<<<<<<<<<<<<<
+ *                 copy_needed = True
+ *             else:
+ */
+    __pyx_t_5 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_alignment); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __pyx_t_6 = PyNumber_Remainder(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+    __pyx_t_5 = __Pyx_PyInt_EqObjC(__pyx_t_6, __pyx_int_0, 0, 0); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1412; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+
+    /* "pyfftw/pyfftw.pyx":1411
+ *             elif (not input_array.strides == self._input_strides):
+ *                 copy_needed = True
+ *             elif not (<intptr_t>np.PyArray_DATA(input_array)             # <<<<<<<<<<<<<<
+ *                     % self.input_alignment == 0):
+ *                 copy_needed = True
+ */
+    __pyx_t_1 = ((!__pyx_t_2) != 0);
+    if (__pyx_t_1) {
+
+      /* "pyfftw/pyfftw.pyx":1413
+ *             elif not (<intptr_t>np.PyArray_DATA(input_array)
+ *                     % self.input_alignment == 0):
+ *                 copy_needed = True             # <<<<<<<<<<<<<<
+ *             else:
+ *                 copy_needed = False
+ */
+      __pyx_v_copy_needed = 1;
+
+      /* "pyfftw/pyfftw.pyx":1411
+ *             elif (not input_array.strides == self._input_strides):
+ *                 copy_needed = True
+ *             elif not (<intptr_t>np.PyArray_DATA(input_array)             # <<<<<<<<<<<<<<
+ *                     % self.input_alignment == 0):
+ *                 copy_needed = True
+ */
+      goto __pyx_L8;
     }
 
-    /* "numpy.pxd":818
- *             offset[0] += 1
- * 
- *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":1415
+ *                 copy_needed = True
+ *             else:
+ *                 copy_needed = False             # <<<<<<<<<<<<<<
  * 
- *         if not PyDataType_HASFIELDS(child):
+ *             if copy_needed:
  */
-    __pyx_t_11 = 0;
-    (__pyx_v_offset[__pyx_t_11]) = ((__pyx_v_offset[__pyx_t_11]) + __pyx_v_child->elsize);
+    /*else*/ {
+      __pyx_v_copy_needed = 0;
+    }
+    __pyx_L8:;
 
-    /* "numpy.pxd":820
- *         offset[0] += child.itemsize
+    /* "pyfftw/pyfftw.pyx":1417
+ *                 copy_needed = False
  * 
- *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
- *             t = child.type_num
- *             if end - f < 5:
+ *             if copy_needed:             # <<<<<<<<<<<<<<
+ * 
+ *                 if not isinstance(input_array, np.ndarray):
  */
-    __pyx_t_7 = (!PyDataType_HASFIELDS(__pyx_v_child));
-    if (__pyx_t_7) {
+    __pyx_t_1 = (__pyx_v_copy_needed != 0);
+    if (__pyx_t_1) {
 
-      /* "numpy.pxd":821
+      /* "pyfftw/pyfftw.pyx":1419
+ *             if copy_needed:
+ * 
+ *                 if not isinstance(input_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *                     input_array = np.asanyarray(input_array)
  * 
- *         if not PyDataType_HASFIELDS(child):
- *             t = child.type_num             # <<<<<<<<<<<<<<
- *             if end - f < 5:
- *                 raise RuntimeError(u"Format string allocated too short.")
  */
-      __pyx_t_3 = PyInt_FromLong(__pyx_v_child->type_num); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __Pyx_XDECREF(__pyx_v_t);
-      __pyx_v_t = __pyx_t_3;
-      __pyx_t_3 = 0;
+      __pyx_t_1 = __Pyx_TypeCheck(__pyx_v_input_array, __pyx_ptype_5numpy_ndarray); 
+      __pyx_t_2 = ((!(__pyx_t_1 != 0)) != 0);
+      if (__pyx_t_2) {
 
-      /* "numpy.pxd":822
- *         if not PyDataType_HASFIELDS(child):
- *             t = child.type_num
- *             if end - f < 5:             # <<<<<<<<<<<<<<
- *                 raise RuntimeError(u"Format string allocated too short.")
+        /* "pyfftw/pyfftw.pyx":1420
  * 
+ *                 if not isinstance(input_array, np.ndarray):
+ *                     input_array = np.asanyarray(input_array)             # <<<<<<<<<<<<<<
+ * 
+ *                 if not input_array.shape == self._input_shape:
  */
-      __pyx_t_7 = ((__pyx_v_end - __pyx_v_f) < 5);
-      if (__pyx_t_7) {
+        __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_6);
+        __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_asanyarray); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+        __pyx_t_6 = NULL;
+        if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) {
+          __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
+          if (likely(__pyx_t_6)) {
+            PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
+            __Pyx_INCREF(__pyx_t_6);
+            __Pyx_INCREF(function);
+            __Pyx_DECREF_SET(__pyx_t_4, function);
+          }
+        }
+        if (!__pyx_t_6) {
+          __pyx_t_5 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_v_input_array); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_5);
+        } else {
+          __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_7);
+          __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
+          __Pyx_INCREF(__pyx_v_input_array);
+          __Pyx_GIVEREF(__pyx_v_input_array);
+          PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_input_array);
+          __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+          __Pyx_GOTREF(__pyx_t_5);
+          __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+        }
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_DECREF_SET(__pyx_v_input_array, __pyx_t_5);
+        __pyx_t_5 = 0;
 
-        /* "numpy.pxd":823
- *             t = child.type_num
- *             if end - f < 5:
- *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+        /* "pyfftw/pyfftw.pyx":1419
+ *             if copy_needed:
+ * 
+ *                 if not isinstance(input_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *                     input_array = np.asanyarray(input_array)
  * 
- *             # Until ticket #99 is fixed, use integers to avoid warnings
  */
-        __pyx_t_3 = PyObject_Call(__pyx_builtin_RuntimeError, ((PyObject *)__pyx_k_tuple_71), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_3);
-        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-        {__pyx_filename = __pyx_f[2]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        goto __pyx_L12;
       }
-      __pyx_L12:;
 
-      /* "numpy.pxd":826
+      /* "pyfftw/pyfftw.pyx":1422
+ *                     input_array = np.asanyarray(input_array)
  * 
- *             # Until ticket #99 is fixed, use integers to avoid warnings
- *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
- *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
- *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *                 if not input_array.shape == self._input_shape:             # <<<<<<<<<<<<<<
+ *                     raise ValueError('Invalid input shape: '
+ *                             'The new input array should be the same shape '
  */
-      __pyx_t_3 = PyInt_FromLong(NPY_BYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_input_array, __pyx_n_s_shape); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_5);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_5, __pyx_v_self->_input_shape, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
       __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 98;
-        goto __pyx_L13;
-      }
+      __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_2 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_1 = ((!__pyx_t_2) != 0);
+      if (__pyx_t_1) {
 
-      /* "numpy.pxd":827
- *             # Until ticket #99 is fixed, use integers to avoid warnings
- *             if   t == NPY_BYTE:        f[0] =  98 #"b"
- *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
- *             elif t == NPY_SHORT:       f[0] = 104 #"h"
- *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+        /* "pyfftw/pyfftw.pyx":1423
+ * 
+ *                 if not input_array.shape == self._input_shape:
+ *                     raise ValueError('Invalid input shape: '             # <<<<<<<<<<<<<<
+ *                             'The new input array should be the same shape '
+ *                             'as the input array used to instantiate the '
+ */
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__22, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+        /* "pyfftw/pyfftw.pyx":1422
+ *                     input_array = np.asanyarray(input_array)
+ * 
+ *                 if not input_array.shape == self._input_shape:             # <<<<<<<<<<<<<<
+ *                     raise ValueError('Invalid input shape: '
+ *                             'The new input array should be the same shape '
  */
-      __pyx_t_5 = PyInt_FromLong(NPY_UBYTE); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 66;
-        goto __pyx_L13;
       }
 
-      /* "numpy.pxd":828
- *             if   t == NPY_BYTE:        f[0] =  98 #"b"
- *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
- *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
- *             elif t == NPY_USHORT:      f[0] =  72 #"H"
- *             elif t == NPY_INT:         f[0] = 105 #"i"
- */
-      __pyx_t_3 = PyInt_FromLong(NPY_SHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 104;
-        goto __pyx_L13;
-      }
-
-      /* "numpy.pxd":829
- *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
- *             elif t == NPY_SHORT:       f[0] = 104 #"h"
- *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
- *             elif t == NPY_INT:         f[0] = 105 #"i"
- *             elif t == NPY_UINT:        f[0] =  73 #"I"
- */
-      __pyx_t_5 = PyInt_FromLong(NPY_USHORT); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 72;
-        goto __pyx_L13;
-      }
-
-      /* "numpy.pxd":830
- *             elif t == NPY_SHORT:       f[0] = 104 #"h"
- *             elif t == NPY_USHORT:      f[0] =  72 #"H"
- *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
- *             elif t == NPY_UINT:        f[0] =  73 #"I"
- *             elif t == NPY_LONG:        f[0] = 108 #"l"
- */
-      __pyx_t_3 = PyInt_FromLong(NPY_INT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 105;
-        goto __pyx_L13;
-      }
-
-      /* "numpy.pxd":831
- *             elif t == NPY_USHORT:      f[0] =  72 #"H"
- *             elif t == NPY_INT:         f[0] = 105 #"i"
- *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
- *             elif t == NPY_LONG:        f[0] = 108 #"l"
- *             elif t == NPY_ULONG:       f[0] = 76  #"L"
- */
-      __pyx_t_5 = PyInt_FromLong(NPY_UINT); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 73;
-        goto __pyx_L13;
-      }
-
-      /* "numpy.pxd":832
- *             elif t == NPY_INT:         f[0] = 105 #"i"
- *             elif t == NPY_UINT:        f[0] =  73 #"I"
- *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
- *             elif t == NPY_ULONG:       f[0] = 76  #"L"
- *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
- */
-      __pyx_t_3 = PyInt_FromLong(NPY_LONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 108;
-        goto __pyx_L13;
-      }
-
-      /* "numpy.pxd":833
- *             elif t == NPY_UINT:        f[0] =  73 #"I"
- *             elif t == NPY_LONG:        f[0] = 108 #"l"
- *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
- *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
- *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
- */
-      __pyx_t_5 = PyInt_FromLong(NPY_ULONG); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 76;
-        goto __pyx_L13;
-      }
-
-      /* "numpy.pxd":834
- *             elif t == NPY_LONG:        f[0] = 108 #"l"
- *             elif t == NPY_ULONG:       f[0] = 76  #"L"
- *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
- *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
- *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+      /* "pyfftw/pyfftw.pyx":1428
+ *                             'object.')
+ * 
+ *                 self._input_array[:] = input_array             # <<<<<<<<<<<<<<
+ * 
+ *                 if output_array is not None:
  */
-      __pyx_t_3 = PyInt_FromLong(NPY_LONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 113;
-        goto __pyx_L13;
-      }
+      if (__Pyx_PyObject_SetSlice(((PyObject *)__pyx_v_self->_input_array), __pyx_v_input_array, 0, 0, NULL, NULL, &__pyx_slice__23, 0, 0, 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-      /* "numpy.pxd":835
- *             elif t == NPY_ULONG:       f[0] = 76  #"L"
- *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
- *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
- *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
- *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+      /* "pyfftw/pyfftw.pyx":1430
+ *                 self._input_array[:] = input_array
+ * 
+ *                 if output_array is not None:             # <<<<<<<<<<<<<<
+ *                     # No point wasting time if no update is necessary
+ *                     # (which the copy above may have avoided)
  */
-      __pyx_t_5 = PyInt_FromLong(NPY_ULONGLONG); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 81;
-        goto __pyx_L13;
-      }
+      __pyx_t_1 = (__pyx_v_output_array != Py_None);
+      __pyx_t_2 = (__pyx_t_1 != 0);
+      if (__pyx_t_2) {
 
-      /* "numpy.pxd":836
- *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
- *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
- *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
- *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
- *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+        /* "pyfftw/pyfftw.pyx":1433
+ *                     # No point wasting time if no update is necessary
+ *                     # (which the copy above may have avoided)
+ *                     input_array = self._input_array             # <<<<<<<<<<<<<<
+ *                     self.update_arrays(input_array, output_array)
+ * 
  */
-      __pyx_t_3 = PyInt_FromLong(NPY_FLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 102;
-        goto __pyx_L13;
-      }
+        __pyx_t_4 = ((PyObject *)__pyx_v_self->_input_array);
+        __Pyx_INCREF(__pyx_t_4);
+        __Pyx_DECREF_SET(__pyx_v_input_array, __pyx_t_4);
+        __pyx_t_4 = 0;
 
-      /* "numpy.pxd":837
- *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
- *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
- *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
- *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
- *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+        /* "pyfftw/pyfftw.pyx":1434
+ *                     # (which the copy above may have avoided)
+ *                     input_array = self._input_array
+ *                     self.update_arrays(input_array, output_array)             # <<<<<<<<<<<<<<
+ * 
+ *             else:
  */
-      __pyx_t_5 = PyInt_FromLong(NPY_DOUBLE); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 100;
-        goto __pyx_L13;
-      }
+        __pyx_t_4 = ((struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *)__pyx_v_self->__pyx_vtab)->update_arrays(__pyx_v_self, __pyx_v_input_array, __pyx_v_output_array, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-      /* "numpy.pxd":838
- *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
- *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
- *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
- *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
- *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+        /* "pyfftw/pyfftw.pyx":1430
+ *                 self._input_array[:] = input_array
+ * 
+ *                 if output_array is not None:             # <<<<<<<<<<<<<<
+ *                     # No point wasting time if no update is necessary
+ *                     # (which the copy above may have avoided)
  */
-      __pyx_t_3 = PyInt_FromLong(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 103;
-        goto __pyx_L13;
       }
 
-      /* "numpy.pxd":839
- *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
- *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
- *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
- *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
- *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+      /* "pyfftw/pyfftw.pyx":1417
+ *                 copy_needed = False
+ * 
+ *             if copy_needed:             # <<<<<<<<<<<<<<
+ * 
+ *                 if not isinstance(input_array, np.ndarray):
  */
-      __pyx_t_5 = PyInt_FromLong(NPY_CFLOAT); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 90;
-        (__pyx_v_f[1]) = 102;
-        __pyx_v_f = (__pyx_v_f + 1);
-        goto __pyx_L13;
-      }
+      goto __pyx_L9;
+    }
 
-      /* "numpy.pxd":840
- *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
- *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
- *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
- *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
- *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+    /* "pyfftw/pyfftw.pyx":1437
+ * 
+ *             else:
+ *                 self.update_arrays(input_array, output_array)             # <<<<<<<<<<<<<<
+ * 
+ *         self.execute()
  */
-      __pyx_t_3 = PyInt_FromLong(NPY_CDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 90;
-        (__pyx_v_f[1]) = 100;
-        __pyx_v_f = (__pyx_v_f + 1);
-        goto __pyx_L13;
-      }
+    /*else*/ {
+      __pyx_t_4 = ((struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *)__pyx_v_self->__pyx_vtab)->update_arrays(__pyx_v_self, __pyx_v_input_array, __pyx_v_output_array, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    }
+    __pyx_L9:;
 
-      /* "numpy.pxd":841
- *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
- *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
- *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
- *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
- *             else:
+    /* "pyfftw/pyfftw.pyx":1397
+ *         '''
+ * 
+ *         if input_array is not None or output_array is not None:             # <<<<<<<<<<<<<<
+ * 
+ *             if input_array is None:
  */
-      __pyx_t_5 = PyInt_FromLong(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_5);
-      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_5, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 90;
-        (__pyx_v_f[1]) = 103;
-        __pyx_v_f = (__pyx_v_f + 1);
-        goto __pyx_L13;
-      }
+  }
 
-      /* "numpy.pxd":842
- *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
- *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
- *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
- *             else:
- *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+  /* "pyfftw/pyfftw.pyx":1439
+ *                 self.update_arrays(input_array, output_array)
+ * 
+ *         self.execute()             # <<<<<<<<<<<<<<
+ * 
+ *         if self._direction == FFTW_BACKWARD and normalise_idft:
  */
-      __pyx_t_3 = PyInt_FromLong(NPY_OBJECT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_GOTREF(__pyx_t_3);
-      __pyx_t_5 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-      __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-      if (__pyx_t_7) {
-        (__pyx_v_f[0]) = 79;
-        goto __pyx_L13;
-      }
-      /*else*/ {
+  __pyx_t_4 = ((struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *)__pyx_v_self->__pyx_vtab)->execute(__pyx_v_self, 0); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1439; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 
-        /* "numpy.pxd":844
- *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
- *             else:
- *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
- *             f += 1
- *         else:
+  /* "pyfftw/pyfftw.pyx":1441
+ *         self.execute()
+ * 
+ *         if self._direction == FFTW_BACKWARD and normalise_idft:             # <<<<<<<<<<<<<<
+ *             self._output_array *= self._normalisation_scaling
+ * 
  */
-        __pyx_t_5 = PyNumber_Remainder(((PyObject *)__pyx_kp_u_66), __pyx_v_t); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(((PyObject *)__pyx_t_5));
-        __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_3);
-        PyTuple_SET_ITEM(__pyx_t_3, 0, ((PyObject *)__pyx_t_5));
-        __Pyx_GIVEREF(((PyObject *)__pyx_t_5));
-        __pyx_t_5 = 0;
-        __pyx_t_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_t_3), NULL); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-        __Pyx_GOTREF(__pyx_t_5);
-        __Pyx_DECREF(((PyObject *)__pyx_t_3)); __pyx_t_3 = 0;
-        __Pyx_Raise(__pyx_t_5, 0, 0, 0);
-        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
-        {__pyx_filename = __pyx_f[2]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      }
-      __pyx_L13:;
+  __pyx_t_1 = ((__pyx_v_self->_direction == __pyx_e_6pyfftw_6pyfftw_FFTW_BACKWARD) != 0);
+  if (__pyx_t_1) {
+  } else {
+    __pyx_t_2 = __pyx_t_1;
+    goto __pyx_L14_bool_binop_done;
+  }
+  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_normalise_idft); if (unlikely(__pyx_t_1 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __pyx_t_1;
+  __pyx_L14_bool_binop_done:;
+  if (__pyx_t_2) {
 
-      /* "numpy.pxd":845
- *             else:
- *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
- *             f += 1             # <<<<<<<<<<<<<<
- *         else:
- *             # Cython ignores struct boundary information ("T{...}"),
+    /* "pyfftw/pyfftw.pyx":1442
+ * 
+ *         if self._direction == FFTW_BACKWARD and normalise_idft:
+ *             self._output_array *= self._normalisation_scaling             # <<<<<<<<<<<<<<
+ * 
+ *         return self._output_array
  */
-      __pyx_v_f = (__pyx_v_f + 1);
-      goto __pyx_L11;
-    }
-    /*else*/ {
+    __pyx_t_4 = PyFloat_FromDouble(__pyx_v_self->_normalisation_scaling); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_5 = PyNumber_InPlaceMultiply(((PyObject *)__pyx_v_self->_output_array), __pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_5);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    if (!(likely(((__pyx_t_5) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_5, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GIVEREF(__pyx_t_5);
+    __Pyx_GOTREF(__pyx_v_self->_output_array);
+    __Pyx_DECREF(((PyObject *)__pyx_v_self->_output_array));
+    __pyx_v_self->_output_array = ((PyArrayObject *)__pyx_t_5);
+    __pyx_t_5 = 0;
 
-      /* "numpy.pxd":849
- *             # Cython ignores struct boundary information ("T{...}"),
- *             # so don't output it
- *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
- *     return f
+    /* "pyfftw/pyfftw.pyx":1441
+ *         self.execute()
+ * 
+ *         if self._direction == FFTW_BACKWARD and normalise_idft:             # <<<<<<<<<<<<<<
+ *             self._output_array *= self._normalisation_scaling
  * 
  */
-      __pyx_t_12 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_12 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-      __pyx_v_f = __pyx_t_12;
-    }
-    __pyx_L11:;
   }
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "numpy.pxd":850
- *             # so don't output it
- *             f = _util_dtypestring(child, f, end, offset)
- *     return f             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1444
+ *             self._output_array *= self._normalisation_scaling
  * 
+ *         return self._output_array             # <<<<<<<<<<<<<<
  * 
+ *     cpdef update_arrays(self,
  */
-  __pyx_r = __pyx_v_f;
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->_output_array));
+  __pyx_r = ((PyObject *)__pyx_v_self->_output_array);
   goto __pyx_L0;
 
-  __pyx_r = 0;
-  goto __pyx_L0;
+  /* "pyfftw/pyfftw.pyx":1339
+ *             free(self._howmany_dims)
+ * 
+ *     def __call__(self, input_array=None, output_array=None,             # <<<<<<<<<<<<<<
+ *             normalise_idft=True):
+ *         '''__call__(input_array=None, output_array=None, normalise_idft=True)
+ */
+
+  /* function exit code */
   __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_3);
   __Pyx_XDECREF(__pyx_t_4);
   __Pyx_XDECREF(__pyx_t_5);
-  __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.__call__", __pyx_clineno, __pyx_lineno, __pyx_filename);
   __pyx_r = NULL;
   __pyx_L0:;
-  __Pyx_XDECREF((PyObject *)__pyx_v_child);
-  __Pyx_XDECREF(__pyx_v_fields);
-  __Pyx_XDECREF(__pyx_v_childname);
-  __Pyx_XDECREF(__pyx_v_new_offset);
-  __Pyx_XDECREF(__pyx_v_t);
+  __Pyx_XDECREF(__pyx_v_input_array);
+  __Pyx_XDECREF(__pyx_v_output_array);
+  __Pyx_XGIVEREF(__pyx_r);
   __Pyx_RefNannyFinishContext();
   return __pyx_r;
 }
 
-/* "numpy.pxd":965
- * 
+/* "pyfftw/pyfftw.pyx":1446
+ *         return self._output_array
  * 
- * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
- *      cdef PyObject* baseptr
- *      if base is None:
+ *     cpdef update_arrays(self,             # <<<<<<<<<<<<<<
+ *             new_input_array, new_output_array):
+ *         '''update_arrays(new_input_array, new_output_array)
  */
 
-static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
-  PyObject *__pyx_v_baseptr;
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_39update_arrays(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_4FFTW_update_arrays(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_new_input_array, PyObject *__pyx_v_new_output_array, int __pyx_skip_dispatch) {
+  PyObject *__pyx_v_new_input_shape = NULL;
+  PyObject *__pyx_v_new_output_shape = NULL;
+  PyObject *__pyx_v_new_input_strides = NULL;
+  PyObject *__pyx_v_new_output_strides = NULL;
+  PyObject *__pyx_r = NULL;
   __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  __Pyx_RefNannySetupContext("set_array_base", 0);
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  Py_ssize_t __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  int __pyx_t_7;
+  int __pyx_t_8;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("update_arrays", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_update_arrays); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_39update_arrays)) {
+      __Pyx_XDECREF(__pyx_r);
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
+      __pyx_t_5 = 0;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+        if (likely(__pyx_t_4)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+          __Pyx_INCREF(__pyx_t_4);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_3, function);
+          __pyx_t_5 = 1;
+        }
+      }
+      __pyx_t_6 = PyTuple_New(2+__pyx_t_5); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      if (__pyx_t_4) {
+        __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_4); __pyx_t_4 = NULL;
+      }
+      __Pyx_INCREF(__pyx_v_new_input_array);
+      __Pyx_GIVEREF(__pyx_v_new_input_array);
+      PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_5, __pyx_v_new_input_array);
+      __Pyx_INCREF(__pyx_v_new_output_array);
+      __Pyx_GIVEREF(__pyx_v_new_output_array);
+      PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_5, __pyx_v_new_output_array);
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_r = __pyx_t_2;
+      __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
 
-  /* "numpy.pxd":967
- * cdef inline void set_array_base(ndarray arr, object base):
- *      cdef PyObject* baseptr
- *      if base is None:             # <<<<<<<<<<<<<<
- *          baseptr = NULL
- *      else:
+  /* "pyfftw/pyfftw.pyx":1469
+ *         object will still be in a sane state).
+ *         '''
+ *         if not isinstance(new_input_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input array: '
+ *                     'The new input array needs to be an instance '
  */
-  __pyx_t_1 = (__pyx_v_base == Py_None);
-  if (__pyx_t_1) {
+  __pyx_t_7 = __Pyx_TypeCheck(__pyx_v_new_input_array, __pyx_ptype_5numpy_ndarray); 
+  __pyx_t_8 = ((!(__pyx_t_7 != 0)) != 0);
+  if (__pyx_t_8) {
 
-    /* "numpy.pxd":968
- *      cdef PyObject* baseptr
- *      if base is None:
- *          baseptr = NULL             # <<<<<<<<<<<<<<
- *      else:
- *          Py_INCREF(base) # important to do this before decref below!
+    /* "pyfftw/pyfftw.pyx":1470
+ *         '''
+ *         if not isinstance(new_input_array, np.ndarray):
+ *             raise ValueError('Invalid input array: '             # <<<<<<<<<<<<<<
+ *                     'The new input array needs to be an instance '
+ *                     'of numpy.ndarray')
+ */
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__24, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "pyfftw/pyfftw.pyx":1469
+ *         object will still be in a sane state).
+ *         '''
+ *         if not isinstance(new_input_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input array: '
+ *                     'The new input array needs to be an instance '
  */
-    __pyx_v_baseptr = NULL;
-    goto __pyx_L3;
   }
-  /*else*/ {
 
-    /* "numpy.pxd":970
- *          baseptr = NULL
- *      else:
- *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
- *          baseptr = <PyObject*>base
- *      Py_XDECREF(arr.base)
+  /* "pyfftw/pyfftw.pyx":1474
+ *                     'of numpy.ndarray')
+ * 
+ *         if not isinstance(new_output_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output array '
+ *                     'The new output array needs to be an instance '
  */
-    Py_INCREF(__pyx_v_base);
+  __pyx_t_8 = __Pyx_TypeCheck(__pyx_v_new_output_array, __pyx_ptype_5numpy_ndarray); 
+  __pyx_t_7 = ((!(__pyx_t_8 != 0)) != 0);
+  if (__pyx_t_7) {
 
-    /* "numpy.pxd":971
- *      else:
- *          Py_INCREF(base) # important to do this before decref below!
- *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
- *      Py_XDECREF(arr.base)
- *      arr.base = baseptr
+    /* "pyfftw/pyfftw.pyx":1475
+ * 
+ *         if not isinstance(new_output_array, np.ndarray):
+ *             raise ValueError('Invalid output array '             # <<<<<<<<<<<<<<
+ *                     'The new output array needs to be an instance '
+ *                     'of numpy.ndarray')
+ */
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__25, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "pyfftw/pyfftw.pyx":1474
+ *                     'of numpy.ndarray')
+ * 
+ *         if not isinstance(new_output_array, np.ndarray):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output array '
+ *                     'The new output array needs to be an instance '
  */
-    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
   }
-  __pyx_L3:;
 
-  /* "numpy.pxd":972
- *          Py_INCREF(base) # important to do this before decref below!
- *          baseptr = <PyObject*>base
- *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
- *      arr.base = baseptr
+  /* "pyfftw/pyfftw.pyx":1479
+ *                     'of numpy.ndarray')
  * 
+ *         if not (<intptr_t>np.PyArray_DATA(new_input_array) %             # <<<<<<<<<<<<<<
+ *                 self.input_alignment == 0):
+ *             raise ValueError('Invalid input alignment: '
  */
-  Py_XDECREF(__pyx_v_arr->base);
+  if (!(likely(((__pyx_v_new_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_new_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_v_new_input_array)))); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
 
-  /* "numpy.pxd":973
- *          baseptr = <PyObject*>base
- *      Py_XDECREF(arr.base)
- *      arr.base = baseptr             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1480
  * 
- * cdef inline object get_array_base(ndarray arr):
+ *         if not (<intptr_t>np.PyArray_DATA(new_input_array) %
+ *                 self.input_alignment == 0):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input alignment: '
+ *                     'The original arrays were %d-byte aligned. It is '
  */
-  __pyx_v_arr->base = __pyx_v_baseptr;
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
 
-  __Pyx_RefNannyFinishContext();
-}
+  /* "pyfftw/pyfftw.pyx":1479
+ *                     'of numpy.ndarray')
+ * 
+ *         if not (<intptr_t>np.PyArray_DATA(new_input_array) %             # <<<<<<<<<<<<<<
+ *                 self.input_alignment == 0):
+ *             raise ValueError('Invalid input alignment: '
+ */
+  __pyx_t_3 = PyNumber_Remainder(__pyx_t_1, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1479; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-/* "numpy.pxd":975
- *      arr.base = baseptr
+  /* "pyfftw/pyfftw.pyx":1480
  * 
- * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
- *     if arr.base is NULL:
- *         return None
+ *         if not (<intptr_t>np.PyArray_DATA(new_input_array) %
+ *                 self.input_alignment == 0):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input alignment: '
+ *                     'The original arrays were %d-byte aligned. It is '
  */
+  __pyx_t_2 = __Pyx_PyInt_EqObjC(__pyx_t_3, __pyx_int_0, 0, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
-  PyObject *__pyx_r = NULL;
-  __Pyx_RefNannyDeclarations
-  int __pyx_t_1;
-  __Pyx_RefNannySetupContext("get_array_base", 0);
+  /* "pyfftw/pyfftw.pyx":1479
+ *                     'of numpy.ndarray')
+ * 
+ *         if not (<intptr_t>np.PyArray_DATA(new_input_array) %             # <<<<<<<<<<<<<<
+ *                 self.input_alignment == 0):
+ *             raise ValueError('Invalid input alignment: '
+ */
+  __pyx_t_8 = ((!__pyx_t_7) != 0);
+  if (__pyx_t_8) {
 
-  /* "numpy.pxd":976
+    /* "pyfftw/pyfftw.pyx":1484
+ *                     'The original arrays were %d-byte aligned. It is '
+ *                     'necessary that the update input array is similarly '
+ *                     'aligned.' % self.input_alignment)             # <<<<<<<<<<<<<<
  * 
- * cdef inline object get_array_base(ndarray arr):
- *     if arr.base is NULL:             # <<<<<<<<<<<<<<
- *         return None
- *     else:
+ *         if not (<intptr_t>np.PyArray_DATA(new_output_array) %
  */
-  __pyx_t_1 = (__pyx_v_arr->base == NULL);
-  if (__pyx_t_1) {
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_input_alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_input_alignment_The_orig, __pyx_t_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-    /* "numpy.pxd":977
- * cdef inline object get_array_base(ndarray arr):
- *     if arr.base is NULL:
- *         return None             # <<<<<<<<<<<<<<
- *     else:
- *         return <object>arr.base
+    /* "pyfftw/pyfftw.pyx":1481
+ *         if not (<intptr_t>np.PyArray_DATA(new_input_array) %
+ *                 self.input_alignment == 0):
+ *             raise ValueError('Invalid input alignment: '             # <<<<<<<<<<<<<<
+ *                     'The original arrays were %d-byte aligned. It is '
+ *                     'necessary that the update input array is similarly '
  */
-    __Pyx_XDECREF(__pyx_r);
-    __Pyx_INCREF(Py_None);
-    __pyx_r = Py_None;
-    goto __pyx_L0;
-    goto __pyx_L3;
-  }
-  /*else*/ {
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_3);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_3);
+    __pyx_t_3 = 0;
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_2, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1481; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-    /* "numpy.pxd":979
- *         return None
- *     else:
- *         return <object>arr.base             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":1479
+ *                     'of numpy.ndarray')
+ * 
+ *         if not (<intptr_t>np.PyArray_DATA(new_input_array) %             # <<<<<<<<<<<<<<
+ *                 self.input_alignment == 0):
+ *             raise ValueError('Invalid input alignment: '
  */
-    __Pyx_XDECREF(__pyx_r);
-    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
-    __pyx_r = ((PyObject *)__pyx_v_arr->base);
-    goto __pyx_L0;
   }
-  __pyx_L3:;
 
-  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
-  __pyx_L0:;
-  __Pyx_XGIVEREF(__pyx_r);
-  __Pyx_RefNannyFinishContext();
-  return __pyx_r;
-}
-static struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW __pyx_vtable_6pyfftw_6pyfftw_FFTW;
+  /* "pyfftw/pyfftw.pyx":1486
+ *                     'aligned.' % self.input_alignment)
+ * 
+ *         if not (<intptr_t>np.PyArray_DATA(new_output_array) %             # <<<<<<<<<<<<<<
+ *                 self.output_alignment == 0):
+ *             raise ValueError('Invalid output alignment: '
+ */
+  if (!(likely(((__pyx_v_new_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_new_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_3 = PyInt_FromSsize_t(((intptr_t)PyArray_DATA(((PyArrayObject *)__pyx_v_new_output_array)))); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
 
-static PyObject *__pyx_tp_new_6pyfftw_6pyfftw_FFTW(PyTypeObject *t, PyObject *a, PyObject *k) {
-  struct __pyx_obj_6pyfftw_6pyfftw_FFTW *p;
-  PyObject *o = (*t->tp_alloc)(t, 0);
-  if (!o) return 0;
-  p = ((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)o);
-  p->__pyx_vtab = __pyx_vtabptr_6pyfftw_6pyfftw_FFTW;
-  p->__pyx___input_array = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->__pyx___output_array = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  p->__pyx___input_strides = Py_None; Py_INCREF(Py_None);
-  p->__pyx___input_byte_strides = Py_None; Py_INCREF(Py_None);
-  p->__pyx___output_strides = Py_None; Py_INCREF(Py_None);
-  p->__pyx___output_byte_strides = Py_None; Py_INCREF(Py_None);
-  p->__pyx___input_shape = Py_None; Py_INCREF(Py_None);
-  p->__pyx___output_shape = Py_None; Py_INCREF(Py_None);
-  p->__pyx___input_dtype = Py_None; Py_INCREF(Py_None);
-  p->__pyx___output_dtype = Py_None; Py_INCREF(Py_None);
-  p->__pyx___flags_used = Py_None; Py_INCREF(Py_None);
-  if (__pyx_pw_6pyfftw_6pyfftw_4FFTW_11__cinit__(o, a, k) < 0) {
-    Py_DECREF(o); o = 0;
-  }
-  return o;
-}
-
-static void __pyx_tp_dealloc_6pyfftw_6pyfftw_FFTW(PyObject *o) {
-  struct __pyx_obj_6pyfftw_6pyfftw_FFTW *p = (struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)o;
-  PyObject_GC_UnTrack(o);
-  {
-    PyObject *etype, *eval, *etb;
-    PyErr_Fetch(&etype, &eval, &etb);
-    ++Py_REFCNT(o);
-    __pyx_pw_6pyfftw_6pyfftw_4FFTW_15__dealloc__(o);
-    if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
-    --Py_REFCNT(o);
-    PyErr_Restore(etype, eval, etb);
-  }
-  Py_CLEAR(p->__pyx___input_array);
-  Py_CLEAR(p->__pyx___output_array);
-  Py_CLEAR(p->__pyx___input_strides);
-  Py_CLEAR(p->__pyx___input_byte_strides);
-  Py_CLEAR(p->__pyx___output_strides);
-  Py_CLEAR(p->__pyx___output_byte_strides);
-  Py_CLEAR(p->__pyx___input_shape);
-  Py_CLEAR(p->__pyx___output_shape);
-  Py_CLEAR(p->__pyx___input_dtype);
-  Py_CLEAR(p->__pyx___output_dtype);
-  Py_CLEAR(p->__pyx___flags_used);
-  PyObject_GC_Track(o);
-  (*Py_TYPE(o)->tp_free)(o);
-}
-
-static int __pyx_tp_traverse_6pyfftw_6pyfftw_FFTW(PyObject *o, visitproc v, void *a) {
-  int e;
-  struct __pyx_obj_6pyfftw_6pyfftw_FFTW *p = (struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)o;
-  if (p->__pyx___input_array) {
-    e = (*v)(((PyObject*)p->__pyx___input_array), a); if (e) return e;
-  }
-  if (p->__pyx___output_array) {
-    e = (*v)(((PyObject*)p->__pyx___output_array), a); if (e) return e;
-  }
-  if (p->__pyx___input_strides) {
-    e = (*v)(p->__pyx___input_strides, a); if (e) return e;
-  }
-  if (p->__pyx___input_byte_strides) {
-    e = (*v)(p->__pyx___input_byte_strides, a); if (e) return e;
-  }
-  if (p->__pyx___output_strides) {
-    e = (*v)(p->__pyx___output_strides, a); if (e) return e;
-  }
-  if (p->__pyx___output_byte_strides) {
-    e = (*v)(p->__pyx___output_byte_strides, a); if (e) return e;
-  }
-  if (p->__pyx___input_shape) {
-    e = (*v)(p->__pyx___input_shape, a); if (e) return e;
-  }
-  if (p->__pyx___output_shape) {
-    e = (*v)(p->__pyx___output_shape, a); if (e) return e;
-  }
-  if (p->__pyx___input_dtype) {
-    e = (*v)(p->__pyx___input_dtype, a); if (e) return e;
-  }
-  if (p->__pyx___output_dtype) {
-    e = (*v)(p->__pyx___output_dtype, a); if (e) return e;
-  }
-  if (p->__pyx___flags_used) {
-    e = (*v)(p->__pyx___flags_used, a); if (e) return e;
-  }
-  return 0;
-}
-
-static int __pyx_tp_clear_6pyfftw_6pyfftw_FFTW(PyObject *o) {
-  struct __pyx_obj_6pyfftw_6pyfftw_FFTW *p = (struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)o;
-  PyObject* tmp;
-  tmp = ((PyObject*)p->__pyx___input_array);
-  p->__pyx___input_array = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx___output_array);
-  p->__pyx___output_array = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx___input_strides);
-  p->__pyx___input_strides = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx___input_byte_strides);
-  p->__pyx___input_byte_strides = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx___output_strides);
-  p->__pyx___output_strides = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx___output_byte_strides);
-  p->__pyx___output_byte_strides = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx___input_shape);
-  p->__pyx___input_shape = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx___output_shape);
-  p->__pyx___output_shape = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx___input_dtype);
-  p->__pyx___input_dtype = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx___output_dtype);
-  p->__pyx___output_dtype = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  tmp = ((PyObject*)p->__pyx___flags_used);
-  p->__pyx___flags_used = Py_None; Py_INCREF(Py_None);
-  Py_XDECREF(tmp);
-  return 0;
-}
-
-static PyMethodDef __pyx_methods_6pyfftw_6pyfftw_FFTW[] = {
-  {__Pyx_NAMESTR("__get_N"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_1__get_N, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_4FFTW___get_N)},
-  {__Pyx_NAMESTR("__get_simd_aligned"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_3__get_simd_aligned, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_4FFTW_2__get_simd_aligned)},
-  {__Pyx_NAMESTR("__get_input_alignment"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_5__get_input_alignment, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_4FFTW_4__get_input_alignment)},
-  {__Pyx_NAMESTR("__get_output_alignment"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_7__get_output_alignment, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_4FFTW_6__get_output_alignment)},
-  {__Pyx_NAMESTR("__get_flags_used"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_9__get_flags_used, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_4FFTW_8__get_flags_used)},
-  {__Pyx_NAMESTR("update_arrays"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_19update_arrays, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_4FFTW_18update_arrays)},
-  {__Pyx_NAMESTR("get_input_array"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_21get_input_array, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_4FFTW_20get_input_array)},
-  {__Pyx_NAMESTR("get_output_array"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_23get_output_array, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_4FFTW_22get_output_array)},
-  {__Pyx_NAMESTR("execute"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_25execute, METH_NOARGS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_4FFTW_24execute)},
-  {0, 0, 0, 0}
-};
-
-static PyNumberMethods __pyx_tp_as_number_FFTW = {
-  0, /*nb_add*/
-  0, /*nb_subtract*/
-  0, /*nb_multiply*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_divide*/
-  #endif
-  0, /*nb_remainder*/
-  0, /*nb_divmod*/
-  0, /*nb_power*/
-  0, /*nb_negative*/
-  0, /*nb_positive*/
-  0, /*nb_absolute*/
-  0, /*nb_nonzero*/
-  0, /*nb_invert*/
-  0, /*nb_lshift*/
-  0, /*nb_rshift*/
-  0, /*nb_and*/
-  0, /*nb_xor*/
-  0, /*nb_or*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_coerce*/
-  #endif
-  0, /*nb_int*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_long*/
-  #else
-  0, /*reserved*/
-  #endif
-  0, /*nb_float*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_oct*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_hex*/
-  #endif
-  0, /*nb_inplace_add*/
-  0, /*nb_inplace_subtract*/
-  0, /*nb_inplace_multiply*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*nb_inplace_divide*/
-  #endif
-  0, /*nb_inplace_remainder*/
-  0, /*nb_inplace_power*/
-  0, /*nb_inplace_lshift*/
-  0, /*nb_inplace_rshift*/
-  0, /*nb_inplace_and*/
-  0, /*nb_inplace_xor*/
-  0, /*nb_inplace_or*/
-  0, /*nb_floor_divide*/
-  0, /*nb_true_divide*/
-  0, /*nb_inplace_floor_divide*/
-  0, /*nb_inplace_true_divide*/
-  #if PY_VERSION_HEX >= 0x02050000
-  0, /*nb_index*/
-  #endif
-};
-
-static PySequenceMethods __pyx_tp_as_sequence_FFTW = {
-  0, /*sq_length*/
-  0, /*sq_concat*/
-  0, /*sq_repeat*/
-  0, /*sq_item*/
-  0, /*sq_slice*/
-  0, /*sq_ass_item*/
-  0, /*sq_ass_slice*/
-  0, /*sq_contains*/
-  0, /*sq_inplace_concat*/
-  0, /*sq_inplace_repeat*/
-};
-
-static PyMappingMethods __pyx_tp_as_mapping_FFTW = {
-  0, /*mp_length*/
-  0, /*mp_subscript*/
-  0, /*mp_ass_subscript*/
-};
-
-static PyBufferProcs __pyx_tp_as_buffer_FFTW = {
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getreadbuffer*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getwritebuffer*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getsegcount*/
-  #endif
-  #if PY_MAJOR_VERSION < 3
-  0, /*bf_getcharbuffer*/
-  #endif
-  #if PY_VERSION_HEX >= 0x02060000
-  0, /*bf_getbuffer*/
-  #endif
-  #if PY_VERSION_HEX >= 0x02060000
-  0, /*bf_releasebuffer*/
-  #endif
-};
-
-static PyTypeObject __pyx_type_6pyfftw_6pyfftw_FFTW = {
-  PyVarObject_HEAD_INIT(0, 0)
-  __Pyx_NAMESTR("pyfftw.pyfftw.FFTW"), /*tp_name*/
-  sizeof(struct __pyx_obj_6pyfftw_6pyfftw_FFTW), /*tp_basicsize*/
-  0, /*tp_itemsize*/
-  __pyx_tp_dealloc_6pyfftw_6pyfftw_FFTW, /*tp_dealloc*/
-  0, /*tp_print*/
-  0, /*tp_getattr*/
-  0, /*tp_setattr*/
-  #if PY_MAJOR_VERSION < 3
-  0, /*tp_compare*/
-  #else
-  0, /*reserved*/
-  #endif
-  0, /*tp_repr*/
-  &__pyx_tp_as_number_FFTW, /*tp_as_number*/
-  &__pyx_tp_as_sequence_FFTW, /*tp_as_sequence*/
-  &__pyx_tp_as_mapping_FFTW, /*tp_as_mapping*/
-  0, /*tp_hash*/
-  __pyx_pw_6pyfftw_6pyfftw_4FFTW_17__call__, /*tp_call*/
-  0, /*tp_str*/
-  0, /*tp_getattro*/
-  0, /*tp_setattro*/
-  &__pyx_tp_as_buffer_FFTW, /*tp_as_buffer*/
-  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
-  __Pyx_DOCSTR("\n    FFTW is a class for computing the complex N-Dimensional DFT or\n    inverse DFT of an array using the FFTW library. The interface is \n    designed to be somewhat pythonic, with the correct transform being \n    inferred from the dtypes of the passed arrays.\n\n    On instantiation, the dtypes and relative shapes of the input array and\n    output arrays are compared to the set of valid (and implemented)\n    :ref:`FFTW schemes <scheme_table>`.  If a match is found, [...]
-  __pyx_tp_traverse_6pyfftw_6pyfftw_FFTW, /*tp_traverse*/
-  __pyx_tp_clear_6pyfftw_6pyfftw_FFTW, /*tp_clear*/
-  0, /*tp_richcompare*/
-  0, /*tp_weaklistoffset*/
-  0, /*tp_iter*/
-  0, /*tp_iternext*/
-  __pyx_methods_6pyfftw_6pyfftw_FFTW, /*tp_methods*/
-  0, /*tp_members*/
-  0, /*tp_getset*/
-  0, /*tp_base*/
-  0, /*tp_dict*/
-  0, /*tp_descr_get*/
-  0, /*tp_descr_set*/
-  0, /*tp_dictoffset*/
-  __pyx_pw_6pyfftw_6pyfftw_4FFTW_13__init__, /*tp_init*/
-  0, /*tp_alloc*/
-  __pyx_tp_new_6pyfftw_6pyfftw_FFTW, /*tp_new*/
-  0, /*tp_free*/
-  0, /*tp_is_gc*/
-  0, /*tp_bases*/
-  0, /*tp_mro*/
-  0, /*tp_cache*/
-  0, /*tp_subclasses*/
-  0, /*tp_weaklist*/
-  0, /*tp_del*/
-  #if PY_VERSION_HEX >= 0x02060000
-  0, /*tp_version_tag*/
-  #endif
-};
-
-static PyMethodDef __pyx_methods[] = {
-  {__Pyx_NAMESTR("n_byte_align_empty"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_1n_byte_align_empty, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_n_byte_align_empty)},
-  {__Pyx_NAMESTR("n_byte_align"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_3n_byte_align, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_2n_byte_align)},
-  {__Pyx_NAMESTR("is_n_byte_aligned"), (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_5is_n_byte_aligned, METH_VARARGS|METH_KEYWORDS, __Pyx_DOCSTR(__pyx_doc_6pyfftw_6pyfftw_4is_n_byte_aligned)},
-  {0, 0, 0, 0}
-};
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef __pyx_moduledef = {
-    PyModuleDef_HEAD_INIT,
-    __Pyx_NAMESTR("pyfftw"),
-    0, /* m_doc */
-    -1, /* m_size */
-    __pyx_methods /* m_methods */,
-    NULL, /* m_reload */
-    NULL, /* m_traverse */
-    NULL, /* m_clear */
-    NULL /* m_free */
-};
-#endif
-
-static __Pyx_StringTabEntry __pyx_string_tab[] = {
-  {&__pyx_kp_s_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 1, 0},
-  {&__pyx_kp_s_11, __pyx_k_11, sizeof(__pyx_k_11), 0, 0, 1, 0},
-  {&__pyx_n_s_129, __pyx_k_129, sizeof(__pyx_k_129), 0, 0, 1, 1},
-  {&__pyx_kp_s_13, __pyx_k_13, sizeof(__pyx_k_13), 0, 0, 1, 0},
-  {&__pyx_n_s_130, __pyx_k_130, sizeof(__pyx_k_130), 0, 0, 1, 1},
-  {&__pyx_n_s_15, __pyx_k_15, sizeof(__pyx_k_15), 0, 0, 1, 1},
-  {&__pyx_kp_s_16, __pyx_k_16, sizeof(__pyx_k_16), 0, 0, 1, 0},
-  {&__pyx_kp_s_17, __pyx_k_17, sizeof(__pyx_k_17), 0, 0, 1, 0},
-  {&__pyx_kp_s_18, __pyx_k_18, sizeof(__pyx_k_18), 0, 0, 1, 0},
-  {&__pyx_kp_s_20, __pyx_k_20, sizeof(__pyx_k_20), 0, 0, 1, 0},
-  {&__pyx_kp_s_22, __pyx_k_22, sizeof(__pyx_k_22), 0, 0, 1, 0},
-  {&__pyx_kp_s_24, __pyx_k_24, sizeof(__pyx_k_24), 0, 0, 1, 0},
-  {&__pyx_kp_s_26, __pyx_k_26, sizeof(__pyx_k_26), 0, 0, 1, 0},
-  {&__pyx_kp_s_28, __pyx_k_28, sizeof(__pyx_k_28), 0, 0, 1, 0},
-  {&__pyx_kp_s_29, __pyx_k_29, sizeof(__pyx_k_29), 0, 0, 1, 0},
-  {&__pyx_kp_s_3, __pyx_k_3, sizeof(__pyx_k_3), 0, 0, 1, 0},
-  {&__pyx_kp_s_30, __pyx_k_30, sizeof(__pyx_k_30), 0, 0, 1, 0},
-  {&__pyx_kp_s_31, __pyx_k_31, sizeof(__pyx_k_31), 0, 0, 1, 0},
-  {&__pyx_kp_s_32, __pyx_k_32, sizeof(__pyx_k_32), 0, 0, 1, 0},
-  {&__pyx_kp_s_33, __pyx_k_33, sizeof(__pyx_k_33), 0, 0, 1, 0},
-  {&__pyx_kp_s_34, __pyx_k_34, sizeof(__pyx_k_34), 0, 0, 1, 0},
-  {&__pyx_kp_s_35, __pyx_k_35, sizeof(__pyx_k_35), 0, 0, 1, 0},
-  {&__pyx_kp_s_36, __pyx_k_36, sizeof(__pyx_k_36), 0, 0, 1, 0},
-  {&__pyx_kp_s_37, __pyx_k_37, sizeof(__pyx_k_37), 0, 0, 1, 0},
-  {&__pyx_kp_s_41, __pyx_k_41, sizeof(__pyx_k_41), 0, 0, 1, 0},
-  {&__pyx_kp_s_43, __pyx_k_43, sizeof(__pyx_k_43), 0, 0, 1, 0},
-  {&__pyx_kp_s_45, __pyx_k_45, sizeof(__pyx_k_45), 0, 0, 1, 0},
-  {&__pyx_kp_s_47, __pyx_k_47, sizeof(__pyx_k_47), 0, 0, 1, 0},
-  {&__pyx_kp_s_48, __pyx_k_48, sizeof(__pyx_k_48), 0, 0, 1, 0},
-  {&__pyx_kp_s_49, __pyx_k_49, sizeof(__pyx_k_49), 0, 0, 1, 0},
-  {&__pyx_kp_s_51, __pyx_k_51, sizeof(__pyx_k_51), 0, 0, 1, 0},
-  {&__pyx_kp_s_54, __pyx_k_54, sizeof(__pyx_k_54), 0, 0, 1, 0},
-  {&__pyx_kp_s_56, __pyx_k_56, sizeof(__pyx_k_56), 0, 0, 1, 0},
-  {&__pyx_kp_s_58, __pyx_k_58, sizeof(__pyx_k_58), 0, 0, 1, 0},
-  {&__pyx_kp_u_60, __pyx_k_60, sizeof(__pyx_k_60), 0, 1, 0, 0},
-  {&__pyx_kp_u_62, __pyx_k_62, sizeof(__pyx_k_62), 0, 1, 0, 0},
-  {&__pyx_kp_u_64, __pyx_k_64, sizeof(__pyx_k_64), 0, 1, 0, 0},
-  {&__pyx_kp_u_66, __pyx_k_66, sizeof(__pyx_k_66), 0, 1, 0, 0},
-  {&__pyx_kp_u_67, __pyx_k_67, sizeof(__pyx_k_67), 0, 1, 0, 0},
-  {&__pyx_kp_s_7, __pyx_k_7, sizeof(__pyx_k_7), 0, 0, 1, 0},
-  {&__pyx_kp_u_70, __pyx_k_70, sizeof(__pyx_k_70), 0, 1, 0, 0},
-  {&__pyx_n_s_76, __pyx_k_76, sizeof(__pyx_k_76), 0, 0, 1, 1},
-  {&__pyx_kp_s_77, __pyx_k_77, sizeof(__pyx_k_77), 0, 0, 1, 0},
-  {&__pyx_n_s_78, __pyx_k_78, sizeof(__pyx_k_78), 0, 0, 1, 1},
-  {&__pyx_n_s_81, __pyx_k_81, sizeof(__pyx_k_81), 0, 0, 1, 1},
-  {&__pyx_kp_s_9, __pyx_k_9, sizeof(__pyx_k_9), 0, 0, 1, 0},
-  {&__pyx_kp_s__32, __pyx_k__32, sizeof(__pyx_k__32), 0, 0, 1, 0},
-  {&__pyx_kp_s__64, __pyx_k__64, sizeof(__pyx_k__64), 0, 0, 1, 0},
-  {&__pyx_n_s__C, __pyx_k__C, sizeof(__pyx_k__C), 0, 0, 1, 1},
-  {&__pyx_n_s__FFTW_BACKWARD, __pyx_k__FFTW_BACKWARD, sizeof(__pyx_k__FFTW_BACKWARD), 0, 0, 1, 1},
-  {&__pyx_n_s__FFTW_DESTROY_INPUT, __pyx_k__FFTW_DESTROY_INPUT, sizeof(__pyx_k__FFTW_DESTROY_INPUT), 0, 0, 1, 1},
-  {&__pyx_n_s__FFTW_ESTIMATE, __pyx_k__FFTW_ESTIMATE, sizeof(__pyx_k__FFTW_ESTIMATE), 0, 0, 1, 1},
-  {&__pyx_n_s__FFTW_EXHAUSTIVE, __pyx_k__FFTW_EXHAUSTIVE, sizeof(__pyx_k__FFTW_EXHAUSTIVE), 0, 0, 1, 1},
-  {&__pyx_n_s__FFTW_FORWARD, __pyx_k__FFTW_FORWARD, sizeof(__pyx_k__FFTW_FORWARD), 0, 0, 1, 1},
-  {&__pyx_n_s__FFTW_MEASURE, __pyx_k__FFTW_MEASURE, sizeof(__pyx_k__FFTW_MEASURE), 0, 0, 1, 1},
-  {&__pyx_n_s__FFTW_PATIENT, __pyx_k__FFTW_PATIENT, sizeof(__pyx_k__FFTW_PATIENT), 0, 0, 1, 1},
-  {&__pyx_n_s__FFTW_UNALIGNED, __pyx_k__FFTW_UNALIGNED, sizeof(__pyx_k__FFTW_UNALIGNED), 0, 0, 1, 1},
-  {&__pyx_n_s__IndexError, __pyx_k__IndexError, sizeof(__pyx_k__IndexError), 0, 0, 1, 1},
-  {&__pyx_n_s__KeyError, __pyx_k__KeyError, sizeof(__pyx_k__KeyError), 0, 0, 1, 1},
-  {&__pyx_n_s__MemoryError, __pyx_k__MemoryError, sizeof(__pyx_k__MemoryError), 0, 0, 1, 1},
-  {&__pyx_n_s__N, __pyx_k__N, sizeof(__pyx_k__N), 0, 0, 1, 1},
-  {&__pyx_n_s__RuntimeError, __pyx_k__RuntimeError, sizeof(__pyx_k__RuntimeError), 0, 0, 1, 1},
-  {&__pyx_n_s__TypeError, __pyx_k__TypeError, sizeof(__pyx_k__TypeError), 0, 0, 1, 1},
-  {&__pyx_n_s__ValueError, __pyx_k__ValueError, sizeof(__pyx_k__ValueError), 0, 0, 1, 1},
-  {&__pyx_n_s____class__, __pyx_k____class__, sizeof(__pyx_k____class__), 0, 0, 1, 1},
-  {&__pyx_n_s____get_N, __pyx_k____get_N, sizeof(__pyx_k____get_N), 0, 0, 1, 1},
-  {&__pyx_n_s____get_flags_used, __pyx_k____get_flags_used, sizeof(__pyx_k____get_flags_used), 0, 0, 1, 1},
-  {&__pyx_n_s____get_simd_aligned, __pyx_k____get_simd_aligned, sizeof(__pyx_k____get_simd_aligned), 0, 0, 1, 1},
-  {&__pyx_n_s____main__, __pyx_k____main__, sizeof(__pyx_k____main__), 0, 0, 1, 1},
-  {&__pyx_n_s____test__, __pyx_k____test__, sizeof(__pyx_k____test__), 0, 0, 1, 1},
-  {&__pyx_n_s___flag_dict, __pyx_k___flag_dict, sizeof(__pyx_k___flag_dict), 0, 0, 1, 1},
-  {&__pyx_n_s__alignment, __pyx_k__alignment, sizeof(__pyx_k__alignment), 0, 0, 1, 1},
-  {&__pyx_n_s__array, __pyx_k__array, sizeof(__pyx_k__array), 0, 0, 1, 1},
-  {&__pyx_n_s__asanyarray, __pyx_k__asanyarray, sizeof(__pyx_k__asanyarray), 0, 0, 1, 1},
-  {&__pyx_n_s__axes, __pyx_k__axes, sizeof(__pyx_k__axes), 0, 0, 1, 1},
-  {&__pyx_n_s__c2c, __pyx_k__c2c, sizeof(__pyx_k__c2c), 0, 0, 1, 1},
-  {&__pyx_n_s__c2r, __pyx_k__c2r, sizeof(__pyx_k__c2r), 0, 0, 1, 1},
-  {&__pyx_n_s__c_wisdom, __pyx_k__c_wisdom, sizeof(__pyx_k__c_wisdom), 0, 0, 1, 1},
-  {&__pyx_n_s__c_wisdom_ptr, __pyx_k__c_wisdom_ptr, sizeof(__pyx_k__c_wisdom_ptr), 0, 0, 1, 1},
-  {&__pyx_n_s__c_wisdomf, __pyx_k__c_wisdomf, sizeof(__pyx_k__c_wisdomf), 0, 0, 1, 1},
-  {&__pyx_n_s__c_wisdomf_ptr, __pyx_k__c_wisdomf_ptr, sizeof(__pyx_k__c_wisdomf_ptr), 0, 0, 1, 1},
-  {&__pyx_n_s__c_wisdoml, __pyx_k__c_wisdoml, sizeof(__pyx_k__c_wisdoml), 0, 0, 1, 1},
-  {&__pyx_n_s__c_wisdoml_ptr, __pyx_k__c_wisdoml_ptr, sizeof(__pyx_k__c_wisdoml_ptr), 0, 0, 1, 1},
-  {&__pyx_n_s__clongdouble, __pyx_k__clongdouble, sizeof(__pyx_k__clongdouble), 0, 0, 1, 1},
-  {&__pyx_n_s__complex128, __pyx_k__complex128, sizeof(__pyx_k__complex128), 0, 0, 1, 1},
-  {&__pyx_n_s__complex64, __pyx_k__complex64, sizeof(__pyx_k__complex64), 0, 0, 1, 1},
-  {&__pyx_n_s__copy, __pyx_k__copy, sizeof(__pyx_k__copy), 0, 0, 1, 1},
-  {&__pyx_n_s__counter, __pyx_k__counter, sizeof(__pyx_k__counter), 0, 0, 1, 1},
-  {&__pyx_n_s__counterf, __pyx_k__counterf, sizeof(__pyx_k__counterf), 0, 0, 1, 1},
-  {&__pyx_n_s__counterl, __pyx_k__counterl, sizeof(__pyx_k__counterl), 0, 0, 1, 1},
-  {&__pyx_n_s__data, __pyx_k__data, sizeof(__pyx_k__data), 0, 0, 1, 1},
-  {&__pyx_n_s__direction, __pyx_k__direction, sizeof(__pyx_k__direction), 0, 0, 1, 1},
-  {&__pyx_n_s__dtype, __pyx_k__dtype, sizeof(__pyx_k__dtype), 0, 0, 1, 1},
-  {&__pyx_n_s__empty, __pyx_k__empty, sizeof(__pyx_k__empty), 0, 0, 1, 1},
-  {&__pyx_n_s__execute, __pyx_k__execute, sizeof(__pyx_k__execute), 0, 0, 1, 1},
-  {&__pyx_n_s__executor, __pyx_k__executor, sizeof(__pyx_k__executor), 0, 0, 1, 1},
-  {&__pyx_n_s__export_wisdom, __pyx_k__export_wisdom, sizeof(__pyx_k__export_wisdom), 0, 0, 1, 1},
-  {&__pyx_n_s__fft_shape_lookup, __pyx_k__fft_shape_lookup, sizeof(__pyx_k__fft_shape_lookup), 0, 0, 1, 1},
-  {&__pyx_n_s__flags, __pyx_k__flags, sizeof(__pyx_k__flags), 0, 0, 1, 1},
-  {&__pyx_n_s__float32, __pyx_k__float32, sizeof(__pyx_k__float32), 0, 0, 1, 1},
-  {&__pyx_n_s__float64, __pyx_k__float64, sizeof(__pyx_k__float64), 0, 0, 1, 1},
-  {&__pyx_n_s__forget_wisdom, __pyx_k__forget_wisdom, sizeof(__pyx_k__forget_wisdom), 0, 0, 1, 1},
-  {&__pyx_n_s__frombuffer, __pyx_k__frombuffer, sizeof(__pyx_k__frombuffer), 0, 0, 1, 1},
-  {&__pyx_n_s__generic_precision, __pyx_k__generic_precision, sizeof(__pyx_k__generic_precision), 0, 0, 1, 1},
-  {&__pyx_n_s__import_wisdom, __pyx_k__import_wisdom, sizeof(__pyx_k__import_wisdom), 0, 0, 1, 1},
-  {&__pyx_n_s__input_alignment, __pyx_k__input_alignment, sizeof(__pyx_k__input_alignment), 0, 0, 1, 1},
-  {&__pyx_n_s__input_array, __pyx_k__input_array, sizeof(__pyx_k__input_array), 0, 0, 1, 1},
-  {&__pyx_n_s__int8, __pyx_k__int8, sizeof(__pyx_k__int8), 0, 0, 1, 1},
-  {&__pyx_n_s__integer, __pyx_k__integer, sizeof(__pyx_k__integer), 0, 0, 1, 1},
-  {&__pyx_n_s__itemsize, __pyx_k__itemsize, sizeof(__pyx_k__itemsize), 0, 0, 1, 1},
-  {&__pyx_n_s__ld, __pyx_k__ld, sizeof(__pyx_k__ld), 0, 0, 1, 1},
-  {&__pyx_n_s__longdouble, __pyx_k__longdouble, sizeof(__pyx_k__longdouble), 0, 0, 1, 1},
-  {&__pyx_n_s__n, __pyx_k__n, sizeof(__pyx_k__n), 0, 0, 1, 1},
-  {&__pyx_n_s__new_input_array, __pyx_k__new_input_array, sizeof(__pyx_k__new_input_array), 0, 0, 1, 1},
-  {&__pyx_n_s__new_output_array, __pyx_k__new_output_array, sizeof(__pyx_k__new_output_array), 0, 0, 1, 1},
-  {&__pyx_n_s__normalise_idft, __pyx_k__normalise_idft, sizeof(__pyx_k__normalise_idft), 0, 0, 1, 1},
-  {&__pyx_n_s__np, __pyx_k__np, sizeof(__pyx_k__np), 0, 0, 1, 1},
-  {&__pyx_n_s__numpy, __pyx_k__numpy, sizeof(__pyx_k__numpy), 0, 0, 1, 1},
-  {&__pyx_n_s__order, __pyx_k__order, sizeof(__pyx_k__order), 0, 0, 1, 1},
-  {&__pyx_n_s__output_alignment, __pyx_k__output_alignment, sizeof(__pyx_k__output_alignment), 0, 0, 1, 1},
-  {&__pyx_n_s__output_array, __pyx_k__output_array, sizeof(__pyx_k__output_array), 0, 0, 1, 1},
-  {&__pyx_n_s__planner, __pyx_k__planner, sizeof(__pyx_k__planner), 0, 0, 1, 1},
-  {&__pyx_n_s__planning_timelimit, __pyx_k__planning_timelimit, sizeof(__pyx_k__planning_timelimit), 0, 0, 1, 1},
-  {&__pyx_n_s__property, __pyx_k__property, sizeof(__pyx_k__property), 0, 0, 1, 1},
-  {&__pyx_n_s__py_wisdom, __pyx_k__py_wisdom, sizeof(__pyx_k__py_wisdom), 0, 0, 1, 1},
-  {&__pyx_n_s__py_wisdomf, __pyx_k__py_wisdomf, sizeof(__pyx_k__py_wisdomf), 0, 0, 1, 1},
-  {&__pyx_n_s__py_wisdoml, __pyx_k__py_wisdoml, sizeof(__pyx_k__py_wisdoml), 0, 0, 1, 1},
-  {&__pyx_n_s__r2c, __pyx_k__r2c, sizeof(__pyx_k__r2c), 0, 0, 1, 1},
-  {&__pyx_n_s__range, __pyx_k__range, sizeof(__pyx_k__range), 0, 0, 1, 1},
-  {&__pyx_n_s__reshape, __pyx_k__reshape, sizeof(__pyx_k__reshape), 0, 0, 1, 1},
-  {&__pyx_n_s__shape, __pyx_k__shape, sizeof(__pyx_k__shape), 0, 0, 1, 1},
-  {&__pyx_n_s__simd_aligned, __pyx_k__simd_aligned, sizeof(__pyx_k__simd_aligned), 0, 0, 1, 1},
-  {&__pyx_n_s__simd_alignment, __pyx_k__simd_alignment, sizeof(__pyx_k__simd_alignment), 0, 0, 1, 1},
-  {&__pyx_n_s__strides, __pyx_k__strides, sizeof(__pyx_k__strides), 0, 0, 1, 1},
-  {&__pyx_n_s__success, __pyx_k__success, sizeof(__pyx_k__success), 0, 0, 1, 1},
-  {&__pyx_n_s__successf, __pyx_k__successf, sizeof(__pyx_k__successf), 0, 0, 1, 1},
-  {&__pyx_n_s__successl, __pyx_k__successl, sizeof(__pyx_k__successl), 0, 0, 1, 1},
-  {&__pyx_n_s__threads, __pyx_k__threads, sizeof(__pyx_k__threads), 0, 0, 1, 1},
-  {&__pyx_n_s__type, __pyx_k__type, sizeof(__pyx_k__type), 0, 0, 1, 1},
-  {&__pyx_n_s__update, __pyx_k__update, sizeof(__pyx_k__update), 0, 0, 1, 1},
-  {&__pyx_n_s__update_arrays, __pyx_k__update_arrays, sizeof(__pyx_k__update_arrays), 0, 0, 1, 1},
-  {&__pyx_n_s__validator, __pyx_k__validator, sizeof(__pyx_k__validator), 0, 0, 1, 1},
-  {&__pyx_n_s__view, __pyx_k__view, sizeof(__pyx_k__view), 0, 0, 1, 1},
-  {&__pyx_n_s__wisdom, __pyx_k__wisdom, sizeof(__pyx_k__wisdom), 0, 0, 1, 1},
-  {0, 0, 0, 0, 0, 0, 0}
-};
-static int __Pyx_InitCachedBuiltins(void) {
-  __pyx_builtin_property = __Pyx_GetName(__pyx_b, __pyx_n_s__property); if (!__pyx_builtin_property) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_TypeError = __Pyx_GetName(__pyx_b, __pyx_n_s__TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_range = __Pyx_GetName(__pyx_b, __pyx_n_s__range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 329; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_ValueError = __Pyx_GetName(__pyx_b, __pyx_n_s__ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_KeyError = __Pyx_GetName(__pyx_b, __pyx_n_s__KeyError); if (!__pyx_builtin_KeyError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 733; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_IndexError = __Pyx_GetName(__pyx_b, __pyx_n_s__IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_MemoryError = __Pyx_GetName(__pyx_b, __pyx_n_s__MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_builtin_RuntimeError = __Pyx_GetName(__pyx_b, __pyx_n_s__RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 975; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  return 0;
-  __pyx_L1_error:;
-  return -1;
-}
-
-static int __Pyx_InitCachedConstants(void) {
-  __Pyx_RefNannyDeclarations
-  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
-
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":88
- * 
- *     if not isinstance(array, np.ndarray):
- *         raise TypeError('Invalid array: n_byte_align requires a subclass '             # <<<<<<<<<<<<<<
- *                 'of ndarray')
+  /* "pyfftw/pyfftw.pyx":1487
  * 
+ *         if not (<intptr_t>np.PyArray_DATA(new_output_array) %
+ *                 self.output_alignment == 0):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output alignment: '
+ *                     'The original arrays were %d-byte aligned. It is '
  */
-  __pyx_k_tuple_2 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_2);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_1));
-  PyTuple_SET_ITEM(__pyx_k_tuple_2, 0, ((PyObject *)__pyx_kp_s_1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_1));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_2));
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":120
- *     '''
- *     if not isinstance(array, np.ndarray):
- *         raise TypeError('Invalid array: is_n_byte_aligned requires a subclass '             # <<<<<<<<<<<<<<
- *                 'of ndarray')
+  /* "pyfftw/pyfftw.pyx":1486
+ *                     'aligned.' % self.input_alignment)
  * 
+ *         if not (<intptr_t>np.PyArray_DATA(new_output_array) %             # <<<<<<<<<<<<<<
+ *                 self.output_alignment == 0):
+ *             raise ValueError('Invalid output alignment: '
  */
-  __pyx_k_tuple_4 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 120; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_4);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_3));
-  PyTuple_SET_ITEM(__pyx_k_tuple_4, 0, ((PyObject *)__pyx_kp_s_3));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_3));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_4));
+  __pyx_t_1 = PyNumber_Remainder(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pyfftw/pyfftw.pyx":694
- *     flags = property(__get_flags_used)
+  /* "pyfftw/pyfftw.pyx":1487
  * 
- *     def __cinit__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
- *             unsigned int threads=1, planning_timelimit=None,
+ *         if not (<intptr_t>np.PyArray_DATA(new_output_array) %
+ *                 self.output_alignment == 0):             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output alignment: '
+ *                     'The original arrays were %d-byte aligned. It is '
  */
-  __pyx_k_tuple_5 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 694; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_5);
-  __Pyx_INCREF(__pyx_int_neg_1);
-  PyTuple_SET_ITEM(__pyx_k_tuple_5, 0, __pyx_int_neg_1);
-  __Pyx_GIVEREF(__pyx_int_neg_1);
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_5));
+  __pyx_t_2 = __Pyx_PyInt_EqObjC(__pyx_t_1, __pyx_int_0, 0, 0); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pyfftw/pyfftw.pyx":695
+  /* "pyfftw/pyfftw.pyx":1486
+ *                     'aligned.' % self.input_alignment)
  * 
- *     def __cinit__(self, input_array, output_array, axes=(-1,),
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),             # <<<<<<<<<<<<<<
- *             unsigned int threads=1, planning_timelimit=None,
- *             *args, **kwargs):
+ *         if not (<intptr_t>np.PyArray_DATA(new_output_array) %             # <<<<<<<<<<<<<<
+ *                 self.output_alignment == 0):
+ *             raise ValueError('Invalid output alignment: '
  */
-  __pyx_k_tuple_6 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 695; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_6);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_MEASURE));
-  PyTuple_SET_ITEM(__pyx_k_tuple_6, 0, ((PyObject *)__pyx_n_s__FFTW_MEASURE));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_MEASURE));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_6));
+  __pyx_t_7 = ((!__pyx_t_8) != 0);
+  if (__pyx_t_7) {
 
-  /* "pyfftw/pyfftw.pyx":716
- *                 _planning_timelimit = planning_timelimit
- *             except TypeError:
- *                 raise TypeError('Invalid planning timelimit: '             # <<<<<<<<<<<<<<
- *                         'The planning timelimit needs to be a float.')
+    /* "pyfftw/pyfftw.pyx":1491
+ *                     'The original arrays were %d-byte aligned. It is '
+ *                     'necessary that the update output array is similarly '
+ *                     'aligned.' % self.output_alignment)             # <<<<<<<<<<<<<<
  * 
+ *         if not new_input_array.dtype == self._input_dtype:
  */
-  __pyx_k_tuple_8 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_8);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_7));
-  PyTuple_SET_ITEM(__pyx_k_tuple_8, 0, ((PyObject *)__pyx_kp_s_7));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_7));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_8));
+    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_output_alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_Invalid_output_alignment_The_ori, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1491; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pyfftw/pyfftw.pyx":720
- * 
- *         if not isinstance(input_array, np.ndarray):
- *             raise ValueError('Invalid input array: '             # <<<<<<<<<<<<<<
- *                     'The input array needs to be an instance '
- *                     'of numpy.ndarray')
+    /* "pyfftw/pyfftw.pyx":1488
+ *         if not (<intptr_t>np.PyArray_DATA(new_output_array) %
+ *                 self.output_alignment == 0):
+ *             raise ValueError('Invalid output alignment: '             # <<<<<<<<<<<<<<
+ *                     'The original arrays were %d-byte aligned. It is '
+ *                     'necessary that the update output array is similarly '
  */
-  __pyx_k_tuple_10 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_10);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_9));
-  PyTuple_SET_ITEM(__pyx_k_tuple_10, 0, ((PyObject *)__pyx_kp_s_9));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_9));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_10));
+    __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_GIVEREF(__pyx_t_1);
+    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
+    __pyx_t_1 = 0;
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_2, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "pyfftw/pyfftw.pyx":725
+    /* "pyfftw/pyfftw.pyx":1486
+ *                     'aligned.' % self.input_alignment)
  * 
- *         if not isinstance(output_array, np.ndarray):
- *             raise ValueError('Invalid output array: '             # <<<<<<<<<<<<<<
- *                     'The output array needs to be an instance '
- *                     'of numpy.ndarray')
+ *         if not (<intptr_t>np.PyArray_DATA(new_output_array) %             # <<<<<<<<<<<<<<
+ *                 self.output_alignment == 0):
+ *             raise ValueError('Invalid output alignment: '
  */
-  __pyx_k_tuple_12 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_12);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_11));
-  PyTuple_SET_ITEM(__pyx_k_tuple_12, 0, ((PyObject *)__pyx_kp_s_11));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_11));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_12));
+  }
 
-  /* "pyfftw/pyfftw.pyx":734
- *             scheme = fftw_schemes[(input_dtype, output_dtype)]
- *         except KeyError:
- *             raise ValueError('Invalid scheme: '             # <<<<<<<<<<<<<<
- *                     'The output array and input array dtypes '
- *                     'do not correspond to a valid fftw scheme.')
+  /* "pyfftw/pyfftw.pyx":1493
+ *                     'aligned.' % self.output_alignment)
+ * 
+ *         if not new_input_array.dtype == self._input_dtype:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input dtype: '
+ *                     'The new input array is not of the same '
  */
-  __pyx_k_tuple_14 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 734; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_14);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_13));
-  PyTuple_SET_ITEM(__pyx_k_tuple_14, 0, ((PyObject *)__pyx_kp_s_13));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_13));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_14));
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_new_input_array, __pyx_n_s_dtype); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_v_self->_input_dtype, Py_EQ); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_8 = ((!__pyx_t_7) != 0);
+  if (__pyx_t_8) {
 
-  /* "pyfftw/pyfftw.pyx":803
+    /* "pyfftw/pyfftw.pyx":1494
  * 
- *         if not direction in scheme_directions[scheme]:
- *             raise ValueError('Invalid direction: '             # <<<<<<<<<<<<<<
- *                     'The direction is not valid for the scheme. '
- *                     'Try setting it explicitly if it is not already.')
+ *         if not new_input_array.dtype == self._input_dtype:
+ *             raise ValueError('Invalid input dtype: '             # <<<<<<<<<<<<<<
+ *                     'The new input array is not of the same '
+ *                     'dtype as was originally planned for.')
  */
-  __pyx_k_tuple_19 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_19);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_18));
-  PyTuple_SET_ITEM(__pyx_k_tuple_19, 0, ((PyObject *)__pyx_kp_s_18));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_18));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_19));
+    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__26, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_2);
+    __Pyx_Raise(__pyx_t_2, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "pyfftw/pyfftw.pyx":827
- * 
- *             if self.__axes[n] >= array_dimension or self.__axes[n] < 0:
- *                 raise IndexError('Invalid axes: '             # <<<<<<<<<<<<<<
- *                     'The axes list cannot contain invalid axes.')
+    /* "pyfftw/pyfftw.pyx":1493
+ *                     'aligned.' % self.output_alignment)
  * 
+ *         if not new_input_array.dtype == self._input_dtype:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input dtype: '
+ *                     'The new input array is not of the same '
  */
-  __pyx_k_tuple_21 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_21);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_20));
-  PyTuple_SET_ITEM(__pyx_k_tuple_21, 0, ((PyObject *)__pyx_kp_s_20));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_20));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_21));
-
-  /* "pyfftw/pyfftw.pyx":845
- *         for n in range(unique_axes_length):
- *             if self.__input_shape[self.__axes[n]] == 0:
- *                 raise ValueError('Zero length array: '             # <<<<<<<<<<<<<<
- *                     'The input array should have no zero length'
- *                     'axes over which the FFT is to be taken')
- */
-  __pyx_k_tuple_23 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 845; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_23);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_22));
-  PyTuple_SET_ITEM(__pyx_k_tuple_23, 0, ((PyObject *)__pyx_kp_s_22));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_22));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_23));
+  }
 
-  /* "pyfftw/pyfftw.pyx":862
- *         if functions['validator'] == -1:
- *             if not (output_array.shape == input_array.shape):
- *                 raise ValueError('Invalid shapes: '             # <<<<<<<<<<<<<<
- *                         'The output array should be the same shape as the '
- *                         'input array for the given array dtypes.')
+  /* "pyfftw/pyfftw.pyx":1498
+ *                     'dtype as was originally planned for.')
+ * 
+ *         if not new_output_array.dtype == self._output_dtype:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output dtype: '
+ *                     'The new output array is not of the same '
  */
-  __pyx_k_tuple_25 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 862; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_25);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_24));
-  PyTuple_SET_ITEM(__pyx_k_tuple_25, 0, ((PyObject *)__pyx_kp_s_24));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_24));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_25));
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_new_output_array, __pyx_n_s_dtype); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_1 = PyObject_RichCompare(__pyx_t_2, __pyx_v_self->_output_dtype, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_7 = ((!__pyx_t_8) != 0);
+  if (__pyx_t_7) {
 
-  /* "pyfftw/pyfftw.pyx":869
- *             if not _validator(input_array, output_array,
- *                     self.__axes, self.__not_axes, unique_axes_length):
- *                 raise ValueError('Invalid shapes: '             # <<<<<<<<<<<<<<
- *                         'The input array and output array are invalid '
- *                         'complementary shapes for their dtypes.')
+    /* "pyfftw/pyfftw.pyx":1499
+ * 
+ *         if not new_output_array.dtype == self._output_dtype:
+ *             raise ValueError('Invalid output dtype: '             # <<<<<<<<<<<<<<
+ *                     'The new output array is not of the same '
+ *                     'dtype as was originally planned for.')
  */
-  __pyx_k_tuple_27 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 869; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_27);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_26));
-  PyTuple_SET_ITEM(__pyx_k_tuple_27, 0, ((PyObject *)__pyx_kp_s_26));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_26));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_27));
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__27, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "pyfftw/pyfftw.pyx":978
- *                     'to the planner returning NULL. This is a bug.')
+    /* "pyfftw/pyfftw.pyx":1498
+ *                     'dtype as was originally planned for.')
  * 
- *     def __init__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
- *             int threads=1, planning_timelimit=None,
+ *         if not new_output_array.dtype == self._output_dtype:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output dtype: '
+ *                     'The new output array is not of the same '
  */
-  __pyx_k_tuple_38 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_38)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 978; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_38);
-  __Pyx_INCREF(__pyx_int_neg_1);
-  PyTuple_SET_ITEM(__pyx_k_tuple_38, 0, __pyx_int_neg_1);
-  __Pyx_GIVEREF(__pyx_int_neg_1);
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_38));
+  }
 
-  /* "pyfftw/pyfftw.pyx":979
+  /* "pyfftw/pyfftw.pyx":1503
+ *                     'dtype as was originally planned for.')
+ * 
+ *         new_input_shape = new_input_array.shape             # <<<<<<<<<<<<<<
+ *         new_output_shape = new_output_array.shape
  * 
- *     def __init__(self, input_array, output_array, axes=(-1,),
- *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),             # <<<<<<<<<<<<<<
- *             int threads=1, planning_timelimit=None,
- *             *args, **kwargs):
  */
-  __pyx_k_tuple_39 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_39)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 979; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_39);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_MEASURE));
-  PyTuple_SET_ITEM(__pyx_k_tuple_39, 0, ((PyObject *)__pyx_n_s__FFTW_MEASURE));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_MEASURE));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_39));
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_new_input_array, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1503; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_new_input_shape = __pyx_t_1;
+  __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1277
+  /* "pyfftw/pyfftw.pyx":1504
  * 
- *                 if not input_array.shape == self.__input_shape:
- *                     raise ValueError('Invalid input shape: '             # <<<<<<<<<<<<<<
- *                             'The new input array should be the same shape '
- *                             'as the input array used to instantiate the '
+ *         new_input_shape = new_input_array.shape
+ *         new_output_shape = new_output_array.shape             # <<<<<<<<<<<<<<
+ * 
+ *         new_input_strides = new_input_array.strides
  */
-  __pyx_k_tuple_42 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_42)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1277; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_42);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_41));
-  PyTuple_SET_ITEM(__pyx_k_tuple_42, 0, ((PyObject *)__pyx_kp_s_41));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_41));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_42));
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_new_output_array, __pyx_n_s_shape); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1504; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_new_output_shape = __pyx_t_1;
+  __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1324
- *         '''
- *         if not isinstance(new_input_array, np.ndarray):
- *             raise ValueError('Invalid input array: '             # <<<<<<<<<<<<<<
- *                     'The new input array needs to be an instance '
- *                     'of numpy.ndarray')
+  /* "pyfftw/pyfftw.pyx":1506
+ *         new_output_shape = new_output_array.shape
+ * 
+ *         new_input_strides = new_input_array.strides             # <<<<<<<<<<<<<<
+ *         new_output_strides = new_output_array.strides
+ * 
  */
-  __pyx_k_tuple_44 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_44)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1324; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_44);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_43));
-  PyTuple_SET_ITEM(__pyx_k_tuple_44, 0, ((PyObject *)__pyx_kp_s_43));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_43));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_44));
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_new_input_array, __pyx_n_s_strides); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_new_input_strides = __pyx_t_1;
+  __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1329
+  /* "pyfftw/pyfftw.pyx":1507
  * 
- *         if not isinstance(new_output_array, np.ndarray):
- *             raise ValueError('Invalid output array '             # <<<<<<<<<<<<<<
- *                     'The new output array needs to be an instance '
- *                     'of numpy.ndarray')
+ *         new_input_strides = new_input_array.strides
+ *         new_output_strides = new_output_array.strides             # <<<<<<<<<<<<<<
+ * 
+ *         if not new_input_shape == self._input_shape:
  */
-  __pyx_k_tuple_46 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_46)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1329; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_46);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_45));
-  PyTuple_SET_ITEM(__pyx_k_tuple_46, 0, ((PyObject *)__pyx_kp_s_45));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_45));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_46));
+  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_new_output_array, __pyx_n_s_strides); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_v_new_output_strides = __pyx_t_1;
+  __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1348
+  /* "pyfftw/pyfftw.pyx":1509
+ *         new_output_strides = new_output_array.strides
  * 
- *         if not new_input_array.dtype == self.__input_dtype:
- *             raise ValueError('Invalid input dtype: '             # <<<<<<<<<<<<<<
- *                     'The new input array is not of the same '
- *                     'dtype as was originally planned for.')
+ *         if not new_input_shape == self._input_shape:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input shape: '
+ *                     'The new input array should be the same shape as '
  */
-  __pyx_k_tuple_50 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_50)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1348; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_50);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_49));
-  PyTuple_SET_ITEM(__pyx_k_tuple_50, 0, ((PyObject *)__pyx_kp_s_49));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_49));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_50));
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_new_input_shape, __pyx_v_self->_input_shape, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1509; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1509; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_8 = ((!__pyx_t_7) != 0);
+  if (__pyx_t_8) {
 
-  /* "pyfftw/pyfftw.pyx":1353
+    /* "pyfftw/pyfftw.pyx":1510
  * 
- *         if not new_output_array.dtype == self.__output_dtype:
- *             raise ValueError('Invalid output dtype: '             # <<<<<<<<<<<<<<
- *                     'The new output array is not of the same '
- *                     'dtype as was originally planned for.')
+ *         if not new_input_shape == self._input_shape:
+ *             raise ValueError('Invalid input shape: '             # <<<<<<<<<<<<<<
+ *                     'The new input array should be the same shape as '
+ *                     'the input array used to instantiate the object.')
  */
-  __pyx_k_tuple_52 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_52)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1353; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_52);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_51));
-  PyTuple_SET_ITEM(__pyx_k_tuple_52, 0, ((PyObject *)__pyx_kp_s_51));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_51));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_52));
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__28, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "pyfftw/pyfftw.pyx":1364
+    /* "pyfftw/pyfftw.pyx":1509
+ *         new_output_strides = new_output_array.strides
  * 
- *         if not new_input_shape == self.__input_shape:
- *             raise ValueError('Invalid input shape: '             # <<<<<<<<<<<<<<
+ *         if not new_input_shape == self._input_shape:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input shape: '
  *                     'The new input array should be the same shape as '
+ */
+  }
+
+  /* "pyfftw/pyfftw.pyx":1514
  *                     'the input array used to instantiate the object.')
+ * 
+ *         if not new_output_shape == self._output_shape:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output shape: '
+ *                     'The new output array should be the same shape as '
  */
-  __pyx_k_tuple_53 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_53)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1364; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_53);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_41));
-  PyTuple_SET_ITEM(__pyx_k_tuple_53, 0, ((PyObject *)__pyx_kp_s_41));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_41));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_53));
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_new_output_shape, __pyx_v_self->_output_shape, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1514; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_7 = ((!__pyx_t_8) != 0);
+  if (__pyx_t_7) {
 
-  /* "pyfftw/pyfftw.pyx":1369
+    /* "pyfftw/pyfftw.pyx":1515
  * 
- *         if not new_output_shape == self.__output_shape:
+ *         if not new_output_shape == self._output_shape:
  *             raise ValueError('Invalid output shape: '             # <<<<<<<<<<<<<<
  *                     'The new output array should be the same shape as '
  *                     'the output array used to instantiate the object.')
  */
-  __pyx_k_tuple_55 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_55)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1369; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_55);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_54));
-  PyTuple_SET_ITEM(__pyx_k_tuple_55, 0, ((PyObject *)__pyx_kp_s_54));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_54));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_55));
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__29, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "pyfftw/pyfftw.pyx":1374
+    /* "pyfftw/pyfftw.pyx":1514
+ *                     'the input array used to instantiate the object.')
  * 
- *         if not new_input_strides == self.__input_byte_strides:
- *             raise ValueError('Invalid input striding: '             # <<<<<<<<<<<<<<
- *                     'The strides should be identical for the new '
- *                     'input array as for the old.')
+ *         if not new_output_shape == self._output_shape:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output shape: '
+ *                     'The new output array should be the same shape as '
  */
-  __pyx_k_tuple_57 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_57)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1374; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_57);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_56));
-  PyTuple_SET_ITEM(__pyx_k_tuple_57, 0, ((PyObject *)__pyx_kp_s_56));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_56));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_57));
+  }
 
-  /* "pyfftw/pyfftw.pyx":1379
+  /* "pyfftw/pyfftw.pyx":1519
+ *                     'the output array used to instantiate the object.')
  * 
- *         if not new_output_strides == self.__output_byte_strides:
- *             raise ValueError('Invalid output striding: '             # <<<<<<<<<<<<<<
+ *         if not new_input_strides == self._input_strides:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input striding: '
  *                     'The strides should be identical for the new '
- *                     'output array as for the old.')
  */
-  __pyx_k_tuple_59 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_59)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1379; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_59);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s_58));
-  PyTuple_SET_ITEM(__pyx_k_tuple_59, 0, ((PyObject *)__pyx_kp_s_58));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s_58));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_59));
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_new_input_strides, __pyx_v_self->_input_strides, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_8 = ((!__pyx_t_7) != 0);
+  if (__pyx_t_8) {
 
-  /* "numpy.pxd":215
- *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":1520
  * 
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *         if not new_input_strides == self._input_strides:
+ *             raise ValueError('Invalid input striding: '             # <<<<<<<<<<<<<<
+ *                     'The strides should be identical for the new '
+ *                     'input array as for the old.')
  */
-  __pyx_k_tuple_61 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_61)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_61);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_60));
-  PyTuple_SET_ITEM(__pyx_k_tuple_61, 0, ((PyObject *)__pyx_kp_u_60));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_60));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_61));
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__30, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "numpy.pxd":219
- *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
- *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
- *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":1519
+ *                     'the output array used to instantiate the object.')
  * 
- *             info.buf = PyArray_DATA(self)
- */
-  __pyx_k_tuple_63 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_63)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 219; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_63);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_62));
-  PyTuple_SET_ITEM(__pyx_k_tuple_63, 0, ((PyObject *)__pyx_kp_u_62));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_62));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_63));
-
-  /* "numpy.pxd":257
- *                 if ((descr.byteorder == c'>' and little_endian) or
- *                     (descr.byteorder == c'<' and not little_endian)):
- *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
- *                 if   t == NPY_BYTE:        f = "b"
- *                 elif t == NPY_UBYTE:       f = "B"
+ *         if not new_input_strides == self._input_strides:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid input striding: '
+ *                     'The strides should be identical for the new '
  */
-  __pyx_k_tuple_65 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_65)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_65);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_65, 0, ((PyObject *)__pyx_kp_u_64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_65));
+  }
 
-  /* "numpy.pxd":799
- * 
- *         if (end - f) - (new_offset - offset[0]) < 15:
- *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1524
+ *                     'input array as for the old.')
  * 
- *         if ((child.byteorder == c'>' and little_endian) or
- */
-  __pyx_k_tuple_68 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_68)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_68);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_67));
-  PyTuple_SET_ITEM(__pyx_k_tuple_68, 0, ((PyObject *)__pyx_kp_u_67));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_67));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_68));
-
-  /* "numpy.pxd":803
- *         if ((child.byteorder == c'>' and little_endian) or
- *             (child.byteorder == c'<' and not little_endian)):
- *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
- *             # One could encode it in the format string and have Cython
- *             # complain instead, BUT: < and > in format strings also imply
+ *         if not new_output_strides == self._output_strides:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output striding: '
+ *                     'The strides should be identical for the new '
  */
-  __pyx_k_tuple_69 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_69)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_69);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_69, 0, ((PyObject *)__pyx_kp_u_64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_69));
+  __pyx_t_1 = PyObject_RichCompare(__pyx_v_new_output_strides, __pyx_v_self->_output_strides, Py_EQ); __Pyx_XGOTREF(__pyx_t_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_8 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_7 = ((!__pyx_t_8) != 0);
+  if (__pyx_t_7) {
 
-  /* "numpy.pxd":823
- *             t = child.type_num
- *             if end - f < 5:
- *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":1525
  * 
- *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *         if not new_output_strides == self._output_strides:
+ *             raise ValueError('Invalid output striding: '             # <<<<<<<<<<<<<<
+ *                     'The strides should be identical for the new '
+ *                     'output array as for the old.')
  */
-  __pyx_k_tuple_71 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_71)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_71);
-  __Pyx_INCREF(((PyObject *)__pyx_kp_u_70));
-  PyTuple_SET_ITEM(__pyx_k_tuple_71, 0, ((PyObject *)__pyx_kp_u_70));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_u_70));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_71));
+    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__31, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __Pyx_Raise(__pyx_t_1, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":31
- * #: A tuple of simd alignments that make sense for this cpu
- * if _simd_alignment == 16:
- *     _valid_simd_alignments = (16,)             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":1524
+ *                     'input array as for the old.')
  * 
- * elif _simd_alignment == 32:
+ *         if not new_output_strides == self._output_strides:             # <<<<<<<<<<<<<<
+ *             raise ValueError('Invalid output striding: '
+ *                     'The strides should be identical for the new '
  */
-  __pyx_k_tuple_72 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_72)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_72);
-  __Pyx_INCREF(__pyx_int_16);
-  PyTuple_SET_ITEM(__pyx_k_tuple_72, 0, __pyx_int_16);
-  __Pyx_GIVEREF(__pyx_int_16);
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_72));
+  }
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":34
- * 
- * elif _simd_alignment == 32:
- *     _valid_simd_alignments = (16, 32)             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1529
+ *                     'output array as for the old.')
  * 
- * else:
- */
-  __pyx_k_tuple_73 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_73)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_73);
-  __Pyx_INCREF(__pyx_int_16);
-  PyTuple_SET_ITEM(__pyx_k_tuple_73, 0, __pyx_int_16);
-  __Pyx_GIVEREF(__pyx_int_16);
-  __Pyx_INCREF(__pyx_int_32);
-  PyTuple_SET_ITEM(__pyx_k_tuple_73, 1, __pyx_int_32);
-  __Pyx_GIVEREF(__pyx_int_32);
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_73));
-
-  /* "pyfftw/pyfftw.pyx":380
- * # Shape lookup functions
- * # ======================
- * def _lookup_shape_r2c_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
- *     return input_array.shape
+ *         self._update_arrays(new_input_array, new_output_array)             # <<<<<<<<<<<<<<
  * 
+ *     cdef _update_arrays(self,
  */
-  __pyx_k_tuple_74 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_74)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_74);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__input_array));
-  PyTuple_SET_ITEM(__pyx_k_tuple_74, 0, ((PyObject *)__pyx_n_s__input_array));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__input_array));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__output_array));
-  PyTuple_SET_ITEM(__pyx_k_tuple_74, 1, ((PyObject *)__pyx_n_s__output_array));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__output_array));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_74));
-  __pyx_k_codeobj_75 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_74, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_77, __pyx_n_s_76, 380, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_75)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_v_new_input_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_new_input_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (!(likely(((__pyx_v_new_output_array) == Py_None) || likely(__Pyx_TypeTest(__pyx_v_new_output_array, __pyx_ptype_5numpy_ndarray))))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = ((struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW *)__pyx_v_self->__pyx_vtab)->_update_arrays(__pyx_v_self, ((PyArrayObject *)__pyx_v_new_input_array), ((PyArrayObject *)__pyx_v_new_output_array)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":383
- *     return input_array.shape
- * 
- * def _lookup_shape_c2r_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
- *     return output_array.shape
+  /* "pyfftw/pyfftw.pyx":1446
+ *         return self._output_array
  * 
+ *     cpdef update_arrays(self,             # <<<<<<<<<<<<<<
+ *             new_input_array, new_output_array):
+ *         '''update_arrays(new_input_array, new_output_array)
  */
-  __pyx_k_tuple_79 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_79)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_79);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__input_array));
-  PyTuple_SET_ITEM(__pyx_k_tuple_79, 0, ((PyObject *)__pyx_n_s__input_array));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__input_array));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__output_array));
-  PyTuple_SET_ITEM(__pyx_k_tuple_79, 1, ((PyObject *)__pyx_n_s__output_array));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__output_array));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_79));
-  __pyx_k_codeobj_80 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_79, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_77, __pyx_n_s_81, 383, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_80)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "pyfftw/pyfftw.pyx":418
- * cdef object fftw_schemes
- * fftw_schemes = {
- *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),             # <<<<<<<<<<<<<<
- *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
- *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
- */
-  __pyx_k_tuple_82 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_82)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_82);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__complex128));
-  PyTuple_SET_ITEM(__pyx_k_tuple_82, 0, ((PyObject *)__pyx_n_s__complex128));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__complex128));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_82));
-  __pyx_k_tuple_83 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_83)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_83);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__complex128));
-  PyTuple_SET_ITEM(__pyx_k_tuple_83, 0, ((PyObject *)__pyx_n_s__complex128));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__complex128));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_83));
-  __pyx_k_tuple_84 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_84)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_84);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_84, 0, ((PyObject *)__pyx_n_s__c2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_84, 1, ((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_84));
-
-  /* "pyfftw/pyfftw.pyx":419
- * fftw_schemes = {
- *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),
- *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),             # <<<<<<<<<<<<<<
- *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
- *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
- */
-  __pyx_k_tuple_85 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_85)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_85);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__complex64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_85, 0, ((PyObject *)__pyx_n_s__complex64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__complex64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_85));
-  __pyx_k_tuple_86 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_86)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_86);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__complex64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_86, 0, ((PyObject *)__pyx_n_s__complex64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__complex64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_86));
-  __pyx_k_tuple_87 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_87)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_87);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_87, 0, ((PyObject *)__pyx_n_s__c2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__32));
-  PyTuple_SET_ITEM(__pyx_k_tuple_87, 1, ((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_87));
-
-  /* "pyfftw/pyfftw.pyx":420
- *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),
- *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
- *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),             # <<<<<<<<<<<<<<
- *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
- *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
- */
-  __pyx_k_tuple_88 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_88)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_88);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__float64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_88, 0, ((PyObject *)__pyx_n_s__float64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__float64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_88));
-  __pyx_k_tuple_89 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_89)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_89);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__complex128));
-  PyTuple_SET_ITEM(__pyx_k_tuple_89, 0, ((PyObject *)__pyx_n_s__complex128));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__complex128));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_89));
-  __pyx_k_tuple_90 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_90)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_90);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__r2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_90, 0, ((PyObject *)__pyx_n_s__r2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__r2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_90, 1, ((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_90));
-
-  /* "pyfftw/pyfftw.pyx":421
- *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
- *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
- *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),             # <<<<<<<<<<<<<<
- *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
- *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
- */
-  __pyx_k_tuple_91 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_91)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_91);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__float32));
-  PyTuple_SET_ITEM(__pyx_k_tuple_91, 0, ((PyObject *)__pyx_n_s__float32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__float32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_91));
-  __pyx_k_tuple_92 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_92)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_92);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__complex64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_92, 0, ((PyObject *)__pyx_n_s__complex64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__complex64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_92));
-  __pyx_k_tuple_93 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_93)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_93);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__r2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_93, 0, ((PyObject *)__pyx_n_s__r2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__r2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__32));
-  PyTuple_SET_ITEM(__pyx_k_tuple_93, 1, ((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_93));
-
-  /* "pyfftw/pyfftw.pyx":422
- *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
- *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
- *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),             # <<<<<<<<<<<<<<
- *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
- * 
- */
-  __pyx_k_tuple_94 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_94)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_94);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__complex128));
-  PyTuple_SET_ITEM(__pyx_k_tuple_94, 0, ((PyObject *)__pyx_n_s__complex128));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__complex128));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_94));
-  __pyx_k_tuple_95 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_95)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_95);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__float64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_95, 0, ((PyObject *)__pyx_n_s__float64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__float64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_95));
-  __pyx_k_tuple_96 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_96)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_96);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2r));
-  PyTuple_SET_ITEM(__pyx_k_tuple_96, 0, ((PyObject *)__pyx_n_s__c2r));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2r));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_96, 1, ((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_96));
-
-  /* "pyfftw/pyfftw.pyx":423
- *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
- *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
- *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}             # <<<<<<<<<<<<<<
- * 
- * if np.dtype('longdouble') != np.dtype('float64'):
- */
-  __pyx_k_tuple_97 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_97)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_97);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__complex64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_97, 0, ((PyObject *)__pyx_n_s__complex64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__complex64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_97));
-  __pyx_k_tuple_98 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_98)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_98);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__float32));
-  PyTuple_SET_ITEM(__pyx_k_tuple_98, 0, ((PyObject *)__pyx_n_s__float32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__float32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_98));
-  __pyx_k_tuple_99 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_99)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_99);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2r));
-  PyTuple_SET_ITEM(__pyx_k_tuple_99, 0, ((PyObject *)__pyx_n_s__c2r));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2r));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__32));
-  PyTuple_SET_ITEM(__pyx_k_tuple_99, 1, ((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_99));
-
-  /* "pyfftw/pyfftw.pyx":425
- *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
- * 
- * if np.dtype('longdouble') != np.dtype('float64'):             # <<<<<<<<<<<<<<
- *     fftw_schemes.update({
- *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
- */
-  __pyx_k_tuple_100 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_100)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_100);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__longdouble));
-  PyTuple_SET_ITEM(__pyx_k_tuple_100, 0, ((PyObject *)__pyx_n_s__longdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__longdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_100));
-  __pyx_k_tuple_101 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_101)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_101);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__float64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_101, 0, ((PyObject *)__pyx_n_s__float64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__float64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_101));
-
-  /* "pyfftw/pyfftw.pyx":427
- * if np.dtype('longdouble') != np.dtype('float64'):
- *     fftw_schemes.update({
- *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),             # <<<<<<<<<<<<<<
- *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),
- *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})
- */
-  __pyx_k_tuple_102 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_102)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 427; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_102);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__clongdouble));
-  PyTuple_SET_ITEM(__pyx_k_tuple_102, 0, ((PyObject *)__pyx_n_s__clongdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__clongdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_102));
-  __pyx_k_tuple_103 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_103)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 427; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_103);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__clongdouble));
-  PyTuple_SET_ITEM(__pyx_k_tuple_103, 0, ((PyObject *)__pyx_n_s__clongdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__clongdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_103));
-  __pyx_k_tuple_104 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_104)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 427; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_104);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_104, 0, ((PyObject *)__pyx_n_s__c2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2c));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__ld));
-  PyTuple_SET_ITEM(__pyx_k_tuple_104, 1, ((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_104));
-
-  /* "pyfftw/pyfftw.pyx":428
- *     fftw_schemes.update({
- *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
- *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),             # <<<<<<<<<<<<<<
- *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.update_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_new_input_shape);
+  __Pyx_XDECREF(__pyx_v_new_output_shape);
+  __Pyx_XDECREF(__pyx_v_new_input_strides);
+  __Pyx_XDECREF(__pyx_v_new_output_strides);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_39update_arrays(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_38update_arrays[] = "update_arrays(new_input_array, new_output_array)\n\n        Update the arrays upon which the DFT is taken.\n\n        The new arrays should be of the same dtypes as the originals, the same\n        shapes as the originals and should have the same strides between axes.\n        If the original data was aligned so as to allow SIMD instructions\n        (e.g. by being aligned on a 16-byte boundary), then the new array must\n   [...]
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_39update_arrays(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyObject *__pyx_v_new_input_array = 0;
+  PyObject *__pyx_v_new_output_array = 0;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("update_arrays (wrapper)", 0);
+  {
+    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_new_input_array,&__pyx_n_s_new_output_array,0};
+    PyObject* values[2] = {0,0};
+    if (unlikely(__pyx_kwds)) {
+      Py_ssize_t kw_args;
+      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
+      switch (pos_args) {
+        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+        case  0: break;
+        default: goto __pyx_L5_argtuple_error;
+      }
+      kw_args = PyDict_Size(__pyx_kwds);
+      switch (pos_args) {
+        case  0:
+        if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_new_input_array)) != 0)) kw_args--;
+        else goto __pyx_L5_argtuple_error;
+        case  1:
+        if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_new_output_array)) != 0)) kw_args--;
+        else {
+          __Pyx_RaiseArgtupleInvalid("update_arrays", 1, 2, 2, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+        }
+      }
+      if (unlikely(kw_args > 0)) {
+        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "update_arrays") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+      }
+    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
+      goto __pyx_L5_argtuple_error;
+    } else {
+      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
+      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
+    }
+    __pyx_v_new_input_array = values[0];
+    __pyx_v_new_output_array = values[1];
+  }
+  goto __pyx_L4_argument_unpacking_done;
+  __pyx_L5_argtuple_error:;
+  __Pyx_RaiseArgtupleInvalid("update_arrays", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
+  __pyx_L3_error:;
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.update_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __Pyx_RefNannyFinishContext();
+  return NULL;
+  __pyx_L4_argument_unpacking_done:;
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_38update_arrays(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self), __pyx_v_new_input_array, __pyx_v_new_output_array);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_38update_arrays(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyObject *__pyx_v_new_input_array, PyObject *__pyx_v_new_output_array) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("update_arrays", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_4FFTW_update_arrays(__pyx_v_self, __pyx_v_new_input_array, __pyx_v_new_output_array, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.update_arrays", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":1531
+ *         self._update_arrays(new_input_array, new_output_array)
  * 
+ *     cdef _update_arrays(self,             # <<<<<<<<<<<<<<
+ *             np.ndarray new_input_array, np.ndarray new_output_array):
+ *         ''' A C interface to the update_arrays method that does not
  */
-  __pyx_k_tuple_105 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_105)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_105);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__longdouble));
-  PyTuple_SET_ITEM(__pyx_k_tuple_105, 0, ((PyObject *)__pyx_n_s__longdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__longdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_105));
-  __pyx_k_tuple_106 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_106)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_106);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__clongdouble));
-  PyTuple_SET_ITEM(__pyx_k_tuple_106, 0, ((PyObject *)__pyx_n_s__clongdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__clongdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_106));
-  __pyx_k_tuple_107 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_107)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_107);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__r2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_107, 0, ((PyObject *)__pyx_n_s__r2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__r2c));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__ld));
-  PyTuple_SET_ITEM(__pyx_k_tuple_107, 1, ((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_107));
-
-  /* "pyfftw/pyfftw.pyx":429
- *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
- *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),
- *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})             # <<<<<<<<<<<<<<
- * 
+
+static PyObject *__pyx_f_6pyfftw_6pyfftw_4FFTW__update_arrays(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, PyArrayObject *__pyx_v_new_input_array, PyArrayObject *__pyx_v_new_output_array) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("_update_arrays", 0);
+
+  /* "pyfftw/pyfftw.pyx":1536
+ *         perform any checks on strides being correct and so on.
+ *         '''
+ *         self._input_array = new_input_array             # <<<<<<<<<<<<<<
+ *         self._output_array = new_output_array
  * 
  */
-  __pyx_k_tuple_108 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_108)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_108);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__clongdouble));
-  PyTuple_SET_ITEM(__pyx_k_tuple_108, 0, ((PyObject *)__pyx_n_s__clongdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__clongdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_108));
-  __pyx_k_tuple_109 = PyTuple_New(1); if (unlikely(!__pyx_k_tuple_109)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_109);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__longdouble));
-  PyTuple_SET_ITEM(__pyx_k_tuple_109, 0, ((PyObject *)__pyx_n_s__longdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__longdouble));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_109));
-  __pyx_k_tuple_110 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_110)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_110);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2r));
-  PyTuple_SET_ITEM(__pyx_k_tuple_110, 0, ((PyObject *)__pyx_n_s__c2r));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2r));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__ld));
-  PyTuple_SET_ITEM(__pyx_k_tuple_110, 1, ((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_110));
-
-  /* "pyfftw/pyfftw.pyx":434
- * cdef object scheme_directions
- * scheme_directions = {
- *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
- *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- */
-  __pyx_k_tuple_111 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_111)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_111);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_111, 0, ((PyObject *)__pyx_n_s__c2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_111, 1, ((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_111));
-
-  /* "pyfftw/pyfftw.pyx":435
- * scheme_directions = {
- *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
- *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('r2c', '64'): ['FFTW_FORWARD'],
- */
-  __pyx_k_tuple_112 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_112)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_112);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_112, 0, ((PyObject *)__pyx_n_s__c2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__32));
-  PyTuple_SET_ITEM(__pyx_k_tuple_112, 1, ((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_112));
-
-  /* "pyfftw/pyfftw.pyx":436
- *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
- *         ('r2c', '64'): ['FFTW_FORWARD'],
- *         ('r2c', '32'): ['FFTW_FORWARD'],
- */
-  __pyx_k_tuple_113 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_113)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_113);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_113, 0, ((PyObject *)__pyx_n_s__c2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2c));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__ld));
-  PyTuple_SET_ITEM(__pyx_k_tuple_113, 1, ((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_113));
-
-  /* "pyfftw/pyfftw.pyx":437
- *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('r2c', '64'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
- *         ('r2c', '32'): ['FFTW_FORWARD'],
- *         ('r2c', 'ld'): ['FFTW_FORWARD'],
+  __Pyx_INCREF(((PyObject *)__pyx_v_new_input_array));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_new_input_array));
+  __Pyx_GOTREF(__pyx_v_self->_input_array);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->_input_array));
+  __pyx_v_self->_input_array = __pyx_v_new_input_array;
+
+  /* "pyfftw/pyfftw.pyx":1537
+ *         '''
+ *         self._input_array = new_input_array
+ *         self._output_array = new_output_array             # <<<<<<<<<<<<<<
+ * 
+ *     def get_input_array(self):
  */
-  __pyx_k_tuple_114 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_114)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_114);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__r2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_114, 0, ((PyObject *)__pyx_n_s__r2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__r2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_114, 1, ((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_114));
-
-  /* "pyfftw/pyfftw.pyx":438
- *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('r2c', '64'): ['FFTW_FORWARD'],
- *         ('r2c', '32'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
- *         ('r2c', 'ld'): ['FFTW_FORWARD'],
- *         ('c2r', '64'): ['FFTW_BACKWARD'],
+  __Pyx_INCREF(((PyObject *)__pyx_v_new_output_array));
+  __Pyx_GIVEREF(((PyObject *)__pyx_v_new_output_array));
+  __Pyx_GOTREF(__pyx_v_self->_output_array);
+  __Pyx_DECREF(((PyObject *)__pyx_v_self->_output_array));
+  __pyx_v_self->_output_array = __pyx_v_new_output_array;
+
+  /* "pyfftw/pyfftw.pyx":1531
+ *         self._update_arrays(new_input_array, new_output_array)
+ * 
+ *     cdef _update_arrays(self,             # <<<<<<<<<<<<<<
+ *             np.ndarray new_input_array, np.ndarray new_output_array):
+ *         ''' A C interface to the update_arrays method that does not
  */
-  __pyx_k_tuple_115 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_115)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_115);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__r2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_115, 0, ((PyObject *)__pyx_n_s__r2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__r2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__32));
-  PyTuple_SET_ITEM(__pyx_k_tuple_115, 1, ((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_115));
-
-  /* "pyfftw/pyfftw.pyx":439
- *         ('r2c', '64'): ['FFTW_FORWARD'],
- *         ('r2c', '32'): ['FFTW_FORWARD'],
- *         ('r2c', 'ld'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
- *         ('c2r', '64'): ['FFTW_BACKWARD'],
- *         ('c2r', '32'): ['FFTW_BACKWARD'],
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":1539
+ *         self._output_array = new_output_array
+ * 
+ *     def get_input_array(self):             # <<<<<<<<<<<<<<
+ *         '''get_input_array()
+ * 
  */
-  __pyx_k_tuple_116 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_116)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_116);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__r2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_116, 0, ((PyObject *)__pyx_n_s__r2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__r2c));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__ld));
-  PyTuple_SET_ITEM(__pyx_k_tuple_116, 1, ((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_116));
-
-  /* "pyfftw/pyfftw.pyx":440
- *         ('r2c', '32'): ['FFTW_FORWARD'],
- *         ('r2c', 'ld'): ['FFTW_FORWARD'],
- *         ('c2r', '64'): ['FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
- *         ('c2r', '32'): ['FFTW_BACKWARD'],
- *         ('c2r', 'ld'): ['FFTW_BACKWARD']}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_41get_input_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_40get_input_array[] = "get_input_array()\n\n        Return the input array that is associated with the FFTW \n        instance.\n\n        *Deprecated since 0.10. Consider using the* :attr:`FFTW.input_array` \n        *property instead.*\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_41get_input_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_input_array (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_40get_input_array(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_40get_input_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  Py_ssize_t __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_input_array", 0);
+
+  /* "pyfftw/pyfftw.pyx":1548
+ *         *property instead.*
+ *         '''
+ *         warnings.warn('get_input_array is deprecated. '             # <<<<<<<<<<<<<<
+ *                 'Consider using the input_array property instead.',
+ *                 DeprecationWarning)
  */
-  __pyx_k_tuple_117 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_117)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_117);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2r));
-  PyTuple_SET_ITEM(__pyx_k_tuple_117, 0, ((PyObject *)__pyx_n_s__c2r));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2r));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_117, 1, ((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_117));
-
-  /* "pyfftw/pyfftw.pyx":441
- *         ('r2c', 'ld'): ['FFTW_FORWARD'],
- *         ('c2r', '64'): ['FFTW_BACKWARD'],
- *         ('c2r', '32'): ['FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
- *         ('c2r', 'ld'): ['FFTW_BACKWARD']}
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_warnings); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_warn); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":1550
+ *         warnings.warn('get_input_array is deprecated. '
+ *                 'Consider using the input_array property instead.',
+ *                 DeprecationWarning)             # <<<<<<<<<<<<<<
  * 
+ *         return self._input_array
  */
-  __pyx_k_tuple_118 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_118)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_118);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2r));
-  PyTuple_SET_ITEM(__pyx_k_tuple_118, 0, ((PyObject *)__pyx_n_s__c2r));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2r));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__32));
-  PyTuple_SET_ITEM(__pyx_k_tuple_118, 1, ((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_118));
+  __pyx_t_2 = NULL;
+  __pyx_t_4 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_2)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_2);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+      __pyx_t_4 = 1;
+    }
+  }
+  __pyx_t_5 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (__pyx_t_2) {
+    __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __pyx_t_2 = NULL;
+  }
+  __Pyx_INCREF(__pyx_kp_s_get_input_array_is_deprecated_Co);
+  __Pyx_GIVEREF(__pyx_kp_s_get_input_array_is_deprecated_Co);
+  PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, __pyx_kp_s_get_input_array_is_deprecated_Co);
+  __Pyx_INCREF(__pyx_builtin_DeprecationWarning);
+  __Pyx_GIVEREF(__pyx_builtin_DeprecationWarning);
+  PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_builtin_DeprecationWarning);
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1548; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":442
- *         ('c2r', '64'): ['FFTW_BACKWARD'],
- *         ('c2r', '32'): ['FFTW_BACKWARD'],
- *         ('c2r', 'ld'): ['FFTW_BACKWARD']}             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1552
+ *                 DeprecationWarning)
  * 
- * # In the following, -1 denotes using the default. A segfault has been
+ *         return self._input_array             # <<<<<<<<<<<<<<
+ * 
+ *     def get_output_array(self):
  */
-  __pyx_k_tuple_119 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_119)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_119);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2r));
-  PyTuple_SET_ITEM(__pyx_k_tuple_119, 0, ((PyObject *)__pyx_n_s__c2r));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2r));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__ld));
-  PyTuple_SET_ITEM(__pyx_k_tuple_119, 1, ((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_119));
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->_input_array));
+  __pyx_r = ((PyObject *)__pyx_v_self->_input_array);
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":450
- * cdef object scheme_functions
- * scheme_functions = {
- *     ('c2c', '64'): {'planner': 0, 'executor':0, 'generic_precision':0,             # <<<<<<<<<<<<<<
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,
- */
-  __pyx_k_tuple_120 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_120)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_120);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_120, 0, ((PyObject *)__pyx_n_s__c2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_120, 1, ((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_120));
-
-  /* "pyfftw/pyfftw.pyx":452
- *     ('c2c', '64'): {'planner': 0, 'executor':0, 'generic_precision':0,
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,             # <<<<<<<<<<<<<<
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,
- */
-  __pyx_k_tuple_121 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_121)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_121);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_121, 0, ((PyObject *)__pyx_n_s__c2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__32));
-  PyTuple_SET_ITEM(__pyx_k_tuple_121, 1, ((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_121));
-
-  /* "pyfftw/pyfftw.pyx":454
- *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,             # <<<<<<<<<<<<<<
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('r2c', '64'): {'planner':3, 'executor':3, 'generic_precision':0,
+  /* "pyfftw/pyfftw.pyx":1539
+ *         self._output_array = new_output_array
+ * 
+ *     def get_input_array(self):             # <<<<<<<<<<<<<<
+ *         '''get_input_array()
+ * 
  */
-  __pyx_k_tuple_122 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_122)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_122);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_122, 0, ((PyObject *)__pyx_n_s__c2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2c));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__ld));
-  PyTuple_SET_ITEM(__pyx_k_tuple_122, 1, ((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_122));
 
-  /* "pyfftw/pyfftw.pyx":456
- *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('r2c', '64'): {'planner':3, 'executor':3, 'generic_precision':0,             # <<<<<<<<<<<<<<
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
- */
-  __pyx_k_tuple_123 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_123)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_123);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__r2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_123, 0, ((PyObject *)__pyx_n_s__r2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__r2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_123, 1, ((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_123));
-
-  /* "pyfftw/pyfftw.pyx":459
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
- *     ('r2c', '32'): {'planner':4, 'executor':4, 'generic_precision':1,             # <<<<<<<<<<<<<<
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
- */
-  __pyx_k_tuple_124 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_124)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_124);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__r2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_124, 0, ((PyObject *)__pyx_n_s__r2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__r2c));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__32));
-  PyTuple_SET_ITEM(__pyx_k_tuple_124, 1, ((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_124));
-
-  /* "pyfftw/pyfftw.pyx":462
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
- *     ('r2c', 'ld'): {'planner':5, 'executor':5, 'generic_precision':2,             # <<<<<<<<<<<<<<
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
- */
-  __pyx_k_tuple_125 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_125)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_125);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__r2c));
-  PyTuple_SET_ITEM(__pyx_k_tuple_125, 0, ((PyObject *)__pyx_n_s__r2c));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__r2c));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__ld));
-  PyTuple_SET_ITEM(__pyx_k_tuple_125, 1, ((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_125));
-
-  /* "pyfftw/pyfftw.pyx":465
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
- *     ('c2r', '64'): {'planner':6, 'executor':6, 'generic_precision':0,             # <<<<<<<<<<<<<<
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
- */
-  __pyx_k_tuple_126 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_126)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_126);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2r));
-  PyTuple_SET_ITEM(__pyx_k_tuple_126, 0, ((PyObject *)__pyx_n_s__c2r));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2r));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__64));
-  PyTuple_SET_ITEM(__pyx_k_tuple_126, 1, ((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__64));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_126));
-
-  /* "pyfftw/pyfftw.pyx":468
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
- *     ('c2r', '32'): {'planner':7, 'executor':7, 'generic_precision':1,             # <<<<<<<<<<<<<<
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
- */
-  __pyx_k_tuple_127 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_127)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_127);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2r));
-  PyTuple_SET_ITEM(__pyx_k_tuple_127, 0, ((PyObject *)__pyx_n_s__c2r));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2r));
-  __Pyx_INCREF(((PyObject *)__pyx_kp_s__32));
-  PyTuple_SET_ITEM(__pyx_k_tuple_127, 1, ((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_kp_s__32));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_127));
-
-  /* "pyfftw/pyfftw.pyx":471
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
- *     ('c2r', 'ld'): {'planner':8, 'executor':8, 'generic_precision':2,             # <<<<<<<<<<<<<<
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays}}
- */
-  __pyx_k_tuple_128 = PyTuple_New(2); if (unlikely(!__pyx_k_tuple_128)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_128);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c2r));
-  PyTuple_SET_ITEM(__pyx_k_tuple_128, 0, ((PyObject *)__pyx_n_s__c2r));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c2r));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__ld));
-  PyTuple_SET_ITEM(__pyx_k_tuple_128, 1, ((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__ld));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_128));
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.get_input_array", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":1458
- * 
- * 
- * def export_wisdom():             # <<<<<<<<<<<<<<
- *     '''export_wisdom()
- * 
- */
-  __pyx_k_tuple_131 = PyTuple_New(12); if (unlikely(!__pyx_k_tuple_131)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_131);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__py_wisdom));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 0, ((PyObject *)__pyx_n_s__py_wisdom));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__py_wisdom));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__py_wisdomf));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 1, ((PyObject *)__pyx_n_s__py_wisdomf));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__py_wisdomf));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__py_wisdoml));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 2, ((PyObject *)__pyx_n_s__py_wisdoml));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__py_wisdoml));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__counter));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 3, ((PyObject *)__pyx_n_s__counter));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__counter));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__counterf));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 4, ((PyObject *)__pyx_n_s__counterf));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__counterf));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__counterl));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 5, ((PyObject *)__pyx_n_s__counterl));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__counterl));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c_wisdom));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 6, ((PyObject *)__pyx_n_s__c_wisdom));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c_wisdom));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c_wisdomf));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 7, ((PyObject *)__pyx_n_s__c_wisdomf));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c_wisdomf));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c_wisdoml));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 8, ((PyObject *)__pyx_n_s__c_wisdoml));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c_wisdoml));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c_wisdom_ptr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 9, ((PyObject *)__pyx_n_s__c_wisdom_ptr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c_wisdom_ptr));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c_wisdomf_ptr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 10, ((PyObject *)__pyx_n_s__c_wisdomf_ptr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c_wisdomf_ptr));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c_wisdoml_ptr));
-  PyTuple_SET_ITEM(__pyx_k_tuple_131, 11, ((PyObject *)__pyx_n_s__c_wisdoml_ptr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c_wisdoml_ptr));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_131));
-  __pyx_k_codeobj_132 = (PyObject*)__Pyx_PyCode_New(0, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_131, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_77, __pyx_n_s__export_wisdom, 1458, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_132)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "pyfftw/pyfftw.pyx":1517
- *     return (py_wisdom, py_wisdomf, py_wisdoml)
+/* "pyfftw/pyfftw.pyx":1554
+ *         return self._input_array
  * 
- * def import_wisdom(wisdom):             # <<<<<<<<<<<<<<
- *     '''import_wisdom(wisdom)
+ *     def get_output_array(self):             # <<<<<<<<<<<<<<
+ *         '''get_output_array()
  * 
  */
-  __pyx_k_tuple_133 = PyTuple_New(7); if (unlikely(!__pyx_k_tuple_133)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1517; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_k_tuple_133);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__wisdom));
-  PyTuple_SET_ITEM(__pyx_k_tuple_133, 0, ((PyObject *)__pyx_n_s__wisdom));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__wisdom));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c_wisdom));
-  PyTuple_SET_ITEM(__pyx_k_tuple_133, 1, ((PyObject *)__pyx_n_s__c_wisdom));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c_wisdom));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c_wisdomf));
-  PyTuple_SET_ITEM(__pyx_k_tuple_133, 2, ((PyObject *)__pyx_n_s__c_wisdomf));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c_wisdomf));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__c_wisdoml));
-  PyTuple_SET_ITEM(__pyx_k_tuple_133, 3, ((PyObject *)__pyx_n_s__c_wisdoml));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__c_wisdoml));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__success));
-  PyTuple_SET_ITEM(__pyx_k_tuple_133, 4, ((PyObject *)__pyx_n_s__success));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__success));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__successf));
-  PyTuple_SET_ITEM(__pyx_k_tuple_133, 5, ((PyObject *)__pyx_n_s__successf));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__successf));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__successl));
-  PyTuple_SET_ITEM(__pyx_k_tuple_133, 6, ((PyObject *)__pyx_n_s__successl));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__successl));
-  __Pyx_GIVEREF(((PyObject *)__pyx_k_tuple_133));
-  __pyx_k_codeobj_134 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_k_tuple_133, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_77, __pyx_n_s__import_wisdom, 1517, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_134)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1517; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-  /* "pyfftw/pyfftw.pyx":1633
- * #    return (success, successf, successl)
- * 
- * def forget_wisdom():             # <<<<<<<<<<<<<<
- *     '''forget_wisdom()
- * 
- */
-  __pyx_k_codeobj_135 = (PyObject*)__Pyx_PyCode_New(0, 0, 0, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_77, __pyx_n_s__forget_wisdom, 1633, __pyx_empty_bytes); if (unlikely(!__pyx_k_codeobj_135)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_RefNannyFinishContext();
-  return 0;
-  __pyx_L1_error:;
-  __Pyx_RefNannyFinishContext();
-  return -1;
-}
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_43get_output_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_42get_output_array[] = "get_output_array()\n\n        Return the output array that is associated with the FFTW\n        instance.\n\n        *Deprecated since 0.10. Consider using the* :attr:`FFTW.output_array` \n        *property instead.*\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_43get_output_array(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("get_output_array (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_42get_output_array(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
 
-static int __Pyx_InitGlobals(void) {
-  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_6 = PyInt_FromLong(6); if (unlikely(!__pyx_int_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_7 = PyInt_FromLong(7); if (unlikely(!__pyx_int_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_8 = PyInt_FromLong(8); if (unlikely(!__pyx_int_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_15 = PyInt_FromLong(15); if (unlikely(!__pyx_int_15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_16 = PyInt_FromLong(16); if (unlikely(!__pyx_int_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  __pyx_int_32 = PyInt_FromLong(32); if (unlikely(!__pyx_int_32)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  return 0;
-  __pyx_L1_error:;
-  return -1;
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
 }
 
-#if PY_MAJOR_VERSION < 3
-PyMODINIT_FUNC initpyfftw(void); /*proto*/
-PyMODINIT_FUNC initpyfftw(void)
-#else
-PyMODINIT_FUNC PyInit_pyfftw(void); /*proto*/
-PyMODINIT_FUNC PyInit_pyfftw(void)
-#endif
-{
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_42get_output_array(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
   PyObject *__pyx_t_1 = NULL;
   PyObject *__pyx_t_2 = NULL;
   PyObject *__pyx_t_3 = NULL;
-  PyObject *__pyx_t_4 = NULL;
-  int __pyx_t_5;
-  PyObject *__pyx_t_6 = NULL;
-  __Pyx_RefNannyDeclarations
-  #if CYTHON_REFNANNY
-  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
-  if (!__Pyx_RefNanny) {
-      PyErr_Clear();
-      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
-      if (!__Pyx_RefNanny)
-          Py_FatalError("failed to import 'refnanny' module");
-  }
-  #endif
-  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_pyfftw(void)", 0);
-  if ( __Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #ifdef __Pyx_CyFunction_USED
-  if (__Pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #endif
-  #ifdef __Pyx_FusedFunction_USED
-  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #endif
-  #ifdef __Pyx_Generator_USED
-  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #endif
-  /*--- Library function declarations ---*/
-  /*--- Threads initialization code ---*/
-  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
-  #ifdef WITH_THREAD /* Python build with threading support? */
-  PyEval_InitThreads();
-  #endif
-  #endif
-  /*--- Module creation code ---*/
-  #if PY_MAJOR_VERSION < 3
-  __pyx_m = Py_InitModule4(__Pyx_NAMESTR("pyfftw"), __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
-  #else
-  __pyx_m = PyModule_Create(&__pyx_moduledef);
-  #endif
-  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #if PY_MAJOR_VERSION >= 3
-  {
-    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    if (!PyDict_GetItemString(modules, "pyfftw.pyfftw")) {
-      if (unlikely(PyDict_SetItemString(modules, "pyfftw.pyfftw", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    }
-  }
-  #endif
-  __pyx_b = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME)); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #if CYTHON_COMPILING_IN_PYPY
-  Py_INCREF(__pyx_b);
-  #endif
-  if (__Pyx_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  /*--- Initialize various global constants etc. ---*/
-  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__pyx_module_is_main_pyfftw__pyfftw) {
-    if (__Pyx_SetAttrString(__pyx_m, "__name__", __pyx_n_s____main__) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
-  }
-  /*--- Builtin init code ---*/
-  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  /*--- Constants init code ---*/
-  if (unlikely(__Pyx_InitCachedConstants() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  /*--- Global init code ---*/
-  __pyx_v_6pyfftw_6pyfftw_directions = Py_None; Py_INCREF(Py_None);
-  __pyx_v_6pyfftw_6pyfftw_flag_dict = Py_None; Py_INCREF(Py_None);
-  __pyx_v_6pyfftw_6pyfftw_fftw_schemes = Py_None; Py_INCREF(Py_None);
-  __pyx_v_6pyfftw_6pyfftw_scheme_directions = Py_None; Py_INCREF(Py_None);
-  __pyx_v_6pyfftw_6pyfftw_scheme_functions = Py_None; Py_INCREF(Py_None);
-  /*--- Variable export code ---*/
-  /*--- Function export code ---*/
-  /*--- Type init code ---*/
-  __pyx_vtabptr_6pyfftw_6pyfftw_FFTW = &__pyx_vtable_6pyfftw_6pyfftw_FFTW;
-  __pyx_vtable_6pyfftw_6pyfftw_FFTW.update_arrays = (PyObject *(*)(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *, PyObject *, PyObject *, int __pyx_skip_dispatch))__pyx_f_6pyfftw_6pyfftw_4FFTW_update_arrays;
-  __pyx_vtable_6pyfftw_6pyfftw_FFTW._update_arrays = (PyObject *(*)(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *, PyArrayObject *, PyArrayObject *))__pyx_f_6pyfftw_6pyfftw_4FFTW__update_arrays;
-  __pyx_vtable_6pyfftw_6pyfftw_FFTW.execute = (PyObject *(*)(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *, int __pyx_skip_dispatch))__pyx_f_6pyfftw_6pyfftw_4FFTW_execute;
-  if (PyType_Ready(&__pyx_type_6pyfftw_6pyfftw_FFTW) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  #if CYTHON_COMPILING_IN_CPYTHON
-  {
-    PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&__pyx_type_6pyfftw_6pyfftw_FFTW, "__init__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
-      __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_12__init__ = *((PyWrapperDescrObject *)wrapper)->d_base;
-      __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_12__init__.doc = __pyx_doc_6pyfftw_6pyfftw_4FFTW_12__init__;
-      ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_12__init__;
-    }
-  }
-  #endif
-  #if CYTHON_COMPILING_IN_CPYTHON
-  {
-    PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&__pyx_type_6pyfftw_6pyfftw_FFTW, "__call__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
-      __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_16__call__ = *((PyWrapperDescrObject *)wrapper)->d_base;
-      __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_16__call__.doc = __pyx_doc_6pyfftw_6pyfftw_4FFTW_16__call__;
-      ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_16__call__;
-    }
-  }
-  #endif
-  if (__Pyx_SetVtable(__pyx_type_6pyfftw_6pyfftw_FFTW.tp_dict, __pyx_vtabptr_6pyfftw_6pyfftw_FFTW) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (__Pyx_SetAttrString(__pyx_m, "FFTW", (PyObject *)&__pyx_type_6pyfftw_6pyfftw_FFTW) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 568; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_6pyfftw_6pyfftw_FFTW = &__pyx_type_6pyfftw_6pyfftw_FFTW;
-  /*--- Type import code ---*/
-  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", 
-  #if CYTHON_COMPILING_IN_PYPY
-  sizeof(PyTypeObject),
-  #else
-  sizeof(PyHeapTypeObject),
-  #endif
-  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 165; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  /*--- Variable import code ---*/
-  /*--- Function import code ---*/
-  /*--- Execution code ---*/
+  Py_ssize_t __pyx_t_4;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("get_output_array", 0);
+
+  /* "pyfftw/pyfftw.pyx":1563
+ *         *property instead.*
+ *         '''
+ *         warnings.warn('get_output_array is deprecated. '             # <<<<<<<<<<<<<<
+ *                 'Consider using the output_array property instead.',
+ *                 DeprecationWarning)
+ */
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_warnings); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_warn); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pyfftw/pyfftw.pyx":19
- * # along with this program.  If not, see <http://www.gnu.org/licenses/>.
+  /* "pyfftw/pyfftw.pyx":1565
+ *         warnings.warn('get_output_array is deprecated. '
+ *                 'Consider using the output_array property instead.',
+ *                 DeprecationWarning)             # <<<<<<<<<<<<<<
  * 
- * import numpy as np             # <<<<<<<<<<<<<<
- * cimport numpy as np
- * from libc.stdlib cimport calloc, malloc, free
+ *         return self._output_array
  */
-  __pyx_t_1 = __Pyx_Import(((PyObject *)__pyx_n_s__numpy), 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = NULL;
+  __pyx_t_4 = 0;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_2)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_2);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+      __pyx_t_4 = 1;
+    }
+  }
+  __pyx_t_5 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  if (__pyx_t_2) {
+    __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __pyx_t_2 = NULL;
+  }
+  __Pyx_INCREF(__pyx_kp_s_get_output_array_is_deprecated_C);
+  __Pyx_GIVEREF(__pyx_kp_s_get_output_array_is_deprecated_C);
+  PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, __pyx_kp_s_get_output_array_is_deprecated_C);
+  __Pyx_INCREF(__pyx_builtin_DeprecationWarning);
+  __Pyx_GIVEREF(__pyx_builtin_DeprecationWarning);
+  PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_builtin_DeprecationWarning);
+  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1563; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 19; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":24
- * 
+  /* "pyfftw/pyfftw.pyx":1567
+ *                 DeprecationWarning)
  * 
- * cdef int _simd_alignment = cpu.simd_alignment()             # <<<<<<<<<<<<<<
+ *         return self._output_array             # <<<<<<<<<<<<<<
  * 
- * #: The optimum SIMD alignment in bytes, found by inspecting the CPU.
+ *     cpdef execute(self):
  */
-  __pyx_v_6pyfftw_6pyfftw__simd_alignment = simd_alignment();
+  __Pyx_XDECREF(__pyx_r);
+  __Pyx_INCREF(((PyObject *)__pyx_v_self->_output_array));
+  __pyx_r = ((PyObject *)__pyx_v_self->_output_array);
+  goto __pyx_L0;
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":27
+  /* "pyfftw/pyfftw.pyx":1554
+ *         return self._input_array
  * 
- * #: The optimum SIMD alignment in bytes, found by inspecting the CPU.
- * simd_alignment = _simd_alignment             # <<<<<<<<<<<<<<
+ *     def get_output_array(self):             # <<<<<<<<<<<<<<
+ *         '''get_output_array()
  * 
- * #: A tuple of simd alignments that make sense for this cpu
  */
-  __pyx_t_1 = PyInt_FromLong(__pyx_v_6pyfftw_6pyfftw__simd_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__simd_alignment, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 27; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":33
- *     _valid_simd_alignments = (16,)
- * 
- * elif _simd_alignment == 32:             # <<<<<<<<<<<<<<
- *     _valid_simd_alignments = (16, 32)
- * 
- */
-  switch (__pyx_v_6pyfftw_6pyfftw__simd_alignment) {
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.get_output_array", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":30
+/* "pyfftw/pyfftw.pyx":1569
+ *         return self._output_array
  * 
- * #: A tuple of simd alignments that make sense for this cpu
- * if _simd_alignment == 16:             # <<<<<<<<<<<<<<
- *     _valid_simd_alignments = (16,)
+ *     cpdef execute(self):             # <<<<<<<<<<<<<<
+ *         '''execute()
  * 
  */
-    case 16:
 
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":31
- * #: A tuple of simd alignments that make sense for this cpu
- * if _simd_alignment == 16:
- *     _valid_simd_alignments = (16,)             # <<<<<<<<<<<<<<
- * 
- * elif _simd_alignment == 32:
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_45execute(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static PyObject *__pyx_f_6pyfftw_6pyfftw_4FFTW_execute(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self, int __pyx_skip_dispatch) {
+  void *__pyx_v_input_pointer;
+  void *__pyx_v_output_pointer;
+  void *__pyx_v_plan;
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_execute __pyx_v_fftw_execute;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  void *__pyx_t_5;
+  __pyx_t_6pyfftw_6pyfftw_fftw_generic_execute __pyx_t_6;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("execute", 0);
+  /* Check if called by wrapper */
+  if (unlikely(__pyx_skip_dispatch)) ;
+  /* Check if overridden in Python */
+  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
+    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_execute); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_45execute)) {
+      __Pyx_XDECREF(__pyx_r);
+      __Pyx_INCREF(__pyx_t_1);
+      __pyx_t_3 = __pyx_t_1; __pyx_t_4 = NULL;
+      if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+        __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
+        if (likely(__pyx_t_4)) {
+          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+          __Pyx_INCREF(__pyx_t_4);
+          __Pyx_INCREF(function);
+          __Pyx_DECREF_SET(__pyx_t_3, function);
+        }
+      }
+      if (__pyx_t_4) {
+        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      } else {
+        __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_r = __pyx_t_2;
+      __pyx_t_2 = 0;
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      goto __pyx_L0;
+    }
+    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  }
+
+  /* "pyfftw/pyfftw.pyx":1578
+ *         '''
+ *         cdef void *input_pointer = (
+ *                 <void *>np.PyArray_DATA(self._input_array))             # <<<<<<<<<<<<<<
+ *         cdef void *output_pointer = (
+ *                 <void *>np.PyArray_DATA(self._output_array))
  */
-    if (PyObject_SetAttr(__pyx_m, __pyx_n_s_15, ((PyObject *)__pyx_k_tuple_72)) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    break;
+  __pyx_t_1 = ((PyObject *)__pyx_v_self->_input_array);
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_v_input_pointer = ((void *)PyArray_DATA(((PyArrayObject *)__pyx_t_1)));
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":33
- *     _valid_simd_alignments = (16,)
+  /* "pyfftw/pyfftw.pyx":1580
+ *                 <void *>np.PyArray_DATA(self._input_array))
+ *         cdef void *output_pointer = (
+ *                 <void *>np.PyArray_DATA(self._output_array))             # <<<<<<<<<<<<<<
  * 
- * elif _simd_alignment == 32:             # <<<<<<<<<<<<<<
- *     _valid_simd_alignments = (16, 32)
+ *         cdef void *plan = self._plan
+ */
+  __pyx_t_1 = ((PyObject *)__pyx_v_self->_output_array);
+  __Pyx_INCREF(__pyx_t_1);
+  __pyx_v_output_pointer = ((void *)PyArray_DATA(((PyArrayObject *)__pyx_t_1)));
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pyfftw/pyfftw.pyx":1582
+ *                 <void *>np.PyArray_DATA(self._output_array))
  * 
+ *         cdef void *plan = self._plan             # <<<<<<<<<<<<<<
+ *         cdef fftw_generic_execute fftw_execute = self._fftw_execute
+ *         with nogil:
  */
-    case 32:
+  __pyx_t_5 = __pyx_v_self->_plan;
+  __pyx_v_plan = __pyx_t_5;
 
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":34
+  /* "pyfftw/pyfftw.pyx":1583
  * 
- * elif _simd_alignment == 32:
- *     _valid_simd_alignments = (16, 32)             # <<<<<<<<<<<<<<
+ *         cdef void *plan = self._plan
+ *         cdef fftw_generic_execute fftw_execute = self._fftw_execute             # <<<<<<<<<<<<<<
+ *         with nogil:
+ *             fftw_execute(plan, input_pointer, output_pointer)
+ */
+  __pyx_t_6 = __pyx_v_self->_fftw_execute;
+  __pyx_v_fftw_execute = __pyx_t_6;
+
+  /* "pyfftw/pyfftw.pyx":1584
+ *         cdef void *plan = self._plan
+ *         cdef fftw_generic_execute fftw_execute = self._fftw_execute
+ *         with nogil:             # <<<<<<<<<<<<<<
+ *             fftw_execute(plan, input_pointer, output_pointer)
  * 
- * else:
  */
-    if (PyObject_SetAttr(__pyx_m, __pyx_n_s_15, ((PyObject *)__pyx_k_tuple_73)) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 34; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    break;
-    default:
+  {
+      #ifdef WITH_THREAD
+      PyThreadState *_save;
+      Py_UNBLOCK_THREADS
+      #endif
+      /*try:*/ {
 
-    /* "/home/whg21/Projects/github/pyFFTW/pyfftw/utils.pxi":37
+        /* "pyfftw/pyfftw.pyx":1585
+ *         cdef fftw_generic_execute fftw_execute = self._fftw_execute
+ *         with nogil:
+ *             fftw_execute(plan, input_pointer, output_pointer)             # <<<<<<<<<<<<<<
  * 
- * else:
- *     _valid_simd_alignments = ()             # <<<<<<<<<<<<<<
+ * cdef void count_char(char c, void *counter_ptr):
+ */
+        __pyx_v_fftw_execute(__pyx_v_plan, __pyx_v_input_pointer, __pyx_v_output_pointer);
+      }
+
+      /* "pyfftw/pyfftw.pyx":1584
+ *         cdef void *plan = self._plan
+ *         cdef fftw_generic_execute fftw_execute = self._fftw_execute
+ *         with nogil:             # <<<<<<<<<<<<<<
+ *             fftw_execute(plan, input_pointer, output_pointer)
  * 
- * cpdef n_byte_align_empty(shape, n, dtype='float64', order='C'):
  */
-    if (PyObject_SetAttr(__pyx_m, __pyx_n_s_15, ((PyObject *)__pyx_empty_tuple)) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    break;
+      /*finally:*/ {
+        /*normal exit:*/{
+          #ifdef WITH_THREAD
+          Py_BLOCK_THREADS
+          #endif
+          goto __pyx_L5;
+        }
+        __pyx_L5:;
+      }
   }
 
-  /* "pyfftw/pyfftw.pyx":31
+  /* "pyfftw/pyfftw.pyx":1569
+ *         return self._output_array
  * 
- * cdef object directions
- * directions = {'FFTW_FORWARD': FFTW_FORWARD,             # <<<<<<<<<<<<<<
- *         'FFTW_BACKWARD': FFTW_BACKWARD}
+ *     cpdef execute(self):             # <<<<<<<<<<<<<<
+ *         '''execute()
  * 
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_t_2 = PyInt_FromLong(__pyx_e_6pyfftw_6pyfftw_FFTW_FORWARD); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__FFTW_FORWARD), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pyfftw/pyfftw.pyx":32
- * cdef object directions
- * directions = {'FFTW_FORWARD': FFTW_FORWARD,
- *         'FFTW_BACKWARD': FFTW_BACKWARD}             # <<<<<<<<<<<<<<
- * 
- * cdef object flag_dict
- */
-  __pyx_t_2 = PyInt_FromLong(__pyx_e_6pyfftw_6pyfftw_FFTW_BACKWARD); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 32; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__FFTW_BACKWARD), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 31; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_directions);
-  __Pyx_DECREF(__pyx_v_6pyfftw_6pyfftw_directions);
-  __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
-  __pyx_v_6pyfftw_6pyfftw_directions = ((PyObject *)__pyx_t_1);
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.execute", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_45execute(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_4FFTW_44execute[] = "execute()\n\n        Execute the planned operation, taking the correct kind of FFT of\n        the input array (i.e. :attr:`FFTW.input_array`), \n        and putting the result in the output array (i.e.\n        :attr:`FFTW.output_array`).\n        ";
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_4FFTW_45execute(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("execute (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_4FFTW_44execute(((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)__pyx_v_self));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_4FFTW_44execute(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *__pyx_v_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("execute", 0);
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __pyx_f_6pyfftw_6pyfftw_4FFTW_execute(__pyx_v_self, 1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1569; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
   __pyx_t_1 = 0;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":35
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("pyfftw.pyfftw.FFTW.execute", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":1587
+ *             fftw_execute(plan, input_pointer, output_pointer)
  * 
- * cdef object flag_dict
- * flag_dict = {'FFTW_MEASURE': FFTW_MEASURE,             # <<<<<<<<<<<<<<
- *         'FFTW_EXHAUSTIVE': FFTW_EXHAUSTIVE,
- *         'FFTW_PATIENT': FFTW_PATIENT,
+ * cdef void count_char(char c, void *counter_ptr):             # <<<<<<<<<<<<<<
+ *     '''
+ *     On every call, increment the derefenced counter_ptr.
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  __pyx_t_2 = PyInt_FromLong(__pyx_e_6pyfftw_6pyfftw_FFTW_MEASURE); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__FFTW_MEASURE), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pyfftw/pyfftw.pyx":36
- * cdef object flag_dict
- * flag_dict = {'FFTW_MEASURE': FFTW_MEASURE,
- *         'FFTW_EXHAUSTIVE': FFTW_EXHAUSTIVE,             # <<<<<<<<<<<<<<
- *         'FFTW_PATIENT': FFTW_PATIENT,
- *         'FFTW_ESTIMATE': FFTW_ESTIMATE,
+static void __pyx_f_6pyfftw_6pyfftw_count_char(CYTHON_UNUSED char __pyx_v_c, void *__pyx_v_counter_ptr) {
+  __Pyx_RefNannyDeclarations
+  int *__pyx_t_1;
+  long __pyx_t_2;
+  __Pyx_RefNannySetupContext("count_char", 0);
+
+  /* "pyfftw/pyfftw.pyx":1591
+ *     On every call, increment the derefenced counter_ptr.
+ *     '''
+ *     (<int *>counter_ptr)[0] += 1             # <<<<<<<<<<<<<<
+ * 
+ * 
  */
-  __pyx_t_2 = PyInt_FromLong(__pyx_e_6pyfftw_6pyfftw_FFTW_EXHAUSTIVE); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__FFTW_EXHAUSTIVE), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = ((int *)__pyx_v_counter_ptr);
+  __pyx_t_2 = 0;
+  (__pyx_t_1[__pyx_t_2]) = ((__pyx_t_1[__pyx_t_2]) + 1);
 
-  /* "pyfftw/pyfftw.pyx":37
- * flag_dict = {'FFTW_MEASURE': FFTW_MEASURE,
- *         'FFTW_EXHAUSTIVE': FFTW_EXHAUSTIVE,
- *         'FFTW_PATIENT': FFTW_PATIENT,             # <<<<<<<<<<<<<<
- *         'FFTW_ESTIMATE': FFTW_ESTIMATE,
- *         'FFTW_UNALIGNED': FFTW_UNALIGNED,
+  /* "pyfftw/pyfftw.pyx":1587
+ *             fftw_execute(plan, input_pointer, output_pointer)
+ * 
+ * cdef void count_char(char c, void *counter_ptr):             # <<<<<<<<<<<<<<
+ *     '''
+ *     On every call, increment the derefenced counter_ptr.
  */
-  __pyx_t_2 = PyInt_FromLong(__pyx_e_6pyfftw_6pyfftw_FFTW_PATIENT); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 37; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__FFTW_PATIENT), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pyfftw/pyfftw.pyx":38
- *         'FFTW_EXHAUSTIVE': FFTW_EXHAUSTIVE,
- *         'FFTW_PATIENT': FFTW_PATIENT,
- *         'FFTW_ESTIMATE': FFTW_ESTIMATE,             # <<<<<<<<<<<<<<
- *         'FFTW_UNALIGNED': FFTW_UNALIGNED,
- *         'FFTW_DESTROY_INPUT': FFTW_DESTROY_INPUT}
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "pyfftw/pyfftw.pyx":1594
+ * 
+ * 
+ * cdef void write_char_to_string(char c, void *string_location_ptr):             # <<<<<<<<<<<<<<
+ *     '''
+ *     Write the passed character c to the memory location
  */
-  __pyx_t_2 = PyInt_FromLong(__pyx_e_6pyfftw_6pyfftw_FFTW_ESTIMATE); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 38; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__FFTW_ESTIMATE), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pyfftw/pyfftw.pyx":39
- *         'FFTW_PATIENT': FFTW_PATIENT,
- *         'FFTW_ESTIMATE': FFTW_ESTIMATE,
- *         'FFTW_UNALIGNED': FFTW_UNALIGNED,             # <<<<<<<<<<<<<<
- *         'FFTW_DESTROY_INPUT': FFTW_DESTROY_INPUT}
+static void __pyx_f_6pyfftw_6pyfftw_write_char_to_string(char __pyx_v_c, void *__pyx_v_string_location_ptr) {
+  char *__pyx_v_write_location;
+  __Pyx_RefNannyDeclarations
+  intptr_t *__pyx_t_1;
+  long __pyx_t_2;
+  __Pyx_RefNannySetupContext("write_char_to_string", 0);
+
+  /* "pyfftw/pyfftw.pyx":1608
+ *     unallocated piece of memory, a segfault will likely occur.
+ *     '''
+ *     cdef char *write_location = <char *>((<intptr_t *>string_location_ptr)[0])             # <<<<<<<<<<<<<<
+ *     write_location[0] = c
  * 
  */
-  __pyx_t_2 = PyInt_FromLong(__pyx_e_6pyfftw_6pyfftw_FFTW_UNALIGNED); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__FFTW_UNALIGNED), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_v_write_location = ((char *)(((intptr_t *)__pyx_v_string_location_ptr)[0]));
 
-  /* "pyfftw/pyfftw.pyx":40
- *         'FFTW_ESTIMATE': FFTW_ESTIMATE,
- *         'FFTW_UNALIGNED': FFTW_UNALIGNED,
- *         'FFTW_DESTROY_INPUT': FFTW_DESTROY_INPUT}             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1609
+ *     '''
+ *     cdef char *write_location = <char *>((<intptr_t *>string_location_ptr)[0])
+ *     write_location[0] = c             # <<<<<<<<<<<<<<
  * 
- * _flag_dict = flag_dict.copy()
+ *     (<intptr_t *>string_location_ptr)[0] += 1
  */
-  __pyx_t_2 = PyInt_FromLong(__pyx_e_6pyfftw_6pyfftw_FFTW_DESTROY_INPUT); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_n_s__FFTW_DESTROY_INPUT), __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_flag_dict);
-  __Pyx_DECREF(__pyx_v_6pyfftw_6pyfftw_flag_dict);
-  __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
-  __pyx_v_6pyfftw_6pyfftw_flag_dict = ((PyObject *)__pyx_t_1);
-  __pyx_t_1 = 0;
+  (__pyx_v_write_location[0]) = __pyx_v_c;
 
-  /* "pyfftw/pyfftw.pyx":42
- *         'FFTW_DESTROY_INPUT': FFTW_DESTROY_INPUT}
+  /* "pyfftw/pyfftw.pyx":1611
+ *     write_location[0] = c
+ * 
+ *     (<intptr_t *>string_location_ptr)[0] += 1             # <<<<<<<<<<<<<<
  * 
- * _flag_dict = flag_dict.copy()             # <<<<<<<<<<<<<<
  * 
- * # Function wrappers
  */
-  __pyx_t_1 = PyObject_GetAttr(__pyx_v_6pyfftw_6pyfftw_flag_dict, __pyx_n_s__copy); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_2 = PyObject_Call(__pyx_t_1, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s___flag_dict, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_1 = ((intptr_t *)__pyx_v_string_location_ptr);
+  __pyx_t_2 = 0;
+  (__pyx_t_1[__pyx_t_2]) = ((__pyx_t_1[__pyx_t_2]) + 1);
 
-  /* "pyfftw/pyfftw.pyx":380
- * # Shape lookup functions
- * # ======================
- * def _lookup_shape_r2c_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
- *     return input_array.shape
+  /* "pyfftw/pyfftw.pyx":1594
+ * 
  * 
+ * cdef void write_char_to_string(char c, void *string_location_ptr):             # <<<<<<<<<<<<<<
+ *     '''
+ *     Write the passed character c to the memory location
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_6pyfftw_6pyfftw_7_lookup_shape_r2c_arrays, NULL, __pyx_n_s_78); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_76, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 380; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pyfftw/pyfftw.pyx":383
- *     return input_array.shape
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "pyfftw/pyfftw.pyx":1614
  * 
- * def _lookup_shape_c2r_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
- *     return output_array.shape
+ * 
+ * def export_wisdom():             # <<<<<<<<<<<<<<
+ *     '''export_wisdom()
  * 
  */
-  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_6pyfftw_6pyfftw_9_lookup_shape_c2r_arrays, NULL, __pyx_n_s_78); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s_81, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 383; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 
-  /* "pyfftw/pyfftw.pyx":417
- * 
- * cdef object fftw_schemes
- * fftw_schemes = {             # <<<<<<<<<<<<<<
- *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),
- *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_21export_wisdom(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_20export_wisdom[] = "export_wisdom()\n\n    Return the FFTW wisdom as a tuple of strings.\n\n    The first string in the tuple is the string for the double\n    precision wisdom. The second string in the tuple is the string \n    for the single precision wisdom. The third string in the tuple \n    is the string for the long double precision wisdom.\n\n    The tuple that is returned from this function can be used as the\n    argument to :func:`~pyfftw [...]
+static PyMethodDef __pyx_mdef_6pyfftw_6pyfftw_21export_wisdom = {"export_wisdom", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_21export_wisdom, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_20export_wisdom};
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_21export_wisdom(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("export_wisdom (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_20export_wisdom(__pyx_self);
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_20export_wisdom(CYTHON_UNUSED PyObject *__pyx_self) {
+  PyObject *__pyx_v_py_wisdom = 0;
+  PyObject *__pyx_v_py_wisdomf = 0;
+  PyObject *__pyx_v_py_wisdoml = 0;
+  int __pyx_v_counter;
+  int __pyx_v_counterf;
+  int __pyx_v_counterl;
+  char *__pyx_v_c_wisdom;
+  char *__pyx_v_c_wisdomf;
+  char *__pyx_v_c_wisdoml;
+  intptr_t __pyx_v_c_wisdom_ptr;
+  intptr_t __pyx_v_c_wisdomf_ptr;
+  intptr_t __pyx_v_c_wisdoml_ptr;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  char const *__pyx_t_6;
+  PyObject *__pyx_t_7 = NULL;
+  PyObject *__pyx_t_8 = NULL;
+  PyObject *__pyx_t_9 = NULL;
+  PyObject *__pyx_t_10 = NULL;
+  PyObject *__pyx_t_11 = NULL;
+  PyObject *__pyx_t_12 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("export_wisdom", 0);
+
+  /* "pyfftw/pyfftw.pyx":1632
+ *     cdef bytes py_wisdoml
+ * 
+ *     cdef int counter = 0             # <<<<<<<<<<<<<<
+ *     cdef int counterf = 0
+ *     cdef int counterl = 0
  */
-  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_2));
+  __pyx_v_counter = 0;
 
-  /* "pyfftw/pyfftw.pyx":418
- * cdef object fftw_schemes
- * fftw_schemes = {
- *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),             # <<<<<<<<<<<<<<
- *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
- *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
+  /* "pyfftw/pyfftw.pyx":1633
+ * 
+ *     cdef int counter = 0
+ *     cdef int counterf = 0             # <<<<<<<<<<<<<<
+ *     cdef int counterl = 0
+ * 
  */
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_82), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_83), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 418; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
-  __Pyx_GIVEREF(__pyx_t_3);
-  __pyx_t_1 = 0;
-  __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_t_4), ((PyObject *)__pyx_k_tuple_84)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  __pyx_v_counterf = 0;
 
-  /* "pyfftw/pyfftw.pyx":419
- * fftw_schemes = {
- *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),
- *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),             # <<<<<<<<<<<<<<
- *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
- *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
+  /* "pyfftw/pyfftw.pyx":1634
+ *     cdef int counter = 0
+ *     cdef int counterf = 0
+ *     cdef int counterl = 0             # <<<<<<<<<<<<<<
+ * 
+ *     fftw_export_wisdom(&count_char, <void *>&counter)
  */
-  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_85), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_86), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 419; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
-  __Pyx_GIVEREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
-  __Pyx_GIVEREF(__pyx_t_3);
-  __pyx_t_4 = 0;
-  __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_t_1), ((PyObject *)__pyx_k_tuple_87)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  __pyx_v_counterl = 0;
 
-  /* "pyfftw/pyfftw.pyx":420
- *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),
- *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
- *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),             # <<<<<<<<<<<<<<
- *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
- *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
+  /* "pyfftw/pyfftw.pyx":1636
+ *     cdef int counterl = 0
+ * 
+ *     fftw_export_wisdom(&count_char, <void *>&counter)             # <<<<<<<<<<<<<<
+ *     fftwf_export_wisdom(&count_char, <void *>&counterf)
+ *     fftwl_export_wisdom(&count_char, <void *>&counterl)
  */
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_88), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_89), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
-  __Pyx_GIVEREF(__pyx_t_3);
-  __pyx_t_1 = 0;
-  __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_t_4), ((PyObject *)__pyx_k_tuple_90)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  fftw_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_count_char), ((void *)(&__pyx_v_counter)));
 
-  /* "pyfftw/pyfftw.pyx":421
- *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
- *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
- *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),             # <<<<<<<<<<<<<<
- *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
- *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
+  /* "pyfftw/pyfftw.pyx":1637
+ * 
+ *     fftw_export_wisdom(&count_char, <void *>&counter)
+ *     fftwf_export_wisdom(&count_char, <void *>&counterf)             # <<<<<<<<<<<<<<
+ *     fftwl_export_wisdom(&count_char, <void *>&counterl)
+ * 
  */
-  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_91), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_92), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
-  __Pyx_GIVEREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
-  __Pyx_GIVEREF(__pyx_t_3);
-  __pyx_t_4 = 0;
-  __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_t_1), ((PyObject *)__pyx_k_tuple_93)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+  fftwf_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_count_char), ((void *)(&__pyx_v_counterf)));
 
-  /* "pyfftw/pyfftw.pyx":422
- *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
- *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
- *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),             # <<<<<<<<<<<<<<
- *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
+  /* "pyfftw/pyfftw.pyx":1638
+ *     fftw_export_wisdom(&count_char, <void *>&counter)
+ *     fftwf_export_wisdom(&count_char, <void *>&counterf)
+ *     fftwl_export_wisdom(&count_char, <void *>&counterl)             # <<<<<<<<<<<<<<
  * 
+ *     cdef char* c_wisdom = <char *>malloc(sizeof(char)*(counter + 1))
  */
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_94), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_95), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
-  __Pyx_GIVEREF(__pyx_t_3);
-  __pyx_t_1 = 0;
-  __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_t_4), ((PyObject *)__pyx_k_tuple_96)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_4)); __pyx_t_4 = 0;
+  fftwl_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_count_char), ((void *)(&__pyx_v_counterl)));
 
-  /* "pyfftw/pyfftw.pyx":423
- *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
- *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
- *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1640
+ *     fftwl_export_wisdom(&count_char, <void *>&counterl)
  * 
- * if np.dtype('longdouble') != np.dtype('float64'):
+ *     cdef char* c_wisdom = <char *>malloc(sizeof(char)*(counter + 1))             # <<<<<<<<<<<<<<
+ *     cdef char* c_wisdomf = <char *>malloc(sizeof(char)*(counterf + 1))
+ *     cdef char* c_wisdoml = <char *>malloc(sizeof(char)*(counterl + 1))
  */
-  __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_97), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_4);
-  __pyx_t_3 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_98), NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  __pyx_t_1 = PyTuple_New(2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
-  __Pyx_GIVEREF(__pyx_t_4);
-  PyTuple_SET_ITEM(__pyx_t_1, 1, __pyx_t_3);
-  __Pyx_GIVEREF(__pyx_t_3);
-  __pyx_t_4 = 0;
-  __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_2, ((PyObject *)__pyx_t_1), ((PyObject *)__pyx_k_tuple_99)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 417; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
-  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_fftw_schemes);
-  __Pyx_DECREF(__pyx_v_6pyfftw_6pyfftw_fftw_schemes);
-  __Pyx_GIVEREF(((PyObject *)__pyx_t_2));
-  __pyx_v_6pyfftw_6pyfftw_fftw_schemes = ((PyObject *)__pyx_t_2);
-  __pyx_t_2 = 0;
+  __pyx_v_c_wisdom = ((char *)malloc(((sizeof(char)) * (__pyx_v_counter + 1))));
 
-  /* "pyfftw/pyfftw.pyx":425
- *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
+  /* "pyfftw/pyfftw.pyx":1641
+ * 
+ *     cdef char* c_wisdom = <char *>malloc(sizeof(char)*(counter + 1))
+ *     cdef char* c_wisdomf = <char *>malloc(sizeof(char)*(counterf + 1))             # <<<<<<<<<<<<<<
+ *     cdef char* c_wisdoml = <char *>malloc(sizeof(char)*(counterl + 1))
  * 
- * if np.dtype('longdouble') != np.dtype('float64'):             # <<<<<<<<<<<<<<
- *     fftw_schemes.update({
- *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
  */
-  __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_100), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_2);
-  __pyx_t_1 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_101), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_3 = PyObject_RichCompare(__pyx_t_2, __pyx_t_1, Py_NE); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 425; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (__pyx_t_5) {
+  __pyx_v_c_wisdomf = ((char *)malloc(((sizeof(char)) * (__pyx_v_counterf + 1))));
 
-    /* "pyfftw/pyfftw.pyx":426
+  /* "pyfftw/pyfftw.pyx":1642
+ *     cdef char* c_wisdom = <char *>malloc(sizeof(char)*(counter + 1))
+ *     cdef char* c_wisdomf = <char *>malloc(sizeof(char)*(counterf + 1))
+ *     cdef char* c_wisdoml = <char *>malloc(sizeof(char)*(counterl + 1))             # <<<<<<<<<<<<<<
  * 
- * if np.dtype('longdouble') != np.dtype('float64'):
- *     fftw_schemes.update({             # <<<<<<<<<<<<<<
- *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
- *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),
+ *     if c_wisdom == NULL or c_wisdomf == NULL or c_wisdoml == NULL:
  */
-    __pyx_t_3 = PyObject_GetAttr(__pyx_v_6pyfftw_6pyfftw_fftw_schemes, __pyx_n_s__update); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_3);
-    __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  __pyx_v_c_wisdoml = ((char *)malloc(((sizeof(char)) * (__pyx_v_counterl + 1))));
 
-    /* "pyfftw/pyfftw.pyx":427
- * if np.dtype('longdouble') != np.dtype('float64'):
- *     fftw_schemes.update({
- *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),             # <<<<<<<<<<<<<<
- *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),
- *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})
+  /* "pyfftw/pyfftw.pyx":1644
+ *     cdef char* c_wisdoml = <char *>malloc(sizeof(char)*(counterl + 1))
+ * 
+ *     if c_wisdom == NULL or c_wisdomf == NULL or c_wisdoml == NULL:             # <<<<<<<<<<<<<<
+ *         raise MemoryError
+ * 
  */
-    __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_102), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 427; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_103), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 427; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 427; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_2);
-    __Pyx_GIVEREF(__pyx_t_2);
-    PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __pyx_t_2 = 0;
-    __pyx_t_4 = 0;
-    if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_t_6), ((PyObject *)__pyx_k_tuple_104)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  __pyx_t_2 = ((__pyx_v_c_wisdom == NULL) != 0);
+  if (!__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L4_bool_binop_done;
+  }
+  __pyx_t_2 = ((__pyx_v_c_wisdomf == NULL) != 0);
+  if (!__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L4_bool_binop_done;
+  }
+  __pyx_t_2 = ((__pyx_v_c_wisdoml == NULL) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L4_bool_binop_done:;
+  if (__pyx_t_1) {
 
-    /* "pyfftw/pyfftw.pyx":428
- *     fftw_schemes.update({
- *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
- *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),             # <<<<<<<<<<<<<<
- *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})
+    /* "pyfftw/pyfftw.pyx":1645
  * 
+ *     if c_wisdom == NULL or c_wisdomf == NULL or c_wisdoml == NULL:
+ *         raise MemoryError             # <<<<<<<<<<<<<<
+ * 
+ *     # Set the pointers to the string pointers
  */
-    __pyx_t_6 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_105), NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_106), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_2 = PyTuple_New(2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_6);
-    __Pyx_GIVEREF(__pyx_t_6);
-    PyTuple_SET_ITEM(__pyx_t_2, 1, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __pyx_t_6 = 0;
-    __pyx_t_4 = 0;
-    if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_t_2), ((PyObject *)__pyx_k_tuple_107)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(((PyObject *)__pyx_t_2)); __pyx_t_2 = 0;
+    PyErr_NoMemory(); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1645; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
 
-    /* "pyfftw/pyfftw.pyx":429
- *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
- *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),
- *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})             # <<<<<<<<<<<<<<
+    /* "pyfftw/pyfftw.pyx":1644
+ *     cdef char* c_wisdoml = <char *>malloc(sizeof(char)*(counterl + 1))
  * 
+ *     if c_wisdom == NULL or c_wisdomf == NULL or c_wisdoml == NULL:             # <<<<<<<<<<<<<<
+ *         raise MemoryError
  * 
  */
-    __pyx_t_2 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_108), NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_2);
-    __pyx_t_4 = PyObject_Call(((PyObject *)((PyObject*)__pyx_ptype_5numpy_dtype)), ((PyObject *)__pyx_k_tuple_109), NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_4);
-    __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_2);
-    __Pyx_GIVEREF(__pyx_t_2);
-    PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_4);
-    __Pyx_GIVEREF(__pyx_t_4);
-    __pyx_t_2 = 0;
-    __pyx_t_4 = 0;
-    if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_t_6), ((PyObject *)__pyx_k_tuple_110)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-    __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_6);
-    PyTuple_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_t_1));
-    __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
-    __pyx_t_1 = 0;
-    __pyx_t_1 = PyObject_Call(__pyx_t_3, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-    __Pyx_GOTREF(__pyx_t_1);
-    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-    __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-    goto __pyx_L2;
   }
-  __pyx_L2:;
 
-  /* "pyfftw/pyfftw.pyx":433
+  /* "pyfftw/pyfftw.pyx":1648
  * 
- * cdef object scheme_directions
- * scheme_directions = {             # <<<<<<<<<<<<<<
- *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *     # Set the pointers to the string pointers
+ *     cdef intptr_t c_wisdom_ptr = <intptr_t>c_wisdom             # <<<<<<<<<<<<<<
+ *     cdef intptr_t c_wisdomf_ptr = <intptr_t>c_wisdomf
+ *     cdef intptr_t c_wisdoml_ptr = <intptr_t>c_wisdoml
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  __pyx_v_c_wisdom_ptr = ((intptr_t)__pyx_v_c_wisdom);
 
-  /* "pyfftw/pyfftw.pyx":434
- * cdef object scheme_directions
- * scheme_directions = {
- *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
- *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+  /* "pyfftw/pyfftw.pyx":1649
+ *     # Set the pointers to the string pointers
+ *     cdef intptr_t c_wisdom_ptr = <intptr_t>c_wisdom
+ *     cdef intptr_t c_wisdomf_ptr = <intptr_t>c_wisdomf             # <<<<<<<<<<<<<<
+ *     cdef intptr_t c_wisdoml_ptr = <intptr_t>c_wisdoml
+ * 
  */
-  __pyx_t_6 = PyList_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  PyList_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  PyList_SET_ITEM(__pyx_t_6, 1, ((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_111), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-
-  /* "pyfftw/pyfftw.pyx":435
- * scheme_directions = {
- *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
- *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('r2c', '64'): ['FFTW_FORWARD'],
- */
-  __pyx_t_6 = PyList_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  PyList_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  PyList_SET_ITEM(__pyx_t_6, 1, ((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_112), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-
-  /* "pyfftw/pyfftw.pyx":436
- *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
- *         ('r2c', '64'): ['FFTW_FORWARD'],
- *         ('r2c', '32'): ['FFTW_FORWARD'],
- */
-  __pyx_t_6 = PyList_New(2); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  PyList_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  PyList_SET_ITEM(__pyx_t_6, 1, ((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_113), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-
-  /* "pyfftw/pyfftw.pyx":437
- *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('r2c', '64'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
- *         ('r2c', '32'): ['FFTW_FORWARD'],
- *         ('r2c', 'ld'): ['FFTW_FORWARD'],
- */
-  __pyx_t_6 = PyList_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 437; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  PyList_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_114), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  __pyx_v_c_wisdomf_ptr = ((intptr_t)__pyx_v_c_wisdomf);
 
-  /* "pyfftw/pyfftw.pyx":438
- *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
- *         ('r2c', '64'): ['FFTW_FORWARD'],
- *         ('r2c', '32'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
- *         ('r2c', 'ld'): ['FFTW_FORWARD'],
- *         ('c2r', '64'): ['FFTW_BACKWARD'],
+  /* "pyfftw/pyfftw.pyx":1650
+ *     cdef intptr_t c_wisdom_ptr = <intptr_t>c_wisdom
+ *     cdef intptr_t c_wisdomf_ptr = <intptr_t>c_wisdomf
+ *     cdef intptr_t c_wisdoml_ptr = <intptr_t>c_wisdoml             # <<<<<<<<<<<<<<
+ * 
+ *     fftw_export_wisdom(&write_char_to_string, <void *>&c_wisdom_ptr)
  */
-  __pyx_t_6 = PyList_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 438; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  PyList_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_115), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  __pyx_v_c_wisdoml_ptr = ((intptr_t)__pyx_v_c_wisdoml);
 
-  /* "pyfftw/pyfftw.pyx":439
- *         ('r2c', '64'): ['FFTW_FORWARD'],
- *         ('r2c', '32'): ['FFTW_FORWARD'],
- *         ('r2c', 'ld'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
- *         ('c2r', '64'): ['FFTW_BACKWARD'],
- *         ('c2r', '32'): ['FFTW_BACKWARD'],
+  /* "pyfftw/pyfftw.pyx":1652
+ *     cdef intptr_t c_wisdoml_ptr = <intptr_t>c_wisdoml
+ * 
+ *     fftw_export_wisdom(&write_char_to_string, <void *>&c_wisdom_ptr)             # <<<<<<<<<<<<<<
+ *     fftwf_export_wisdom(&write_char_to_string, <void *>&c_wisdomf_ptr)
+ *     fftwl_export_wisdom(&write_char_to_string, <void *>&c_wisdoml_ptr)
  */
-  __pyx_t_6 = PyList_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  PyList_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_FORWARD));
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_116), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  fftw_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_write_char_to_string), ((void *)(&__pyx_v_c_wisdom_ptr)));
 
-  /* "pyfftw/pyfftw.pyx":440
- *         ('r2c', '32'): ['FFTW_FORWARD'],
- *         ('r2c', 'ld'): ['FFTW_FORWARD'],
- *         ('c2r', '64'): ['FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
- *         ('c2r', '32'): ['FFTW_BACKWARD'],
- *         ('c2r', 'ld'): ['FFTW_BACKWARD']}
+  /* "pyfftw/pyfftw.pyx":1653
+ * 
+ *     fftw_export_wisdom(&write_char_to_string, <void *>&c_wisdom_ptr)
+ *     fftwf_export_wisdom(&write_char_to_string, <void *>&c_wisdomf_ptr)             # <<<<<<<<<<<<<<
+ *     fftwl_export_wisdom(&write_char_to_string, <void *>&c_wisdoml_ptr)
+ * 
  */
-  __pyx_t_6 = PyList_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  PyList_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_117), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  fftwf_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_write_char_to_string), ((void *)(&__pyx_v_c_wisdomf_ptr)));
 
-  /* "pyfftw/pyfftw.pyx":441
- *         ('r2c', 'ld'): ['FFTW_FORWARD'],
- *         ('c2r', '64'): ['FFTW_BACKWARD'],
- *         ('c2r', '32'): ['FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
- *         ('c2r', 'ld'): ['FFTW_BACKWARD']}
+  /* "pyfftw/pyfftw.pyx":1654
+ *     fftw_export_wisdom(&write_char_to_string, <void *>&c_wisdom_ptr)
+ *     fftwf_export_wisdom(&write_char_to_string, <void *>&c_wisdomf_ptr)
+ *     fftwl_export_wisdom(&write_char_to_string, <void *>&c_wisdoml_ptr)             # <<<<<<<<<<<<<<
  * 
+ *     # Write the last byte as the null byte
  */
-  __pyx_t_6 = PyList_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  PyList_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_118), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  fftwl_export_wisdom((&__pyx_f_6pyfftw_6pyfftw_write_char_to_string), ((void *)(&__pyx_v_c_wisdoml_ptr)));
 
-  /* "pyfftw/pyfftw.pyx":442
- *         ('c2r', '64'): ['FFTW_BACKWARD'],
- *         ('c2r', '32'): ['FFTW_BACKWARD'],
- *         ('c2r', 'ld'): ['FFTW_BACKWARD']}             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1657
  * 
- * # In the following, -1 denotes using the default. A segfault has been
+ *     # Write the last byte as the null byte
+ *     c_wisdom[counter] = 0             # <<<<<<<<<<<<<<
+ *     c_wisdomf[counterf] = 0
+ *     c_wisdoml[counterl] = 0
  */
-  __pyx_t_6 = PyList_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  __Pyx_INCREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  PyList_SET_ITEM(__pyx_t_6, 0, ((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  __Pyx_GIVEREF(((PyObject *)__pyx_n_s__FFTW_BACKWARD));
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_119), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_scheme_directions);
-  __Pyx_DECREF(__pyx_v_6pyfftw_6pyfftw_scheme_directions);
-  __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
-  __pyx_v_6pyfftw_6pyfftw_scheme_directions = ((PyObject *)__pyx_t_1);
-  __pyx_t_1 = 0;
+  (__pyx_v_c_wisdom[__pyx_v_counter]) = 0;
 
-  /* "pyfftw/pyfftw.pyx":449
- * # that scheme_functions is an internal cdef object.
- * cdef object scheme_functions
- * scheme_functions = {             # <<<<<<<<<<<<<<
- *     ('c2c', '64'): {'planner': 0, 'executor':0, 'generic_precision':0,
- *         'validator': -1, 'fft_shape_lookup': -1},
+  /* "pyfftw/pyfftw.pyx":1658
+ *     # Write the last byte as the null byte
+ *     c_wisdom[counter] = 0
+ *     c_wisdomf[counterf] = 0             # <<<<<<<<<<<<<<
+ *     c_wisdoml[counterl] = 0
+ * 
  */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
+  (__pyx_v_c_wisdomf[__pyx_v_counterf]) = 0;
 
-  /* "pyfftw/pyfftw.pyx":450
- * cdef object scheme_functions
- * scheme_functions = {
- *     ('c2c', '64'): {'planner': 0, 'executor':0, 'generic_precision':0,             # <<<<<<<<<<<<<<
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,
- */
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_6));
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__planner), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__executor), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__generic_precision), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__validator), __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__fft_shape_lookup), __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_120), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-
-  /* "pyfftw/pyfftw.pyx":452
- *     ('c2c', '64'): {'planner': 0, 'executor':0, 'generic_precision':0,
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,             # <<<<<<<<<<<<<<
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,
- */
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_6));
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__planner), __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__executor), __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__generic_precision), __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__validator), __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__fft_shape_lookup), __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 452; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_121), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-
-  /* "pyfftw/pyfftw.pyx":454
- *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,             # <<<<<<<<<<<<<<
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('r2c', '64'): {'planner':3, 'executor':3, 'generic_precision':0,
+  /* "pyfftw/pyfftw.pyx":1659
+ *     c_wisdom[counter] = 0
+ *     c_wisdomf[counterf] = 0
+ *     c_wisdoml[counterl] = 0             # <<<<<<<<<<<<<<
+ * 
+ *     try:
  */
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_6));
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__planner), __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__executor), __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__generic_precision), __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__validator), __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__fft_shape_lookup), __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_122), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  (__pyx_v_c_wisdoml[__pyx_v_counterl]) = 0;
 
-  /* "pyfftw/pyfftw.pyx":456
- *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,
- *         'validator': -1, 'fft_shape_lookup': -1},
- *     ('r2c', '64'): {'planner':3, 'executor':3, 'generic_precision':0,             # <<<<<<<<<<<<<<
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+  /* "pyfftw/pyfftw.pyx":1661
+ *     c_wisdoml[counterl] = 0
+ * 
+ *     try:             # <<<<<<<<<<<<<<
+ *         py_wisdom = c_wisdom
+ *         py_wisdomf = c_wisdomf
  */
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_6));
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__planner), __pyx_int_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__executor), __pyx_int_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__generic_precision), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__validator), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*try:*/ {
 
-  /* "pyfftw/pyfftw.pyx":458
- *     ('r2c', '64'): {'planner':3, 'executor':3, 'generic_precision':0,
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},             # <<<<<<<<<<<<<<
- *     ('r2c', '32'): {'planner':4, 'executor':4, 'generic_precision':1,
- *         'validator': 0,
+    /* "pyfftw/pyfftw.pyx":1662
+ * 
+ *     try:
+ *         py_wisdom = c_wisdom             # <<<<<<<<<<<<<<
+ *         py_wisdomf = c_wisdomf
+ *         py_wisdoml = c_wisdoml
  */
-  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s_76); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__fft_shape_lookup), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_123), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+    __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_c_wisdom); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1662; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_v_py_wisdom = ((PyObject*)__pyx_t_3);
+    __pyx_t_3 = 0;
 
-  /* "pyfftw/pyfftw.pyx":459
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
- *     ('r2c', '32'): {'planner':4, 'executor':4, 'generic_precision':1,             # <<<<<<<<<<<<<<
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+    /* "pyfftw/pyfftw.pyx":1663
+ *     try:
+ *         py_wisdom = c_wisdom
+ *         py_wisdomf = c_wisdomf             # <<<<<<<<<<<<<<
+ *         py_wisdoml = c_wisdoml
+ * 
  */
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_6));
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__planner), __pyx_int_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__executor), __pyx_int_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__generic_precision), __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__validator), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_c_wisdomf); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1663; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_v_py_wisdomf = ((PyObject*)__pyx_t_3);
+    __pyx_t_3 = 0;
 
-  /* "pyfftw/pyfftw.pyx":461
- *     ('r2c', '32'): {'planner':4, 'executor':4, 'generic_precision':1,
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},             # <<<<<<<<<<<<<<
- *     ('r2c', 'ld'): {'planner':5, 'executor':5, 'generic_precision':2,
- *         'validator': 0,
+    /* "pyfftw/pyfftw.pyx":1664
+ *         py_wisdom = c_wisdom
+ *         py_wisdomf = c_wisdomf
+ *         py_wisdoml = c_wisdoml             # <<<<<<<<<<<<<<
+ * 
+ *     finally:
  */
-  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s_76); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__fft_shape_lookup), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 459; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_124), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+    __pyx_t_3 = __Pyx_PyBytes_FromString(__pyx_v_c_wisdoml); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1664; __pyx_clineno = __LINE__; goto __pyx_L8_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __pyx_v_py_wisdoml = ((PyObject*)__pyx_t_3);
+    __pyx_t_3 = 0;
+  }
 
-  /* "pyfftw/pyfftw.pyx":462
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
- *     ('r2c', 'ld'): {'planner':5, 'executor':5, 'generic_precision':2,             # <<<<<<<<<<<<<<
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+  /* "pyfftw/pyfftw.pyx":1667
+ * 
+ *     finally:
+ *         free(c_wisdom)             # <<<<<<<<<<<<<<
+ *         free(c_wisdomf)
+ *         free(c_wisdoml)
  */
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_6));
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__planner), __pyx_int_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__executor), __pyx_int_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__generic_precision), __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__validator), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*finally:*/ {
+    /*normal exit:*/{
+      free(__pyx_v_c_wisdom);
 
-  /* "pyfftw/pyfftw.pyx":464
- *     ('r2c', 'ld'): {'planner':5, 'executor':5, 'generic_precision':2,
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},             # <<<<<<<<<<<<<<
- *     ('c2r', '64'): {'planner':6, 'executor':6, 'generic_precision':0,
- *         'validator': 1,
+      /* "pyfftw/pyfftw.pyx":1668
+ *     finally:
+ *         free(c_wisdom)
+ *         free(c_wisdomf)             # <<<<<<<<<<<<<<
+ *         free(c_wisdoml)
+ * 
  */
-  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s_76); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__fft_shape_lookup), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_125), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+      free(__pyx_v_c_wisdomf);
 
-  /* "pyfftw/pyfftw.pyx":465
- *         'validator': 0,
- *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
- *     ('c2r', '64'): {'planner':6, 'executor':6, 'generic_precision':0,             # <<<<<<<<<<<<<<
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
+      /* "pyfftw/pyfftw.pyx":1669
+ *         free(c_wisdom)
+ *         free(c_wisdomf)
+ *         free(c_wisdoml)             # <<<<<<<<<<<<<<
+ * 
+ *     return (py_wisdom, py_wisdomf, py_wisdoml)
+ */
+      free(__pyx_v_c_wisdoml);
+      goto __pyx_L9;
+    }
+    /*exception exit:*/{
+      __pyx_L8_error:;
+      __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0;
+      __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_10, &__pyx_t_11, &__pyx_t_12);
+      if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9) < 0)) __Pyx_ErrFetch(&__pyx_t_7, &__pyx_t_8, &__pyx_t_9);
+      __Pyx_XGOTREF(__pyx_t_7);
+      __Pyx_XGOTREF(__pyx_t_8);
+      __Pyx_XGOTREF(__pyx_t_9);
+      __Pyx_XGOTREF(__pyx_t_10);
+      __Pyx_XGOTREF(__pyx_t_11);
+      __Pyx_XGOTREF(__pyx_t_12);
+      __pyx_t_4 = __pyx_lineno; __pyx_t_5 = __pyx_clineno; __pyx_t_6 = __pyx_filename;
+      {
+
+        /* "pyfftw/pyfftw.pyx":1667
+ * 
+ *     finally:
+ *         free(c_wisdom)             # <<<<<<<<<<<<<<
+ *         free(c_wisdomf)
+ *         free(c_wisdoml)
  */
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_6));
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__planner), __pyx_int_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__executor), __pyx_int_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__generic_precision), __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__validator), __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        free(__pyx_v_c_wisdom);
 
-  /* "pyfftw/pyfftw.pyx":467
- *     ('c2r', '64'): {'planner':6, 'executor':6, 'generic_precision':0,
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays},             # <<<<<<<<<<<<<<
- *     ('c2r', '32'): {'planner':7, 'executor':7, 'generic_precision':1,
- *         'validator': 1,
+        /* "pyfftw/pyfftw.pyx":1668
+ *     finally:
+ *         free(c_wisdom)
+ *         free(c_wisdomf)             # <<<<<<<<<<<<<<
+ *         free(c_wisdoml)
+ * 
  */
-  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s_81); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__fft_shape_lookup), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_126), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+        free(__pyx_v_c_wisdomf);
 
-  /* "pyfftw/pyfftw.pyx":468
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
- *     ('c2r', '32'): {'planner':7, 'executor':7, 'generic_precision':1,             # <<<<<<<<<<<<<<
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
+        /* "pyfftw/pyfftw.pyx":1669
+ *         free(c_wisdom)
+ *         free(c_wisdomf)
+ *         free(c_wisdoml)             # <<<<<<<<<<<<<<
+ * 
+ *     return (py_wisdom, py_wisdomf, py_wisdoml)
  */
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_6));
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__planner), __pyx_int_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__executor), __pyx_int_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__generic_precision), __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__validator), __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        free(__pyx_v_c_wisdoml);
+      }
+      if (PY_MAJOR_VERSION >= 3) {
+        __Pyx_XGIVEREF(__pyx_t_10);
+        __Pyx_XGIVEREF(__pyx_t_11);
+        __Pyx_XGIVEREF(__pyx_t_12);
+        __Pyx_ExceptionReset(__pyx_t_10, __pyx_t_11, __pyx_t_12);
+      }
+      __Pyx_XGIVEREF(__pyx_t_7);
+      __Pyx_XGIVEREF(__pyx_t_8);
+      __Pyx_XGIVEREF(__pyx_t_9);
+      __Pyx_ErrRestore(__pyx_t_7, __pyx_t_8, __pyx_t_9);
+      __pyx_t_7 = 0; __pyx_t_8 = 0; __pyx_t_9 = 0; __pyx_t_10 = 0; __pyx_t_11 = 0; __pyx_t_12 = 0;
+      __pyx_lineno = __pyx_t_4; __pyx_clineno = __pyx_t_5; __pyx_filename = __pyx_t_6;
+      goto __pyx_L1_error;
+    }
+    __pyx_L9:;
+  }
 
-  /* "pyfftw/pyfftw.pyx":470
- *     ('c2r', '32'): {'planner':7, 'executor':7, 'generic_precision':1,
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays},             # <<<<<<<<<<<<<<
- *     ('c2r', 'ld'): {'planner':8, 'executor':8, 'generic_precision':2,
- *         'validator': 1,
+  /* "pyfftw/pyfftw.pyx":1671
+ *         free(c_wisdoml)
+ * 
+ *     return (py_wisdom, py_wisdomf, py_wisdoml)             # <<<<<<<<<<<<<<
+ * 
+ * def import_wisdom(wisdom):
  */
-  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s_81); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1671; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__fft_shape_lookup), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_127), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
+  __Pyx_INCREF(__pyx_v_py_wisdom);
+  __Pyx_GIVEREF(__pyx_v_py_wisdom);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_py_wisdom);
+  __Pyx_INCREF(__pyx_v_py_wisdomf);
+  __Pyx_GIVEREF(__pyx_v_py_wisdomf);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_py_wisdomf);
+  __Pyx_INCREF(__pyx_v_py_wisdoml);
+  __Pyx_GIVEREF(__pyx_v_py_wisdoml);
+  PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_py_wisdoml);
+  __pyx_r = __pyx_t_3;
+  __pyx_t_3 = 0;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":471
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
- *     ('c2r', 'ld'): {'planner':8, 'executor':8, 'generic_precision':2,             # <<<<<<<<<<<<<<
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays}}
- */
-  __pyx_t_6 = PyDict_New(); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_6));
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__planner), __pyx_int_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__executor), __pyx_int_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__generic_precision), __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__validator), __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-
-  /* "pyfftw/pyfftw.pyx":473
- *     ('c2r', 'ld'): {'planner':8, 'executor':8, 'generic_precision':2,
- *         'validator': 1,
- *         'fft_shape_lookup': _lookup_shape_c2r_arrays}}             # <<<<<<<<<<<<<<
- * 
- * # Initialize the module
- */
-  __pyx_t_3 = __Pyx_GetName(__pyx_m, __pyx_n_s_81); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 473; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_3);
-  if (PyDict_SetItem(__pyx_t_6, ((PyObject *)__pyx_n_s__fft_shape_lookup), __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
-  if (PyDict_SetItem(__pyx_t_1, ((PyObject *)__pyx_k_tuple_128), ((PyObject *)__pyx_t_6)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_scheme_functions);
-  __Pyx_DECREF(__pyx_v_6pyfftw_6pyfftw_scheme_functions);
-  __Pyx_GIVEREF(((PyObject *)__pyx_t_1));
-  __pyx_v_6pyfftw_6pyfftw_scheme_functions = ((PyObject *)__pyx_t_1);
-  __pyx_t_1 = 0;
-
-  /* "pyfftw/pyfftw.pyx":478
+  /* "pyfftw/pyfftw.pyx":1614
  * 
- * # Define the functions
- * _build_planner_list()             # <<<<<<<<<<<<<<
- * _build_destroyer_list()
- * _build_executor_list()
- */
-  __pyx_f_6pyfftw_6pyfftw__build_planner_list();
-
-  /* "pyfftw/pyfftw.pyx":479
- * # Define the functions
- * _build_planner_list()
- * _build_destroyer_list()             # <<<<<<<<<<<<<<
- * _build_executor_list()
- * _build_nthreads_plan_setters_list()
- */
-  __pyx_f_6pyfftw_6pyfftw__build_destroyer_list();
-
-  /* "pyfftw/pyfftw.pyx":480
- * _build_planner_list()
- * _build_destroyer_list()
- * _build_executor_list()             # <<<<<<<<<<<<<<
- * _build_nthreads_plan_setters_list()
- * _build_validators_list()
- */
-  __pyx_f_6pyfftw_6pyfftw__build_executor_list();
-
-  /* "pyfftw/pyfftw.pyx":481
- * _build_destroyer_list()
- * _build_executor_list()
- * _build_nthreads_plan_setters_list()             # <<<<<<<<<<<<<<
- * _build_validators_list()
- * _build_set_timelimit_funcs_list()
- */
-  __pyx_f_6pyfftw_6pyfftw__build_nthreads_plan_setters_list();
-
-  /* "pyfftw/pyfftw.pyx":482
- * _build_executor_list()
- * _build_nthreads_plan_setters_list()
- * _build_validators_list()             # <<<<<<<<<<<<<<
- * _build_set_timelimit_funcs_list()
  * 
- */
-  __pyx_f_6pyfftw_6pyfftw__build_validators_list();
-
-  /* "pyfftw/pyfftw.pyx":483
- * _build_nthreads_plan_setters_list()
- * _build_validators_list()
- * _build_set_timelimit_funcs_list()             # <<<<<<<<<<<<<<
+ * def export_wisdom():             # <<<<<<<<<<<<<<
+ *     '''export_wisdom()
  * 
- * fftw_init_threads()
  */
-  __pyx_f_6pyfftw_6pyfftw__build_set_timelimit_funcs_list();
 
-  /* "pyfftw/pyfftw.pyx":485
- * _build_set_timelimit_funcs_list()
- * 
- * fftw_init_threads()             # <<<<<<<<<<<<<<
- * fftwf_init_threads()
- * fftwl_init_threads()
- */
-  fftw_init_threads();
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_AddTraceback("pyfftw.pyfftw.export_wisdom", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF(__pyx_v_py_wisdom);
+  __Pyx_XDECREF(__pyx_v_py_wisdomf);
+  __Pyx_XDECREF(__pyx_v_py_wisdoml);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":486
+/* "pyfftw/pyfftw.pyx":1673
+ *     return (py_wisdom, py_wisdomf, py_wisdoml)
  * 
- * fftw_init_threads()
- * fftwf_init_threads()             # <<<<<<<<<<<<<<
- * fftwl_init_threads()
+ * def import_wisdom(wisdom):             # <<<<<<<<<<<<<<
+ *     '''import_wisdom(wisdom)
  * 
  */
-  fftwf_init_threads();
 
-  /* "pyfftw/pyfftw.pyx":487
- * fftw_init_threads()
- * fftwf_init_threads()
- * fftwl_init_threads()             # <<<<<<<<<<<<<<
- * 
- * # Set the cleanup routine
- */
-  fftwl_init_threads();
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_23import_wisdom(PyObject *__pyx_self, PyObject *__pyx_v_wisdom); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_22import_wisdom[] = "import_wisdom(wisdom)\n\n    Function that imports wisdom from the passed tuple\n    of strings.\n\n    The first string in the tuple is the string for the double\n    precision wisdom. The second string in the tuple is the string \n    for the single precision wisdom. The third string in the tuple \n    is the string for the long double precision wisdom.\n\n    The tuple that is returned from :func:`~pyfftw.export_wisdom`\n    c [...]
+static PyMethodDef __pyx_mdef_6pyfftw_6pyfftw_23import_wisdom = {"import_wisdom", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_23import_wisdom, METH_O, __pyx_doc_6pyfftw_6pyfftw_22import_wisdom};
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_23import_wisdom(PyObject *__pyx_self, PyObject *__pyx_v_wisdom) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("import_wisdom (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_22import_wisdom(__pyx_self, ((PyObject *)__pyx_v_wisdom));
 
-  /* "pyfftw/pyfftw.pyx":498
- *     fftwl_cleanup_threads()
- * 
- * Py_AtExit(_cleanup)             # <<<<<<<<<<<<<<
- * 
- * # Helper functions
- */
-  Py_AtExit(__pyx_f_6pyfftw_6pyfftw__cleanup);
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
 
-  /* "pyfftw/pyfftw.pyx":647
- *         return self.__N
- * 
- *     N = property(__get_N)             # <<<<<<<<<<<<<<
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_22import_wisdom(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_wisdom) {
+  char *__pyx_v_c_wisdom;
+  char *__pyx_v_c_wisdomf;
+  char *__pyx_v_c_wisdoml;
+  int __pyx_v_success;
+  int __pyx_v_successf;
+  int __pyx_v_successl;
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  char *__pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  PyObject *__pyx_t_5 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("import_wisdom", 0);
+
+  /* "pyfftw/pyfftw.pyx":1692
+ *     '''
  * 
- *     def __get_simd_aligned(self):
+ *     cdef char* c_wisdom = wisdom[0]             # <<<<<<<<<<<<<<
+ *     cdef char* c_wisdomf = wisdom[1]
+ *     cdef char* c_wisdoml = wisdom[2]
  */
-  __pyx_t_1 = __Pyx_GetName((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s____get_N); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_wisdom, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1692; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
   __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_builtin_property, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s__N, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 647; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_AsString(__pyx_t_1); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1692; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_c_wisdom = __pyx_t_2;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
 
-  /* "pyfftw/pyfftw.pyx":656
- *         return self.__simd_allowed
+  /* "pyfftw/pyfftw.pyx":1693
  * 
- *     simd_aligned = property(__get_simd_aligned)             # <<<<<<<<<<<<<<
+ *     cdef char* c_wisdom = wisdom[0]
+ *     cdef char* c_wisdomf = wisdom[1]             # <<<<<<<<<<<<<<
+ *     cdef char* c_wisdoml = wisdom[2]
  * 
- *     def __get_input_alignment(self):
  */
-  __pyx_t_1 = __Pyx_GetName((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s____get_simd_aligned); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_builtin_property, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_wisdom, 1, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1693; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s__simd_aligned, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 656; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_AsString(__pyx_t_1); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1693; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_c_wisdomf = __pyx_t_2;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
 
-  /* "pyfftw/pyfftw.pyx":670
- *         return self.__input_array_alignment
- * 
- *     input_alignment = property(__get_input_alignment)             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1694
+ *     cdef char* c_wisdom = wisdom[0]
+ *     cdef char* c_wisdomf = wisdom[1]
+ *     cdef char* c_wisdoml = wisdom[2]             # <<<<<<<<<<<<<<
  * 
- *     def __get_output_alignment(self):
+ *     cdef bint success = fftw_import_wisdom_from_string(c_wisdom)
  */
-  __pyx_t_1 = __Pyx_GetName((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_129); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_builtin_property, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_1 = __Pyx_GetItemInt(__pyx_v_wisdom, 2, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(__pyx_t_1 == NULL)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1694; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
   __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s__input_alignment, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 670; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_t_2 = __Pyx_PyObject_AsString(__pyx_t_1); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1694; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_v_c_wisdoml = __pyx_t_2;
   __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
 
-  /* "pyfftw/pyfftw.pyx":682
- *         return self.__output_array_alignment
- * 
- *     output_alignment = property(__get_output_alignment)             # <<<<<<<<<<<<<<
+  /* "pyfftw/pyfftw.pyx":1696
+ *     cdef char* c_wisdoml = wisdom[2]
  * 
- *     def __get_flags_used(self):
+ *     cdef bint success = fftw_import_wisdom_from_string(c_wisdom)             # <<<<<<<<<<<<<<
+ *     cdef bint successf = fftwf_import_wisdom_from_string(c_wisdomf)
+ *     cdef bint successl = fftwl_import_wisdom_from_string(c_wisdoml)
  */
-  __pyx_t_1 = __Pyx_GetName((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_130); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_builtin_property, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s__output_alignment, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 682; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+  __pyx_v_success = fftw_import_wisdom_from_string(__pyx_v_c_wisdom);
 
-  /* "pyfftw/pyfftw.pyx":692
- *         return tuple(self.__flags_used)
+  /* "pyfftw/pyfftw.pyx":1697
  * 
- *     flags = property(__get_flags_used)             # <<<<<<<<<<<<<<
+ *     cdef bint success = fftw_import_wisdom_from_string(c_wisdom)
+ *     cdef bint successf = fftwf_import_wisdom_from_string(c_wisdomf)             # <<<<<<<<<<<<<<
+ *     cdef bint successl = fftwl_import_wisdom_from_string(c_wisdoml)
  * 
- *     def __cinit__(self, input_array, output_array, axes=(-1,),
  */
-  __pyx_t_1 = __Pyx_GetName((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s____get_flags_used); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 692; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 692; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_6);
-  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
-  __pyx_t_1 = PyObject_Call(__pyx_builtin_property, ((PyObject *)__pyx_t_6), NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 692; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __Pyx_DECREF(((PyObject *)__pyx_t_6)); __pyx_t_6 = 0;
-  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s__flags, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 692; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
-  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+  __pyx_v_successf = fftwf_import_wisdom_from_string(__pyx_v_c_wisdomf);
 
-  /* "pyfftw/pyfftw.pyx":1194
- * 
- *     def __call__(self, input_array=None, output_array=None,
- *             normalise_idft=True):             # <<<<<<<<<<<<<<
- *         '''__call__(input_array=None, output_array=None, normalise_idft=True)
+  /* "pyfftw/pyfftw.pyx":1698
+ *     cdef bint success = fftw_import_wisdom_from_string(c_wisdom)
+ *     cdef bint successf = fftwf_import_wisdom_from_string(c_wisdomf)
+ *     cdef bint successl = fftwl_import_wisdom_from_string(c_wisdoml)             # <<<<<<<<<<<<<<
  * 
+ *     return (success, successf, successl)
  */
-  __pyx_t_1 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  __pyx_k_40 = __pyx_t_1;
-  __Pyx_GIVEREF(__pyx_t_1);
-  __pyx_t_1 = 0;
+  __pyx_v_successl = fftwl_import_wisdom_from_string(__pyx_v_c_wisdoml);
 
-  /* "pyfftw/pyfftw.pyx":1458
- * 
+  /* "pyfftw/pyfftw.pyx":1700
+ *     cdef bint successl = fftwl_import_wisdom_from_string(c_wisdoml)
  * 
- * def export_wisdom():             # <<<<<<<<<<<<<<
- *     '''export_wisdom()
+ *     return (success, successf, successl)             # <<<<<<<<<<<<<<
  * 
+ * #def export_wisdom_to_files(
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6pyfftw_6pyfftw_11export_wisdom, NULL, __pyx_n_s_78); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_v_success); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1700; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
   __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__export_wisdom, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1458; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_v_successf); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1700; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_4 = __Pyx_PyBool_FromLong(__pyx_v_successl); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1700; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_5 = PyTuple_New(3); if (unlikely(!__pyx_t_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1700; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_5);
+  __Pyx_GIVEREF(__pyx_t_1);
+  PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_5, 1, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_5, 2, __pyx_t_4);
+  __pyx_t_1 = 0;
+  __pyx_t_3 = 0;
+  __pyx_t_4 = 0;
+  __pyx_r = __pyx_t_5;
+  __pyx_t_5 = 0;
+  goto __pyx_L0;
 
-  /* "pyfftw/pyfftw.pyx":1517
+  /* "pyfftw/pyfftw.pyx":1673
  *     return (py_wisdom, py_wisdomf, py_wisdoml)
  * 
  * def import_wisdom(wisdom):             # <<<<<<<<<<<<<<
  *     '''import_wisdom(wisdom)
  * 
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6pyfftw_6pyfftw_13import_wisdom, NULL, __pyx_n_s_78); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1517; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__import_wisdom, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1517; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1633
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_5);
+  __Pyx_AddTraceback("pyfftw.pyfftw.import_wisdom", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "pyfftw/pyfftw.pyx":1789
  * #    return (success, successf, successl)
  * 
  * def forget_wisdom():             # <<<<<<<<<<<<<<
  *     '''forget_wisdom()
  * 
  */
-  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6pyfftw_6pyfftw_15forget_wisdom, NULL, __pyx_n_s_78); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(__pyx_t_1);
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s__forget_wisdom, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 
-  /* "pyfftw/pyfftw.pyx":1
- * # Copyright 2012 Knowledge Economy Developments Ltd             # <<<<<<<<<<<<<<
- * #
- * # Henry Gomersall
- */
-  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_GOTREF(((PyObject *)__pyx_t_1));
-  if (PyObject_SetAttr(__pyx_m, __pyx_n_s____test__, ((PyObject *)__pyx_t_1)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
-  __Pyx_DECREF(((PyObject *)__pyx_t_1)); __pyx_t_1 = 0;
+/* Python wrapper */
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_25forget_wisdom(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused); /*proto*/
+static char __pyx_doc_6pyfftw_6pyfftw_24forget_wisdom[] = "forget_wisdom()\n\n    Forget all the accumulated wisdom.\n    ";
+static PyMethodDef __pyx_mdef_6pyfftw_6pyfftw_25forget_wisdom = {"forget_wisdom", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_25forget_wisdom, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_24forget_wisdom};
+static PyObject *__pyx_pw_6pyfftw_6pyfftw_25forget_wisdom(PyObject *__pyx_self, CYTHON_UNUSED PyObject *unused) {
+  PyObject *__pyx_r = 0;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("forget_wisdom (wrapper)", 0);
+  __pyx_r = __pyx_pf_6pyfftw_6pyfftw_24forget_wisdom(__pyx_self);
 
-  /* "numpy.pxd":975
- *      arr.base = baseptr
- * 
- * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
- *     if arr.base is NULL:
- *         return None
- */
-  goto __pyx_L0;
-  __pyx_L1_error:;
-  __Pyx_XDECREF(__pyx_t_1);
-  __Pyx_XDECREF(__pyx_t_2);
-  __Pyx_XDECREF(__pyx_t_3);
-  __Pyx_XDECREF(__pyx_t_4);
-  __Pyx_XDECREF(__pyx_t_6);
-  if (__pyx_m) {
-    __Pyx_AddTraceback("init pyfftw.pyfftw", __pyx_clineno, __pyx_lineno, __pyx_filename);
-    Py_DECREF(__pyx_m); __pyx_m = 0;
-  } else if (!PyErr_Occurred()) {
-    PyErr_SetString(PyExc_ImportError, "init pyfftw.pyfftw");
-  }
-  __pyx_L0:;
+  /* function exit code */
   __Pyx_RefNannyFinishContext();
-  #if PY_MAJOR_VERSION < 3
-  return;
-  #else
-  return __pyx_m;
-  #endif
+  return __pyx_r;
 }
 
-/* Runtime support code */
-#if CYTHON_REFNANNY
-static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
-    PyObject *m = NULL, *p = NULL;
-    void *r = NULL;
-    m = PyImport_ImportModule((char *)modname);
-    if (!m) goto end;
-    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
-    if (!p) goto end;
-    r = PyLong_AsVoidPtr(p);
-end:
-    Py_XDECREF(p);
-    Py_XDECREF(m);
-    return (__Pyx_RefNannyAPIStruct *)r;
+static PyObject *__pyx_pf_6pyfftw_6pyfftw_24forget_wisdom(CYTHON_UNUSED PyObject *__pyx_self) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("forget_wisdom", 0);
+
+  /* "pyfftw/pyfftw.pyx":1794
+ *     Forget all the accumulated wisdom.
+ *     '''
+ *     fftw_forget_wisdom()             # <<<<<<<<<<<<<<
+ *     fftwf_forget_wisdom()
+ *     fftwl_forget_wisdom()
+ */
+  fftw_forget_wisdom();
+
+  /* "pyfftw/pyfftw.pyx":1795
+ *     '''
+ *     fftw_forget_wisdom()
+ *     fftwf_forget_wisdom()             # <<<<<<<<<<<<<<
+ *     fftwl_forget_wisdom()
+ * 
+ */
+  fftwf_forget_wisdom();
+
+  /* "pyfftw/pyfftw.pyx":1796
+ *     fftw_forget_wisdom()
+ *     fftwf_forget_wisdom()
+ *     fftwl_forget_wisdom()             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  fftwl_forget_wisdom();
+
+  /* "pyfftw/pyfftw.pyx":1789
+ * #    return (success, successf, successl)
+ * 
+ * def forget_wisdom():             # <<<<<<<<<<<<<<
+ *     '''forget_wisdom()
+ * 
+ */
+
+  /* function exit code */
+  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
 }
-#endif /* CYTHON_REFNANNY */
 
-static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
-    PyObject *result;
-    result = PyObject_GetAttr(dict, name);
-    if (!result) {
-        if (dict != __pyx_b) {
-            PyErr_Clear();
-            result = PyObject_GetAttr(__pyx_b, name);
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":197
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
+static CYTHON_UNUSED int __pyx_pw_5numpy_7ndarray_1__getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__getbuffer__ (wrapper)", 0);
+  __pyx_r = __pyx_pf_5numpy_7ndarray___getbuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info), ((int)__pyx_v_flags));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
+  int __pyx_v_copy_shape;
+  int __pyx_v_i;
+  int __pyx_v_ndim;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  int __pyx_v_t;
+  char *__pyx_v_f;
+  PyArray_Descr *__pyx_v_descr = 0;
+  int __pyx_v_offset;
+  int __pyx_v_hasfields;
+  int __pyx_r;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  int __pyx_t_4;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  char *__pyx_t_7;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("__getbuffer__", 0);
+  if (__pyx_v_info != NULL) {
+    __pyx_v_info->obj = Py_None; __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(__pyx_v_info->obj);
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":203
+ *             # of flags
+ * 
+ *             if info == NULL: return             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int copy_shape, i, ndim
+ */
+  __pyx_t_1 = ((__pyx_v_info == NULL) != 0);
+  if (__pyx_t_1) {
+    __pyx_r = 0;
+    goto __pyx_L0;
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":206
+ * 
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":207
+ *             cdef int copy_shape, i, ndim
+ *             cdef int endian_detector = 1
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ * 
+ *             ndim = PyArray_NDIM(self)
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":209
+ *             cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ * 
+ *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_v_ndim = PyArray_NDIM(__pyx_v_self);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":211
+ *             ndim = PyArray_NDIM(self)
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 copy_shape = 1
+ *             else:
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":212
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 copy_shape = 1             # <<<<<<<<<<<<<<
+ *             else:
+ *                 copy_shape = 0
+ */
+    __pyx_v_copy_shape = 1;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":211
+ *             ndim = PyArray_NDIM(self)
+ * 
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 copy_shape = 1
+ *             else:
+ */
+    goto __pyx_L4;
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":214
+ *                 copy_shape = 1
+ *             else:
+ *                 copy_shape = 0             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ */
+  /*else*/ {
+    __pyx_v_copy_shape = 0;
+  }
+  __pyx_L4:;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":216
+ *                 copy_shape = 0
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L6_bool_binop_done;
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":217
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_C_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L6_bool_binop_done:;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":216
+ *                 copy_shape = 0
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ */
+  if (__pyx_t_1) {
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__32, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[2]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":216
+ *                 copy_shape = 0
+ * 
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ */
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":220
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+  __pyx_t_2 = (((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L9_bool_binop_done;
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":221
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ */
+  __pyx_t_2 = ((!(PyArray_CHKFLAGS(__pyx_v_self, NPY_F_CONTIGUOUS) != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L9_bool_binop_done:;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":220
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+  if (__pyx_t_1) {
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__33, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    {__pyx_filename = __pyx_f[2]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":220
+ *                 raise ValueError(u"ndarray is not C contiguous")
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ */
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":224
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")
+ * 
+ *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
+ *             info.ndim = ndim
+ *             if copy_shape:
+ */
+  __pyx_v_info->buf = PyArray_DATA(__pyx_v_self);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":225
+ * 
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim             # <<<<<<<<<<<<<<
+ *             if copy_shape:
+ *                 # Allocate new buffer for strides and shape info.
+ */
+  __pyx_v_info->ndim = __pyx_v_ndim;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":226
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim
+ *             if copy_shape:             # <<<<<<<<<<<<<<
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ */
+  __pyx_t_1 = (__pyx_v_copy_shape != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":229
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)             # <<<<<<<<<<<<<<
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ */
+    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * ((size_t)__pyx_v_ndim)) * 2)));
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":230
+ *                 # This is allocated as one block, strides first.
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ */
+    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":231
+ *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * <size_t>ndim * 2)
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):             # <<<<<<<<<<<<<<
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ */
+    __pyx_t_4 = __pyx_v_ndim;
+    for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
+      __pyx_v_i = __pyx_t_5;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":232
+ *                 info.shape = info.strides + ndim
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ */
+      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(__pyx_v_self)[__pyx_v_i]);
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":233
+ *                 for i in range(ndim):
+ *                     info.strides[i] = PyArray_STRIDES(self)[i]
+ *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ */
+      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(__pyx_v_self)[__pyx_v_i]);
+    }
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":226
+ *             info.buf = PyArray_DATA(self)
+ *             info.ndim = ndim
+ *             if copy_shape:             # <<<<<<<<<<<<<<
+ *                 # Allocate new buffer for strides and shape info.
+ *                 # This is allocated as one block, strides first.
+ */
+    goto __pyx_L11;
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":235
+ *                     info.shape[i] = PyArray_DIMS(self)[i]
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ */
+  /*else*/ {
+    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(__pyx_v_self));
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":236
+ *             else:
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ */
+    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(__pyx_v_self));
+  }
+  __pyx_L11:;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":237
+ *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ */
+  __pyx_v_info->suboffsets = NULL;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":238
+ *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
+ *             info.readonly = not PyArray_ISWRITEABLE(self)
+ * 
+ */
+  __pyx_v_info->itemsize = PyArray_ITEMSIZE(__pyx_v_self);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":239
+ *             info.suboffsets = NULL
+ *             info.itemsize = PyArray_ITEMSIZE(self)
+ *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
+ * 
+ *             cdef int t
+ */
+  __pyx_v_info->readonly = (!(PyArray_ISWRITEABLE(__pyx_v_self) != 0));
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":242
+ * 
+ *             cdef int t
+ *             cdef char* f = NULL             # <<<<<<<<<<<<<<
+ *             cdef dtype descr = self.descr
+ *             cdef int offset
+ */
+  __pyx_v_f = NULL;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":243
+ *             cdef int t
+ *             cdef char* f = NULL
+ *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
+ *             cdef int offset
+ * 
+ */
+  __pyx_t_3 = ((PyObject *)__pyx_v_self->descr);
+  __Pyx_INCREF(__pyx_t_3);
+  __pyx_v_descr = ((PyArray_Descr *)__pyx_t_3);
+  __pyx_t_3 = 0;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":246
+ *             cdef int offset
+ * 
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields and not copy_shape:
+ */
+  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":248
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ * 
+ *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
+ *                 # do not call releasebuffer
+ *                 info.obj = None
+ */
+  __pyx_t_2 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_2) {
+  } else {
+    __pyx_t_1 = __pyx_t_2;
+    goto __pyx_L15_bool_binop_done;
+  }
+  __pyx_t_2 = ((!(__pyx_v_copy_shape != 0)) != 0);
+  __pyx_t_1 = __pyx_t_2;
+  __pyx_L15_bool_binop_done:;
+  if (__pyx_t_1) {
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":250
+ *             if not hasfields and not copy_shape:
+ *                 # do not call releasebuffer
+ *                 info.obj = None             # <<<<<<<<<<<<<<
+ *             else:
+ *                 # need to call releasebuffer
+ */
+    __Pyx_INCREF(Py_None);
+    __Pyx_GIVEREF(Py_None);
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = Py_None;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":248
+ *             cdef bint hasfields = PyDataType_HASFIELDS(descr)
+ * 
+ *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
+ *                 # do not call releasebuffer
+ *                 info.obj = None
+ */
+    goto __pyx_L14;
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":253
+ *             else:
+ *                 # need to call releasebuffer
+ *                 info.obj = self             # <<<<<<<<<<<<<<
+ * 
+ *             if not hasfields:
+ */
+  /*else*/ {
+    __Pyx_INCREF(((PyObject *)__pyx_v_self));
+    __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj);
+    __pyx_v_info->obj = ((PyObject *)__pyx_v_self);
+  }
+  __pyx_L14:;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":255
+ *                 info.obj = self
+ * 
+ *             if not hasfields:             # <<<<<<<<<<<<<<
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ */
+  __pyx_t_1 = ((!(__pyx_v_hasfields != 0)) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":256
+ * 
+ *             if not hasfields:
+ *                 t = descr.type_num             # <<<<<<<<<<<<<<
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ */
+    __pyx_t_4 = __pyx_v_descr->type_num;
+    __pyx_v_t = __pyx_t_4;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ *             if not hasfields:
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '>') != 0);
+    if (!__pyx_t_2) {
+      goto __pyx_L20_next_or;
+    } else {
+    }
+    __pyx_t_2 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_L20_next_or:;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":258
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ */
+    __pyx_t_2 = ((__pyx_v_descr->byteorder == '<') != 0);
+    if (__pyx_t_2) {
+    } else {
+      __pyx_t_1 = __pyx_t_2;
+      goto __pyx_L19_bool_binop_done;
+    }
+    __pyx_t_2 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_1 = __pyx_t_2;
+    __pyx_L19_bool_binop_done:;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ *             if not hasfields:
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ */
+    if (__pyx_t_1) {
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":259
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__34, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":257
+ *             if not hasfields:
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ */
+    }
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":260
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ */
+    switch (__pyx_v_t) {
+      case NPY_BYTE:
+      __pyx_v_f = __pyx_k_b;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":261
+ *                     raise ValueError(u"Non-native byte order not supported")
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ */
+      case NPY_UBYTE:
+      __pyx_v_f = __pyx_k_B;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":262
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ */
+      case NPY_SHORT:
+      __pyx_v_f = __pyx_k_h;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":263
+ *                 elif t == NPY_UBYTE:       f = "B"
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ */
+      case NPY_USHORT:
+      __pyx_v_f = __pyx_k_H;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":264
+ *                 elif t == NPY_SHORT:       f = "h"
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ */
+      case NPY_INT:
+      __pyx_v_f = __pyx_k_i;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":265
+ *                 elif t == NPY_USHORT:      f = "H"
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ */
+      case NPY_UINT:
+      __pyx_v_f = __pyx_k_I;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":266
+ *                 elif t == NPY_INT:         f = "i"
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ */
+      case NPY_LONG:
+      __pyx_v_f = __pyx_k_l;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":267
+ *                 elif t == NPY_UINT:        f = "I"
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ */
+      case NPY_ULONG:
+      __pyx_v_f = __pyx_k_L;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":268
+ *                 elif t == NPY_LONG:        f = "l"
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ */
+      case NPY_LONGLONG:
+      __pyx_v_f = __pyx_k_q;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":269
+ *                 elif t == NPY_ULONG:       f = "L"
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ */
+      case NPY_ULONGLONG:
+      __pyx_v_f = __pyx_k_Q;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":270
+ *                 elif t == NPY_LONGLONG:    f = "q"
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ */
+      case NPY_FLOAT:
+      __pyx_v_f = __pyx_k_f;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":271
+ *                 elif t == NPY_ULONGLONG:   f = "Q"
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ */
+      case NPY_DOUBLE:
+      __pyx_v_f = __pyx_k_d;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":272
+ *                 elif t == NPY_FLOAT:       f = "f"
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ */
+      case NPY_LONGDOUBLE:
+      __pyx_v_f = __pyx_k_g;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":273
+ *                 elif t == NPY_DOUBLE:      f = "d"
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ */
+      case NPY_CFLOAT:
+      __pyx_v_f = __pyx_k_Zf;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":274
+ *                 elif t == NPY_LONGDOUBLE:  f = "g"
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"
+ */
+      case NPY_CDOUBLE:
+      __pyx_v_f = __pyx_k_Zd;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":275
+ *                 elif t == NPY_CFLOAT:      f = "Zf"
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ */
+      case NPY_CLONGDOUBLE:
+      __pyx_v_f = __pyx_k_Zg;
+      break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":276
+ *                 elif t == NPY_CDOUBLE:     f = "Zd"
+ *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
+ *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      case NPY_OBJECT:
+      __pyx_v_f = __pyx_k_O;
+      break;
+      default:
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":278
+ *                 elif t == NPY_OBJECT:      f = "O"
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *                 info.format = f
+ *                 return
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_int(__pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_6 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_t_3); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_GIVEREF(__pyx_t_6);
+      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_6);
+      __pyx_t_6 = 0;
+      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_3, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __Pyx_Raise(__pyx_t_6, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 278; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      break;
+    }
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":279
+ *                 else:
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f             # <<<<<<<<<<<<<<
+ *                 return
+ *             else:
+ */
+    __pyx_v_info->format = __pyx_v_f;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":280
+ *                     raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *                 info.format = f
+ *                 return             # <<<<<<<<<<<<<<
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ */
+    __pyx_r = 0;
+    goto __pyx_L0;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":255
+ *                 info.obj = self
+ * 
+ *             if not hasfields:             # <<<<<<<<<<<<<<
+ *                 t = descr.type_num
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ */
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":282
+ *                 return
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)             # <<<<<<<<<<<<<<
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ */
+  /*else*/ {
+    __pyx_v_info->format = ((char *)malloc(0xFF));
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":283
+ *             else:
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment             # <<<<<<<<<<<<<<
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ */
+    (__pyx_v_info->format[0]) = '^';
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":284
+ *                 info.format = <char*>stdlib.malloc(_buffer_format_string_len)
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0             # <<<<<<<<<<<<<<
+ *                 f = _util_dtypestring(descr, info.format + 1,
+ *                                       info.format + _buffer_format_string_len,
+ */
+    __pyx_v_offset = 0;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":285
+ *                 info.format[0] = c'^' # Native data types, manual alignment
+ *                 offset = 0
+ *                 f = _util_dtypestring(descr, info.format + 1,             # <<<<<<<<<<<<<<
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ */
+    __pyx_t_7 = __pyx_f_5numpy__util_dtypestring(__pyx_v_descr, (__pyx_v_info->format + 1), (__pyx_v_info->format + 0xFF), (&__pyx_v_offset)); if (unlikely(__pyx_t_7 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __pyx_v_f = __pyx_t_7;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":288
+ *                                       info.format + _buffer_format_string_len,
+ *                                       &offset)
+ *                 f[0] = c'\0' # Terminate format string             # <<<<<<<<<<<<<<
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ */
+    (__pyx_v_f[0]) = '\x00';
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":197
+ *         # experimental exception made for __getbuffer__ and __releasebuffer__
+ *         # -- the details of this may change.
+ *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
+ *             # This implementation of getbuffer is geared towards Cython
+ *             # requirements, and does not yet fullfill the PEP.
+ */
+
+  /* function exit code */
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_AddTraceback("numpy.ndarray.__getbuffer__", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = -1;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj != NULL) {
+    __Pyx_GOTREF(__pyx_v_info->obj);
+    __Pyx_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
+  }
+  goto __pyx_L2;
+  __pyx_L0:;
+  if (__pyx_v_info != NULL && __pyx_v_info->obj == Py_None) {
+    __Pyx_GOTREF(Py_None);
+    __Pyx_DECREF(Py_None); __pyx_v_info->obj = NULL;
+  }
+  __pyx_L2:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_descr);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":290
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+/* Python wrapper */
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
+static CYTHON_UNUSED void __pyx_pw_5numpy_7ndarray_3__releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__releasebuffer__ (wrapper)", 0);
+  __pyx_pf_5numpy_7ndarray_2__releasebuffer__(((PyArrayObject *)__pyx_v_self), ((Py_buffer *)__pyx_v_info));
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+static void __pyx_pf_5numpy_7ndarray_2__releasebuffer__(PyArrayObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("__releasebuffer__", 0);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  __pyx_t_1 = (PyArray_HASFIELDS(__pyx_v_self) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":292
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)
+ */
+    free(__pyx_v_info->format);
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":291
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):
+ *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ */
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":293
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.strides)
+ *                 # info.shape was stored after info.strides in the same block
+ */
+  __pyx_t_1 = (((sizeof(npy_intp)) != (sizeof(Py_ssize_t))) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":294
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
+ *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
+ *                 # info.shape was stored after info.strides in the same block
+ * 
+ */
+    free(__pyx_v_info->strides);
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":293
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
+ *                 stdlib.free(info.strides)
+ *                 # info.shape was stored after info.strides in the same block
+ */
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":290
+ *                 f[0] = c'\0' # Terminate format string
+ * 
+ *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
+ *             if PyArray_HASFIELDS(self):
+ *                 stdlib.free(info.format)
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":770
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__pyx_v_a) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":771
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):
+ *     return PyArray_MultiIterNew(1, <void*>a)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 771; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":770
+ * ctypedef npy_cdouble     complex_t
+ * 
+ * cdef inline object PyArray_MultiIterNew1(a):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew1", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":773
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__pyx_v_a, PyObject *__pyx_v_b) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":774
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 774; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":773
+ *     return PyArray_MultiIterNew(1, <void*>a)
+ * 
+ * cdef inline object PyArray_MultiIterNew2(a, b):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew2", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":776
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":777
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 777; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":776
+ *     return PyArray_MultiIterNew(2, <void*>a, <void*>b)
+ * 
+ * cdef inline object PyArray_MultiIterNew3(a, b, c):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew3", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":779
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":780
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 780; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":779
+ *     return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
+ * 
+ * cdef inline object PyArray_MultiIterNew4(a, b, c, d):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew4", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":782
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__pyx_v_a, PyObject *__pyx_v_b, PyObject *__pyx_v_c, PyObject *__pyx_v_d, PyObject *__pyx_v_e) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":783
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
+ */
+  __Pyx_XDECREF(__pyx_r);
+  __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 783; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_r = __pyx_t_1;
+  __pyx_t_1 = 0;
+  goto __pyx_L0;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":782
+ *     return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
+ * 
+ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):             # <<<<<<<<<<<<<<
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_AddTraceback("numpy.PyArray_MultiIterNew5", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = 0;
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":785
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+static CYTHON_INLINE char *__pyx_f_5numpy__util_dtypestring(PyArray_Descr *__pyx_v_descr, char *__pyx_v_f, char *__pyx_v_end, int *__pyx_v_offset) {
+  PyArray_Descr *__pyx_v_child = 0;
+  int __pyx_v_endian_detector;
+  int __pyx_v_little_endian;
+  PyObject *__pyx_v_fields = 0;
+  PyObject *__pyx_v_childname = NULL;
+  PyObject *__pyx_v_new_offset = NULL;
+  PyObject *__pyx_v_t = NULL;
+  char *__pyx_r;
+  __Pyx_RefNannyDeclarations
+  PyObject *__pyx_t_1 = NULL;
+  Py_ssize_t __pyx_t_2;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  int __pyx_t_6;
+  int __pyx_t_7;
+  long __pyx_t_8;
+  char *__pyx_t_9;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannySetupContext("_util_dtypestring", 0);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":790
+ * 
+ *     cdef dtype child
+ *     cdef int endian_detector = 1             # <<<<<<<<<<<<<<
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
+ *     cdef tuple fields
+ */
+  __pyx_v_endian_detector = 1;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":791
+ *     cdef dtype child
+ *     cdef int endian_detector = 1
+ *     cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)             # <<<<<<<<<<<<<<
+ *     cdef tuple fields
+ * 
+ */
+  __pyx_v_little_endian = ((((char *)(&__pyx_v_endian_detector))[0]) != 0);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  if (unlikely(__pyx_v_descr->names == Py_None)) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+    {__pyx_filename = __pyx_f[2]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __pyx_t_1 = __pyx_v_descr->names; __Pyx_INCREF(__pyx_t_1); __pyx_t_2 = 0;
+  for (;;) {
+    if (__pyx_t_2 >= PyTuple_GET_SIZE(__pyx_t_1)) break;
+    #if CYTHON_COMPILING_IN_CPYTHON
+    __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_1, __pyx_t_2); __Pyx_INCREF(__pyx_t_3); __pyx_t_2++; if (unlikely(0 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    #else
+    __pyx_t_3 = PySequence_ITEM(__pyx_t_1, __pyx_t_2); __pyx_t_2++; if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 794; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    #endif
+    __Pyx_XDECREF_SET(__pyx_v_childname, __pyx_t_3);
+    __pyx_t_3 = 0;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":795
+ * 
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]             # <<<<<<<<<<<<<<
+ *         child, new_offset = fields
+ * 
+ */
+    if (unlikely(__pyx_v_descr->fields == Py_None)) {
+      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not subscriptable");
+      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    __pyx_t_3 = __Pyx_PyDict_GetItem(__pyx_v_descr->fields, __pyx_v_childname); if (unlikely(__pyx_t_3 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+    __Pyx_GOTREF(__pyx_t_3);
+    if (!(likely(PyTuple_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None)||(PyErr_Format(PyExc_TypeError, "Expected %.16s, got %.200s", "tuple", Py_TYPE(__pyx_t_3)->tp_name), 0))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_fields, ((PyObject*)__pyx_t_3));
+    __pyx_t_3 = 0;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":796
+ *     for childname in descr.names:
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields             # <<<<<<<<<<<<<<
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ */
+    if (likely(__pyx_v_fields != Py_None)) {
+      PyObject* sequence = __pyx_v_fields;
+      #if CYTHON_COMPILING_IN_CPYTHON
+      Py_ssize_t size = Py_SIZE(sequence);
+      #else
+      Py_ssize_t size = PySequence_Size(sequence);
+      #endif
+      if (unlikely(size != 2)) {
+        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
+        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
+        {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      #if CYTHON_COMPILING_IN_CPYTHON
+      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
+      __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); 
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_4);
+      #else
+      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      #endif
+    } else {
+      __Pyx_RaiseNoneNotIterableError(); {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+    if (!(likely(((__pyx_t_3) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_dtype))))) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 796; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_XDECREF_SET(__pyx_v_child, ((PyArray_Descr *)__pyx_t_3));
+    __pyx_t_3 = 0;
+    __Pyx_XDECREF_SET(__pyx_v_new_offset, __pyx_t_4);
+    __pyx_t_4 = 0;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":798
+ *         child, new_offset = fields
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ */
+    __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_3 = PyNumber_Subtract(__pyx_v_new_offset, __pyx_t_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+    __pyx_t_5 = __Pyx_PyInt_As_int(__pyx_t_3); if (unlikely((__pyx_t_5 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 798; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __pyx_t_6 = ((((__pyx_v_end - __pyx_v_f) - ((int)__pyx_t_5)) < 15) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__35, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":798
+ *         child, new_offset = fields
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:             # <<<<<<<<<<<<<<
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ */
+    }
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '>') != 0);
+    if (!__pyx_t_7) {
+      goto __pyx_L8_next_or;
+    } else {
+    }
+    __pyx_t_7 = (__pyx_v_little_endian != 0);
+    if (!__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_L8_next_or:;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":802
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):             # <<<<<<<<<<<<<<
+ *             raise ValueError(u"Non-native byte order not supported")
+ *             # One could encode it in the format string and have Cython
+ */
+    __pyx_t_7 = ((__pyx_v_child->byteorder == '<') != 0);
+    if (__pyx_t_7) {
+    } else {
+      __pyx_t_6 = __pyx_t_7;
+      goto __pyx_L7_bool_binop_done;
+    }
+    __pyx_t_7 = ((!(__pyx_v_little_endian != 0)) != 0);
+    __pyx_t_6 = __pyx_t_7;
+    __pyx_L7_bool_binop_done:;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")
+ */
+    if (__pyx_t_6) {
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_tuple__36, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      {__pyx_filename = __pyx_f[2]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":801
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or             # <<<<<<<<<<<<<<
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")
+ */
+    }
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":813
+ * 
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:             # <<<<<<<<<<<<<<
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ */
+    while (1) {
+      __pyx_t_3 = __Pyx_PyInt_From_int((__pyx_v_offset[0])); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_v_new_offset, Py_LT); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (!__pyx_t_6) break;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":814
+ *         # Output padding bytes
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte             # <<<<<<<<<<<<<<
+ *             f += 1
+ *             offset[0] += 1
+ */
+      (__pyx_v_f[0]) = 0x78;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":815
+ *         while offset[0] < new_offset:
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1             # <<<<<<<<<<<<<<
+ *             offset[0] += 1
+ * 
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":816
+ *             f[0] = 120 # "x"; pad byte
+ *             f += 1
+ *             offset[0] += 1             # <<<<<<<<<<<<<<
+ * 
+ *         offset[0] += child.itemsize
+ */
+      __pyx_t_8 = 0;
+      (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + 1);
+    }
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":818
+ *             offset[0] += 1
+ * 
+ *         offset[0] += child.itemsize             # <<<<<<<<<<<<<<
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ */
+    __pyx_t_8 = 0;
+    (__pyx_v_offset[__pyx_t_8]) = ((__pyx_v_offset[__pyx_t_8]) + __pyx_v_child->elsize);
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":820
+ *         offset[0] += child.itemsize
+ * 
+ *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
+ *             t = child.type_num
+ *             if end - f < 5:
+ */
+    __pyx_t_6 = ((!(PyDataType_HASFIELDS(__pyx_v_child) != 0)) != 0);
+    if (__pyx_t_6) {
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":821
+ * 
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num             # <<<<<<<<<<<<<<
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_child->type_num); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 821; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __Pyx_XDECREF_SET(__pyx_v_t, __pyx_t_4);
+      __pyx_t_4 = 0;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":822
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num
+ *             if end - f < 5:             # <<<<<<<<<<<<<<
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ * 
+ */
+      __pyx_t_6 = (((__pyx_v_end - __pyx_v_f) < 5) != 0);
+      if (__pyx_t_6) {
+
+        /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_builtin_RuntimeError, __pyx_tuple__37, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_Raise(__pyx_t_4, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        {__pyx_filename = __pyx_f[2]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+        /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":822
+ *         if not PyDataType_HASFIELDS(child):
+ *             t = child.type_num
+ *             if end - f < 5:             # <<<<<<<<<<<<<<
+ *                 raise RuntimeError(u"Format string allocated too short.")
+ * 
+ */
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":826
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_BYTE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 826; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 98;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":827
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UBYTE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 66;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":828
+ *             if   t == NPY_BYTE:        f[0] =  98 #"b"
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_SHORT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 828; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 0x68;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":829
+ *             elif t == NPY_UBYTE:       f[0] =  66 #"B"
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_USHORT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 829; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 72;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":830
+ *             elif t == NPY_SHORT:       f[0] = 104 #"h"
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_INT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 830; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 0x69;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":831
+ *             elif t == NPY_USHORT:      f[0] =  72 #"H"
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_UINT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 831; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 73;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":832
+ *             elif t == NPY_INT:         f[0] = 105 #"i"
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 832; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 0x6C;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":833
+ *             elif t == NPY_UINT:        f[0] =  73 #"I"
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 76;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":834
+ *             elif t == NPY_LONG:        f[0] = 108 #"l"
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGLONG); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 834; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 0x71;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":835
+ *             elif t == NPY_ULONG:       f[0] = 76  #"L"
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_ULONGLONG); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 835; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 81;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":836
+ *             elif t == NPY_LONGLONG:    f[0] = 113 #"q"
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_FLOAT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 836; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 0x66;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":837
+ *             elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_DOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 0x64;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":838
+ *             elif t == NPY_FLOAT:       f[0] = 102 #"f"
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_LONGDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 838; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 0x67;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":839
+ *             elif t == NPY_DOUBLE:      f[0] = 100 #"d"
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CFLOAT); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 839; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 0x66;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":840
+ *             elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd             # <<<<<<<<<<<<<<
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CDOUBLE); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 0x64;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":841
+ *             elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg             # <<<<<<<<<<<<<<
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ */
+      __pyx_t_3 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_CLONGDOUBLE); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_3);
+      __pyx_t_4 = PyObject_RichCompare(__pyx_v_t, __pyx_t_3, Py_EQ); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 841; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 90;
+        (__pyx_v_f[1]) = 0x67;
+        __pyx_v_f = (__pyx_v_f + 1);
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":842
+ *             elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
+ *             elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ */
+      __pyx_t_4 = __Pyx_PyInt_From_enum__NPY_TYPES(NPY_OBJECT); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_4);
+      __pyx_t_3 = PyObject_RichCompare(__pyx_v_t, __pyx_t_4, Py_EQ); __Pyx_XGOTREF(__pyx_t_3); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+      __pyx_t_6 = __Pyx_PyObject_IsTrue(__pyx_t_3); if (unlikely(__pyx_t_6 < 0)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+      if (__pyx_t_6) {
+        (__pyx_v_f[0]) = 79;
+        goto __pyx_L15;
+      }
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":844
+ *             elif t == NPY_OBJECT:      f[0] = 79 #"O"
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
+ *             f += 1
+ *         else:
+ */
+      /*else*/ {
+        __pyx_t_3 = PyUnicode_Format(__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_v_t); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_4);
+        __Pyx_GIVEREF(__pyx_t_3);
+        PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+        __pyx_t_3 = 0;
+        __pyx_t_3 = __Pyx_PyObject_Call(__pyx_builtin_ValueError, __pyx_t_4, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+        __Pyx_GOTREF(__pyx_t_3);
+        __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+        __Pyx_Raise(__pyx_t_3, 0, 0, 0);
+        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+        {__pyx_filename = __pyx_f[2]; __pyx_lineno = 844; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      }
+      __pyx_L15:;
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":845
+ *             else:
+ *                 raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
+ *             f += 1             # <<<<<<<<<<<<<<
+ *         else:
+ *             # Cython ignores struct boundary information ("T{...}"),
+ */
+      __pyx_v_f = (__pyx_v_f + 1);
+
+      /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":820
+ *         offset[0] += child.itemsize
+ * 
+ *         if not PyDataType_HASFIELDS(child):             # <<<<<<<<<<<<<<
+ *             t = child.type_num
+ *             if end - f < 5:
+ */
+      goto __pyx_L13;
+    }
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":849
+ *             # Cython ignores struct boundary information ("T{...}"),
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)             # <<<<<<<<<<<<<<
+ *     return f
+ * 
+ */
+    /*else*/ {
+      __pyx_t_9 = __pyx_f_5numpy__util_dtypestring(__pyx_v_child, __pyx_v_f, __pyx_v_end, __pyx_v_offset); if (unlikely(__pyx_t_9 == NULL)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 849; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __pyx_v_f = __pyx_t_9;
+    }
+    __pyx_L13:;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":794
+ *     cdef tuple fields
+ * 
+ *     for childname in descr.names:             # <<<<<<<<<<<<<<
+ *         fields = descr.fields[childname]
+ *         child, new_offset = fields
+ */
+  }
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":850
+ *             # so don't output it
+ *             f = _util_dtypestring(child, f, end, offset)
+ *     return f             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_r = __pyx_v_f;
+  goto __pyx_L0;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":785
+ *     return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
+ * 
+ * cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:             # <<<<<<<<<<<<<<
+ *     # Recursive utility function used in __getbuffer__ to get format
+ *     # string. The new location in the format string is returned.
+ */
+
+  /* function exit code */
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_AddTraceback("numpy._util_dtypestring", __pyx_clineno, __pyx_lineno, __pyx_filename);
+  __pyx_r = NULL;
+  __pyx_L0:;
+  __Pyx_XDECREF((PyObject *)__pyx_v_child);
+  __Pyx_XDECREF(__pyx_v_fields);
+  __Pyx_XDECREF(__pyx_v_childname);
+  __Pyx_XDECREF(__pyx_v_new_offset);
+  __Pyx_XDECREF(__pyx_v_t);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_arr, PyObject *__pyx_v_base) {
+  PyObject *__pyx_v_baseptr;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  int __pyx_t_2;
+  __Pyx_RefNannySetupContext("set_array_base", 0);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":968
+ * cdef inline void set_array_base(ndarray arr, object base):
+ *      cdef PyObject* baseptr
+ *      if base is None:             # <<<<<<<<<<<<<<
+ *          baseptr = NULL
+ *      else:
+ */
+  __pyx_t_1 = (__pyx_v_base == Py_None);
+  __pyx_t_2 = (__pyx_t_1 != 0);
+  if (__pyx_t_2) {
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":969
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ *          baseptr = NULL             # <<<<<<<<<<<<<<
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ */
+    __pyx_v_baseptr = NULL;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":968
+ * cdef inline void set_array_base(ndarray arr, object base):
+ *      cdef PyObject* baseptr
+ *      if base is None:             # <<<<<<<<<<<<<<
+ *          baseptr = NULL
+ *      else:
+ */
+    goto __pyx_L3;
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":971
+ *          baseptr = NULL
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!             # <<<<<<<<<<<<<<
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ */
+  /*else*/ {
+    Py_INCREF(__pyx_v_base);
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":972
+ *      else:
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base             # <<<<<<<<<<<<<<
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr
+ */
+    __pyx_v_baseptr = ((PyObject *)__pyx_v_base);
+  }
+  __pyx_L3:;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":973
+ *          Py_INCREF(base) # important to do this before decref below!
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)             # <<<<<<<<<<<<<<
+ *      arr.base = baseptr
+ * 
+ */
+  Py_XDECREF(__pyx_v_arr->base);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":974
+ *          baseptr = <PyObject*>base
+ *      Py_XDECREF(arr.base)
+ *      arr.base = baseptr             # <<<<<<<<<<<<<<
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ */
+  __pyx_v_arr->base = __pyx_v_baseptr;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":966
+ * 
+ * 
+ * cdef inline void set_array_base(ndarray arr, object base):             # <<<<<<<<<<<<<<
+ *      cdef PyObject* baseptr
+ *      if base is None:
+ */
+
+  /* function exit code */
+  __Pyx_RefNannyFinishContext();
+}
+
+/* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__pyx_v_arr) {
+  PyObject *__pyx_r = NULL;
+  __Pyx_RefNannyDeclarations
+  int __pyx_t_1;
+  __Pyx_RefNannySetupContext("get_array_base", 0);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":977
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:             # <<<<<<<<<<<<<<
+ *         return None
+ *     else:
+ */
+  __pyx_t_1 = ((__pyx_v_arr->base == NULL) != 0);
+  if (__pyx_t_1) {
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":978
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:
+ *         return None             # <<<<<<<<<<<<<<
+ *     else:
+ *         return <object>arr.base
+ */
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(Py_None);
+    __pyx_r = Py_None;
+    goto __pyx_L0;
+
+    /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":977
+ * 
+ * cdef inline object get_array_base(ndarray arr):
+ *     if arr.base is NULL:             # <<<<<<<<<<<<<<
+ *         return None
+ *     else:
+ */
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":980
+ *         return None
+ *     else:
+ *         return <object>arr.base             # <<<<<<<<<<<<<<
+ */
+  /*else*/ {
+    __Pyx_XDECREF(__pyx_r);
+    __Pyx_INCREF(((PyObject *)__pyx_v_arr->base));
+    __pyx_r = ((PyObject *)__pyx_v_arr->base);
+    goto __pyx_L0;
+  }
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /* function exit code */
+  __pyx_L0:;
+  __Pyx_XGIVEREF(__pyx_r);
+  __Pyx_RefNannyFinishContext();
+  return __pyx_r;
+}
+static struct __pyx_vtabstruct_6pyfftw_6pyfftw_FFTW __pyx_vtable_6pyfftw_6pyfftw_FFTW;
+
+static PyObject *__pyx_tp_new_6pyfftw_6pyfftw_FFTW(PyTypeObject *t, PyObject *a, PyObject *k) {
+  struct __pyx_obj_6pyfftw_6pyfftw_FFTW *p;
+  PyObject *o;
+  if (likely((t->tp_flags & Py_TPFLAGS_IS_ABSTRACT) == 0)) {
+    o = (*t->tp_alloc)(t, 0);
+  } else {
+    o = (PyObject *) PyBaseObject_Type.tp_new(t, __pyx_empty_tuple, 0);
+  }
+  if (unlikely(!o)) return 0;
+  p = ((struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)o);
+  p->__pyx_vtab = __pyx_vtabptr_6pyfftw_6pyfftw_FFTW;
+  p->_input_array = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  p->_output_array = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  p->_input_item_strides = Py_None; Py_INCREF(Py_None);
+  p->_input_strides = Py_None; Py_INCREF(Py_None);
+  p->_output_item_strides = Py_None; Py_INCREF(Py_None);
+  p->_output_strides = Py_None; Py_INCREF(Py_None);
+  p->_input_shape = Py_None; Py_INCREF(Py_None);
+  p->_output_shape = Py_None; Py_INCREF(Py_None);
+  p->_input_dtype = Py_None; Py_INCREF(Py_None);
+  p->_output_dtype = Py_None; Py_INCREF(Py_None);
+  p->_flags_used = Py_None; Py_INCREF(Py_None);
+  if (unlikely(__pyx_pw_6pyfftw_6pyfftw_4FFTW_31__cinit__(o, a, k) < 0)) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_6pyfftw_6pyfftw_FFTW(PyObject *o) {
+  struct __pyx_obj_6pyfftw_6pyfftw_FFTW *p = (struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)o;
+  #if PY_VERSION_HEX >= 0x030400a1
+  if (unlikely(Py_TYPE(o)->tp_finalize) && !_PyGC_FINALIZED(o)) {
+    if (PyObject_CallFinalizerFromDealloc(o)) return;
+  }
+  #endif
+  PyObject_GC_UnTrack(o);
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++Py_REFCNT(o);
+    __pyx_pw_6pyfftw_6pyfftw_4FFTW_35__dealloc__(o);
+    --Py_REFCNT(o);
+    PyErr_Restore(etype, eval, etb);
+  }
+  Py_CLEAR(p->_input_array);
+  Py_CLEAR(p->_output_array);
+  Py_CLEAR(p->_input_item_strides);
+  Py_CLEAR(p->_input_strides);
+  Py_CLEAR(p->_output_item_strides);
+  Py_CLEAR(p->_output_strides);
+  Py_CLEAR(p->_input_shape);
+  Py_CLEAR(p->_output_shape);
+  Py_CLEAR(p->_input_dtype);
+  Py_CLEAR(p->_output_dtype);
+  Py_CLEAR(p->_flags_used);
+  (*Py_TYPE(o)->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_6pyfftw_6pyfftw_FFTW(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_6pyfftw_6pyfftw_FFTW *p = (struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)o;
+  if (p->_input_array) {
+    e = (*v)(((PyObject*)p->_input_array), a); if (e) return e;
+  }
+  if (p->_output_array) {
+    e = (*v)(((PyObject*)p->_output_array), a); if (e) return e;
+  }
+  if (p->_input_item_strides) {
+    e = (*v)(p->_input_item_strides, a); if (e) return e;
+  }
+  if (p->_input_strides) {
+    e = (*v)(p->_input_strides, a); if (e) return e;
+  }
+  if (p->_output_item_strides) {
+    e = (*v)(p->_output_item_strides, a); if (e) return e;
+  }
+  if (p->_output_strides) {
+    e = (*v)(p->_output_strides, a); if (e) return e;
+  }
+  if (p->_input_shape) {
+    e = (*v)(p->_input_shape, a); if (e) return e;
+  }
+  if (p->_output_shape) {
+    e = (*v)(p->_output_shape, a); if (e) return e;
+  }
+  if (p->_input_dtype) {
+    e = (*v)(p->_input_dtype, a); if (e) return e;
+  }
+  if (p->_output_dtype) {
+    e = (*v)(p->_output_dtype, a); if (e) return e;
+  }
+  if (p->_flags_used) {
+    e = (*v)(p->_flags_used, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_6pyfftw_6pyfftw_FFTW(PyObject *o) {
+  PyObject* tmp;
+  struct __pyx_obj_6pyfftw_6pyfftw_FFTW *p = (struct __pyx_obj_6pyfftw_6pyfftw_FFTW *)o;
+  tmp = ((PyObject*)p->_input_array);
+  p->_input_array = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->_output_array);
+  p->_output_array = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->_input_item_strides);
+  p->_input_item_strides = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->_input_strides);
+  p->_input_strides = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->_output_item_strides);
+  p->_output_item_strides = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->_output_strides);
+  p->_output_strides = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->_input_shape);
+  p->_input_shape = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->_output_shape);
+  p->_output_shape = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->_input_dtype);
+  p->_input_dtype = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->_output_dtype);
+  p->_output_dtype = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  tmp = ((PyObject*)p->_flags_used);
+  p->_flags_used = Py_None; Py_INCREF(Py_None);
+  Py_XDECREF(tmp);
+  return 0;
+}
+
+static PyMethodDef __pyx_methods_6pyfftw_6pyfftw_FFTW[] = {
+  {"_get_N", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_1_get_N, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW__get_N},
+  {"_get_simd_aligned", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_3_get_simd_aligned, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_2_get_simd_aligned},
+  {"_get_input_alignment", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_5_get_input_alignment, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_4_get_input_alignment},
+  {"_get_output_alignment", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_7_get_output_alignment, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_6_get_output_alignment},
+  {"_get_flags_used", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_9_get_flags_used, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_8_get_flags_used},
+  {"_get_input_array", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_11_get_input_array, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_10_get_input_array},
+  {"_get_output_array", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_13_get_output_array, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_12_get_output_array},
+  {"_get_input_strides", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_15_get_input_strides, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_14_get_input_strides},
+  {"_get_output_strides", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_17_get_output_strides, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_16_get_output_strides},
+  {"_get_input_shape", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_19_get_input_shape, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_18_get_input_shape},
+  {"_get_output_shape", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_21_get_output_shape, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_20_get_output_shape},
+  {"_get_input_dtype", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_23_get_input_dtype, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_22_get_input_dtype},
+  {"_get_output_dtype", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_25_get_output_dtype, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_24_get_output_dtype},
+  {"_get_direction", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_27_get_direction, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_26_get_direction},
+  {"_get_axes", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_29_get_axes, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_28_get_axes},
+  {"update_arrays", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_39update_arrays, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_38update_arrays},
+  {"get_input_array", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_41get_input_array, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_40get_input_array},
+  {"get_output_array", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_43get_output_array, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_42get_output_array},
+  {"execute", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_4FFTW_45execute, METH_NOARGS, __pyx_doc_6pyfftw_6pyfftw_4FFTW_44execute},
+  {0, 0, 0, 0}
+};
+
+static PyTypeObject __pyx_type_6pyfftw_6pyfftw_FFTW = {
+  PyVarObject_HEAD_INIT(0, 0)
+  "pyfftw.pyfftw.FFTW", /*tp_name*/
+  sizeof(struct __pyx_obj_6pyfftw_6pyfftw_FFTW), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_6pyfftw_6pyfftw_FFTW, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  #if PY_MAJOR_VERSION < 3
+  0, /*tp_compare*/
+  #endif
+  #if PY_MAJOR_VERSION >= 3
+  0, /*tp_as_async*/
+  #endif
+  0, /*tp_repr*/
+  0, /*tp_as_number*/
+  0, /*tp_as_sequence*/
+  0, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  __pyx_pw_6pyfftw_6pyfftw_4FFTW_37__call__, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  0, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_VERSION_TAG|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_HAVE_NEWBUFFER|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "\n    FFTW is a class for computing the complex N-Dimensional DFT or\n    inverse DFT of an array using the FFTW library. The interface is \n    designed to be somewhat pythonic, with the correct transform being \n    inferred from the dtypes of the passed arrays.\n\n    On instantiation, the dtypes and relative shapes of the input array and\n    output arrays are compared to the set of valid (and implemented)\n    :ref:`FFTW schemes <scheme_table>`.  If a match is found, the plan tha [...]
+  __pyx_tp_traverse_6pyfftw_6pyfftw_FFTW, /*tp_traverse*/
+  __pyx_tp_clear_6pyfftw_6pyfftw_FFTW, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_6pyfftw_6pyfftw_FFTW, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  __pyx_pw_6pyfftw_6pyfftw_4FFTW_33__init__, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_6pyfftw_6pyfftw_FFTW, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+  0, /*tp_del*/
+  0, /*tp_version_tag*/
+  #if PY_VERSION_HEX >= 0x030400a1
+  0, /*tp_finalize*/
+  #endif
+};
+
+static PyMethodDef __pyx_methods[] = {
+  {"n_byte_align_empty", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_1n_byte_align_empty, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6pyfftw_6pyfftw_n_byte_align_empty},
+  {"n_byte_align", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_3n_byte_align, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6pyfftw_6pyfftw_2n_byte_align},
+  {"byte_align", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_5byte_align, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6pyfftw_6pyfftw_4byte_align},
+  {"is_byte_aligned", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_7is_byte_aligned, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6pyfftw_6pyfftw_6is_byte_aligned},
+  {"is_n_byte_aligned", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_9is_n_byte_aligned, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6pyfftw_6pyfftw_8is_n_byte_aligned},
+  {"empty_aligned", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_11empty_aligned, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6pyfftw_6pyfftw_10empty_aligned},
+  {"zeros_aligned", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_13zeros_aligned, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6pyfftw_6pyfftw_12zeros_aligned},
+  {"ones_aligned", (PyCFunction)__pyx_pw_6pyfftw_6pyfftw_15ones_aligned, METH_VARARGS|METH_KEYWORDS, __pyx_doc_6pyfftw_6pyfftw_14ones_aligned},
+  {0, 0, 0, 0}
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef __pyx_moduledef = {
+  #if PY_VERSION_HEX < 0x03020000
+    { PyObject_HEAD_INIT(NULL) NULL, 0, NULL },
+  #else
+    PyModuleDef_HEAD_INIT,
+  #endif
+    "pyfftw",
+    0, /* m_doc */
+    -1, /* m_size */
+    __pyx_methods /* m_methods */,
+    NULL, /* m_reload */
+    NULL, /* m_traverse */
+    NULL, /* m_clear */
+    NULL /* m_free */
+};
+#endif
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_kp_s_32, __pyx_k_32, sizeof(__pyx_k_32), 0, 0, 1, 0},
+  {&__pyx_kp_s_64, __pyx_k_64, sizeof(__pyx_k_64), 0, 0, 1, 0},
+  {&__pyx_n_s_C, __pyx_k_C, sizeof(__pyx_k_C), 0, 0, 1, 1},
+  {&__pyx_n_s_DeprecationWarning, __pyx_k_DeprecationWarning, sizeof(__pyx_k_DeprecationWarning), 0, 0, 1, 1},
+  {&__pyx_kp_s_Dimensions_of_the_input_array_mu, __pyx_k_Dimensions_of_the_input_array_mu, sizeof(__pyx_k_Dimensions_of_the_input_array_mu), 0, 0, 1, 0},
+  {&__pyx_kp_s_Dimensions_of_the_output_array_m, __pyx_k_Dimensions_of_the_output_array_m, sizeof(__pyx_k_Dimensions_of_the_output_array_m), 0, 0, 1, 0},
+  {&__pyx_n_s_FFTW_BACKWARD, __pyx_k_FFTW_BACKWARD, sizeof(__pyx_k_FFTW_BACKWARD), 0, 0, 1, 1},
+  {&__pyx_n_s_FFTW_DESTROY_INPUT, __pyx_k_FFTW_DESTROY_INPUT, sizeof(__pyx_k_FFTW_DESTROY_INPUT), 0, 0, 1, 1},
+  {&__pyx_n_s_FFTW_ESTIMATE, __pyx_k_FFTW_ESTIMATE, sizeof(__pyx_k_FFTW_ESTIMATE), 0, 0, 1, 1},
+  {&__pyx_n_s_FFTW_EXHAUSTIVE, __pyx_k_FFTW_EXHAUSTIVE, sizeof(__pyx_k_FFTW_EXHAUSTIVE), 0, 0, 1, 1},
+  {&__pyx_n_s_FFTW_FORWARD, __pyx_k_FFTW_FORWARD, sizeof(__pyx_k_FFTW_FORWARD), 0, 0, 1, 1},
+  {&__pyx_n_s_FFTW_MEASURE, __pyx_k_FFTW_MEASURE, sizeof(__pyx_k_FFTW_MEASURE), 0, 0, 1, 1},
+  {&__pyx_n_s_FFTW_PATIENT, __pyx_k_FFTW_PATIENT, sizeof(__pyx_k_FFTW_PATIENT), 0, 0, 1, 1},
+  {&__pyx_n_s_FFTW_UNALIGNED, __pyx_k_FFTW_UNALIGNED, sizeof(__pyx_k_FFTW_UNALIGNED), 0, 0, 1, 1},
+  {&__pyx_n_s_FFTW_WISDOM_ONLY, __pyx_k_FFTW_WISDOM_ONLY, sizeof(__pyx_k_FFTW_WISDOM_ONLY), 0, 0, 1, 1},
+  {&__pyx_kp_u_Format_string_allocated_too_shor, __pyx_k_Format_string_allocated_too_shor, sizeof(__pyx_k_Format_string_allocated_too_shor), 0, 1, 0, 0},
+  {&__pyx_kp_u_Format_string_allocated_too_shor_2, __pyx_k_Format_string_allocated_too_shor_2, sizeof(__pyx_k_Format_string_allocated_too_shor_2), 0, 1, 0, 0},
+  {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Invalid_array_byte_align_require, __pyx_k_Invalid_array_byte_align_require, sizeof(__pyx_k_Invalid_array_byte_align_require), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_array_is_n_byte_aligned, __pyx_k_Invalid_array_is_n_byte_aligned, sizeof(__pyx_k_Invalid_array_is_n_byte_aligned), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_axes_The_axes_list_canno, __pyx_k_Invalid_axes_The_axes_list_canno, sizeof(__pyx_k_Invalid_axes_The_axes_list_canno), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_direction_The_direction, __pyx_k_Invalid_direction_The_direction, sizeof(__pyx_k_Invalid_direction_The_direction), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_flag, __pyx_k_Invalid_flag, sizeof(__pyx_k_Invalid_flag), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_input_alignment_The_inpu, __pyx_k_Invalid_input_alignment_The_inpu, sizeof(__pyx_k_Invalid_input_alignment_The_inpu), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_input_alignment_The_orig, __pyx_k_Invalid_input_alignment_The_orig, sizeof(__pyx_k_Invalid_input_alignment_The_orig), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_input_array_The_input_ar, __pyx_k_Invalid_input_array_The_input_ar, sizeof(__pyx_k_Invalid_input_array_The_input_ar), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_input_array_The_new_inpu, __pyx_k_Invalid_input_array_The_new_inpu, sizeof(__pyx_k_Invalid_input_array_The_new_inpu), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_input_dtype_The_new_inpu, __pyx_k_Invalid_input_dtype_The_new_inpu, sizeof(__pyx_k_Invalid_input_dtype_The_new_inpu), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_input_shape_The_new_inpu, __pyx_k_Invalid_input_shape_The_new_inpu, sizeof(__pyx_k_Invalid_input_shape_The_new_inpu), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_input_striding_The_strid, __pyx_k_Invalid_input_striding_The_strid, sizeof(__pyx_k_Invalid_input_striding_The_strid), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_output_alignment_The_ori, __pyx_k_Invalid_output_alignment_The_ori, sizeof(__pyx_k_Invalid_output_alignment_The_ori), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_output_alignment_The_out, __pyx_k_Invalid_output_alignment_The_out, sizeof(__pyx_k_Invalid_output_alignment_The_out), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_output_array_The_new_out, __pyx_k_Invalid_output_array_The_new_out, sizeof(__pyx_k_Invalid_output_array_The_new_out), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_output_array_The_output, __pyx_k_Invalid_output_array_The_output, sizeof(__pyx_k_Invalid_output_array_The_output), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_output_dtype_The_new_out, __pyx_k_Invalid_output_dtype_The_new_out, sizeof(__pyx_k_Invalid_output_dtype_The_new_out), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_output_shape_The_new_out, __pyx_k_Invalid_output_shape_The_new_out, sizeof(__pyx_k_Invalid_output_shape_The_new_out), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_output_striding_The_stri, __pyx_k_Invalid_output_striding_The_stri, sizeof(__pyx_k_Invalid_output_striding_The_stri), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_planning_timelimit_The_p, __pyx_k_Invalid_planning_timelimit_The_p, sizeof(__pyx_k_Invalid_planning_timelimit_The_p), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_scheme_The_output_array, __pyx_k_Invalid_scheme_The_output_array, sizeof(__pyx_k_Invalid_scheme_The_output_array), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_shapes_The_input_array_a, __pyx_k_Invalid_shapes_The_input_array_a, sizeof(__pyx_k_Invalid_shapes_The_input_array_a), 0, 0, 1, 0},
+  {&__pyx_kp_s_Invalid_shapes_The_output_array, __pyx_k_Invalid_shapes_The_output_array, sizeof(__pyx_k_Invalid_shapes_The_output_array), 0, 0, 1, 0},
+  {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1},
+  {&__pyx_n_s_Lock, __pyx_k_Lock, sizeof(__pyx_k_Lock), 0, 0, 1, 1},
+  {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1},
+  {&__pyx_n_s_N, __pyx_k_N, sizeof(__pyx_k_N), 0, 0, 1, 1},
+  {&__pyx_kp_s_No_FFTW_wisdom_is_known_for_this, __pyx_k_No_FFTW_wisdom_is_known_for_this, sizeof(__pyx_k_No_FFTW_wisdom_is_known_for_this), 0, 0, 1, 0},
+  {&__pyx_kp_u_Non_native_byte_order_not_suppor, __pyx_k_Non_native_byte_order_not_suppor, sizeof(__pyx_k_Non_native_byte_order_not_suppor), 0, 1, 0, 0},
+  {&__pyx_n_s_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Strides_of_the_input_array_must, __pyx_k_Strides_of_the_input_array_must, sizeof(__pyx_k_Strides_of_the_input_array_must), 0, 0, 1, 0},
+  {&__pyx_kp_s_Strides_of_the_output_array_must, __pyx_k_Strides_of_the_output_array_must, sizeof(__pyx_k_Strides_of_the_output_array_must), 0, 0, 1, 0},
+  {&__pyx_kp_s_The_data_has_an_uncaught_error_t, __pyx_k_The_data_has_an_uncaught_error_t, sizeof(__pyx_k_The_data_has_an_uncaught_error_t), 0, 0, 1, 0},
+  {&__pyx_kp_s_This_function_is_deprecated_in_f, __pyx_k_This_function_is_deprecated_in_f, sizeof(__pyx_k_This_function_is_deprecated_in_f), 0, 0, 1, 0},
+  {&__pyx_kp_s_This_function_is_deprecated_in_f_2, __pyx_k_This_function_is_deprecated_in_f_2, sizeof(__pyx_k_This_function_is_deprecated_in_f_2), 0, 0, 1, 0},
+  {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1},
+  {&__pyx_n_s_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 0, 0, 1, 1},
+  {&__pyx_kp_s_Zero_length_array_The_input_arra, __pyx_k_Zero_length_array_The_input_arra, sizeof(__pyx_k_Zero_length_array_The_input_arra), 0, 0, 1, 0},
+  {&__pyx_kp_s__17, __pyx_k__17, sizeof(__pyx_k__17), 0, 0, 1, 0},
+  {&__pyx_n_s_alignment, __pyx_k_alignment, sizeof(__pyx_k_alignment), 0, 0, 1, 1},
+  {&__pyx_n_s_append, __pyx_k_append, sizeof(__pyx_k_append), 0, 0, 1, 1},
+  {&__pyx_n_s_array, __pyx_k_array, sizeof(__pyx_k_array), 0, 0, 1, 1},
+  {&__pyx_n_s_asanyarray, __pyx_k_asanyarray, sizeof(__pyx_k_asanyarray), 0, 0, 1, 1},
+  {&__pyx_n_s_axes, __pyx_k_axes, sizeof(__pyx_k_axes), 0, 0, 1, 1},
+  {&__pyx_n_s_c2c, __pyx_k_c2c, sizeof(__pyx_k_c2c), 0, 0, 1, 1},
+  {&__pyx_n_s_c2r, __pyx_k_c2r, sizeof(__pyx_k_c2r), 0, 0, 1, 1},
+  {&__pyx_n_s_c_wisdom, __pyx_k_c_wisdom, sizeof(__pyx_k_c_wisdom), 0, 0, 1, 1},
+  {&__pyx_n_s_c_wisdom_ptr, __pyx_k_c_wisdom_ptr, sizeof(__pyx_k_c_wisdom_ptr), 0, 0, 1, 1},
+  {&__pyx_n_s_c_wisdomf, __pyx_k_c_wisdomf, sizeof(__pyx_k_c_wisdomf), 0, 0, 1, 1},
+  {&__pyx_n_s_c_wisdomf_ptr, __pyx_k_c_wisdomf_ptr, sizeof(__pyx_k_c_wisdomf_ptr), 0, 0, 1, 1},
+  {&__pyx_n_s_c_wisdoml, __pyx_k_c_wisdoml, sizeof(__pyx_k_c_wisdoml), 0, 0, 1, 1},
+  {&__pyx_n_s_c_wisdoml_ptr, __pyx_k_c_wisdoml_ptr, sizeof(__pyx_k_c_wisdoml_ptr), 0, 0, 1, 1},
+  {&__pyx_n_s_class, __pyx_k_class, sizeof(__pyx_k_class), 0, 0, 1, 1},
+  {&__pyx_n_s_clongdouble, __pyx_k_clongdouble, sizeof(__pyx_k_clongdouble), 0, 0, 1, 1},
+  {&__pyx_n_s_complex128, __pyx_k_complex128, sizeof(__pyx_k_complex128), 0, 0, 1, 1},
+  {&__pyx_n_s_complex64, __pyx_k_complex64, sizeof(__pyx_k_complex64), 0, 0, 1, 1},
+  {&__pyx_n_s_copy, __pyx_k_copy, sizeof(__pyx_k_copy), 0, 0, 1, 1},
+  {&__pyx_n_s_counter, __pyx_k_counter, sizeof(__pyx_k_counter), 0, 0, 1, 1},
+  {&__pyx_n_s_counterf, __pyx_k_counterf, sizeof(__pyx_k_counterf), 0, 0, 1, 1},
+  {&__pyx_n_s_counterl, __pyx_k_counterl, sizeof(__pyx_k_counterl), 0, 0, 1, 1},
+  {&__pyx_n_s_data, __pyx_k_data, sizeof(__pyx_k_data), 0, 0, 1, 1},
+  {&__pyx_n_s_direction, __pyx_k_direction, sizeof(__pyx_k_direction), 0, 0, 1, 1},
+  {&__pyx_n_s_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 0, 0, 1, 1},
+  {&__pyx_n_s_empty, __pyx_k_empty, sizeof(__pyx_k_empty), 0, 0, 1, 1},
+  {&__pyx_n_s_empty_aligned, __pyx_k_empty_aligned, sizeof(__pyx_k_empty_aligned), 0, 0, 1, 1},
+  {&__pyx_n_s_enter, __pyx_k_enter, sizeof(__pyx_k_enter), 0, 0, 1, 1},
+  {&__pyx_n_s_execute, __pyx_k_execute, sizeof(__pyx_k_execute), 0, 0, 1, 1},
+  {&__pyx_n_s_executor, __pyx_k_executor, sizeof(__pyx_k_executor), 0, 0, 1, 1},
+  {&__pyx_n_s_exit, __pyx_k_exit, sizeof(__pyx_k_exit), 0, 0, 1, 1},
+  {&__pyx_n_s_export_wisdom, __pyx_k_export_wisdom, sizeof(__pyx_k_export_wisdom), 0, 0, 1, 1},
+  {&__pyx_n_s_fft_shape_lookup, __pyx_k_fft_shape_lookup, sizeof(__pyx_k_fft_shape_lookup), 0, 0, 1, 1},
+  {&__pyx_n_s_fill, __pyx_k_fill, sizeof(__pyx_k_fill), 0, 0, 1, 1},
+  {&__pyx_n_s_flag_dict, __pyx_k_flag_dict, sizeof(__pyx_k_flag_dict), 0, 0, 1, 1},
+  {&__pyx_n_s_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 0, 0, 1, 1},
+  {&__pyx_n_s_float32, __pyx_k_float32, sizeof(__pyx_k_float32), 0, 0, 1, 1},
+  {&__pyx_n_s_float64, __pyx_k_float64, sizeof(__pyx_k_float64), 0, 0, 1, 1},
+  {&__pyx_n_s_forget_wisdom, __pyx_k_forget_wisdom, sizeof(__pyx_k_forget_wisdom), 0, 0, 1, 1},
+  {&__pyx_n_s_frombuffer, __pyx_k_frombuffer, sizeof(__pyx_k_frombuffer), 0, 0, 1, 1},
+  {&__pyx_n_s_generic_precision, __pyx_k_generic_precision, sizeof(__pyx_k_generic_precision), 0, 0, 1, 1},
+  {&__pyx_n_s_get_N, __pyx_k_get_N, sizeof(__pyx_k_get_N), 0, 0, 1, 1},
+  {&__pyx_n_s_get_axes, __pyx_k_get_axes, sizeof(__pyx_k_get_axes), 0, 0, 1, 1},
+  {&__pyx_n_s_get_direction, __pyx_k_get_direction, sizeof(__pyx_k_get_direction), 0, 0, 1, 1},
+  {&__pyx_n_s_get_flags_used, __pyx_k_get_flags_used, sizeof(__pyx_k_get_flags_used), 0, 0, 1, 1},
+  {&__pyx_n_s_get_input_alignment, __pyx_k_get_input_alignment, sizeof(__pyx_k_get_input_alignment), 0, 0, 1, 1},
+  {&__pyx_n_s_get_input_array, __pyx_k_get_input_array, sizeof(__pyx_k_get_input_array), 0, 0, 1, 1},
+  {&__pyx_kp_s_get_input_array_is_deprecated_Co, __pyx_k_get_input_array_is_deprecated_Co, sizeof(__pyx_k_get_input_array_is_deprecated_Co), 0, 0, 1, 0},
+  {&__pyx_n_s_get_input_dtype, __pyx_k_get_input_dtype, sizeof(__pyx_k_get_input_dtype), 0, 0, 1, 1},
+  {&__pyx_n_s_get_input_shape, __pyx_k_get_input_shape, sizeof(__pyx_k_get_input_shape), 0, 0, 1, 1},
+  {&__pyx_n_s_get_input_strides, __pyx_k_get_input_strides, sizeof(__pyx_k_get_input_strides), 0, 0, 1, 1},
+  {&__pyx_n_s_get_output_alignment, __pyx_k_get_output_alignment, sizeof(__pyx_k_get_output_alignment), 0, 0, 1, 1},
+  {&__pyx_n_s_get_output_array, __pyx_k_get_output_array, sizeof(__pyx_k_get_output_array), 0, 0, 1, 1},
+  {&__pyx_kp_s_get_output_array_is_deprecated_C, __pyx_k_get_output_array_is_deprecated_C, sizeof(__pyx_k_get_output_array_is_deprecated_C), 0, 0, 1, 0},
+  {&__pyx_n_s_get_output_dtype, __pyx_k_get_output_dtype, sizeof(__pyx_k_get_output_dtype), 0, 0, 1, 1},
+  {&__pyx_n_s_get_output_shape, __pyx_k_get_output_shape, sizeof(__pyx_k_get_output_shape), 0, 0, 1, 1},
+  {&__pyx_n_s_get_output_strides, __pyx_k_get_output_strides, sizeof(__pyx_k_get_output_strides), 0, 0, 1, 1},
+  {&__pyx_n_s_get_simd_aligned, __pyx_k_get_simd_aligned, sizeof(__pyx_k_get_simd_aligned), 0, 0, 1, 1},
+  {&__pyx_kp_s_home_whg_Projects_github_pyFFTW, __pyx_k_home_whg_Projects_github_pyFFTW, sizeof(__pyx_k_home_whg_Projects_github_pyFFTW), 0, 0, 1, 0},
+  {&__pyx_n_s_import, __pyx_k_import, sizeof(__pyx_k_import), 0, 0, 1, 1},
+  {&__pyx_n_s_import_wisdom, __pyx_k_import_wisdom, sizeof(__pyx_k_import_wisdom), 0, 0, 1, 1},
+  {&__pyx_n_s_input_alignment, __pyx_k_input_alignment, sizeof(__pyx_k_input_alignment), 0, 0, 1, 1},
+  {&__pyx_n_s_input_array, __pyx_k_input_array, sizeof(__pyx_k_input_array), 0, 0, 1, 1},
+  {&__pyx_n_s_input_dtype, __pyx_k_input_dtype, sizeof(__pyx_k_input_dtype), 0, 0, 1, 1},
+  {&__pyx_n_s_input_shape, __pyx_k_input_shape, sizeof(__pyx_k_input_shape), 0, 0, 1, 1},
+  {&__pyx_n_s_input_strides, __pyx_k_input_strides, sizeof(__pyx_k_input_strides), 0, 0, 1, 1},
+  {&__pyx_n_s_int8, __pyx_k_int8, sizeof(__pyx_k_int8), 0, 0, 1, 1},
+  {&__pyx_n_s_integer, __pyx_k_integer, sizeof(__pyx_k_integer), 0, 0, 1, 1},
+  {&__pyx_kp_s_is_not_a_valid_planner_flag, __pyx_k_is_not_a_valid_planner_flag, sizeof(__pyx_k_is_not_a_valid_planner_flag), 0, 0, 1, 0},
+  {&__pyx_n_s_itemsize, __pyx_k_itemsize, sizeof(__pyx_k_itemsize), 0, 0, 1, 1},
+  {&__pyx_n_s_ld, __pyx_k_ld, sizeof(__pyx_k_ld), 0, 0, 1, 1},
+  {&__pyx_kp_s_less_than, __pyx_k_less_than, sizeof(__pyx_k_less_than), 0, 0, 1, 0},
+  {&__pyx_n_s_longdouble, __pyx_k_longdouble, sizeof(__pyx_k_longdouble), 0, 0, 1, 1},
+  {&__pyx_n_s_lookup_shape_c2r_arrays, __pyx_k_lookup_shape_c2r_arrays, sizeof(__pyx_k_lookup_shape_c2r_arrays), 0, 0, 1, 1},
+  {&__pyx_n_s_lookup_shape_r2c_arrays, __pyx_k_lookup_shape_r2c_arrays, sizeof(__pyx_k_lookup_shape_r2c_arrays), 0, 0, 1, 1},
+  {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1},
+  {&__pyx_n_s_n, __pyx_k_n, sizeof(__pyx_k_n), 0, 0, 1, 1},
+  {&__pyx_kp_u_ndarray_is_not_C_contiguous, __pyx_k_ndarray_is_not_C_contiguous, sizeof(__pyx_k_ndarray_is_not_C_contiguous), 0, 1, 0, 0},
+  {&__pyx_kp_u_ndarray_is_not_Fortran_contiguou, __pyx_k_ndarray_is_not_Fortran_contiguou, sizeof(__pyx_k_ndarray_is_not_Fortran_contiguou), 0, 1, 0, 0},
+  {&__pyx_n_s_new_input_array, __pyx_k_new_input_array, sizeof(__pyx_k_new_input_array), 0, 0, 1, 1},
+  {&__pyx_n_s_new_output_array, __pyx_k_new_output_array, sizeof(__pyx_k_new_output_array), 0, 0, 1, 1},
+  {&__pyx_n_s_normalise_idft, __pyx_k_normalise_idft, sizeof(__pyx_k_normalise_idft), 0, 0, 1, 1},
+  {&__pyx_n_s_np, __pyx_k_np, sizeof(__pyx_k_np), 0, 0, 1, 1},
+  {&__pyx_n_s_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 0, 0, 1, 1},
+  {&__pyx_n_s_order, __pyx_k_order, sizeof(__pyx_k_order), 0, 0, 1, 1},
+  {&__pyx_n_s_output_alignment, __pyx_k_output_alignment, sizeof(__pyx_k_output_alignment), 0, 0, 1, 1},
+  {&__pyx_n_s_output_array, __pyx_k_output_array, sizeof(__pyx_k_output_array), 0, 0, 1, 1},
+  {&__pyx_n_s_output_dtype, __pyx_k_output_dtype, sizeof(__pyx_k_output_dtype), 0, 0, 1, 1},
+  {&__pyx_n_s_output_shape, __pyx_k_output_shape, sizeof(__pyx_k_output_shape), 0, 0, 1, 1},
+  {&__pyx_n_s_output_strides, __pyx_k_output_strides, sizeof(__pyx_k_output_strides), 0, 0, 1, 1},
+  {&__pyx_n_s_planner, __pyx_k_planner, sizeof(__pyx_k_planner), 0, 0, 1, 1},
+  {&__pyx_n_s_planning_timelimit, __pyx_k_planning_timelimit, sizeof(__pyx_k_planning_timelimit), 0, 0, 1, 1},
+  {&__pyx_n_s_property, __pyx_k_property, sizeof(__pyx_k_property), 0, 0, 1, 1},
+  {&__pyx_n_s_py_wisdom, __pyx_k_py_wisdom, sizeof(__pyx_k_py_wisdom), 0, 0, 1, 1},
+  {&__pyx_n_s_py_wisdomf, __pyx_k_py_wisdomf, sizeof(__pyx_k_py_wisdomf), 0, 0, 1, 1},
+  {&__pyx_n_s_py_wisdoml, __pyx_k_py_wisdoml, sizeof(__pyx_k_py_wisdoml), 0, 0, 1, 1},
+  {&__pyx_n_s_pyfftw_pyfftw, __pyx_k_pyfftw_pyfftw, sizeof(__pyx_k_pyfftw_pyfftw), 0, 0, 1, 1},
+  {&__pyx_n_s_pyx_vtable, __pyx_k_pyx_vtable, sizeof(__pyx_k_pyx_vtable), 0, 0, 1, 1},
+  {&__pyx_n_s_r2c, __pyx_k_r2c, sizeof(__pyx_k_r2c), 0, 0, 1, 1},
+  {&__pyx_n_s_range, __pyx_k_range, sizeof(__pyx_k_range), 0, 0, 1, 1},
+  {&__pyx_n_s_real, __pyx_k_real, sizeof(__pyx_k_real), 0, 0, 1, 1},
+  {&__pyx_n_s_reshape, __pyx_k_reshape, sizeof(__pyx_k_reshape), 0, 0, 1, 1},
+  {&__pyx_n_s_shape, __pyx_k_shape, sizeof(__pyx_k_shape), 0, 0, 1, 1},
+  {&__pyx_n_s_simd_aligned, __pyx_k_simd_aligned, sizeof(__pyx_k_simd_aligned), 0, 0, 1, 1},
+  {&__pyx_n_s_simd_alignment, __pyx_k_simd_alignment, sizeof(__pyx_k_simd_alignment), 0, 0, 1, 1},
+  {&__pyx_n_s_strides, __pyx_k_strides, sizeof(__pyx_k_strides), 0, 0, 1, 1},
+  {&__pyx_n_s_success, __pyx_k_success, sizeof(__pyx_k_success), 0, 0, 1, 1},
+  {&__pyx_n_s_successf, __pyx_k_successf, sizeof(__pyx_k_successf), 0, 0, 1, 1},
+  {&__pyx_n_s_successl, __pyx_k_successl, sizeof(__pyx_k_successl), 0, 0, 1, 1},
+  {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1},
+  {&__pyx_n_s_threading, __pyx_k_threading, sizeof(__pyx_k_threading), 0, 0, 1, 1},
+  {&__pyx_n_s_threads, __pyx_k_threads, sizeof(__pyx_k_threads), 0, 0, 1, 1},
+  {&__pyx_kp_s_to_the_planner_returning_NULL_Th, __pyx_k_to_the_planner_returning_NULL_Th, sizeof(__pyx_k_to_the_planner_returning_NULL_Th), 0, 0, 1, 0},
+  {&__pyx_n_s_type, __pyx_k_type, sizeof(__pyx_k_type), 0, 0, 1, 1},
+  {&__pyx_kp_u_unknown_dtype_code_in_numpy_pxd, __pyx_k_unknown_dtype_code_in_numpy_pxd, sizeof(__pyx_k_unknown_dtype_code_in_numpy_pxd), 0, 1, 0, 0},
+  {&__pyx_n_s_update, __pyx_k_update, sizeof(__pyx_k_update), 0, 0, 1, 1},
+  {&__pyx_n_s_update_arrays, __pyx_k_update_arrays, sizeof(__pyx_k_update_arrays), 0, 0, 1, 1},
+  {&__pyx_n_s_valid_simd_alignments, __pyx_k_valid_simd_alignments, sizeof(__pyx_k_valid_simd_alignments), 0, 0, 1, 1},
+  {&__pyx_n_s_validator, __pyx_k_validator, sizeof(__pyx_k_validator), 0, 0, 1, 1},
+  {&__pyx_n_s_view, __pyx_k_view, sizeof(__pyx_k_view), 0, 0, 1, 1},
+  {&__pyx_n_s_warn, __pyx_k_warn, sizeof(__pyx_k_warn), 0, 0, 1, 1},
+  {&__pyx_n_s_warnings, __pyx_k_warnings, sizeof(__pyx_k_warnings), 0, 0, 1, 1},
+  {&__pyx_n_s_wisdom, __pyx_k_wisdom, sizeof(__pyx_k_wisdom), 0, 0, 1, 1},
+  {0, 0, 0, 0, 0, 0, 0}
+};
+static int __Pyx_InitCachedBuiltins(void) {
+  __pyx_builtin_property = __Pyx_GetBuiltinName(__pyx_n_s_property); if (!__pyx_builtin_property) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 675; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_DeprecationWarning = __Pyx_GetBuiltinName(__pyx_n_s_DeprecationWarning); if (!__pyx_builtin_DeprecationWarning) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_range = __Pyx_GetBuiltinName(__pyx_n_s_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 357; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_ValueError = __Pyx_GetBuiltinName(__pyx_n_s_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 850; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_MemoryError = __Pyx_GetBuiltinName(__pyx_n_s_MemoryError); if (!__pyx_builtin_MemoryError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1026; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_builtin_RuntimeError = __Pyx_GetBuiltinName(__pyx_n_s_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+static int __Pyx_InitCachedConstants(void) {
+  __Pyx_RefNannyDeclarations
+  __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0);
+
+  /* "pyfftw/utils.pxi":111
+ * 
+ *     if not isinstance(array, np.ndarray):
+ *         raise TypeError('Invalid array: byte_align requires a subclass '             # <<<<<<<<<<<<<<
+ *                 'of ndarray')
+ * 
+ */
+  __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_Invalid_array_byte_align_require); if (unlikely(!__pyx_tuple_)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple_);
+  __Pyx_GIVEREF(__pyx_tuple_);
+
+  /* "pyfftw/utils.pxi":132
+ *         _array_aligned = empty_aligned(array.shape, dtype, n=n)
+ * 
+ *         _array_aligned[:] = array             # <<<<<<<<<<<<<<
+ * 
+ *         array = _array_aligned.view(type=array.__class__)
+ */
+  __pyx_slice__2 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_slice__2);
+  __Pyx_GIVEREF(__pyx_slice__2);
+
+  /* "pyfftw/utils.pxi":148
+ *     '''
+ *     if not isinstance(array, np.ndarray):
+ *         raise TypeError('Invalid array: is_n_byte_aligned requires a subclass '             # <<<<<<<<<<<<<<
+ *                 'of ndarray')
+ * 
+ */
+  __pyx_tuple__3 = PyTuple_Pack(1, __pyx_kp_s_Invalid_array_is_n_byte_aligned); if (unlikely(!__pyx_tuple__3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__3);
+  __Pyx_GIVEREF(__pyx_tuple__3);
+
+  /* "pyfftw/utils.pxi":227
+ *     '''
+ *     array = empty_aligned(shape, dtype=dtype, order=order, n=n)
+ *     array.fill(0)             # <<<<<<<<<<<<<<
+ *     return array
+ * 
+ */
+  __pyx_tuple__4 = PyTuple_Pack(1, __pyx_int_0); if (unlikely(!__pyx_tuple__4)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__4);
+  __Pyx_GIVEREF(__pyx_tuple__4);
+
+  /* "pyfftw/utils.pxi":244
+ *     '''
+ *     array = empty_aligned(shape, dtype=dtype, order=order, n=n)
+ *     array.fill(1)             # <<<<<<<<<<<<<<
+ *     return array
+ */
+  __pyx_tuple__5 = PyTuple_Pack(1, __pyx_int_1); if (unlikely(!__pyx_tuple__5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__5);
+  __Pyx_GIVEREF(__pyx_tuple__5);
+
+  /* "pyfftw/pyfftw.pyx":811
+ *     axes = property(_get_axes)
+ * 
+ *     def __cinit__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
+ *                   direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
+ *                   unsigned int threads=1, planning_timelimit=None,
+ */
+  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__6);
+  __Pyx_GIVEREF(__pyx_tuple__6);
+
+  /* "pyfftw/pyfftw.pyx":812
+ * 
+ *     def __cinit__(self, input_array, output_array, axes=(-1,),
+ *                   direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),             # <<<<<<<<<<<<<<
+ *                   unsigned int threads=1, planning_timelimit=None,
+ *                   *args, **kwargs):
+ */
+  __pyx_tuple__7 = PyTuple_Pack(1, __pyx_n_s_FFTW_MEASURE); if (unlikely(!__pyx_tuple__7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 812; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__7);
+  __Pyx_GIVEREF(__pyx_tuple__7);
+
+  /* "pyfftw/pyfftw.pyx":833
+ *                 _planning_timelimit = planning_timelimit
+ *             except TypeError:
+ *                 raise TypeError('Invalid planning timelimit: '             # <<<<<<<<<<<<<<
+ *                         'The planning timelimit needs to be a float.')
+ * 
+ */
+  __pyx_tuple__8 = PyTuple_Pack(1, __pyx_kp_s_Invalid_planning_timelimit_The_p); if (unlikely(!__pyx_tuple__8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 833; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__8);
+  __Pyx_GIVEREF(__pyx_tuple__8);
+
+  /* "pyfftw/pyfftw.pyx":837
+ * 
+ *         if not isinstance(input_array, np.ndarray):
+ *             raise ValueError('Invalid input array: '             # <<<<<<<<<<<<<<
+ *                     'The input array needs to be an instance '
+ *                     'of numpy.ndarray')
+ */
+  __pyx_tuple__9 = PyTuple_Pack(1, __pyx_kp_s_Invalid_input_array_The_input_ar); if (unlikely(!__pyx_tuple__9)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 837; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__9);
+  __Pyx_GIVEREF(__pyx_tuple__9);
+
+  /* "pyfftw/pyfftw.pyx":842
+ * 
+ *         if not isinstance(output_array, np.ndarray):
+ *             raise ValueError('Invalid output array: '             # <<<<<<<<<<<<<<
+ *                     'The output array needs to be an instance '
+ *                     'of numpy.ndarray')
+ */
+  __pyx_tuple__10 = PyTuple_Pack(1, __pyx_kp_s_Invalid_output_array_The_output); if (unlikely(!__pyx_tuple__10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 842; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__10);
+  __Pyx_GIVEREF(__pyx_tuple__10);
+
+  /* "pyfftw/pyfftw.pyx":851
+ *             scheme = fftw_schemes[(input_dtype, output_dtype)]
+ *         except KeyError:
+ *             raise ValueError('Invalid scheme: '             # <<<<<<<<<<<<<<
+ *                     'The output array and input array dtypes '
+ *                     'do not correspond to a valid fftw scheme.')
+ */
+  __pyx_tuple__11 = PyTuple_Pack(1, __pyx_kp_s_Invalid_scheme_The_output_array); if (unlikely(!__pyx_tuple__11)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 851; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__11);
+  __Pyx_GIVEREF(__pyx_tuple__11);
+
+  /* "pyfftw/pyfftw.pyx":927
+ * 
+ *         if not direction in scheme_directions[scheme]:
+ *             raise ValueError('Invalid direction: '             # <<<<<<<<<<<<<<
+ *                     'The direction is not valid for the scheme. '
+ *                     'Try setting it explicitly if it is not already.')
+ */
+  __pyx_tuple__12 = PyTuple_Pack(1, __pyx_kp_s_Invalid_direction_The_direction); if (unlikely(!__pyx_tuple__12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 927; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__12);
+  __Pyx_GIVEREF(__pyx_tuple__12);
+
+  /* "pyfftw/pyfftw.pyx":951
+ * 
+ *             if self._axes[n] >= array_dimension or self._axes[n] < 0:
+ *                 raise IndexError('Invalid axes: '             # <<<<<<<<<<<<<<
+ *                     'The axes list cannot contain invalid axes.')
+ * 
+ */
+  __pyx_tuple__13 = PyTuple_Pack(1, __pyx_kp_s_Invalid_axes_The_axes_list_canno); if (unlikely(!__pyx_tuple__13)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 951; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__13);
+  __Pyx_GIVEREF(__pyx_tuple__13);
+
+  /* "pyfftw/pyfftw.pyx":969
+ *         for n in range(unique_axes_length):
+ *             if self._input_shape[self._axes[n]] == 0:
+ *                 raise ValueError('Zero length array: '             # <<<<<<<<<<<<<<
+ *                     'The input array should have no zero length'
+ *                     'axes over which the FFT is to be taken')
+ */
+  __pyx_tuple__14 = PyTuple_Pack(1, __pyx_kp_s_Zero_length_array_The_input_arra); if (unlikely(!__pyx_tuple__14)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 969; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__14);
+  __Pyx_GIVEREF(__pyx_tuple__14);
+
+  /* "pyfftw/pyfftw.pyx":986
+ *         if functions['validator'] == -1:
+ *             if not (output_array.shape == input_array.shape):
+ *                 raise ValueError('Invalid shapes: '             # <<<<<<<<<<<<<<
+ *                         'The output array should be the same shape as the '
+ *                         'input array for the given array dtypes.')
+ */
+  __pyx_tuple__15 = PyTuple_Pack(1, __pyx_kp_s_Invalid_shapes_The_output_array); if (unlikely(!__pyx_tuple__15)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 986; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__15);
+  __Pyx_GIVEREF(__pyx_tuple__15);
+
+  /* "pyfftw/pyfftw.pyx":993
+ *             if not _validator(input_array, output_array,
+ *                     self._axes, self._not_axes, unique_axes_length):
+ *                 raise ValueError('Invalid shapes: '             # <<<<<<<<<<<<<<
+ *                         'The input array and output array are invalid '
+ *                         'complementary shapes for their dtypes.')
+ */
+  __pyx_tuple__16 = PyTuple_Pack(1, __pyx_kp_s_Invalid_shapes_The_input_array_a); if (unlikely(!__pyx_tuple__16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 993; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__16);
+  __Pyx_GIVEREF(__pyx_tuple__16);
+
+  /* "pyfftw/pyfftw.pyx":1101
+ *         cdef unsigned c_flags = self._flags
+ * 
+ *         with plan_lock, nogil:             # <<<<<<<<<<<<<<
+ *             plan = fftw_planner(rank, dims, howmany_rank, howmany_dims,
+ *                                 _in, _out, sign, c_flags)
+ */
+  __pyx_tuple__18 = PyTuple_Pack(3, Py_None, Py_None, Py_None); if (unlikely(!__pyx_tuple__18)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1101; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__18);
+  __Pyx_GIVEREF(__pyx_tuple__18);
+
+  /* "pyfftw/pyfftw.pyx":1108
+ *         if self._plan == NULL:
+ *             if 'FFTW_WISDOM_ONLY' in flags:
+ *                 raise RuntimeError('No FFTW wisdom is known for this plan.')             # <<<<<<<<<<<<<<
+ *             else:
+ *                 raise RuntimeError('The data has an uncaught error that led '+
+ */
+  __pyx_tuple__19 = PyTuple_Pack(1, __pyx_kp_s_No_FFTW_wisdom_is_known_for_this); if (unlikely(!__pyx_tuple__19)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__19);
+  __Pyx_GIVEREF(__pyx_tuple__19);
+
+  /* "pyfftw/pyfftw.pyx":1113
+ *                     'to the planner returning NULL. This is a bug.')
+ * 
+ *     def __init__(self, input_array, output_array, axes=(-1,),             # <<<<<<<<<<<<<<
+ *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),
+ *             int threads=1, planning_timelimit=None):
+ */
+  __pyx_tuple__20 = PyTuple_Pack(1, __pyx_int_neg_1); if (unlikely(!__pyx_tuple__20)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1113; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__20);
+  __Pyx_GIVEREF(__pyx_tuple__20);
+
+  /* "pyfftw/pyfftw.pyx":1114
+ * 
+ *     def __init__(self, input_array, output_array, axes=(-1,),
+ *             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',),             # <<<<<<<<<<<<<<
+ *             int threads=1, planning_timelimit=None):
+ *         '''
+ */
+  __pyx_tuple__21 = PyTuple_Pack(1, __pyx_n_s_FFTW_MEASURE); if (unlikely(!__pyx_tuple__21)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__21);
+  __Pyx_GIVEREF(__pyx_tuple__21);
+
+  /* "pyfftw/pyfftw.pyx":1423
+ * 
+ *                 if not input_array.shape == self._input_shape:
+ *                     raise ValueError('Invalid input shape: '             # <<<<<<<<<<<<<<
+ *                             'The new input array should be the same shape '
+ *                             'as the input array used to instantiate the '
+ */
+  __pyx_tuple__22 = PyTuple_Pack(1, __pyx_kp_s_Invalid_input_shape_The_new_inpu); if (unlikely(!__pyx_tuple__22)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__22);
+  __Pyx_GIVEREF(__pyx_tuple__22);
+
+  /* "pyfftw/pyfftw.pyx":1428
+ *                             'object.')
+ * 
+ *                 self._input_array[:] = input_array             # <<<<<<<<<<<<<<
+ * 
+ *                 if output_array is not None:
+ */
+  __pyx_slice__23 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_slice__23)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_slice__23);
+  __Pyx_GIVEREF(__pyx_slice__23);
+
+  /* "pyfftw/pyfftw.pyx":1470
+ *         '''
+ *         if not isinstance(new_input_array, np.ndarray):
+ *             raise ValueError('Invalid input array: '             # <<<<<<<<<<<<<<
+ *                     'The new input array needs to be an instance '
+ *                     'of numpy.ndarray')
+ */
+  __pyx_tuple__24 = PyTuple_Pack(1, __pyx_kp_s_Invalid_input_array_The_new_inpu); if (unlikely(!__pyx_tuple__24)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__24);
+  __Pyx_GIVEREF(__pyx_tuple__24);
+
+  /* "pyfftw/pyfftw.pyx":1475
+ * 
+ *         if not isinstance(new_output_array, np.ndarray):
+ *             raise ValueError('Invalid output array '             # <<<<<<<<<<<<<<
+ *                     'The new output array needs to be an instance '
+ *                     'of numpy.ndarray')
+ */
+  __pyx_tuple__25 = PyTuple_Pack(1, __pyx_kp_s_Invalid_output_array_The_new_out); if (unlikely(!__pyx_tuple__25)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1475; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__25);
+  __Pyx_GIVEREF(__pyx_tuple__25);
+
+  /* "pyfftw/pyfftw.pyx":1494
+ * 
+ *         if not new_input_array.dtype == self._input_dtype:
+ *             raise ValueError('Invalid input dtype: '             # <<<<<<<<<<<<<<
+ *                     'The new input array is not of the same '
+ *                     'dtype as was originally planned for.')
+ */
+  __pyx_tuple__26 = PyTuple_Pack(1, __pyx_kp_s_Invalid_input_dtype_The_new_inpu); if (unlikely(!__pyx_tuple__26)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__26);
+  __Pyx_GIVEREF(__pyx_tuple__26);
+
+  /* "pyfftw/pyfftw.pyx":1499
+ * 
+ *         if not new_output_array.dtype == self._output_dtype:
+ *             raise ValueError('Invalid output dtype: '             # <<<<<<<<<<<<<<
+ *                     'The new output array is not of the same '
+ *                     'dtype as was originally planned for.')
+ */
+  __pyx_tuple__27 = PyTuple_Pack(1, __pyx_kp_s_Invalid_output_dtype_The_new_out); if (unlikely(!__pyx_tuple__27)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__27);
+  __Pyx_GIVEREF(__pyx_tuple__27);
+
+  /* "pyfftw/pyfftw.pyx":1510
+ * 
+ *         if not new_input_shape == self._input_shape:
+ *             raise ValueError('Invalid input shape: '             # <<<<<<<<<<<<<<
+ *                     'The new input array should be the same shape as '
+ *                     'the input array used to instantiate the object.')
+ */
+  __pyx_tuple__28 = PyTuple_Pack(1, __pyx_kp_s_Invalid_input_shape_The_new_inpu); if (unlikely(!__pyx_tuple__28)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1510; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__28);
+  __Pyx_GIVEREF(__pyx_tuple__28);
+
+  /* "pyfftw/pyfftw.pyx":1515
+ * 
+ *         if not new_output_shape == self._output_shape:
+ *             raise ValueError('Invalid output shape: '             # <<<<<<<<<<<<<<
+ *                     'The new output array should be the same shape as '
+ *                     'the output array used to instantiate the object.')
+ */
+  __pyx_tuple__29 = PyTuple_Pack(1, __pyx_kp_s_Invalid_output_shape_The_new_out); if (unlikely(!__pyx_tuple__29)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1515; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__29);
+  __Pyx_GIVEREF(__pyx_tuple__29);
+
+  /* "pyfftw/pyfftw.pyx":1520
+ * 
+ *         if not new_input_strides == self._input_strides:
+ *             raise ValueError('Invalid input striding: '             # <<<<<<<<<<<<<<
+ *                     'The strides should be identical for the new '
+ *                     'input array as for the old.')
+ */
+  __pyx_tuple__30 = PyTuple_Pack(1, __pyx_kp_s_Invalid_input_striding_The_strid); if (unlikely(!__pyx_tuple__30)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__30);
+  __Pyx_GIVEREF(__pyx_tuple__30);
+
+  /* "pyfftw/pyfftw.pyx":1525
+ * 
+ *         if not new_output_strides == self._output_strides:
+ *             raise ValueError('Invalid output striding: '             # <<<<<<<<<<<<<<
+ *                     'The strides should be identical for the new '
+ *                     'output array as for the old.')
+ */
+  __pyx_tuple__31 = PyTuple_Pack(1, __pyx_kp_s_Invalid_output_striding_The_stri); if (unlikely(!__pyx_tuple__31)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__31);
+  __Pyx_GIVEREF(__pyx_tuple__31);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":218
+ *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not C contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ */
+  __pyx_tuple__32 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_C_contiguous); if (unlikely(!__pyx_tuple__32)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__32);
+  __Pyx_GIVEREF(__pyx_tuple__32);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":222
+ *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
+ *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
+ *                 raise ValueError(u"ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
+ * 
+ *             info.buf = PyArray_DATA(self)
+ */
+  __pyx_tuple__33 = PyTuple_Pack(1, __pyx_kp_u_ndarray_is_not_Fortran_contiguou); if (unlikely(!__pyx_tuple__33)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 222; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__33);
+  __Pyx_GIVEREF(__pyx_tuple__33);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":259
+ *                 if ((descr.byteorder == c'>' and little_endian) or
+ *                     (descr.byteorder == c'<' and not little_endian)):
+ *                     raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *                 if   t == NPY_BYTE:        f = "b"
+ *                 elif t == NPY_UBYTE:       f = "B"
+ */
+  __pyx_tuple__34 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__34)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__34);
+  __Pyx_GIVEREF(__pyx_tuple__34);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":799
+ * 
+ *         if (end - f) - <int>(new_offset - offset[0]) < 15:
+ *             raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")             # <<<<<<<<<<<<<<
+ * 
+ *         if ((child.byteorder == c'>' and little_endian) or
+ */
+  __pyx_tuple__35 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor); if (unlikely(!__pyx_tuple__35)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 799; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__35);
+  __Pyx_GIVEREF(__pyx_tuple__35);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":803
+ *         if ((child.byteorder == c'>' and little_endian) or
+ *             (child.byteorder == c'<' and not little_endian)):
+ *             raise ValueError(u"Non-native byte order not supported")             # <<<<<<<<<<<<<<
+ *             # One could encode it in the format string and have Cython
+ *             # complain instead, BUT: < and > in format strings also imply
+ */
+  __pyx_tuple__36 = PyTuple_Pack(1, __pyx_kp_u_Non_native_byte_order_not_suppor); if (unlikely(!__pyx_tuple__36)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__36);
+  __Pyx_GIVEREF(__pyx_tuple__36);
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":823
+ *             t = child.type_num
+ *             if end - f < 5:
+ *                 raise RuntimeError(u"Format string allocated too short.")             # <<<<<<<<<<<<<<
+ * 
+ *             # Until ticket #99 is fixed, use integers to avoid warnings
+ */
+  __pyx_tuple__37 = PyTuple_Pack(1, __pyx_kp_u_Format_string_allocated_too_shor_2); if (unlikely(!__pyx_tuple__37)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__37);
+  __Pyx_GIVEREF(__pyx_tuple__37);
+
+  /* "pyfftw/utils.pxi":51
+ * #: A tuple of simd alignments that make sense for this cpu
+ * if _simd_alignment == 16:
+ *     _valid_simd_alignments = (16,)             # <<<<<<<<<<<<<<
+ * 
+ * elif _simd_alignment == 32:
+ */
+  __pyx_tuple__38 = PyTuple_Pack(1, __pyx_int_16); if (unlikely(!__pyx_tuple__38)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__38);
+  __Pyx_GIVEREF(__pyx_tuple__38);
+
+  /* "pyfftw/utils.pxi":54
+ * 
+ * elif _simd_alignment == 32:
+ *     _valid_simd_alignments = (16, 32)             # <<<<<<<<<<<<<<
+ * 
+ * else:
+ */
+  __pyx_tuple__39 = PyTuple_Pack(2, __pyx_int_16, __pyx_int_32); if (unlikely(!__pyx_tuple__39)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__39);
+  __Pyx_GIVEREF(__pyx_tuple__39);
+
+  /* "pyfftw/pyfftw.pyx":408
+ * # Shape lookup functions
+ * # ======================
+ * def _lookup_shape_r2c_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
+ *     return input_array.shape
+ * 
+ */
+  __pyx_tuple__40 = PyTuple_Pack(2, __pyx_n_s_input_array, __pyx_n_s_output_array); if (unlikely(!__pyx_tuple__40)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__40);
+  __Pyx_GIVEREF(__pyx_tuple__40);
+  __pyx_codeobj__41 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__40, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_whg_Projects_github_pyFFTW, __pyx_n_s_lookup_shape_r2c_arrays, 408, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__41)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "pyfftw/pyfftw.pyx":411
+ *     return input_array.shape
+ * 
+ * def _lookup_shape_c2r_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
+ *     return output_array.shape
+ * 
+ */
+  __pyx_tuple__42 = PyTuple_Pack(2, __pyx_n_s_input_array, __pyx_n_s_output_array); if (unlikely(!__pyx_tuple__42)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__42);
+  __Pyx_GIVEREF(__pyx_tuple__42);
+  __pyx_codeobj__43 = (PyObject*)__Pyx_PyCode_New(2, 0, 2, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__42, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_whg_Projects_github_pyFFTW, __pyx_n_s_lookup_shape_c2r_arrays, 411, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__43)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "pyfftw/pyfftw.pyx":446
+ * cdef object fftw_schemes
+ * fftw_schemes = {
+ *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
+ *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
+ */
+  __pyx_tuple__44 = PyTuple_Pack(1, __pyx_n_s_complex128); if (unlikely(!__pyx_tuple__44)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__44);
+  __Pyx_GIVEREF(__pyx_tuple__44);
+  __pyx_tuple__45 = PyTuple_Pack(1, __pyx_n_s_complex128); if (unlikely(!__pyx_tuple__45)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__45);
+  __Pyx_GIVEREF(__pyx_tuple__45);
+  __pyx_tuple__46 = PyTuple_Pack(2, __pyx_n_s_c2c, __pyx_kp_s_64); if (unlikely(!__pyx_tuple__46)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__46);
+  __Pyx_GIVEREF(__pyx_tuple__46);
+
+  /* "pyfftw/pyfftw.pyx":447
+ * fftw_schemes = {
+ *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),
+ *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
+ *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
+ */
+  __pyx_tuple__47 = PyTuple_Pack(1, __pyx_n_s_complex64); if (unlikely(!__pyx_tuple__47)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__47);
+  __Pyx_GIVEREF(__pyx_tuple__47);
+  __pyx_tuple__48 = PyTuple_Pack(1, __pyx_n_s_complex64); if (unlikely(!__pyx_tuple__48)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__48);
+  __Pyx_GIVEREF(__pyx_tuple__48);
+  __pyx_tuple__49 = PyTuple_Pack(2, __pyx_n_s_c2c, __pyx_kp_s_32); if (unlikely(!__pyx_tuple__49)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__49);
+  __Pyx_GIVEREF(__pyx_tuple__49);
+
+  /* "pyfftw/pyfftw.pyx":448
+ *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),
+ *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
+ *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
+ *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
+ */
+  __pyx_tuple__50 = PyTuple_Pack(1, __pyx_n_s_float64); if (unlikely(!__pyx_tuple__50)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__50);
+  __Pyx_GIVEREF(__pyx_tuple__50);
+  __pyx_tuple__51 = PyTuple_Pack(1, __pyx_n_s_complex128); if (unlikely(!__pyx_tuple__51)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__51);
+  __Pyx_GIVEREF(__pyx_tuple__51);
+  __pyx_tuple__52 = PyTuple_Pack(2, __pyx_n_s_r2c, __pyx_kp_s_64); if (unlikely(!__pyx_tuple__52)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__52);
+  __Pyx_GIVEREF(__pyx_tuple__52);
+
+  /* "pyfftw/pyfftw.pyx":449
+ *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
+ *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
+ *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
+ *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
+ */
+  __pyx_tuple__53 = PyTuple_Pack(1, __pyx_n_s_float32); if (unlikely(!__pyx_tuple__53)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__53);
+  __Pyx_GIVEREF(__pyx_tuple__53);
+  __pyx_tuple__54 = PyTuple_Pack(1, __pyx_n_s_complex64); if (unlikely(!__pyx_tuple__54)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__54);
+  __Pyx_GIVEREF(__pyx_tuple__54);
+  __pyx_tuple__55 = PyTuple_Pack(2, __pyx_n_s_r2c, __pyx_kp_s_32); if (unlikely(!__pyx_tuple__55)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__55);
+  __Pyx_GIVEREF(__pyx_tuple__55);
+
+  /* "pyfftw/pyfftw.pyx":450
+ *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
+ *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
+ *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
+ * 
+ */
+  __pyx_tuple__56 = PyTuple_Pack(1, __pyx_n_s_complex128); if (unlikely(!__pyx_tuple__56)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__56);
+  __Pyx_GIVEREF(__pyx_tuple__56);
+  __pyx_tuple__57 = PyTuple_Pack(1, __pyx_n_s_float64); if (unlikely(!__pyx_tuple__57)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__57);
+  __Pyx_GIVEREF(__pyx_tuple__57);
+  __pyx_tuple__58 = PyTuple_Pack(2, __pyx_n_s_c2r, __pyx_kp_s_64); if (unlikely(!__pyx_tuple__58)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__58);
+  __Pyx_GIVEREF(__pyx_tuple__58);
+
+  /* "pyfftw/pyfftw.pyx":451
+ *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
+ *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
+ *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}             # <<<<<<<<<<<<<<
+ * 
+ * if np.dtype('longdouble') != np.dtype('float64'):
+ */
+  __pyx_tuple__59 = PyTuple_Pack(1, __pyx_n_s_complex64); if (unlikely(!__pyx_tuple__59)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__59);
+  __Pyx_GIVEREF(__pyx_tuple__59);
+  __pyx_tuple__60 = PyTuple_Pack(1, __pyx_n_s_float32); if (unlikely(!__pyx_tuple__60)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__60);
+  __Pyx_GIVEREF(__pyx_tuple__60);
+  __pyx_tuple__61 = PyTuple_Pack(2, __pyx_n_s_c2r, __pyx_kp_s_32); if (unlikely(!__pyx_tuple__61)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__61);
+  __Pyx_GIVEREF(__pyx_tuple__61);
+
+  /* "pyfftw/pyfftw.pyx":453
+ *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
+ * 
+ * if np.dtype('longdouble') != np.dtype('float64'):             # <<<<<<<<<<<<<<
+ *     fftw_schemes.update({
+ *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
+ */
+  __pyx_tuple__62 = PyTuple_Pack(1, __pyx_n_s_longdouble); if (unlikely(!__pyx_tuple__62)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__62);
+  __Pyx_GIVEREF(__pyx_tuple__62);
+  __pyx_tuple__63 = PyTuple_Pack(1, __pyx_n_s_float64); if (unlikely(!__pyx_tuple__63)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__63);
+  __Pyx_GIVEREF(__pyx_tuple__63);
+
+  /* "pyfftw/pyfftw.pyx":455
+ * if np.dtype('longdouble') != np.dtype('float64'):
+ *     fftw_schemes.update({
+ *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),
+ *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})
+ */
+  __pyx_tuple__64 = PyTuple_Pack(1, __pyx_n_s_clongdouble); if (unlikely(!__pyx_tuple__64)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__64);
+  __Pyx_GIVEREF(__pyx_tuple__64);
+  __pyx_tuple__65 = PyTuple_Pack(1, __pyx_n_s_clongdouble); if (unlikely(!__pyx_tuple__65)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__65);
+  __Pyx_GIVEREF(__pyx_tuple__65);
+  __pyx_tuple__66 = PyTuple_Pack(2, __pyx_n_s_c2c, __pyx_n_s_ld); if (unlikely(!__pyx_tuple__66)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__66);
+  __Pyx_GIVEREF(__pyx_tuple__66);
+
+  /* "pyfftw/pyfftw.pyx":456
+ *     fftw_schemes.update({
+ *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
+ *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})
+ * 
+ */
+  __pyx_tuple__67 = PyTuple_Pack(1, __pyx_n_s_longdouble); if (unlikely(!__pyx_tuple__67)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__67);
+  __Pyx_GIVEREF(__pyx_tuple__67);
+  __pyx_tuple__68 = PyTuple_Pack(1, __pyx_n_s_clongdouble); if (unlikely(!__pyx_tuple__68)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__68);
+  __Pyx_GIVEREF(__pyx_tuple__68);
+  __pyx_tuple__69 = PyTuple_Pack(2, __pyx_n_s_r2c, __pyx_n_s_ld); if (unlikely(!__pyx_tuple__69)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__69);
+  __Pyx_GIVEREF(__pyx_tuple__69);
+
+  /* "pyfftw/pyfftw.pyx":457
+ *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
+ *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),
+ *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_tuple__70 = PyTuple_Pack(1, __pyx_n_s_clongdouble); if (unlikely(!__pyx_tuple__70)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__70);
+  __Pyx_GIVEREF(__pyx_tuple__70);
+  __pyx_tuple__71 = PyTuple_Pack(1, __pyx_n_s_longdouble); if (unlikely(!__pyx_tuple__71)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__71);
+  __Pyx_GIVEREF(__pyx_tuple__71);
+  __pyx_tuple__72 = PyTuple_Pack(2, __pyx_n_s_c2r, __pyx_n_s_ld); if (unlikely(!__pyx_tuple__72)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__72);
+  __Pyx_GIVEREF(__pyx_tuple__72);
+
+  /* "pyfftw/pyfftw.pyx":462
+ * cdef object scheme_directions
+ * scheme_directions = {
+ *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
+ *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ */
+  __pyx_tuple__73 = PyTuple_Pack(2, __pyx_n_s_c2c, __pyx_kp_s_64); if (unlikely(!__pyx_tuple__73)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__73);
+  __Pyx_GIVEREF(__pyx_tuple__73);
+
+  /* "pyfftw/pyfftw.pyx":463
+ * scheme_directions = {
+ *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
+ *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('r2c', '64'): ['FFTW_FORWARD'],
+ */
+  __pyx_tuple__74 = PyTuple_Pack(2, __pyx_n_s_c2c, __pyx_kp_s_32); if (unlikely(!__pyx_tuple__74)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__74);
+  __Pyx_GIVEREF(__pyx_tuple__74);
+
+  /* "pyfftw/pyfftw.pyx":464
+ *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
+ *         ('r2c', '64'): ['FFTW_FORWARD'],
+ *         ('r2c', '32'): ['FFTW_FORWARD'],
+ */
+  __pyx_tuple__75 = PyTuple_Pack(2, __pyx_n_s_c2c, __pyx_n_s_ld); if (unlikely(!__pyx_tuple__75)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__75);
+  __Pyx_GIVEREF(__pyx_tuple__75);
+
+  /* "pyfftw/pyfftw.pyx":465
+ *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('r2c', '64'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
+ *         ('r2c', '32'): ['FFTW_FORWARD'],
+ *         ('r2c', 'ld'): ['FFTW_FORWARD'],
+ */
+  __pyx_tuple__76 = PyTuple_Pack(2, __pyx_n_s_r2c, __pyx_kp_s_64); if (unlikely(!__pyx_tuple__76)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__76);
+  __Pyx_GIVEREF(__pyx_tuple__76);
+
+  /* "pyfftw/pyfftw.pyx":466
+ *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('r2c', '64'): ['FFTW_FORWARD'],
+ *         ('r2c', '32'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
+ *         ('r2c', 'ld'): ['FFTW_FORWARD'],
+ *         ('c2r', '64'): ['FFTW_BACKWARD'],
+ */
+  __pyx_tuple__77 = PyTuple_Pack(2, __pyx_n_s_r2c, __pyx_kp_s_32); if (unlikely(!__pyx_tuple__77)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__77);
+  __Pyx_GIVEREF(__pyx_tuple__77);
+
+  /* "pyfftw/pyfftw.pyx":467
+ *         ('r2c', '64'): ['FFTW_FORWARD'],
+ *         ('r2c', '32'): ['FFTW_FORWARD'],
+ *         ('r2c', 'ld'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
+ *         ('c2r', '64'): ['FFTW_BACKWARD'],
+ *         ('c2r', '32'): ['FFTW_BACKWARD'],
+ */
+  __pyx_tuple__78 = PyTuple_Pack(2, __pyx_n_s_r2c, __pyx_n_s_ld); if (unlikely(!__pyx_tuple__78)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__78);
+  __Pyx_GIVEREF(__pyx_tuple__78);
+
+  /* "pyfftw/pyfftw.pyx":468
+ *         ('r2c', '32'): ['FFTW_FORWARD'],
+ *         ('r2c', 'ld'): ['FFTW_FORWARD'],
+ *         ('c2r', '64'): ['FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
+ *         ('c2r', '32'): ['FFTW_BACKWARD'],
+ *         ('c2r', 'ld'): ['FFTW_BACKWARD']}
+ */
+  __pyx_tuple__79 = PyTuple_Pack(2, __pyx_n_s_c2r, __pyx_kp_s_64); if (unlikely(!__pyx_tuple__79)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__79);
+  __Pyx_GIVEREF(__pyx_tuple__79);
+
+  /* "pyfftw/pyfftw.pyx":469
+ *         ('r2c', 'ld'): ['FFTW_FORWARD'],
+ *         ('c2r', '64'): ['FFTW_BACKWARD'],
+ *         ('c2r', '32'): ['FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
+ *         ('c2r', 'ld'): ['FFTW_BACKWARD']}
+ * 
+ */
+  __pyx_tuple__80 = PyTuple_Pack(2, __pyx_n_s_c2r, __pyx_kp_s_32); if (unlikely(!__pyx_tuple__80)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__80);
+  __Pyx_GIVEREF(__pyx_tuple__80);
+
+  /* "pyfftw/pyfftw.pyx":470
+ *         ('c2r', '64'): ['FFTW_BACKWARD'],
+ *         ('c2r', '32'): ['FFTW_BACKWARD'],
+ *         ('c2r', 'ld'): ['FFTW_BACKWARD']}             # <<<<<<<<<<<<<<
+ * 
+ * # In the following, -1 denotes using the default. A segfault has been
+ */
+  __pyx_tuple__81 = PyTuple_Pack(2, __pyx_n_s_c2r, __pyx_n_s_ld); if (unlikely(!__pyx_tuple__81)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__81);
+  __Pyx_GIVEREF(__pyx_tuple__81);
+
+  /* "pyfftw/pyfftw.pyx":478
+ * cdef object scheme_functions
+ * scheme_functions = {
+ *     ('c2c', '64'): {'planner': 0, 'executor':0, 'generic_precision':0,             # <<<<<<<<<<<<<<
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,
+ */
+  __pyx_tuple__82 = PyTuple_Pack(2, __pyx_n_s_c2c, __pyx_kp_s_64); if (unlikely(!__pyx_tuple__82)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__82);
+  __Pyx_GIVEREF(__pyx_tuple__82);
+
+  /* "pyfftw/pyfftw.pyx":480
+ *     ('c2c', '64'): {'planner': 0, 'executor':0, 'generic_precision':0,
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,             # <<<<<<<<<<<<<<
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,
+ */
+  __pyx_tuple__83 = PyTuple_Pack(2, __pyx_n_s_c2c, __pyx_kp_s_32); if (unlikely(!__pyx_tuple__83)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__83);
+  __Pyx_GIVEREF(__pyx_tuple__83);
+
+  /* "pyfftw/pyfftw.pyx":482
+ *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,             # <<<<<<<<<<<<<<
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('r2c', '64'): {'planner':3, 'executor':3, 'generic_precision':0,
+ */
+  __pyx_tuple__84 = PyTuple_Pack(2, __pyx_n_s_c2c, __pyx_n_s_ld); if (unlikely(!__pyx_tuple__84)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__84);
+  __Pyx_GIVEREF(__pyx_tuple__84);
+
+  /* "pyfftw/pyfftw.pyx":484
+ *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('r2c', '64'): {'planner':3, 'executor':3, 'generic_precision':0,             # <<<<<<<<<<<<<<
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ */
+  __pyx_tuple__85 = PyTuple_Pack(2, __pyx_n_s_r2c, __pyx_kp_s_64); if (unlikely(!__pyx_tuple__85)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__85);
+  __Pyx_GIVEREF(__pyx_tuple__85);
+
+  /* "pyfftw/pyfftw.pyx":487
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ *     ('r2c', '32'): {'planner':4, 'executor':4, 'generic_precision':1,             # <<<<<<<<<<<<<<
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ */
+  __pyx_tuple__86 = PyTuple_Pack(2, __pyx_n_s_r2c, __pyx_kp_s_32); if (unlikely(!__pyx_tuple__86)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__86);
+  __Pyx_GIVEREF(__pyx_tuple__86);
+
+  /* "pyfftw/pyfftw.pyx":490
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ *     ('r2c', 'ld'): {'planner':5, 'executor':5, 'generic_precision':2,             # <<<<<<<<<<<<<<
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ */
+  __pyx_tuple__87 = PyTuple_Pack(2, __pyx_n_s_r2c, __pyx_n_s_ld); if (unlikely(!__pyx_tuple__87)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__87);
+  __Pyx_GIVEREF(__pyx_tuple__87);
+
+  /* "pyfftw/pyfftw.pyx":493
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ *     ('c2r', '64'): {'planner':6, 'executor':6, 'generic_precision':0,             # <<<<<<<<<<<<<<
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
+ */
+  __pyx_tuple__88 = PyTuple_Pack(2, __pyx_n_s_c2r, __pyx_kp_s_64); if (unlikely(!__pyx_tuple__88)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__88);
+  __Pyx_GIVEREF(__pyx_tuple__88);
+
+  /* "pyfftw/pyfftw.pyx":496
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
+ *     ('c2r', '32'): {'planner':7, 'executor':7, 'generic_precision':1,             # <<<<<<<<<<<<<<
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
+ */
+  __pyx_tuple__89 = PyTuple_Pack(2, __pyx_n_s_c2r, __pyx_kp_s_32); if (unlikely(!__pyx_tuple__89)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__89);
+  __Pyx_GIVEREF(__pyx_tuple__89);
+
+  /* "pyfftw/pyfftw.pyx":499
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
+ *     ('c2r', 'ld'): {'planner':8, 'executor':8, 'generic_precision':2,             # <<<<<<<<<<<<<<
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays}}
+ */
+  __pyx_tuple__90 = PyTuple_Pack(2, __pyx_n_s_c2r, __pyx_n_s_ld); if (unlikely(!__pyx_tuple__90)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__90);
+  __Pyx_GIVEREF(__pyx_tuple__90);
+
+  /* "pyfftw/pyfftw.pyx":1614
+ * 
+ * 
+ * def export_wisdom():             # <<<<<<<<<<<<<<
+ *     '''export_wisdom()
+ * 
+ */
+  __pyx_tuple__91 = PyTuple_Pack(12, __pyx_n_s_py_wisdom, __pyx_n_s_py_wisdomf, __pyx_n_s_py_wisdoml, __pyx_n_s_counter, __pyx_n_s_counterf, __pyx_n_s_counterl, __pyx_n_s_c_wisdom, __pyx_n_s_c_wisdomf, __pyx_n_s_c_wisdoml, __pyx_n_s_c_wisdom_ptr, __pyx_n_s_c_wisdomf_ptr, __pyx_n_s_c_wisdoml_ptr); if (unlikely(!__pyx_tuple__91)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__91);
+  __Pyx_GIVEREF(__pyx_tuple__91);
+  __pyx_codeobj__92 = (PyObject*)__Pyx_PyCode_New(0, 0, 12, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__91, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_whg_Projects_github_pyFFTW, __pyx_n_s_export_wisdom, 1614, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__92)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "pyfftw/pyfftw.pyx":1673
+ *     return (py_wisdom, py_wisdomf, py_wisdoml)
+ * 
+ * def import_wisdom(wisdom):             # <<<<<<<<<<<<<<
+ *     '''import_wisdom(wisdom)
+ * 
+ */
+  __pyx_tuple__93 = PyTuple_Pack(7, __pyx_n_s_wisdom, __pyx_n_s_c_wisdom, __pyx_n_s_c_wisdomf, __pyx_n_s_c_wisdoml, __pyx_n_s_success, __pyx_n_s_successf, __pyx_n_s_successl); if (unlikely(!__pyx_tuple__93)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_tuple__93);
+  __Pyx_GIVEREF(__pyx_tuple__93);
+  __pyx_codeobj__94 = (PyObject*)__Pyx_PyCode_New(1, 0, 7, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__93, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_whg_Projects_github_pyFFTW, __pyx_n_s_import_wisdom, 1673, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__94)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "pyfftw/pyfftw.pyx":1789
+ * #    return (success, successf, successl)
+ * 
+ * def forget_wisdom():             # <<<<<<<<<<<<<<
+ *     '''forget_wisdom()
+ * 
+ */
+  __pyx_codeobj__95 = (PyObject*)__Pyx_PyCode_New(0, 0, 0, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_home_whg_Projects_github_pyFFTW, __pyx_n_s_forget_wisdom, 1789, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__95)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_RefNannyFinishContext();
+  return 0;
+  __pyx_L1_error:;
+  __Pyx_RefNannyFinishContext();
+  return -1;
+}
+
+static int __Pyx_InitGlobals(void) {
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_3 = PyInt_FromLong(3); if (unlikely(!__pyx_int_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_4 = PyInt_FromLong(4); if (unlikely(!__pyx_int_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_5 = PyInt_FromLong(5); if (unlikely(!__pyx_int_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_6 = PyInt_FromLong(6); if (unlikely(!__pyx_int_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_7 = PyInt_FromLong(7); if (unlikely(!__pyx_int_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_8 = PyInt_FromLong(8); if (unlikely(!__pyx_int_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_16 = PyInt_FromLong(16); if (unlikely(!__pyx_int_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_32 = PyInt_FromLong(32); if (unlikely(!__pyx_int_32)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_int_neg_1 = PyInt_FromLong(-1); if (unlikely(!__pyx_int_neg_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  return 0;
+  __pyx_L1_error:;
+  return -1;
+}
+
+#if PY_MAJOR_VERSION < 3
+PyMODINIT_FUNC initpyfftw(void); /*proto*/
+PyMODINIT_FUNC initpyfftw(void)
+#else
+PyMODINIT_FUNC PyInit_pyfftw(void); /*proto*/
+PyMODINIT_FUNC PyInit_pyfftw(void)
+#endif
+{
+  PyObject *__pyx_t_1 = NULL;
+  PyObject *__pyx_t_2 = NULL;
+  PyObject *__pyx_t_3 = NULL;
+  PyObject *__pyx_t_4 = NULL;
+  int __pyx_t_5;
+  PyObject *__pyx_t_6 = NULL;
+  PyObject *__pyx_t_7 = NULL;
+  int __pyx_lineno = 0;
+  const char *__pyx_filename = NULL;
+  int __pyx_clineno = 0;
+  __Pyx_RefNannyDeclarations
+  #if CYTHON_REFNANNY
+  __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny");
+  if (!__Pyx_RefNanny) {
+      PyErr_Clear();
+      __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny");
+      if (!__Pyx_RefNanny)
+          Py_FatalError("failed to import 'refnanny' module");
+  }
+  #endif
+  __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit_pyfftw(void)", 0);
+  if (__Pyx_check_binary_version() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #ifdef __Pyx_CyFunction_USED
+  if (__pyx_CyFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_FusedFunction_USED
+  if (__pyx_FusedFunction_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Coroutine_USED
+  if (__pyx_Coroutine_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_Generator_USED
+  if (__pyx_Generator_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  #ifdef __Pyx_StopAsyncIteration_USED
+  if (__pyx_StopAsyncIteration_init() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  /*--- Library function declarations ---*/
+  /*--- Threads initialization code ---*/
+  #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS
+  #ifdef WITH_THREAD /* Python build with threading support? */
+  PyEval_InitThreads();
+  #endif
+  #endif
+  /*--- Module creation code ---*/
+  #if PY_MAJOR_VERSION < 3
+  __pyx_m = Py_InitModule4("pyfftw", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m);
+  #else
+  __pyx_m = PyModule_Create(&__pyx_moduledef);
+  #endif
+  if (unlikely(!__pyx_m)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  Py_INCREF(__pyx_d);
+  __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if CYTHON_COMPILING_IN_PYPY
+  Py_INCREF(__pyx_b);
+  #endif
+  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
+  /*--- Initialize various global constants etc. ---*/
+  if (__Pyx_InitGlobals() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+  if (__Pyx_init_sys_getdefaultencoding_params() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+  if (__pyx_module_is_main_pyfftw__pyfftw) {
+    if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  #if PY_MAJOR_VERSION >= 3
+  {
+    PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (!PyDict_GetItemString(modules, "pyfftw.pyfftw")) {
+      if (unlikely(PyDict_SetItemString(modules, "pyfftw.pyfftw", __pyx_m) < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    }
+  }
+  #endif
+  /*--- Builtin init code ---*/
+  if (__Pyx_InitCachedBuiltins() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Constants init code ---*/
+  if (__Pyx_InitCachedConstants() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Global init code ---*/
+  __pyx_v_6pyfftw_6pyfftw_directions = Py_None; Py_INCREF(Py_None);
+  __pyx_v_6pyfftw_6pyfftw_directions_lookup = Py_None; Py_INCREF(Py_None);
+  __pyx_v_6pyfftw_6pyfftw_flag_dict = Py_None; Py_INCREF(Py_None);
+  __pyx_v_6pyfftw_6pyfftw_plan_lock = Py_None; Py_INCREF(Py_None);
+  __pyx_v_6pyfftw_6pyfftw_fftw_schemes = Py_None; Py_INCREF(Py_None);
+  __pyx_v_6pyfftw_6pyfftw_scheme_directions = Py_None; Py_INCREF(Py_None);
+  __pyx_v_6pyfftw_6pyfftw_scheme_functions = Py_None; Py_INCREF(Py_None);
+  /*--- Variable export code ---*/
+  /*--- Function export code ---*/
+  /*--- Type init code ---*/
+  __pyx_vtabptr_6pyfftw_6pyfftw_FFTW = &__pyx_vtable_6pyfftw_6pyfftw_FFTW;
+  __pyx_vtable_6pyfftw_6pyfftw_FFTW.update_arrays = (PyObject *(*)(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *, PyObject *, PyObject *, int __pyx_skip_dispatch))__pyx_f_6pyfftw_6pyfftw_4FFTW_update_arrays;
+  __pyx_vtable_6pyfftw_6pyfftw_FFTW._update_arrays = (PyObject *(*)(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *, PyArrayObject *, PyArrayObject *))__pyx_f_6pyfftw_6pyfftw_4FFTW__update_arrays;
+  __pyx_vtable_6pyfftw_6pyfftw_FFTW.execute = (PyObject *(*)(struct __pyx_obj_6pyfftw_6pyfftw_FFTW *, int __pyx_skip_dispatch))__pyx_f_6pyfftw_6pyfftw_4FFTW_execute;
+  if (PyType_Ready(&__pyx_type_6pyfftw_6pyfftw_FFTW) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_type_6pyfftw_6pyfftw_FFTW.tp_print = 0;
+  #if CYTHON_COMPILING_IN_CPYTHON
+  {
+    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_6pyfftw_6pyfftw_FFTW, "__init__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+      __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_32__init__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+      __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_32__init__.doc = __pyx_doc_6pyfftw_6pyfftw_4FFTW_32__init__;
+      ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_32__init__;
+    }
+  }
+  #endif
+  #if CYTHON_COMPILING_IN_CPYTHON
+  {
+    PyObject *wrapper = PyObject_GetAttrString((PyObject *)&__pyx_type_6pyfftw_6pyfftw_FFTW, "__call__"); if (unlikely(!wrapper)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {
+      __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_36__call__ = *((PyWrapperDescrObject *)wrapper)->d_base;
+      __pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_36__call__.doc = __pyx_doc_6pyfftw_6pyfftw_4FFTW_36__call__;
+      ((PyWrapperDescrObject *)wrapper)->d_base = &__pyx_wrapperbase_6pyfftw_6pyfftw_4FFTW_36__call__;
+    }
+  }
+  #endif
+  if (__Pyx_SetVtable(__pyx_type_6pyfftw_6pyfftw_FFTW.tp_dict, __pyx_vtabptr_6pyfftw_6pyfftw_FFTW) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyObject_SetAttrString(__pyx_m, "FFTW", (PyObject *)&__pyx_type_6pyfftw_6pyfftw_FFTW) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 597; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_6pyfftw_6pyfftw_FFTW = &__pyx_type_6pyfftw_6pyfftw_FFTW;
+  /*--- Type import code ---*/
+  __pyx_ptype_7cpython_4type_type = __Pyx_ImportType(__Pyx_BUILTIN_MODULE_NAME, "type", 
+  #if CYTHON_COMPILING_IN_PYPY
+  sizeof(PyTypeObject),
+  #else
+  sizeof(PyHeapTypeObject),
+  #endif
+  0); if (unlikely(!__pyx_ptype_7cpython_4type_type)) {__pyx_filename = __pyx_f[3]; __pyx_lineno = 9; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr), 0); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 155; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_flatiter = __Pyx_ImportType("numpy", "flatiter", sizeof(PyArrayIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_flatiter)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_broadcast = __Pyx_ImportType("numpy", "broadcast", sizeof(PyArrayMultiIterObject), 0); if (unlikely(!__pyx_ptype_5numpy_broadcast)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject), 0); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __pyx_ptype_5numpy_ufunc = __Pyx_ImportType("numpy", "ufunc", sizeof(PyUFuncObject), 0); if (unlikely(!__pyx_ptype_5numpy_ufunc)) {__pyx_filename = __pyx_f[2]; __pyx_lineno = 861; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  /*--- Variable import code ---*/
+  /*--- Function import code ---*/
+  /*--- Execution code ---*/
+  #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED)
+  if (__Pyx_patch_abc() < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  #endif
+
+  /* "pyfftw/pyfftw.pyx":35
+ * #
+ * 
+ * import numpy as np             # <<<<<<<<<<<<<<
+ * cimport numpy as np
+ * from libc.stdlib cimport calloc, malloc, free
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 35; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pyfftw/pyfftw.pyx":41
+ * from libc cimport limits
+ * 
+ * import warnings             # <<<<<<<<<<<<<<
+ * import threading
+ * 
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_warnings, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_warnings, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pyfftw/pyfftw.pyx":42
+ * 
+ * import warnings
+ * import threading             # <<<<<<<<<<<<<<
+ * 
+ * include 'utils.pxi'
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_threading, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_threading, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 42; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pyfftw/utils.pxi":41
+ * cimport cpu
+ * from libc.stdint cimport intptr_t
+ * import warnings             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+  __pyx_t_1 = __Pyx_Import(__pyx_n_s_warnings, 0, -1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_warnings, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pyfftw/utils.pxi":44
+ * 
+ * 
+ * cdef int _simd_alignment = cpu.simd_alignment()             # <<<<<<<<<<<<<<
+ * 
+ * #: The optimum SIMD alignment in bytes, found by inspecting the CPU.
+ */
+  __pyx_v_6pyfftw_6pyfftw__simd_alignment = simd_alignment();
+
+  /* "pyfftw/utils.pxi":47
+ * 
+ * #: The optimum SIMD alignment in bytes, found by inspecting the CPU.
+ * simd_alignment = _simd_alignment             # <<<<<<<<<<<<<<
+ * 
+ * #: A tuple of simd alignments that make sense for this cpu
+ */
+  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_6pyfftw_6pyfftw__simd_alignment); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_simd_alignment, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pyfftw/utils.pxi":50
+ * 
+ * #: A tuple of simd alignments that make sense for this cpu
+ * if _simd_alignment == 16:             # <<<<<<<<<<<<<<
+ *     _valid_simd_alignments = (16,)
+ * 
+ */
+  switch (__pyx_v_6pyfftw_6pyfftw__simd_alignment) {
+    case 16:
+
+    /* "pyfftw/utils.pxi":51
+ * #: A tuple of simd alignments that make sense for this cpu
+ * if _simd_alignment == 16:
+ *     _valid_simd_alignments = (16,)             # <<<<<<<<<<<<<<
+ * 
+ * elif _simd_alignment == 32:
+ */
+    if (PyDict_SetItem(__pyx_d, __pyx_n_s_valid_simd_alignments, __pyx_tuple__38) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "pyfftw/utils.pxi":50
+ * 
+ * #: A tuple of simd alignments that make sense for this cpu
+ * if _simd_alignment == 16:             # <<<<<<<<<<<<<<
+ *     _valid_simd_alignments = (16,)
+ * 
+ */
+    break;
+
+    /* "pyfftw/utils.pxi":53
+ *     _valid_simd_alignments = (16,)
+ * 
+ * elif _simd_alignment == 32:             # <<<<<<<<<<<<<<
+ *     _valid_simd_alignments = (16, 32)
+ * 
+ */
+    case 32:
+
+    /* "pyfftw/utils.pxi":54
+ * 
+ * elif _simd_alignment == 32:
+ *     _valid_simd_alignments = (16, 32)             # <<<<<<<<<<<<<<
+ * 
+ * else:
+ */
+    if (PyDict_SetItem(__pyx_d, __pyx_n_s_valid_simd_alignments, __pyx_tuple__39) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+    /* "pyfftw/utils.pxi":53
+ *     _valid_simd_alignments = (16,)
+ * 
+ * elif _simd_alignment == 32:             # <<<<<<<<<<<<<<
+ *     _valid_simd_alignments = (16, 32)
+ * 
+ */
+    break;
+    default:
+
+    /* "pyfftw/utils.pxi":57
+ * 
+ * else:
+ *     _valid_simd_alignments = ()             # <<<<<<<<<<<<<<
+ * 
+ * cpdef n_byte_align_empty(shape, n, dtype='float64', order='C'):
+ */
+    if (PyDict_SetItem(__pyx_d, __pyx_n_s_valid_simd_alignments, __pyx_empty_tuple) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    break;
+  }
+
+  /* "pyfftw/pyfftw.pyx":50
+ * 
+ * cdef object directions
+ * directions = {'FFTW_FORWARD': FFTW_FORWARD,             # <<<<<<<<<<<<<<
+ *         'FFTW_BACKWARD': FFTW_BACKWARD}
+ * 
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_e_6pyfftw_6pyfftw_FFTW_FORWARD); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_FFTW_FORWARD, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":51
+ * cdef object directions
+ * directions = {'FFTW_FORWARD': FFTW_FORWARD,
+ *         'FFTW_BACKWARD': FFTW_BACKWARD}             # <<<<<<<<<<<<<<
+ * 
+ * cdef object directions_lookup
+ */
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_e_6pyfftw_6pyfftw_FFTW_BACKWARD); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_FFTW_BACKWARD, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_directions);
+  __Pyx_DECREF_SET(__pyx_v_6pyfftw_6pyfftw_directions, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "pyfftw/pyfftw.pyx":54
+ * 
+ * cdef object directions_lookup
+ * directions_lookup = {FFTW_FORWARD: 'FFTW_FORWARD',             # <<<<<<<<<<<<<<
+ *         FFTW_BACKWARD: 'FFTW_BACKWARD'}
+ * 
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_e_6pyfftw_6pyfftw_FFTW_FORWARD); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_t_2, __pyx_n_s_FFTW_FORWARD) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":55
+ * cdef object directions_lookup
+ * directions_lookup = {FFTW_FORWARD: 'FFTW_FORWARD',
+ *         FFTW_BACKWARD: 'FFTW_BACKWARD'}             # <<<<<<<<<<<<<<
+ * 
+ * cdef object flag_dict
+ */
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_e_6pyfftw_6pyfftw_FFTW_BACKWARD); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_t_2, __pyx_n_s_FFTW_BACKWARD) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_directions_lookup);
+  __Pyx_DECREF_SET(__pyx_v_6pyfftw_6pyfftw_directions_lookup, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "pyfftw/pyfftw.pyx":58
+ * 
+ * cdef object flag_dict
+ * flag_dict = {'FFTW_MEASURE': FFTW_MEASURE,             # <<<<<<<<<<<<<<
+ *         'FFTW_EXHAUSTIVE': FFTW_EXHAUSTIVE,
+ *         'FFTW_PATIENT': FFTW_PATIENT,
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_e_6pyfftw_6pyfftw_FFTW_MEASURE); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_FFTW_MEASURE, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":59
+ * cdef object flag_dict
+ * flag_dict = {'FFTW_MEASURE': FFTW_MEASURE,
+ *         'FFTW_EXHAUSTIVE': FFTW_EXHAUSTIVE,             # <<<<<<<<<<<<<<
+ *         'FFTW_PATIENT': FFTW_PATIENT,
+ *         'FFTW_ESTIMATE': FFTW_ESTIMATE,
+ */
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_e_6pyfftw_6pyfftw_FFTW_EXHAUSTIVE); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_FFTW_EXHAUSTIVE, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":60
+ * flag_dict = {'FFTW_MEASURE': FFTW_MEASURE,
+ *         'FFTW_EXHAUSTIVE': FFTW_EXHAUSTIVE,
+ *         'FFTW_PATIENT': FFTW_PATIENT,             # <<<<<<<<<<<<<<
+ *         'FFTW_ESTIMATE': FFTW_ESTIMATE,
+ *         'FFTW_UNALIGNED': FFTW_UNALIGNED,
+ */
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_e_6pyfftw_6pyfftw_FFTW_PATIENT); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_FFTW_PATIENT, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":61
+ *         'FFTW_EXHAUSTIVE': FFTW_EXHAUSTIVE,
+ *         'FFTW_PATIENT': FFTW_PATIENT,
+ *         'FFTW_ESTIMATE': FFTW_ESTIMATE,             # <<<<<<<<<<<<<<
+ *         'FFTW_UNALIGNED': FFTW_UNALIGNED,
+ *         'FFTW_DESTROY_INPUT': FFTW_DESTROY_INPUT,
+ */
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_e_6pyfftw_6pyfftw_FFTW_ESTIMATE); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_FFTW_ESTIMATE, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":62
+ *         'FFTW_PATIENT': FFTW_PATIENT,
+ *         'FFTW_ESTIMATE': FFTW_ESTIMATE,
+ *         'FFTW_UNALIGNED': FFTW_UNALIGNED,             # <<<<<<<<<<<<<<
+ *         'FFTW_DESTROY_INPUT': FFTW_DESTROY_INPUT,
+ *         'FFTW_WISDOM_ONLY': FFTW_WISDOM_ONLY}
+ */
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_e_6pyfftw_6pyfftw_FFTW_UNALIGNED); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_FFTW_UNALIGNED, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":63
+ *         'FFTW_ESTIMATE': FFTW_ESTIMATE,
+ *         'FFTW_UNALIGNED': FFTW_UNALIGNED,
+ *         'FFTW_DESTROY_INPUT': FFTW_DESTROY_INPUT,             # <<<<<<<<<<<<<<
+ *         'FFTW_WISDOM_ONLY': FFTW_WISDOM_ONLY}
+ * 
+ */
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_e_6pyfftw_6pyfftw_FFTW_DESTROY_INPUT); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_FFTW_DESTROY_INPUT, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":64
+ *         'FFTW_UNALIGNED': FFTW_UNALIGNED,
+ *         'FFTW_DESTROY_INPUT': FFTW_DESTROY_INPUT,
+ *         'FFTW_WISDOM_ONLY': FFTW_WISDOM_ONLY}             # <<<<<<<<<<<<<<
+ * 
+ * _flag_dict = flag_dict.copy()
+ */
+  __pyx_t_2 = __Pyx_PyInt_From_int(__pyx_e_6pyfftw_6pyfftw_FFTW_WISDOM_ONLY); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_FFTW_WISDOM_ONLY, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_flag_dict);
+  __Pyx_DECREF_SET(__pyx_v_6pyfftw_6pyfftw_flag_dict, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "pyfftw/pyfftw.pyx":66
+ *         'FFTW_WISDOM_ONLY': FFTW_WISDOM_ONLY}
+ * 
+ * _flag_dict = flag_dict.copy()             # <<<<<<<<<<<<<<
+ * 
+ * # Need a global lock to protect FFTW planning so that multiple Python threads
+ */
+  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_6pyfftw_6pyfftw_flag_dict, __pyx_n_s_copy); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_2))) {
+    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
+    if (likely(__pyx_t_3)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
+      __Pyx_INCREF(__pyx_t_3);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_2, function);
+    }
+  }
+  if (__pyx_t_3) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  } else {
+    __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_flag_dict, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 66; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pyfftw/pyfftw.pyx":70
+ * # Need a global lock to protect FFTW planning so that multiple Python threads
+ * # do not attempt to plan simultaneously.
+ * cdef object plan_lock = threading.Lock()             # <<<<<<<<<<<<<<
+ * 
+ * # Function wrappers
+ */
+  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_threading); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_Lock); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  __pyx_t_2 = NULL;
+  if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_3))) {
+    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
+    if (likely(__pyx_t_2)) {
+      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+      __Pyx_INCREF(__pyx_t_2);
+      __Pyx_INCREF(function);
+      __Pyx_DECREF_SET(__pyx_t_3, function);
+    }
+  }
+  if (__pyx_t_2) {
+    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  } else {
+    __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  }
+  __Pyx_GOTREF(__pyx_t_1);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_plan_lock);
+  __Pyx_DECREF_SET(__pyx_v_6pyfftw_6pyfftw_plan_lock, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "pyfftw/pyfftw.pyx":408
+ * # Shape lookup functions
+ * # ======================
+ * def _lookup_shape_r2c_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
+ *     return input_array.shape
+ * 
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6pyfftw_6pyfftw_17_lookup_shape_r2c_arrays, NULL, __pyx_n_s_pyfftw_pyfftw); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_lookup_shape_r2c_arrays, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 408; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pyfftw/pyfftw.pyx":411
+ *     return input_array.shape
+ * 
+ * def _lookup_shape_c2r_arrays(input_array, output_array):             # <<<<<<<<<<<<<<
+ *     return output_array.shape
+ * 
+ */
+  __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_6pyfftw_6pyfftw_19_lookup_shape_c2r_arrays, NULL, __pyx_n_s_pyfftw_pyfftw); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_lookup_shape_c2r_arrays, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 411; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+
+  /* "pyfftw/pyfftw.pyx":446
+ * cdef object fftw_schemes
+ * fftw_schemes = {
+ *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
+ *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
+ */
+  __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__44, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__45, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+  __pyx_t_3 = 0;
+  __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_t_1, __pyx_t_4, __pyx_tuple__46) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "pyfftw/pyfftw.pyx":447
+ * fftw_schemes = {
+ *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),
+ *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
+ *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
+ */
+  __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__47, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__48, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+  __pyx_t_4 = 0;
+  __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_t_1, __pyx_t_3, __pyx_tuple__49) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":448
+ *         (np.dtype('complex128'), np.dtype('complex128')): ('c2c', '64'),
+ *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
+ *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
+ *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
+ */
+  __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__50, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__51, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 448; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+  __pyx_t_3 = 0;
+  __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_t_1, __pyx_t_4, __pyx_tuple__52) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "pyfftw/pyfftw.pyx":449
+ *         (np.dtype('complex64'), np.dtype('complex64')): ('c2c', '32'),
+ *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
+ *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
+ *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
+ */
+  __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__53, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__54, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+  __pyx_t_4 = 0;
+  __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_t_1, __pyx_t_3, __pyx_tuple__55) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":450
+ *         (np.dtype('float64'), np.dtype('complex128')): ('r2c', '64'),
+ *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
+ *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
+ * 
+ */
+  __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__56, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__57, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_3);
+  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_2);
+  __pyx_t_3 = 0;
+  __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_t_1, __pyx_t_4, __pyx_tuple__58) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+  /* "pyfftw/pyfftw.pyx":451
+ *         (np.dtype('float32'), np.dtype('complex64')): ('r2c', '32'),
+ *         (np.dtype('complex128'), np.dtype('float64')): ('c2r', '64'),
+ *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}             # <<<<<<<<<<<<<<
+ * 
+ * if np.dtype('longdouble') != np.dtype('float64'):
+ */
+  __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__59, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_4);
+  __pyx_t_2 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__60, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 451; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_4);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
+  __pyx_t_4 = 0;
+  __pyx_t_2 = 0;
+  if (PyDict_SetItem(__pyx_t_1, __pyx_t_3, __pyx_tuple__61) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 446; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_fftw_schemes);
+  __Pyx_DECREF_SET(__pyx_v_6pyfftw_6pyfftw_fftw_schemes, __pyx_t_1);
+  __Pyx_GIVEREF(__pyx_t_1);
+  __pyx_t_1 = 0;
+
+  /* "pyfftw/pyfftw.pyx":453
+ *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
+ * 
+ * if np.dtype('longdouble') != np.dtype('float64'):             # <<<<<<<<<<<<<<
+ *     fftw_schemes.update({
+ *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
+ */
+  __pyx_t_1 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__62, NULL); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_1);
+  __pyx_t_3 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__63, NULL); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __pyx_t_2 = PyObject_RichCompare(__pyx_t_1, __pyx_t_3, Py_NE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 453; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  if (__pyx_t_5) {
+
+    /* "pyfftw/pyfftw.pyx":454
+ * 
+ * if np.dtype('longdouble') != np.dtype('float64'):
+ *     fftw_schemes.update({             # <<<<<<<<<<<<<<
+ *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
+ *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),
+ */
+    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_6pyfftw_6pyfftw_fftw_schemes, __pyx_n_s_update); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_3);
+
+    /* "pyfftw/pyfftw.pyx":455
+ * if np.dtype('longdouble') != np.dtype('float64'):
+ *     fftw_schemes.update({
+ *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),
+ *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})
+ */
+    __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_1);
+    __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__64, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__65, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_6);
+    __pyx_t_4 = 0;
+    __pyx_t_6 = 0;
+    if (PyDict_SetItem(__pyx_t_1, __pyx_t_7, __pyx_tuple__66) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+
+    /* "pyfftw/pyfftw.pyx":456
+ *     fftw_schemes.update({
+ *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
+ *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),             # <<<<<<<<<<<<<<
+ *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})
+ * 
+ */
+    __pyx_t_7 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__67, NULL); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__68, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_7);
+    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_6);
+    __pyx_t_7 = 0;
+    __pyx_t_6 = 0;
+    if (PyDict_SetItem(__pyx_t_1, __pyx_t_4, __pyx_tuple__69) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+
+    /* "pyfftw/pyfftw.pyx":457
+ *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
+ *         (np.dtype('longdouble'), np.dtype('clongdouble')): ('r2c', 'ld'),
+ *         (np.dtype('clongdouble'), np.dtype('longdouble')): ('c2r', 'ld')})             # <<<<<<<<<<<<<<
+ * 
+ * 
+ */
+    __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__70, NULL); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_4);
+    __pyx_t_6 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5numpy_dtype), __pyx_tuple__71, NULL); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_6);
+    __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_GOTREF(__pyx_t_7);
+    __Pyx_GIVEREF(__pyx_t_4);
+    PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4);
+    __Pyx_GIVEREF(__pyx_t_6);
+    PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_6);
+    __pyx_t_4 = 0;
+    __pyx_t_6 = 0;
+    if (PyDict_SetItem(__pyx_t_1, __pyx_t_7, __pyx_tuple__72) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
+    __pyx_t_7 = NULL;
+    if (CYTHON_COMPILING_IN_CPYTHON && likely(PyMethod_Check(__pyx_t_3))) {
+      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_3);
+      if (likely(__pyx_t_7)) {
+        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
+        __Pyx_INCREF(__pyx_t_7);
+        __Pyx_INCREF(function);
+        __Pyx_DECREF_SET(__pyx_t_3, function);
+      }
+    }
+    if (!__pyx_t_7) {
+      __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_t_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+      __Pyx_GOTREF(__pyx_t_2);
+    } else {
+      __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_6);
+      __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7); __pyx_t_7 = NULL;
+      __Pyx_GIVEREF(__pyx_t_1);
+      PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_1);
+      __pyx_t_1 = 0;
+      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 454; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+      __Pyx_GOTREF(__pyx_t_2);
+      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+    }
+    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+    /* "pyfftw/pyfftw.pyx":453
+ *         (np.dtype('complex64'), np.dtype('float32')): ('c2r', '32')}
+ * 
+ * if np.dtype('longdouble') != np.dtype('float64'):             # <<<<<<<<<<<<<<
+ *     fftw_schemes.update({
+ *         (np.dtype('clongdouble'), np.dtype('clongdouble')): ('c2c', 'ld'),
+ */
+  }
+
+  /* "pyfftw/pyfftw.pyx":462
+ * cdef object scheme_directions
+ * scheme_directions = {
+ *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
+ *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyList_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_n_s_FFTW_FORWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_FORWARD);
+  PyList_SET_ITEM(__pyx_t_3, 0, __pyx_n_s_FFTW_FORWARD);
+  __Pyx_INCREF(__pyx_n_s_FFTW_BACKWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_BACKWARD);
+  PyList_SET_ITEM(__pyx_t_3, 1, __pyx_n_s_FFTW_BACKWARD);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__73, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":463
+ * scheme_directions = {
+ *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
+ *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('r2c', '64'): ['FFTW_FORWARD'],
+ */
+  __pyx_t_3 = PyList_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_n_s_FFTW_FORWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_FORWARD);
+  PyList_SET_ITEM(__pyx_t_3, 0, __pyx_n_s_FFTW_FORWARD);
+  __Pyx_INCREF(__pyx_n_s_FFTW_BACKWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_BACKWARD);
+  PyList_SET_ITEM(__pyx_t_3, 1, __pyx_n_s_FFTW_BACKWARD);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__74, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":464
+ *         ('c2c', '64'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
+ *         ('r2c', '64'): ['FFTW_FORWARD'],
+ *         ('r2c', '32'): ['FFTW_FORWARD'],
+ */
+  __pyx_t_3 = PyList_New(2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 464; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_n_s_FFTW_FORWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_FORWARD);
+  PyList_SET_ITEM(__pyx_t_3, 0, __pyx_n_s_FFTW_FORWARD);
+  __Pyx_INCREF(__pyx_n_s_FFTW_BACKWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_BACKWARD);
+  PyList_SET_ITEM(__pyx_t_3, 1, __pyx_n_s_FFTW_BACKWARD);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__75, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":465
+ *         ('c2c', '32'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('r2c', '64'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
+ *         ('r2c', '32'): ['FFTW_FORWARD'],
+ *         ('r2c', 'ld'): ['FFTW_FORWARD'],
+ */
+  __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 465; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_n_s_FFTW_FORWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_FORWARD);
+  PyList_SET_ITEM(__pyx_t_3, 0, __pyx_n_s_FFTW_FORWARD);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__76, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":466
+ *         ('c2c', 'ld'): ['FFTW_FORWARD', 'FFTW_BACKWARD'],
+ *         ('r2c', '64'): ['FFTW_FORWARD'],
+ *         ('r2c', '32'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
+ *         ('r2c', 'ld'): ['FFTW_FORWARD'],
+ *         ('c2r', '64'): ['FFTW_BACKWARD'],
+ */
+  __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_n_s_FFTW_FORWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_FORWARD);
+  PyList_SET_ITEM(__pyx_t_3, 0, __pyx_n_s_FFTW_FORWARD);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__77, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":467
+ *         ('r2c', '64'): ['FFTW_FORWARD'],
+ *         ('r2c', '32'): ['FFTW_FORWARD'],
+ *         ('r2c', 'ld'): ['FFTW_FORWARD'],             # <<<<<<<<<<<<<<
+ *         ('c2r', '64'): ['FFTW_BACKWARD'],
+ *         ('c2r', '32'): ['FFTW_BACKWARD'],
+ */
+  __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_n_s_FFTW_FORWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_FORWARD);
+  PyList_SET_ITEM(__pyx_t_3, 0, __pyx_n_s_FFTW_FORWARD);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__78, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":468
+ *         ('r2c', '32'): ['FFTW_FORWARD'],
+ *         ('r2c', 'ld'): ['FFTW_FORWARD'],
+ *         ('c2r', '64'): ['FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
+ *         ('c2r', '32'): ['FFTW_BACKWARD'],
+ *         ('c2r', 'ld'): ['FFTW_BACKWARD']}
+ */
+  __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 468; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_n_s_FFTW_BACKWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_BACKWARD);
+  PyList_SET_ITEM(__pyx_t_3, 0, __pyx_n_s_FFTW_BACKWARD);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__79, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":469
+ *         ('r2c', 'ld'): ['FFTW_FORWARD'],
+ *         ('c2r', '64'): ['FFTW_BACKWARD'],
+ *         ('c2r', '32'): ['FFTW_BACKWARD'],             # <<<<<<<<<<<<<<
+ *         ('c2r', 'ld'): ['FFTW_BACKWARD']}
+ * 
+ */
+  __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 469; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_n_s_FFTW_BACKWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_BACKWARD);
+  PyList_SET_ITEM(__pyx_t_3, 0, __pyx_n_s_FFTW_BACKWARD);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__80, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":470
+ *         ('c2r', '64'): ['FFTW_BACKWARD'],
+ *         ('c2r', '32'): ['FFTW_BACKWARD'],
+ *         ('c2r', 'ld'): ['FFTW_BACKWARD']}             # <<<<<<<<<<<<<<
+ * 
+ * # In the following, -1 denotes using the default. A segfault has been
+ */
+  __pyx_t_3 = PyList_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 470; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_INCREF(__pyx_n_s_FFTW_BACKWARD);
+  __Pyx_GIVEREF(__pyx_n_s_FFTW_BACKWARD);
+  PyList_SET_ITEM(__pyx_t_3, 0, __pyx_n_s_FFTW_BACKWARD);
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__81, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 462; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_scheme_directions);
+  __Pyx_DECREF_SET(__pyx_v_6pyfftw_6pyfftw_scheme_directions, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":478
+ * cdef object scheme_functions
+ * scheme_functions = {
+ *     ('c2c', '64'): {'planner': 0, 'executor':0, 'generic_precision':0,             # <<<<<<<<<<<<<<
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_planner, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_executor, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_generic_precision, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_validator, __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_fft_shape_lookup, __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__82, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":480
+ *     ('c2c', '64'): {'planner': 0, 'executor':0, 'generic_precision':0,
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,             # <<<<<<<<<<<<<<
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,
+ */
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_planner, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_executor, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_generic_precision, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_validator, __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_fft_shape_lookup, __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 480; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__83, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":482
+ *     ('c2c', '32'): {'planner':1, 'executor':1, 'generic_precision':1,
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,             # <<<<<<<<<<<<<<
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('r2c', '64'): {'planner':3, 'executor':3, 'generic_precision':0,
+ */
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_planner, __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_executor, __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_generic_precision, __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_validator, __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_fft_shape_lookup, __pyx_int_neg_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__84, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":484
+ *     ('c2c', 'ld'): {'planner':2, 'executor':2, 'generic_precision':2,
+ *         'validator': -1, 'fft_shape_lookup': -1},
+ *     ('r2c', '64'): {'planner':3, 'executor':3, 'generic_precision':0,             # <<<<<<<<<<<<<<
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ */
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_planner, __pyx_int_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_executor, __pyx_int_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_generic_precision, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_validator, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "pyfftw/pyfftw.pyx":486
+ *     ('r2c', '64'): {'planner':3, 'executor':3, 'generic_precision':0,
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},             # <<<<<<<<<<<<<<
+ *     ('r2c', '32'): {'planner':4, 'executor':4, 'generic_precision':1,
+ *         'validator': 0,
+ */
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_lookup_shape_r2c_arrays); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_fft_shape_lookup, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 484; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__85, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":487
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ *     ('r2c', '32'): {'planner':4, 'executor':4, 'generic_precision':1,             # <<<<<<<<<<<<<<
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ */
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_planner, __pyx_int_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_executor, __pyx_int_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_generic_precision, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_validator, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "pyfftw/pyfftw.pyx":489
+ *     ('r2c', '32'): {'planner':4, 'executor':4, 'generic_precision':1,
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},             # <<<<<<<<<<<<<<
+ *     ('r2c', 'ld'): {'planner':5, 'executor':5, 'generic_precision':2,
+ *         'validator': 0,
+ */
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_lookup_shape_r2c_arrays); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 489; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_fft_shape_lookup, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__86, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":490
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ *     ('r2c', 'ld'): {'planner':5, 'executor':5, 'generic_precision':2,             # <<<<<<<<<<<<<<
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ */
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_planner, __pyx_int_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_executor, __pyx_int_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_generic_precision, __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_validator, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "pyfftw/pyfftw.pyx":492
+ *     ('r2c', 'ld'): {'planner':5, 'executor':5, 'generic_precision':2,
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},             # <<<<<<<<<<<<<<
+ *     ('c2r', '64'): {'planner':6, 'executor':6, 'generic_precision':0,
+ *         'validator': 1,
+ */
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_lookup_shape_r2c_arrays); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_fft_shape_lookup, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 490; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__87, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":493
+ *         'validator': 0,
+ *         'fft_shape_lookup': _lookup_shape_r2c_arrays},
+ *     ('c2r', '64'): {'planner':6, 'executor':6, 'generic_precision':0,             # <<<<<<<<<<<<<<
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
+ */
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_planner, __pyx_int_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_executor, __pyx_int_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_generic_precision, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_validator, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "pyfftw/pyfftw.pyx":495
+ *     ('c2r', '64'): {'planner':6, 'executor':6, 'generic_precision':0,
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays},             # <<<<<<<<<<<<<<
+ *     ('c2r', '32'): {'planner':7, 'executor':7, 'generic_precision':1,
+ *         'validator': 1,
+ */
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_lookup_shape_c2r_arrays); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_fft_shape_lookup, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__88, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":496
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
+ *     ('c2r', '32'): {'planner':7, 'executor':7, 'generic_precision':1,             # <<<<<<<<<<<<<<
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
+ */
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_planner, __pyx_int_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_executor, __pyx_int_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_generic_precision, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_validator, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "pyfftw/pyfftw.pyx":498
+ *     ('c2r', '32'): {'planner':7, 'executor':7, 'generic_precision':1,
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays},             # <<<<<<<<<<<<<<
+ *     ('c2r', 'ld'): {'planner':8, 'executor':8, 'generic_precision':2,
+ *         'validator': 1,
+ */
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_lookup_shape_c2r_arrays); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 498; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_fft_shape_lookup, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 496; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__89, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+
+  /* "pyfftw/pyfftw.pyx":499
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays},
+ *     ('c2r', 'ld'): {'planner':8, 'executor':8, 'generic_precision':2,             # <<<<<<<<<<<<<<
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays}}
+ */
+  __pyx_t_3 = PyDict_New(); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_planner, __pyx_int_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_executor, __pyx_int_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_generic_precision, __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_validator, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+
+  /* "pyfftw/pyfftw.pyx":501
+ *     ('c2r', 'ld'): {'planner':8, 'executor':8, 'generic_precision':2,
+ *         'validator': 1,
+ *         'fft_shape_lookup': _lookup_shape_c2r_arrays}}             # <<<<<<<<<<<<<<
+ * 
+ * # Initialize the module
+ */
+  __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_lookup_shape_c2r_arrays); if (unlikely(!__pyx_t_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_6);
+  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_fft_shape_lookup, __pyx_t_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
+  if (PyDict_SetItem(__pyx_t_2, __pyx_tuple__90, __pyx_t_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 478; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  __Pyx_XGOTREF(__pyx_v_6pyfftw_6pyfftw_scheme_functions);
+  __Pyx_DECREF_SET(__pyx_v_6pyfftw_6pyfftw_scheme_functions, __pyx_t_2);
+  __Pyx_GIVEREF(__pyx_t_2);
+  __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":506
+ * 
+ * # Define the functions
+ * _build_planner_list()             # <<<<<<<<<<<<<<
+ * _build_destroyer_list()
+ * _build_executor_list()
+ */
+  __pyx_f_6pyfftw_6pyfftw__build_planner_list();
+
+  /* "pyfftw/pyfftw.pyx":507
+ * # Define the functions
+ * _build_planner_list()
+ * _build_destroyer_list()             # <<<<<<<<<<<<<<
+ * _build_executor_list()
+ * _build_nthreads_plan_setters_list()
+ */
+  __pyx_f_6pyfftw_6pyfftw__build_destroyer_list();
+
+  /* "pyfftw/pyfftw.pyx":508
+ * _build_planner_list()
+ * _build_destroyer_list()
+ * _build_executor_list()             # <<<<<<<<<<<<<<
+ * _build_nthreads_plan_setters_list()
+ * _build_validators_list()
+ */
+  __pyx_f_6pyfftw_6pyfftw__build_executor_list();
+
+  /* "pyfftw/pyfftw.pyx":509
+ * _build_destroyer_list()
+ * _build_executor_list()
+ * _build_nthreads_plan_setters_list()             # <<<<<<<<<<<<<<
+ * _build_validators_list()
+ * _build_set_timelimit_funcs_list()
+ */
+  __pyx_f_6pyfftw_6pyfftw__build_nthreads_plan_setters_list();
+
+  /* "pyfftw/pyfftw.pyx":510
+ * _build_executor_list()
+ * _build_nthreads_plan_setters_list()
+ * _build_validators_list()             # <<<<<<<<<<<<<<
+ * _build_set_timelimit_funcs_list()
+ * 
+ */
+  __pyx_f_6pyfftw_6pyfftw__build_validators_list();
+
+  /* "pyfftw/pyfftw.pyx":511
+ * _build_nthreads_plan_setters_list()
+ * _build_validators_list()
+ * _build_set_timelimit_funcs_list()             # <<<<<<<<<<<<<<
+ * 
+ * fftw_init_threads()
+ */
+  __pyx_f_6pyfftw_6pyfftw__build_set_timelimit_funcs_list();
+
+  /* "pyfftw/pyfftw.pyx":513
+ * _build_set_timelimit_funcs_list()
+ * 
+ * fftw_init_threads()             # <<<<<<<<<<<<<<
+ * fftwf_init_threads()
+ * fftwl_init_threads()
+ */
+  fftw_init_threads();
+
+  /* "pyfftw/pyfftw.pyx":514
+ * 
+ * fftw_init_threads()
+ * fftwf_init_threads()             # <<<<<<<<<<<<<<
+ * fftwl_init_threads()
+ * 
+ */
+  fftwf_init_threads();
+
+  /* "pyfftw/pyfftw.pyx":515
+ * fftw_init_threads()
+ * fftwf_init_threads()
+ * fftwl_init_threads()             # <<<<<<<<<<<<<<
+ * 
+ * # Set the cleanup routine
+ */
+  fftwl_init_threads();
+
+  /* "pyfftw/pyfftw.pyx":526
+ *     fftwl_cleanup_threads()
+ * 
+ * Py_AtExit(_cleanup)             # <<<<<<<<<<<<<<
+ * 
+ * # Helper functions
+ */
+  Py_AtExit(__pyx_f_6pyfftw_6pyfftw__cleanup);
+
+  /* "pyfftw/pyfftw.pyx":675
+ *         return self._N
+ * 
+ *     N = property(_get_N)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_simd_aligned(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_N); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 675; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 675; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 675; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_N, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 675; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":684
+ *         return self._simd_allowed
+ * 
+ *     simd_aligned = property(_get_simd_aligned)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_input_alignment(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_simd_aligned); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 684; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 684; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 684; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_simd_aligned, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 684; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":698
+ *         return self._input_array_alignment
+ * 
+ *     input_alignment = property(_get_input_alignment)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_output_alignment(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_input_alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_input_alignment, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":710
+ *         return self._output_array_alignment
+ * 
+ *     output_alignment = property(_get_output_alignment)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_flags_used(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_output_alignment); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_output_alignment, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 710; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":720
+ *         return tuple(self._flags_used)
+ * 
+ *     flags = property(_get_flags_used)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_input_array(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_flags_used); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_flags, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":729
+ *         return self._input_array
+ * 
+ *     input_array = property(_get_input_array)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_output_array(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_input_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_input_array, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":738
+ *         return self._output_array
+ * 
+ *     output_array = property(_get_output_array)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_input_strides(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_output_array); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_output_array, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 738; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":746
+ *         return self._input_strides
+ * 
+ *     input_strides = property(_get_input_strides)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_output_strides(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_input_strides); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_input_strides, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 746; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":754
+ *         return self._output_strides
+ * 
+ *     output_strides = property(_get_output_strides)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_input_shape(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_output_strides); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 754; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 754; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 754; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_output_strides, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 754; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":762
+ *         return self._input_shape
+ * 
+ *     input_shape = property(_get_input_shape)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_output_shape(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_input_shape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_input_shape, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 762; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":770
+ *         return self._output_shape
+ * 
+ *     output_shape = property(_get_output_shape)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_input_dtype(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_output_shape); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_output_shape, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 770; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":778
+ *         return self._input_dtype
+ * 
+ *     input_dtype = property(_get_input_dtype)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_output_dtype(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_input_dtype); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_input_dtype, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 778; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":786
+ *         return self._output_dtype
+ * 
+ *     output_dtype = property(_get_output_dtype)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_direction(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_output_dtype); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 786; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 786; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 786; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_output_dtype, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 786; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":795
+ *         return directions_lookup[self._direction]
+ * 
+ *     direction = property(_get_direction)             # <<<<<<<<<<<<<<
+ * 
+ *     def _get_axes(self):
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_direction); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_direction, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 795; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":809
+ *         return tuple(axes)
+ * 
+ *     axes = property(_get_axes)             # <<<<<<<<<<<<<<
+ * 
+ *     def __cinit__(self, input_array, output_array, axes=(-1,),
+ */
+  __pyx_t_2 = __Pyx_GetNameInClass((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW, __pyx_n_s_get_axes); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __pyx_t_3 = PyTuple_New(1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_3);
+  __Pyx_GIVEREF(__pyx_t_2);
+  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_2);
+  __pyx_t_2 = 0;
+  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_builtin_property, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+  if (PyDict_SetItem((PyObject *)__pyx_ptype_6pyfftw_6pyfftw_FFTW->tp_dict, __pyx_n_s_axes, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 809; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+  PyType_Modified(__pyx_ptype_6pyfftw_6pyfftw_FFTW);
+
+  /* "pyfftw/pyfftw.pyx":1614
+ * 
+ * 
+ * def export_wisdom():             # <<<<<<<<<<<<<<
+ *     '''export_wisdom()
+ * 
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_6pyfftw_6pyfftw_21export_wisdom, NULL, __pyx_n_s_pyfftw_pyfftw); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_export_wisdom, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1614; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":1673
+ *     return (py_wisdom, py_wisdomf, py_wisdoml)
+ * 
+ * def import_wisdom(wisdom):             # <<<<<<<<<<<<<<
+ *     '''import_wisdom(wisdom)
+ * 
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_6pyfftw_6pyfftw_23import_wisdom, NULL, __pyx_n_s_pyfftw_pyfftw); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_import_wisdom, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1673; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":1789
+ * #    return (success, successf, successl)
+ * 
+ * def forget_wisdom():             # <<<<<<<<<<<<<<
+ *     '''forget_wisdom()
+ * 
+ */
+  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_6pyfftw_6pyfftw_25forget_wisdom, NULL, __pyx_n_s_pyfftw_pyfftw); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_forget_wisdom, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1789; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "pyfftw/pyfftw.pyx":1
+ * # Copyright 2015 Knowledge Economy Developments Ltd             # <<<<<<<<<<<<<<
+ * #
+ * # Henry Gomersall
+ */
+  __pyx_t_2 = PyDict_New(); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_GOTREF(__pyx_t_2);
+  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
+  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+
+  /* "../../../../../usr/lib/python2.7/dist-packages/Cython/Includes/numpy/__init__.pxd":976
+ *      arr.base = baseptr
+ * 
+ * cdef inline object get_array_base(ndarray arr):             # <<<<<<<<<<<<<<
+ *     if arr.base is NULL:
+ *         return None
+ */
+
+  /*--- Wrapped vars code ---*/
+
+  goto __pyx_L0;
+  __pyx_L1_error:;
+  __Pyx_XDECREF(__pyx_t_1);
+  __Pyx_XDECREF(__pyx_t_2);
+  __Pyx_XDECREF(__pyx_t_3);
+  __Pyx_XDECREF(__pyx_t_4);
+  __Pyx_XDECREF(__pyx_t_6);
+  __Pyx_XDECREF(__pyx_t_7);
+  if (__pyx_m) {
+    if (__pyx_d) {
+      __Pyx_AddTraceback("init pyfftw.pyfftw", __pyx_clineno, __pyx_lineno, __pyx_filename);
+    }
+    Py_DECREF(__pyx_m); __pyx_m = 0;
+  } else if (!PyErr_Occurred()) {
+    PyErr_SetString(PyExc_ImportError, "init pyfftw.pyfftw");
+  }
+  __pyx_L0:;
+  __Pyx_RefNannyFinishContext();
+  #if PY_MAJOR_VERSION < 3
+  return;
+  #else
+  return __pyx_m;
+  #endif
+}
+
+/* --- Runtime support code --- */
+#if CYTHON_REFNANNY
+static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
+    PyObject *m = NULL, *p = NULL;
+    void *r = NULL;
+    m = PyImport_ImportModule((char *)modname);
+    if (!m) goto end;
+    p = PyObject_GetAttrString(m, (char *)"RefNannyAPI");
+    if (!p) goto end;
+    r = PyLong_AsVoidPtr(p);
+end:
+    Py_XDECREF(p);
+    Py_XDECREF(m);
+    return (__Pyx_RefNannyAPIStruct *)r;
+}
+#endif
+
+static PyObject *__Pyx_GetBuiltinName(PyObject *name) {
+    PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name);
+    if (unlikely(!result)) {
+        PyErr_Format(PyExc_NameError,
+#if PY_MAJOR_VERSION >= 3
+            "name '%U' is not defined", name);
+#else
+            "name '%.200s' is not defined", PyString_AS_STRING(name));
+#endif
+    }
+    return result;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
+    PyObject *result;
+#if CYTHON_COMPILING_IN_CPYTHON
+    result = PyDict_GetItem(__pyx_d, name);
+    if (likely(result)) {
+        Py_INCREF(result);
+    } else {
+#else
+    result = PyObject_GetItem(__pyx_d, name);
+    if (!result) {
+        PyErr_Clear();
+#endif
+        result = __Pyx_GetBuiltinName(name);
+    }
+    return result;
+}
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) {
+    PyObject *result;
+    ternaryfunc call = func->ob_type->tp_call;
+    if (unlikely(!call))
+        return PyObject_Call(func, arg, kw);
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+        return NULL;
+    result = (*call)(func, arg, kw);
+    Py_LeaveRecursiveCall();
+    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+        PyErr_SetString(
+            PyExc_SystemError,
+            "NULL result without error in PyObject_Call");
+    }
+    return result;
+}
+#endif
+
+static void __Pyx_RaiseArgtupleInvalid(
+    const char* func_name,
+    int exact,
+    Py_ssize_t num_min,
+    Py_ssize_t num_max,
+    Py_ssize_t num_found)
+{
+    Py_ssize_t num_expected;
+    const char *more_or_less;
+    if (num_found < num_min) {
+        num_expected = num_min;
+        more_or_less = "at least";
+    } else {
+        num_expected = num_max;
+        more_or_less = "at most";
+    }
+    if (exact) {
+        more_or_less = "exactly";
+    }
+    PyErr_Format(PyExc_TypeError,
+                 "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)",
+                 func_name, more_or_less, num_expected,
+                 (num_expected == 1) ? "" : "s", num_found);
+}
+
+static void __Pyx_RaiseDoubleKeywordsError(
+    const char* func_name,
+    PyObject* kw_name)
+{
+    PyErr_Format(PyExc_TypeError,
+        #if PY_MAJOR_VERSION >= 3
+        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
+        #else
+        "%s() got multiple values for keyword argument '%s'", func_name,
+        PyString_AsString(kw_name));
+        #endif
+}
+
+static int __Pyx_ParseOptionalKeywords(
+    PyObject *kwds,
+    PyObject **argnames[],
+    PyObject *kwds2,
+    PyObject *values[],
+    Py_ssize_t num_pos_args,
+    const char* function_name)
+{
+    PyObject *key = 0, *value = 0;
+    Py_ssize_t pos = 0;
+    PyObject*** name;
+    PyObject*** first_kw_arg = argnames + num_pos_args;
+    while (PyDict_Next(kwds, &pos, &key, &value)) {
+        name = first_kw_arg;
+        while (*name && (**name != key)) name++;
+        if (*name) {
+            values[name-argnames] = value;
+            continue;
+        }
+        name = first_kw_arg;
+        #if PY_MAJOR_VERSION < 3
+        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
+            while (*name) {
+                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
+                        && _PyString_Eq(**name, key)) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    if ((**argname == key) || (
+                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
+                             && _PyString_Eq(**argname, key))) {
+                        goto arg_passed_twice;
+                    }
+                    argname++;
+                }
+            }
+        } else
+        #endif
+        if (likely(PyUnicode_Check(key))) {
+            while (*name) {
+                int cmp = (**name == key) ? 0 :
+                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
+                #endif
+                    PyUnicode_Compare(**name, key);
+                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                if (cmp == 0) {
+                    values[name-argnames] = value;
+                    break;
+                }
+                name++;
+            }
+            if (*name) continue;
+            else {
+                PyObject*** argname = argnames;
+                while (argname != first_kw_arg) {
+                    int cmp = (**argname == key) ? 0 :
+                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
+                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
+                    #endif
+                        PyUnicode_Compare(**argname, key);
+                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
+                    if (cmp == 0) goto arg_passed_twice;
+                    argname++;
+                }
+            }
+        } else
+            goto invalid_keyword_type;
+        if (kwds2) {
+            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
+        } else {
+            goto invalid_keyword;
+        }
+    }
+    return 0;
+arg_passed_twice:
+    __Pyx_RaiseDoubleKeywordsError(function_name, key);
+    goto bad;
+invalid_keyword_type:
+    PyErr_Format(PyExc_TypeError,
+        "%.200s() keywords must be strings", function_name);
+    goto bad;
+invalid_keyword:
+    PyErr_Format(PyExc_TypeError,
+    #if PY_MAJOR_VERSION < 3
+        "%.200s() got an unexpected keyword argument '%.200s'",
+        function_name, PyString_AsString(key));
+    #else
+        "%s() got an unexpected keyword argument '%U'",
+        function_name, key);
+    #endif
+bad:
+    return -1;
+}
+
+static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
+    PyThreadState *tstate = PyThreadState_GET();
+    tmp_type = tstate->curexc_type;
+    tmp_value = tstate->curexc_value;
+    tmp_tb = tstate->curexc_traceback;
+    tstate->curexc_type = type;
+    tstate->curexc_value = value;
+    tstate->curexc_traceback = tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_Restore(type, value, tb);
+#endif
+}
+static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->curexc_type;
+    *value = tstate->curexc_value;
+    *tb = tstate->curexc_traceback;
+    tstate->curexc_type = 0;
+    tstate->curexc_value = 0;
+    tstate->curexc_traceback = 0;
+#else
+    PyErr_Fetch(type, value, tb);
+#endif
+}
+
+#if PY_MAJOR_VERSION < 3
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
+                        CYTHON_UNUSED PyObject *cause) {
+    Py_XINCREF(type);
+    if (!value || value == Py_None)
+        value = NULL;
+    else
+        Py_INCREF(value);
+    if (!tb || tb == Py_None)
+        tb = NULL;
+    else {
+        Py_INCREF(tb);
+        if (!PyTraceBack_Check(tb)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: arg 3 must be a traceback or None");
+            goto raise_error;
+        }
+    }
+    if (PyType_Check(type)) {
+#if CYTHON_COMPILING_IN_PYPY
+        if (!value) {
+            Py_INCREF(Py_None);
+            value = Py_None;
+        }
+#endif
+        PyErr_NormalizeException(&type, &value, &tb);
+    } else {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(type);
+        Py_INCREF(type);
+        if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
+            PyErr_SetString(PyExc_TypeError,
+                "raise: exception class must be a subclass of BaseException");
+            goto raise_error;
+        }
+    }
+    __Pyx_ErrRestore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+#else
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
+    PyObject* owned_instance = NULL;
+    if (tb == Py_None) {
+        tb = 0;
+    } else if (tb && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto bad;
+    }
+    if (value == Py_None)
+        value = 0;
+    if (PyExceptionInstance_Check(type)) {
+        if (value) {
+            PyErr_SetString(PyExc_TypeError,
+                "instance exception may not have a separate value");
+            goto bad;
+        }
+        value = type;
+        type = (PyObject*) Py_TYPE(value);
+    } else if (PyExceptionClass_Check(type)) {
+        PyObject *instance_class = NULL;
+        if (value && PyExceptionInstance_Check(value)) {
+            instance_class = (PyObject*) Py_TYPE(value);
+            if (instance_class != type) {
+                int is_subclass = PyObject_IsSubclass(instance_class, type);
+                if (!is_subclass) {
+                    instance_class = NULL;
+                } else if (unlikely(is_subclass == -1)) {
+                    goto bad;
+                } else {
+                    type = instance_class;
+                }
+            }
+        }
+        if (!instance_class) {
+            PyObject *args;
+            if (!value)
+                args = PyTuple_New(0);
+            else if (PyTuple_Check(value)) {
+                Py_INCREF(value);
+                args = value;
+            } else
+                args = PyTuple_Pack(1, value);
+            if (!args)
+                goto bad;
+            owned_instance = PyObject_Call(type, args, NULL);
+            Py_DECREF(args);
+            if (!owned_instance)
+                goto bad;
+            value = owned_instance;
+            if (!PyExceptionInstance_Check(value)) {
+                PyErr_Format(PyExc_TypeError,
+                             "calling %R should have returned an instance of "
+                             "BaseException, not %R",
+                             type, Py_TYPE(value));
+                goto bad;
+            }
+        }
+    } else {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: exception class must be a subclass of BaseException");
+        goto bad;
+    }
+#if PY_VERSION_HEX >= 0x03030000
+    if (cause) {
+#else
+    if (cause && cause != Py_None) {
+#endif
+        PyObject *fixed_cause;
+        if (cause == Py_None) {
+            fixed_cause = NULL;
+        } else if (PyExceptionClass_Check(cause)) {
+            fixed_cause = PyObject_CallObject(cause, NULL);
+            if (fixed_cause == NULL)
+                goto bad;
+        } else if (PyExceptionInstance_Check(cause)) {
+            fixed_cause = cause;
+            Py_INCREF(fixed_cause);
+        } else {
+            PyErr_SetString(PyExc_TypeError,
+                            "exception causes must derive from "
+                            "BaseException");
+            goto bad;
         }
-        if (!result) {
-            PyErr_SetObject(PyExc_NameError, name);
+        PyException_SetCause(value, fixed_cause);
+    }
+    PyErr_SetObject(type, value);
+    if (tb) {
+#if CYTHON_COMPILING_IN_PYPY
+        PyObject *tmp_type, *tmp_value, *tmp_tb;
+        PyErr_Fetch(&tmp_type, &tmp_value, &tmp_tb);
+        Py_INCREF(tb);
+        PyErr_Restore(tmp_type, tmp_value, tb);
+        Py_XDECREF(tmp_tb);
+#else
+        PyThreadState *tstate = PyThreadState_GET();
+        PyObject* tmp_tb = tstate->curexc_traceback;
+        if (tb != tmp_tb) {
+            Py_INCREF(tb);
+            tstate->curexc_traceback = tb;
+            Py_XDECREF(tmp_tb);
         }
+#endif
     }
-    return result;
+bad:
+    Py_XDECREF(owned_instance);
+    return;
 }
+#endif
 
 static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
     if (unlikely(!type)) {
-        PyErr_Format(PyExc_SystemError, "Missing type object");
+        PyErr_SetString(PyExc_SystemError, "Missing type object");
         return 0;
     }
     if (likely(PyObject_TypeCheck(obj, type)))
@@ -15070,666 +19088,1702 @@ static CYTHON_INLINE int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
     return 0;
 }
 
-static void __Pyx_RaiseArgtupleInvalid(
-    const char* func_name,
-    int exact,
-    Py_ssize_t num_min,
-    Py_ssize_t num_max,
-    Py_ssize_t num_found)
-{
-    Py_ssize_t num_expected;
-    const char *more_or_less;
-    if (num_found < num_min) {
-        num_expected = num_min;
-        more_or_less = "at least";
-    } else {
-        num_expected = num_max;
-        more_or_less = "at most";
+static CYTHON_INLINE int __Pyx_PyObject_SetSlice(PyObject* obj, PyObject* value,
+        Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
+        int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyMappingMethods* mp;
+#if PY_MAJOR_VERSION < 3
+    PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
+    if (likely(ms && ms->sq_ass_slice)) {
+        if (!has_cstart) {
+            if (_py_start && (*_py_start != Py_None)) {
+                cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
+                if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstart = 0;
+        }
+        if (!has_cstop) {
+            if (_py_stop && (*_py_stop != Py_None)) {
+                cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
+                if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstop = PY_SSIZE_T_MAX;
+        }
+        if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
+            Py_ssize_t l = ms->sq_length(obj);
+            if (likely(l >= 0)) {
+                if (cstop < 0) {
+                    cstop += l;
+                    if (cstop < 0) cstop = 0;
+                }
+                if (cstart < 0) {
+                    cstart += l;
+                    if (cstart < 0) cstart = 0;
+                }
+            } else {
+                if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                    PyErr_Clear();
+                else
+                    goto bad;
+            }
+        }
+        return ms->sq_ass_slice(obj, cstart, cstop, value);
     }
-    if (exact) {
-        more_or_less = "exactly";
+#endif
+    mp = Py_TYPE(obj)->tp_as_mapping;
+    if (likely(mp && mp->mp_ass_subscript))
+#endif
+    {
+        int result;
+        PyObject *py_slice, *py_start, *py_stop;
+        if (_py_slice) {
+            py_slice = *_py_slice;
+        } else {
+            PyObject* owned_start = NULL;
+            PyObject* owned_stop = NULL;
+            if (_py_start) {
+                py_start = *_py_start;
+            } else {
+                if (has_cstart) {
+                    owned_start = py_start = PyInt_FromSsize_t(cstart);
+                    if (unlikely(!py_start)) goto bad;
+                } else
+                    py_start = Py_None;
+            }
+            if (_py_stop) {
+                py_stop = *_py_stop;
+            } else {
+                if (has_cstop) {
+                    owned_stop = py_stop = PyInt_FromSsize_t(cstop);
+                    if (unlikely(!py_stop)) {
+                        Py_XDECREF(owned_start);
+                        goto bad;
+                    }
+                } else
+                    py_stop = Py_None;
+            }
+            py_slice = PySlice_New(py_start, py_stop, Py_None);
+            Py_XDECREF(owned_start);
+            Py_XDECREF(owned_stop);
+            if (unlikely(!py_slice)) goto bad;
+        }
+#if CYTHON_COMPILING_IN_CPYTHON
+        result = mp->mp_ass_subscript(obj, py_slice, value);
+#else
+        result = value ? PyObject_SetItem(obj, py_slice, value) : PyObject_DelItem(obj, py_slice);
+#endif
+        if (!_py_slice) {
+            Py_DECREF(py_slice);
+        }
+        return result;
     }
     PyErr_Format(PyExc_TypeError,
-                 "%s() takes %s %" CYTHON_FORMAT_SSIZE_T "d positional argument%s (%" CYTHON_FORMAT_SSIZE_T "d given)",
-                 func_name, more_or_less, num_expected,
-                 (num_expected == 1) ? "" : "s", num_found);
-}
-
-static void __Pyx_RaiseDoubleKeywordsError(
-    const char* func_name,
-    PyObject* kw_name)
-{
-    PyErr_Format(PyExc_TypeError,
-        #if PY_MAJOR_VERSION >= 3
-        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
-        #else
-        "%s() got multiple values for keyword argument '%s'", func_name,
-        PyString_AsString(kw_name));
-        #endif
+        "'%.200s' object does not support slice %.10s",
+        Py_TYPE(obj)->tp_name, value ? "assignment" : "deletion");
+bad:
+    return -1;
 }
 
-static int __Pyx_ParseOptionalKeywords(
-    PyObject *kwds,
-    PyObject **argnames[],
-    PyObject *kwds2,
-    PyObject *values[],
-    Py_ssize_t num_pos_args,
-    const char* function_name)
-{
-    PyObject *key = 0, *value = 0;
-    Py_ssize_t pos = 0;
-    PyObject*** name;
-    PyObject*** first_kw_arg = argnames + num_pos_args;
-    while (PyDict_Next(kwds, &pos, &key, &value)) {
-        name = first_kw_arg;
-        while (*name && (**name != key)) name++;
-        if (*name) {
-            values[name-argnames] = value;
-            continue;
+static CYTHON_INLINE PyObject* __Pyx_PyObject_GetSlice(PyObject* obj,
+        Py_ssize_t cstart, Py_ssize_t cstop,
+        PyObject** _py_start, PyObject** _py_stop, PyObject** _py_slice,
+        int has_cstart, int has_cstop, CYTHON_UNUSED int wraparound) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyMappingMethods* mp;
+#if PY_MAJOR_VERSION < 3
+    PySequenceMethods* ms = Py_TYPE(obj)->tp_as_sequence;
+    if (likely(ms && ms->sq_slice)) {
+        if (!has_cstart) {
+            if (_py_start && (*_py_start != Py_None)) {
+                cstart = __Pyx_PyIndex_AsSsize_t(*_py_start);
+                if ((cstart == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstart = 0;
         }
-        name = first_kw_arg;
-        #if PY_MAJOR_VERSION < 3
-        if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) {
-            while (*name) {
-                if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key))
-                        && _PyString_Eq(**name, key)) {
-                    values[name-argnames] = value;
-                    break;
+        if (!has_cstop) {
+            if (_py_stop && (*_py_stop != Py_None)) {
+                cstop = __Pyx_PyIndex_AsSsize_t(*_py_stop);
+                if ((cstop == (Py_ssize_t)-1) && PyErr_Occurred()) goto bad;
+            } else
+                cstop = PY_SSIZE_T_MAX;
+        }
+        if (wraparound && unlikely((cstart < 0) | (cstop < 0)) && likely(ms->sq_length)) {
+            Py_ssize_t l = ms->sq_length(obj);
+            if (likely(l >= 0)) {
+                if (cstop < 0) {
+                    cstop += l;
+                    if (cstop < 0) cstop = 0;
                 }
-                name++;
-            }
-            if (*name) continue;
-            else {
-                PyObject*** argname = argnames;
-                while (argname != first_kw_arg) {
-                    if ((**argname == key) || (
-                            (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key))
-                             && _PyString_Eq(**argname, key))) {
-                        goto arg_passed_twice;
-                    }
-                    argname++;
+                if (cstart < 0) {
+                    cstart += l;
+                    if (cstart < 0) cstart = 0;
                 }
+            } else {
+                if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                    PyErr_Clear();
+                else
+                    goto bad;
             }
-        } else
-        #endif
-        if (likely(PyUnicode_Check(key))) {
-            while (*name) {
-                int cmp = (**name == key) ? 0 :
-                #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
-                    (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 :
-                #endif
-                    PyUnicode_Compare(**name, key);
-                if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
-                if (cmp == 0) {
-                    values[name-argnames] = value;
-                    break;
-                }
-                name++;
+        }
+        return ms->sq_slice(obj, cstart, cstop);
+    }
+#endif
+    mp = Py_TYPE(obj)->tp_as_mapping;
+    if (likely(mp && mp->mp_subscript))
+#endif
+    {
+        PyObject* result;
+        PyObject *py_slice, *py_start, *py_stop;
+        if (_py_slice) {
+            py_slice = *_py_slice;
+        } else {
+            PyObject* owned_start = NULL;
+            PyObject* owned_stop = NULL;
+            if (_py_start) {
+                py_start = *_py_start;
+            } else {
+                if (has_cstart) {
+                    owned_start = py_start = PyInt_FromSsize_t(cstart);
+                    if (unlikely(!py_start)) goto bad;
+                } else
+                    py_start = Py_None;
             }
-            if (*name) continue;
-            else {
-                PyObject*** argname = argnames;
-                while (argname != first_kw_arg) {
-                    int cmp = (**argname == key) ? 0 :
-                    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3
-                        (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 :
-                    #endif
-                        PyUnicode_Compare(**argname, key);
-                    if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad;
-                    if (cmp == 0) goto arg_passed_twice;
-                    argname++;
-                }
+            if (_py_stop) {
+                py_stop = *_py_stop;
+            } else {
+                if (has_cstop) {
+                    owned_stop = py_stop = PyInt_FromSsize_t(cstop);
+                    if (unlikely(!py_stop)) {
+                        Py_XDECREF(owned_start);
+                        goto bad;
+                    }
+                } else
+                    py_stop = Py_None;
             }
-        } else
-            goto invalid_keyword_type;
-        if (kwds2) {
-            if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
-        } else {
-            goto invalid_keyword;
+            py_slice = PySlice_New(py_start, py_stop, Py_None);
+            Py_XDECREF(owned_start);
+            Py_XDECREF(owned_stop);
+            if (unlikely(!py_slice)) goto bad;
         }
+#if CYTHON_COMPILING_IN_CPYTHON
+        result = mp->mp_subscript(obj, py_slice);
+#else
+        result = PyObject_GetItem(obj, py_slice);
+#endif
+        if (!_py_slice) {
+            Py_DECREF(py_slice);
+        }
+        return result;
     }
-    return 0;
-arg_passed_twice:
-    __Pyx_RaiseDoubleKeywordsError(function_name, key);
-    goto bad;
-invalid_keyword_type:
-    PyErr_Format(PyExc_TypeError,
-        "%s() keywords must be strings", function_name);
-    goto bad;
-invalid_keyword:
     PyErr_Format(PyExc_TypeError,
-    #if PY_MAJOR_VERSION < 3
-        "%s() got an unexpected keyword argument '%s'",
-        function_name, PyString_AsString(key));
-    #else
-        "%s() got an unexpected keyword argument '%U'",
-        function_name, key);
-    #endif
+        "'%.200s' object is unsliceable", Py_TYPE(obj)->tp_name);
 bad:
-    return -1;
+    return NULL;
+}
+
+static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
+    long q = a / b;
+    long r = a - q*b;
+    q -= ((r != 0) & ((r ^ b) < 0));
+    return q;
+}
+
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Generic(PyObject *o, PyObject* j) {
+    PyObject *r;
+    if (!j) return NULL;
+    r = PyObject_GetItem(o, j);
+    Py_DECREF(j);
+    return r;
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, Py_ssize_t i,
+                                                              CYTHON_NCP_UNUSED int wraparound,
+                                                              CYTHON_NCP_UNUSED int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyList_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyList_GET_SIZE(o)))) {
+        PyObject *r = PyList_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, Py_ssize_t i,
+                                                              CYTHON_NCP_UNUSED int wraparound,
+                                                              CYTHON_NCP_UNUSED int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (wraparound & unlikely(i < 0)) i += PyTuple_GET_SIZE(o);
+    if ((!boundscheck) || likely((0 <= i) & (i < PyTuple_GET_SIZE(o)))) {
+        PyObject *r = PyTuple_GET_ITEM(o, i);
+        Py_INCREF(r);
+        return r;
+    }
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+#else
+    return PySequence_GetItem(o, i);
+#endif
+}
+static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Fast(PyObject *o, Py_ssize_t i, int is_list,
+                                                     CYTHON_NCP_UNUSED int wraparound,
+                                                     CYTHON_NCP_UNUSED int boundscheck) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (is_list || PyList_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyList_GET_SIZE(o);
+        if ((!boundscheck) || (likely((n >= 0) & (n < PyList_GET_SIZE(o))))) {
+            PyObject *r = PyList_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    }
+    else if (PyTuple_CheckExact(o)) {
+        Py_ssize_t n = ((!wraparound) | likely(i >= 0)) ? i : i + PyTuple_GET_SIZE(o);
+        if ((!boundscheck) || likely((n >= 0) & (n < PyTuple_GET_SIZE(o)))) {
+            PyObject *r = PyTuple_GET_ITEM(o, n);
+            Py_INCREF(r);
+            return r;
+        }
+    } else {
+        PySequenceMethods *m = Py_TYPE(o)->tp_as_sequence;
+        if (likely(m && m->sq_item)) {
+            if (wraparound && unlikely(i < 0) && likely(m->sq_length)) {
+                Py_ssize_t l = m->sq_length(o);
+                if (likely(l >= 0)) {
+                    i += l;
+                } else {
+                    if (PyErr_ExceptionMatches(PyExc_OverflowError))
+                        PyErr_Clear();
+                    else
+                        return NULL;
+                }
+            }
+            return m->sq_item(o, i);
+        }
+    }
+#else
+    if (is_list || PySequence_Check(o)) {
+        return PySequence_GetItem(o, i);
+    }
+#endif
+    return __Pyx_GetItemInt_Generic(o, PyInt_FromSsize_t(i));
+}
+
+static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
+#if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
+    *type = tstate->exc_type;
+    *value = tstate->exc_value;
+    *tb = tstate->exc_traceback;
+    Py_XINCREF(*type);
+    Py_XINCREF(*value);
+    Py_XINCREF(*tb);
+#else
+    PyErr_GetExcInfo(type, value, tb);
+#endif
 }
-
-static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
+static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
 #if CYTHON_COMPILING_IN_CPYTHON
     PyObject *tmp_type, *tmp_value, *tmp_tb;
     PyThreadState *tstate = PyThreadState_GET();
-    tmp_type = tstate->curexc_type;
-    tmp_value = tstate->curexc_value;
-    tmp_tb = tstate->curexc_traceback;
-    tstate->curexc_type = type;
-    tstate->curexc_value = value;
-    tstate->curexc_traceback = tb;
+    tmp_type = tstate->exc_type;
+    tmp_value = tstate->exc_value;
+    tmp_tb = tstate->exc_traceback;
+    tstate->exc_type = type;
+    tstate->exc_value = value;
+    tstate->exc_traceback = tb;
     Py_XDECREF(tmp_type);
     Py_XDECREF(tmp_value);
     Py_XDECREF(tmp_tb);
 #else
-    PyErr_Restore(type, value, tb);
+    PyErr_SetExcInfo(type, value, tb);
 #endif
 }
-static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
+
+static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
+    PyObject *local_type, *local_value, *local_tb;
 #if CYTHON_COMPILING_IN_CPYTHON
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
     PyThreadState *tstate = PyThreadState_GET();
-    *type = tstate->curexc_type;
-    *value = tstate->curexc_value;
-    *tb = tstate->curexc_traceback;
+    local_type = tstate->curexc_type;
+    local_value = tstate->curexc_value;
+    local_tb = tstate->curexc_traceback;
     tstate->curexc_type = 0;
     tstate->curexc_value = 0;
     tstate->curexc_traceback = 0;
 #else
-    PyErr_Fetch(type, value, tb);
+    PyErr_Fetch(&local_type, &local_value, &local_tb);
+#endif
+    PyErr_NormalizeException(&local_type, &local_value, &local_tb);
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (unlikely(tstate->curexc_type))
+#else
+    if (unlikely(PyErr_Occurred()))
+#endif
+        goto bad;
+    #if PY_MAJOR_VERSION >= 3
+    if (local_tb) {
+        if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
+            goto bad;
+    }
+    #endif
+    Py_XINCREF(local_tb);
+    Py_XINCREF(local_type);
+    Py_XINCREF(local_value);
+    *type = local_type;
+    *value = local_value;
+    *tb = local_tb;
+#if CYTHON_COMPILING_IN_CPYTHON
+    tmp_type = tstate->exc_type;
+    tmp_value = tstate->exc_value;
+    tmp_tb = tstate->exc_traceback;
+    tstate->exc_type = local_type;
+    tstate->exc_value = local_value;
+    tstate->exc_traceback = local_tb;
+    Py_XDECREF(tmp_type);
+    Py_XDECREF(tmp_value);
+    Py_XDECREF(tmp_tb);
+#else
+    PyErr_SetExcInfo(local_type, local_value, local_tb);
 #endif
+    return 0;
+bad:
+    *type = 0;
+    *value = 0;
+    *tb = 0;
+    Py_XDECREF(local_type);
+    Py_XDECREF(local_value);
+    Py_XDECREF(local_tb);
+    return -1;
 }
 
-#if PY_MAJOR_VERSION < 3
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb,
-                        CYTHON_UNUSED PyObject *cause) {
-    Py_XINCREF(type);
-    if (!value || value == Py_None)
-        value = NULL;
-    else
-        Py_INCREF(value);
-    if (!tb || tb == Py_None)
-        tb = NULL;
-    else {
-        Py_INCREF(tb);
-        if (!PyTraceBack_Check(tb)) {
-            PyErr_SetString(PyExc_TypeError,
-                "raise: arg 3 must be a traceback or None");
-            goto raise_error;
+#if CYTHON_USE_PYLONG_INTERNALS
+  #include "longintrepr.h"
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx_PyInt_EqObjC(PyObject *op1, PyObject *op2, CYTHON_UNUSED long intval, CYTHON_UNUSED int inplace) {
+    if (op1 == op2) {
+        Py_RETURN_TRUE;
+    }
+    #if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_CheckExact(op1))) {
+        const long b = intval;
+        long a = PyInt_AS_LONG(op1);
+        if (a == b) {
+            Py_RETURN_TRUE;
+        } else {
+            Py_RETURN_FALSE;
         }
     }
-    #if PY_VERSION_HEX < 0x02050000
-    if (PyClass_Check(type)) {
-    #else
-    if (PyType_Check(type)) {
     #endif
-#if CYTHON_COMPILING_IN_PYPY
-        if (!value) {
-            Py_INCREF(Py_None);
-            value = Py_None;
-        }
-#endif
-        PyErr_NormalizeException(&type, &value, &tb);
-    } else {
-        if (value) {
-            PyErr_SetString(PyExc_TypeError,
-                "instance exception may not have a separate value");
-            goto raise_error;
-        }
-        value = type;
-        #if PY_VERSION_HEX < 0x02050000
-            if (PyInstance_Check(type)) {
-                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
-                Py_INCREF(type);
+    #if CYTHON_USE_PYLONG_INTERNALS && PY_MAJOR_VERSION >= 3
+    if (likely(PyLong_CheckExact(op1))) {
+        const long b = intval;
+        long a;
+        const digit* digits = ((PyLongObject*)op1)->ob_digit;
+        const Py_ssize_t size = Py_SIZE(op1);
+        if (likely(__Pyx_sst_abs(size) <= 1)) {
+            a = likely(size) ? digits[0] : 0;
+            if (size == -1) a = -a;
+        } else {
+            switch (size) {
+                case -2:
+                    if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) {
+                        a = -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
+                        break;
+                    }
+                case 2:
+                    if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) {
+                        a = (long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
+                        break;
+                    }
+                case -3:
+                    if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) {
+                        a = -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
+                        break;
+                    }
+                case 3:
+                    if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) {
+                        a = (long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
+                        break;
+                    }
+                case -4:
+                    if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) {
+                        a = -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
+                        break;
+                    }
+                case 4:
+                    if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) {
+                        a = (long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]));
+                        break;
+                    }
+                #if PyLong_SHIFT < 30 && PyLong_SHIFT != 15
+                default: return PyLong_Type.tp_richcompare(op1, op2, Py_EQ);
+                #else
+                default: Py_RETURN_FALSE;
+                #endif
             }
-            else {
-                type = 0;
-                PyErr_SetString(PyExc_TypeError,
-                    "raise: exception must be an old-style class or instance");
-                goto raise_error;
+        }
+            if (a == b) {
+                Py_RETURN_TRUE;
+            } else {
+                Py_RETURN_FALSE;
             }
-        #else
-            type = (PyObject*) Py_TYPE(type);
-            Py_INCREF(type);
-            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
-                PyErr_SetString(PyExc_TypeError,
-                    "raise: exception class must be a subclass of BaseException");
-                goto raise_error;
+    }
+    #endif
+    if (PyFloat_CheckExact(op1)) {
+        const long b = intval;
+        double a = PyFloat_AS_DOUBLE(op1);
+            if ((double)a == (double)b) {
+                Py_RETURN_TRUE;
+            } else {
+                Py_RETURN_FALSE;
             }
-        #endif
     }
-    __Pyx_ErrRestore(type, value, tb);
-    return;
-raise_error:
-    Py_XDECREF(value);
-    Py_XDECREF(type);
-    Py_XDECREF(tb);
-    return;
+    return PyObject_RichCompare(op1, op2, Py_EQ);
 }
-#else /* Python 3+ */
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb, PyObject *cause) {
-    PyObject* owned_instance = NULL;
-    if (tb == Py_None) {
-        tb = 0;
-    } else if (tb && !PyTraceBack_Check(tb)) {
-        PyErr_SetString(PyExc_TypeError,
-            "raise: arg 3 must be a traceback or None");
-        goto bad;
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) {
+    PyObject *self, *result;
+    PyCFunction cfunc;
+    cfunc = PyCFunction_GET_FUNCTION(func);
+    self = PyCFunction_GET_SELF(func);
+    if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object")))
+        return NULL;
+    result = cfunc(self, arg);
+    Py_LeaveRecursiveCall();
+    if (unlikely(!result) && unlikely(!PyErr_Occurred())) {
+        PyErr_SetString(
+            PyExc_SystemError,
+            "NULL result without error in PyObject_Call");
     }
-    if (value == Py_None)
-        value = 0;
-    if (PyExceptionInstance_Check(type)) {
-        if (value) {
-            PyErr_SetString(PyExc_TypeError,
-                "instance exception may not have a separate value");
-            goto bad;
+    return result;
+}
+#endif
+
+#if CYTHON_COMPILING_IN_CPYTHON
+static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+    PyObject *result;
+    PyObject *args = PyTuple_New(1);
+    if (unlikely(!args)) return NULL;
+    Py_INCREF(arg);
+    PyTuple_SET_ITEM(args, 0, arg);
+    result = __Pyx_PyObject_Call(func, args, NULL);
+    Py_DECREF(args);
+    return result;
+}
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+#ifdef __Pyx_CyFunction_USED
+    if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
+#else
+    if (likely(PyCFunction_Check(func))) {
+#endif
+        if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) {
+            return __Pyx_PyObject_CallMethO(func, arg);
         }
-        value = type;
-        type = (PyObject*) Py_TYPE(value);
-    } else if (PyExceptionClass_Check(type)) {
-        PyObject *args;
-        if (!value)
-            args = PyTuple_New(0);
-        else if (PyTuple_Check(value)) {
-            Py_INCREF(value);
-            args = value;
+    }
+    return __Pyx__PyObject_CallOneArg(func, arg);
+}
+#else
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) {
+    PyObject* args = PyTuple_Pack(1, arg);
+    return (likely(args)) ? __Pyx_PyObject_Call(func, args, NULL) : NULL;
+}
+#endif
+
+static PyObject* __Pyx_PyObject_CallMethod1(PyObject* obj, PyObject* method_name, PyObject* arg) {
+    PyObject *method, *result = NULL;
+    method = __Pyx_PyObject_GetAttrStr(obj, method_name);
+    if (unlikely(!method)) goto bad;
+#if CYTHON_COMPILING_IN_CPYTHON
+    if (likely(PyMethod_Check(method))) {
+        PyObject *self = PyMethod_GET_SELF(method);
+        if (likely(self)) {
+            PyObject *args;
+            PyObject *function = PyMethod_GET_FUNCTION(method);
+            args = PyTuple_New(2);
+            if (unlikely(!args)) goto bad;
+            Py_INCREF(self);
+            PyTuple_SET_ITEM(args, 0, self);
+            Py_INCREF(arg);
+            PyTuple_SET_ITEM(args, 1, arg);
+            Py_INCREF(function);
+            Py_DECREF(method); method = NULL;
+            result = __Pyx_PyObject_Call(function, args, NULL);
+            Py_DECREF(args);
+            Py_DECREF(function);
+            return result;
         }
-        else
-            args = PyTuple_Pack(1, value);
-        if (!args)
-            goto bad;
-        owned_instance = PyEval_CallObject(type, args);
-        Py_DECREF(args);
-        if (!owned_instance)
-            goto bad;
-        value = owned_instance;
-        if (!PyExceptionInstance_Check(value)) {
+    }
+#endif
+    result = __Pyx_PyObject_CallOneArg(method, arg);
+bad:
+    Py_XDECREF(method);
+    return result;
+}
+
+static CYTHON_INLINE int __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
+    if (likely(PyList_CheckExact(L))) {
+        if (unlikely(__Pyx_PyList_Append(L, x) < 0)) return -1;
+    } else {
+        PyObject* retval = __Pyx_PyObject_CallMethod1(L, __pyx_n_s_append, x);
+        if (unlikely(!retval))
+            return -1;
+        Py_DECREF(retval);
+    }
+    return 0;
+}
+
+static CYTHON_INLINE intptr_t __Pyx_mod_intptr_t(intptr_t a, intptr_t b) {
+    intptr_t r = a % b;
+    r += ((r != 0) & ((r ^ b) < 0)) * b;
+    return r;
+}
+
+static double __Pyx__PyObject_AsDouble(PyObject* obj) {
+    PyObject* float_value;
+#if CYTHON_COMPILING_IN_PYPY
+    float_value = PyNumber_Float(obj);  if (0) goto bad;
+#else
+    PyNumberMethods *nb = Py_TYPE(obj)->tp_as_number;
+    if (likely(nb) && likely(nb->nb_float)) {
+        float_value = nb->nb_float(obj);
+        if (likely(float_value) && unlikely(!PyFloat_Check(float_value))) {
             PyErr_Format(PyExc_TypeError,
-                         "calling %R should have returned an instance of "
-                         "BaseException, not %R",
-                         type, Py_TYPE(value));
+                "__float__ returned non-float (type %.200s)",
+                Py_TYPE(float_value)->tp_name);
+            Py_DECREF(float_value);
             goto bad;
         }
+    } else if (PyUnicode_CheckExact(obj) || PyBytes_CheckExact(obj)) {
+#if PY_MAJOR_VERSION >= 3
+        float_value = PyFloat_FromString(obj);
+#else
+        float_value = PyFloat_FromString(obj, 0);
+#endif
     } else {
-        PyErr_SetString(PyExc_TypeError,
-            "raise: exception class must be a subclass of BaseException");
-        goto bad;
+        PyObject* args = PyTuple_New(1);
+        if (unlikely(!args)) goto bad;
+        PyTuple_SET_ITEM(args, 0, obj);
+        float_value = PyObject_Call((PyObject*)&PyFloat_Type, args, 0);
+        PyTuple_SET_ITEM(args, 0, 0);
+        Py_DECREF(args);
     }
-    if (cause && cause != Py_None) {
-        PyObject *fixed_cause;
-        if (PyExceptionClass_Check(cause)) {
-            fixed_cause = PyObject_CallObject(cause, NULL);
-            if (fixed_cause == NULL)
-                goto bad;
-        }
-        else if (PyExceptionInstance_Check(cause)) {
-            fixed_cause = cause;
-            Py_INCREF(fixed_cause);
-        }
-        else {
-            PyErr_SetString(PyExc_TypeError,
-                            "exception causes must derive from "
-                            "BaseException");
-            goto bad;
+#endif
+    if (likely(float_value)) {
+        double value = PyFloat_AS_DOUBLE(float_value);
+        Py_DECREF(float_value);
+        return value;
+    }
+bad:
+    return (double)-1;
+}
+
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+    return PyObject_RichCompareBool(s1, s2, equals);
+#else
+    if (s1 == s2) {
+        return (equals == Py_EQ);
+    } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+        const char *ps1, *ps2;
+        Py_ssize_t length = PyBytes_GET_SIZE(s1);
+        if (length != PyBytes_GET_SIZE(s2))
+            return (equals == Py_NE);
+        ps1 = PyBytes_AS_STRING(s1);
+        ps2 = PyBytes_AS_STRING(s2);
+        if (ps1[0] != ps2[0]) {
+            return (equals == Py_NE);
+        } else if (length == 1) {
+            return (equals == Py_EQ);
+        } else {
+            int result = memcmp(ps1, ps2, (size_t)length);
+            return (equals == Py_EQ) ? (result == 0) : (result != 0);
         }
-        PyException_SetCause(value, fixed_cause);
+    } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+        return (equals == Py_NE);
+    } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+        return (equals == Py_NE);
+    } else {
+        int result;
+        PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+        if (!py_result)
+            return -1;
+        result = __Pyx_PyObject_IsTrue(py_result);
+        Py_DECREF(py_result);
+        return result;
+    }
+#endif
+}
+
+static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
+#if CYTHON_COMPILING_IN_PYPY
+    return PyObject_RichCompareBool(s1, s2, equals);
+#else
+#if PY_MAJOR_VERSION < 3
+    PyObject* owned_ref = NULL;
+#endif
+    int s1_is_unicode, s2_is_unicode;
+    if (s1 == s2) {
+        goto return_eq;
+    }
+    s1_is_unicode = PyUnicode_CheckExact(s1);
+    s2_is_unicode = PyUnicode_CheckExact(s2);
+#if PY_MAJOR_VERSION < 3
+    if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
+        owned_ref = PyUnicode_FromObject(s2);
+        if (unlikely(!owned_ref))
+            return -1;
+        s2 = owned_ref;
+        s2_is_unicode = 1;
+    } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
+        owned_ref = PyUnicode_FromObject(s1);
+        if (unlikely(!owned_ref))
+            return -1;
+        s1 = owned_ref;
+        s1_is_unicode = 1;
+    } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
+        return __Pyx_PyBytes_Equals(s1, s2, equals);
     }
-    PyErr_SetObject(type, value);
-    if (tb) {
-        PyThreadState *tstate = PyThreadState_GET();
-        PyObject* tmp_tb = tstate->curexc_traceback;
-        if (tb != tmp_tb) {
-            Py_INCREF(tb);
-            tstate->curexc_traceback = tb;
-            Py_XDECREF(tmp_tb);
+#endif
+    if (s1_is_unicode & s2_is_unicode) {
+        Py_ssize_t length;
+        int kind;
+        void *data1, *data2;
+        if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0))
+            return -1;
+        length = __Pyx_PyUnicode_GET_LENGTH(s1);
+        if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
+            goto return_ne;
+        }
+        kind = __Pyx_PyUnicode_KIND(s1);
+        if (kind != __Pyx_PyUnicode_KIND(s2)) {
+            goto return_ne;
         }
+        data1 = __Pyx_PyUnicode_DATA(s1);
+        data2 = __Pyx_PyUnicode_DATA(s2);
+        if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
+            goto return_ne;
+        } else if (length == 1) {
+            goto return_eq;
+        } else {
+            int result = memcmp(data1, data2, (size_t)(length * kind));
+            #if PY_MAJOR_VERSION < 3
+            Py_XDECREF(owned_ref);
+            #endif
+            return (equals == Py_EQ) ? (result == 0) : (result != 0);
+        }
+    } else if ((s1 == Py_None) & s2_is_unicode) {
+        goto return_ne;
+    } else if ((s2 == Py_None) & s1_is_unicode) {
+        goto return_ne;
+    } else {
+        int result;
+        PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+        if (!py_result)
+            return -1;
+        result = __Pyx_PyObject_IsTrue(py_result);
+        Py_DECREF(py_result);
+        return result;
     }
-bad:
-    Py_XDECREF(owned_instance);
-    return;
-}
+return_eq:
+    #if PY_MAJOR_VERSION < 3
+    Py_XDECREF(owned_ref);
+    #endif
+    return (equals == Py_EQ);
+return_ne:
+    #if PY_MAJOR_VERSION < 3
+    Py_XDECREF(owned_ref);
+    #endif
+    return (equals == Py_NE);
 #endif
-
-static CYTHON_INLINE long __Pyx_div_long(long a, long b) {
-    long q = a / b;
-    long r = a - q*b;
-    q -= ((r != 0) & ((r ^ b) < 0));
-    return q;
 }
 
-static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
-    PyObject *local_type, *local_value, *local_tb;
 #if CYTHON_COMPILING_IN_CPYTHON
-    PyObject *tmp_type, *tmp_value, *tmp_tb;
-    PyThreadState *tstate = PyThreadState_GET();
-    local_type = tstate->curexc_type;
-    local_value = tstate->curexc_value;
-    local_tb = tstate->curexc_traceback;
-    tstate->curexc_type = 0;
-    tstate->curexc_value = 0;
-    tstate->curexc_traceback = 0;
+static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) {
+#ifdef __Pyx_CyFunction_USED
+    if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) {
 #else
-    PyErr_Fetch(&local_type, &local_value, &local_tb);
+    if (likely(PyCFunction_Check(func))) {
 #endif
-    PyErr_NormalizeException(&local_type, &local_value, &local_tb);
-#if CYTHON_COMPILING_IN_CPYTHON
-    if (unlikely(tstate->curexc_type))
-#else
-    if (unlikely(PyErr_Occurred()))
+        if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) {
+            return __Pyx_PyObject_CallMethO(func, NULL);
+        }
+    }
+    return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL);
+}
 #endif
-        goto bad;
-    #if PY_MAJOR_VERSION >= 3
-    if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
-        goto bad;
-    #endif
-    Py_INCREF(local_type);
-    Py_INCREF(local_value);
-    Py_INCREF(local_tb);
-    *type = local_type;
-    *value = local_value;
-    *tb = local_tb;
+
+static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, PyObject **tb) {
+    PyObject *tmp_type, *tmp_value, *tmp_tb;
 #if CYTHON_COMPILING_IN_CPYTHON
+    PyThreadState *tstate = PyThreadState_GET();
     tmp_type = tstate->exc_type;
     tmp_value = tstate->exc_value;
     tmp_tb = tstate->exc_traceback;
-    tstate->exc_type = local_type;
-    tstate->exc_value = local_value;
-    tstate->exc_traceback = local_tb;
-    /* Make sure tstate is in a consistent state when we XDECREF
-       these objects (DECREF may run arbitrary code). */
-    Py_XDECREF(tmp_type);
-    Py_XDECREF(tmp_value);
-    Py_XDECREF(tmp_tb);
+    tstate->exc_type = *type;
+    tstate->exc_value = *value;
+    tstate->exc_traceback = *tb;
 #else
-    PyErr_SetExcInfo(local_type, local_value, local_tb);
+    PyErr_GetExcInfo(&tmp_type, &tmp_value, &tmp_tb);
+    PyErr_SetExcInfo(*type, *value, *tb);
+#endif
+    *type = tmp_type;
+    *value = tmp_value;
+    *tb = tmp_tb;
+}
+
+static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
+    PyErr_Format(PyExc_ValueError,
+                 "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
+    PyErr_Format(PyExc_ValueError,
+                 "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack",
+                 index, (index == 1) ? "" : "s");
+}
+
+static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
+    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
+}
+
+static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
+#if PY_VERSION_HEX >= 0x02070000
+    PyObject *ob = PyCapsule_New(vtable, 0, 0);
+#else
+    PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
 #endif
+    if (!ob)
+        goto bad;
+    if (PyDict_SetItem(dict, __pyx_n_s_pyx_vtable, ob) < 0)
+        goto bad;
+    Py_DECREF(ob);
     return 0;
 bad:
-    *type = 0;
-    *value = 0;
-    *tb = 0;
-    Py_XDECREF(local_type);
-    Py_XDECREF(local_value);
-    Py_XDECREF(local_tb);
-    return -1;
+    Py_XDECREF(ob);
+    return -1;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, int level) {
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    #if PY_VERSION_HEX < 0x03030000
+    PyObject *py_import;
+    py_import = __Pyx_PyObject_GetAttrStr(__pyx_b, __pyx_n_s_import);
+    if (!py_import)
+        goto bad;
+    #endif
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    {
+        #if PY_MAJOR_VERSION >= 3
+        if (level == -1) {
+            if (strchr(__Pyx_MODULE_NAME, '.')) {
+                #if PY_VERSION_HEX < 0x03030000
+                PyObject *py_level = PyInt_FromLong(1);
+                if (!py_level)
+                    goto bad;
+                module = PyObject_CallFunctionObjArgs(py_import,
+                    name, global_dict, empty_dict, list, py_level, NULL);
+                Py_DECREF(py_level);
+                #else
+                module = PyImport_ImportModuleLevelObject(
+                    name, global_dict, empty_dict, list, 1);
+                #endif
+                if (!module) {
+                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
+                        goto bad;
+                    PyErr_Clear();
+                }
+            }
+            level = 0;
+        }
+        #endif
+        if (!module) {
+            #if PY_VERSION_HEX < 0x03030000
+            PyObject *py_level = PyInt_FromLong(level);
+            if (!py_level)
+                goto bad;
+            module = PyObject_CallFunctionObjArgs(py_import,
+                name, global_dict, empty_dict, list, py_level, NULL);
+            Py_DECREF(py_level);
+            #else
+            module = PyImport_ImportModuleLevelObject(
+                name, global_dict, empty_dict, list, level);
+            #endif
+        }
+    }
+bad:
+    #if PY_VERSION_HEX < 0x03030000
+    Py_XDECREF(py_import);
+    #endif
+    Py_XDECREF(empty_list);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static PyObject *__Pyx_GetNameInClass(PyObject *nmspace, PyObject *name) {
+    PyObject *result;
+    result = __Pyx_PyObject_GetAttrStr(nmspace, name);
+    if (!result)
+        result = __Pyx_GetModuleGlobalName(name);
+    return result;
+}
+
+static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
+    int start = 0, mid = 0, end = count - 1;
+    if (end >= 0 && code_line > entries[end].code_line) {
+        return count;
+    }
+    while (start < end) {
+        mid = start + (end - start) / 2;
+        if (code_line < entries[mid].code_line) {
+            end = mid;
+        } else if (code_line > entries[mid].code_line) {
+             start = mid + 1;
+        } else {
+            return mid;
+        }
+    }
+    if (code_line <= entries[mid].code_line) {
+        return mid;
+    } else {
+        return mid + 1;
+    }
+}
+static PyCodeObject *__pyx_find_code_object(int code_line) {
+    PyCodeObject* code_object;
+    int pos;
+    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
+        return NULL;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
+        return NULL;
+    }
+    code_object = __pyx_code_cache.entries[pos].code_object;
+    Py_INCREF(code_object);
+    return code_object;
+}
+static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
+    int pos, i;
+    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
+    if (unlikely(!code_line)) {
+        return;
+    }
+    if (unlikely(!entries)) {
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (likely(entries)) {
+            __pyx_code_cache.entries = entries;
+            __pyx_code_cache.max_count = 64;
+            __pyx_code_cache.count = 1;
+            entries[0].code_line = code_line;
+            entries[0].code_object = code_object;
+            Py_INCREF(code_object);
+        }
+        return;
+    }
+    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
+    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
+        PyCodeObject* tmp = entries[pos].code_object;
+        entries[pos].code_object = code_object;
+        Py_DECREF(tmp);
+        return;
+    }
+    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
+        int new_max = __pyx_code_cache.max_count + 64;
+        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
+            __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry));
+        if (unlikely(!entries)) {
+            return;
+        }
+        __pyx_code_cache.entries = entries;
+        __pyx_code_cache.max_count = new_max;
+    }
+    for (i=__pyx_code_cache.count; i>pos; i--) {
+        entries[i] = entries[i-1];
+    }
+    entries[pos].code_line = code_line;
+    entries[pos].code_object = code_object;
+    __pyx_code_cache.count++;
+    Py_INCREF(code_object);
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
+            const char *funcname, int c_line,
+            int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    #if PY_MAJOR_VERSION < 3
+    py_srcfile = PyString_FromString(filename);
+    #else
+    py_srcfile = PyUnicode_FromString(filename);
+    #endif
+    if (!py_srcfile) goto bad;
+    if (c_line) {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #else
+        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
+        #endif
+    }
+    else {
+        #if PY_MAJOR_VERSION < 3
+        py_funcname = PyString_FromString(funcname);
+        #else
+        py_funcname = PyUnicode_FromString(funcname);
+        #endif
+    }
+    if (!py_funcname) goto bad;
+    py_code = __Pyx_PyCode_New(
+        0,
+        0,
+        0,
+        0,
+        0,
+        __pyx_empty_bytes, /*PyObject *code,*/
+        __pyx_empty_tuple, /*PyObject *consts,*/
+        __pyx_empty_tuple, /*PyObject *names,*/
+        __pyx_empty_tuple, /*PyObject *varnames,*/
+        __pyx_empty_tuple, /*PyObject *freevars,*/
+        __pyx_empty_tuple, /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        py_line,
+        __pyx_empty_bytes  /*PyObject *lnotab*/
+    );
+    Py_DECREF(py_srcfile);
+    Py_DECREF(py_funcname);
+    return py_code;
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    return NULL;
 }
-
-static CYTHON_INLINE intptr_t __Pyx_mod_intptr_t(intptr_t a, intptr_t b) {
-    intptr_t r = a % b;
-    r += ((r != 0) & ((r ^ b) < 0)) * b;
-    return r;
+static void __Pyx_AddTraceback(const char *funcname, int c_line,
+                               int py_line, const char *filename) {
+    PyCodeObject *py_code = 0;
+    PyFrameObject *py_frame = 0;
+    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
+    if (!py_code) {
+        py_code = __Pyx_CreateCodeObjectForTraceback(
+            funcname, c_line, py_line, filename);
+        if (!py_code) goto bad;
+        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
+    }
+    py_frame = PyFrame_New(
+        PyThreadState_GET(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        __pyx_d,      /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = py_line;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
 }
 
-static double __Pyx__PyObject_AsDouble(PyObject* obj) {
-    PyObject* float_value;
-#if CYTHON_COMPILING_IN_PYPY
-    float_value = PyNumber_Float(obj);
-#else
-    if (Py_TYPE(obj)->tp_as_number && Py_TYPE(obj)->tp_as_number->nb_float) {
-        return PyFloat_AsDouble(obj);
-    } else if (PyUnicode_CheckExact(obj) || PyBytes_CheckExact(obj)) {
-#if PY_MAJOR_VERSION >= 3
-        float_value = PyFloat_FromString(obj);
-#else
-        float_value = PyFloat_FromString(obj, 0);
-#endif
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int(int value) {
+    const int neg_one = (int) -1, const_zero = (int) 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(int) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) {
+            return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value);
+        }
     } else {
-        PyObject* args = PyTuple_New(1);
-        if (unlikely(!args)) goto bad;
-        PyTuple_SET_ITEM(args, 0, obj);
-        float_value = PyObject_Call((PyObject*)&PyFloat_Type, args, 0);
-        PyTuple_SET_ITEM(args, 0, 0);
-        Py_DECREF(args);
+        if (sizeof(int) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) {
+            return PyLong_FromLongLong((PY_LONG_LONG) value);
+        }
     }
-#endif
-    if (likely(float_value)) {
-        double value = PyFloat_AS_DOUBLE(float_value);
-        Py_DECREF(float_value);
-        return value;
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(int),
+                                     little, !is_unsigned);
     }
-bad:
-    return (double)-1;
-}
-
-static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) {
-    PyErr_Format(PyExc_ValueError,
-                 "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected);
-}
-
-static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) {
-    PyErr_Format(PyExc_ValueError,
-                 "need more than %" CYTHON_FORMAT_SSIZE_T "d value%s to unpack",
-                 index, (index == 1) ? "" : "s");
 }
 
-static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) {
-    PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
-}
+#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\
+    __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0)
+#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\
+    __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1)
+#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\
+    {\
+        func_type value = func_value;\
+        if (sizeof(target_type) < sizeof(func_type)) {\
+            if (unlikely(value != (func_type) (target_type) value)) {\
+                func_type zero = 0;\
+                if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\
+                    return (target_type) -1;\
+                if (is_unsigned && unlikely(value < zero))\
+                    goto raise_neg_overflow;\
+                else\
+                    goto raise_overflow;\
+            }\
+        }\
+        return (target_type) value;\
+    }
 
-static CYTHON_INLINE int __Pyx_IterFinish(void) {
-#if CYTHON_COMPILING_IN_CPYTHON
-    PyThreadState *tstate = PyThreadState_GET();
-    PyObject* exc_type = tstate->curexc_type;
-    if (unlikely(exc_type)) {
-        if (likely(exc_type == PyExc_StopIteration) || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)) {
-            PyObject *exc_value, *exc_tb;
-            exc_value = tstate->curexc_value;
-            exc_tb = tstate->curexc_traceback;
-            tstate->curexc_type = 0;
-            tstate->curexc_value = 0;
-            tstate->curexc_traceback = 0;
-            Py_DECREF(exc_type);
-            Py_XDECREF(exc_value);
-            Py_XDECREF(exc_tb);
-            return 0;
+static CYTHON_INLINE unsigned int __Pyx_PyInt_As_unsigned_int(PyObject *x) {
+    const unsigned int neg_one = (unsigned int) -1, const_zero = (unsigned int) 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(unsigned int) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(unsigned int, long, PyInt_AS_LONG(x))
         } else {
-            return -1;
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (unsigned int) val;
         }
-    }
-    return 0;
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_USE_PYLONG_INTERNALS
+            const digit* digits = ((PyLongObject*)x)->ob_digit;
+            switch (Py_SIZE(x)) {
+                case  0: return (unsigned int) 0;
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned int, digit, digits[0])
+                case 2:
+                    if (8 * sizeof(unsigned int) > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(unsigned int) >= 2 * PyLong_SHIFT) {
+                            return (unsigned int) (((((unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0]));
+                        }
+                    }
+                    break;
+                case 3:
+                    if (8 * sizeof(unsigned int) > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(unsigned int) >= 3 * PyLong_SHIFT) {
+                            return (unsigned int) (((((((unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0]));
+                        }
+                    }
+                    break;
+                case 4:
+                    if (8 * sizeof(unsigned int) > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(unsigned int) >= 4 * PyLong_SHIFT) {
+                            return (unsigned int) (((((((((unsigned int)digits[3]) << PyLong_SHIFT) | (unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0]));
+                        }
+                    }
+                    break;
+            }
+#endif
+#if CYTHON_COMPILING_IN_CPYTHON
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
 #else
-    if (unlikely(PyErr_Occurred())) {
-        if (likely(PyErr_ExceptionMatches(PyExc_StopIteration))) {
-            PyErr_Clear();
-            return 0;
+            {
+                int result = PyObject_RichCompareBool(x, Py_False, Py_LT);
+                if (unlikely(result < 0))
+                    return (unsigned int) -1;
+                if (unlikely(result == 1))
+                    goto raise_neg_overflow;
+            }
+#endif
+            if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT_EXC(unsigned int, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(unsigned int) <= sizeof(unsigned PY_LONG_LONG)) {
+                __PYX_VERIFY_RETURN_INT_EXC(unsigned int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x))
+            }
         } else {
-            return -1;
+#if CYTHON_USE_PYLONG_INTERNALS
+            const digit* digits = ((PyLongObject*)x)->ob_digit;
+            switch (Py_SIZE(x)) {
+                case  0: return (unsigned int) 0;
+                case -1: __PYX_VERIFY_RETURN_INT(unsigned int, sdigit, -(sdigit) digits[0])
+                case  1: __PYX_VERIFY_RETURN_INT(unsigned int,  digit, +digits[0])
+                case -2:
+                    if (8 * sizeof(unsigned int) - 1 > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(unsigned int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(unsigned int) - 1 > 2 * PyLong_SHIFT) {
+                            return (unsigned int) (((unsigned int)-1)*(((((unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0])));
+                        }
+                    }
+                    break;
+                case 2:
+                    if (8 * sizeof(unsigned int) > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(unsigned int) - 1 > 2 * PyLong_SHIFT) {
+                            return (unsigned int) ((((((unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0])));
+                        }
+                    }
+                    break;
+                case -3:
+                    if (8 * sizeof(unsigned int) - 1 > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(unsigned int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(unsigned int) - 1 > 3 * PyLong_SHIFT) {
+                            return (unsigned int) (((unsigned int)-1)*(((((((unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0])));
+                        }
+                    }
+                    break;
+                case 3:
+                    if (8 * sizeof(unsigned int) > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(unsigned int) - 1 > 3 * PyLong_SHIFT) {
+                            return (unsigned int) ((((((((unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0])));
+                        }
+                    }
+                    break;
+                case -4:
+                    if (8 * sizeof(unsigned int) - 1 > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(unsigned int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(unsigned int) - 1 > 4 * PyLong_SHIFT) {
+                            return (unsigned int) (((unsigned int)-1)*(((((((((unsigned int)digits[3]) << PyLong_SHIFT) | (unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0])));
+                        }
+                    }
+                    break;
+                case 4:
+                    if (8 * sizeof(unsigned int) > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(unsigned int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(unsigned int) - 1 > 4 * PyLong_SHIFT) {
+                            return (unsigned int) ((((((((((unsigned int)digits[3]) << PyLong_SHIFT) | (unsigned int)digits[2]) << PyLong_SHIFT) | (unsigned int)digits[1]) << PyLong_SHIFT) | (unsigned int)digits[0])));
+                        }
+                    }
+                    break;
+            }
+#endif
+            if (sizeof(unsigned int) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT_EXC(unsigned int, long, PyLong_AsLong(x))
+            } else if (sizeof(unsigned int) <= sizeof(PY_LONG_LONG)) {
+                __PYX_VERIFY_RETURN_INT_EXC(unsigned int, PY_LONG_LONG, PyLong_AsLongLong(x))
+            }
         }
-    }
-    return 0;
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            unsigned int val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
 #endif
-}
-
-static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) {
-    if (unlikely(retval)) {
-        Py_DECREF(retval);
-        __Pyx_RaiseTooManyValuesError(expected);
-        return -1;
+            return (unsigned int) -1;
+        }
     } else {
-        return __Pyx_IterFinish();
+        unsigned int val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (unsigned int) -1;
+        val = __Pyx_PyInt_As_unsigned_int(tmp);
+        Py_DECREF(tmp);
+        return val;
     }
-    return 0;
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to unsigned int");
+    return (unsigned int) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to unsigned int");
+    return (unsigned int) -1;
 }
 
-static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
-#if CYTHON_COMPILING_IN_CPYTHON
-    PyThreadState *tstate = PyThreadState_GET();
-    *type = tstate->exc_type;
-    *value = tstate->exc_value;
-    *tb = tstate->exc_traceback;
-    Py_XINCREF(*type);
-    Py_XINCREF(*value);
-    Py_XINCREF(*tb);
-#else
-    PyErr_GetExcInfo(type, value, tb);
+static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
+    const int neg_one = (int) -1, const_zero = (int) 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(int) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (int) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_USE_PYLONG_INTERNALS
+            const digit* digits = ((PyLongObject*)x)->ob_digit;
+            switch (Py_SIZE(x)) {
+                case  0: return (int) 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0])
+                case 2:
+                    if (8 * sizeof(int) > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) {
+                            return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]));
+                        }
+                    }
+                    break;
+                case 3:
+                    if (8 * sizeof(int) > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) {
+                            return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]));
+                        }
+                    }
+                    break;
+                case 4:
+                    if (8 * sizeof(int) > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) {
+                            return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]));
+                        }
+                    }
+                    break;
+            }
 #endif
-}
-static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
 #if CYTHON_COMPILING_IN_CPYTHON
-    PyObject *tmp_type, *tmp_value, *tmp_tb;
-    PyThreadState *tstate = PyThreadState_GET();
-    tmp_type = tstate->exc_type;
-    tmp_value = tstate->exc_value;
-    tmp_tb = tstate->exc_traceback;
-    tstate->exc_type = type;
-    tstate->exc_value = value;
-    tstate->exc_traceback = tb;
-    Py_XDECREF(tmp_type);
-    Py_XDECREF(tmp_value);
-    Py_XDECREF(tmp_tb);
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
 #else
-    PyErr_SetExcInfo(type, value, tb);
+            {
+                int result = PyObject_RichCompareBool(x, Py_False, Py_LT);
+                if (unlikely(result < 0))
+                    return (int) -1;
+                if (unlikely(result == 1))
+                    goto raise_neg_overflow;
+            }
 #endif
-}
-
-static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list, long level) {
-    PyObject *py_import = 0;
-    PyObject *empty_list = 0;
-    PyObject *module = 0;
-    PyObject *global_dict = 0;
-    PyObject *empty_dict = 0;
-    PyObject *list;
-    py_import = __Pyx_GetAttrString(__pyx_b, "__import__");
-    if (!py_import)
-        goto bad;
-    if (from_list)
-        list = from_list;
-    else {
-        empty_list = PyList_New(0);
-        if (!empty_list)
-            goto bad;
-        list = empty_list;
-    }
-    global_dict = PyModule_GetDict(__pyx_m);
-    if (!global_dict)
-        goto bad;
-    empty_dict = PyDict_New();
-    if (!empty_dict)
-        goto bad;
-    #if PY_VERSION_HEX >= 0x02050000
-    {
-        #if PY_MAJOR_VERSION >= 3
-        if (level == -1) {
-            if (strchr(__Pyx_MODULE_NAME, '.')) {
-                /* try package relative import first */
-                PyObject *py_level = PyInt_FromLong(1);
-                if (!py_level)
-                    goto bad;
-                module = PyObject_CallFunctionObjArgs(py_import,
-                    name, global_dict, empty_dict, list, py_level, NULL);
-                Py_DECREF(py_level);
-                if (!module) {
-                    if (!PyErr_ExceptionMatches(PyExc_ImportError))
-                        goto bad;
-                    PyErr_Clear();
-                }
+            if (sizeof(int) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) {
+                __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_USE_PYLONG_INTERNALS
+            const digit* digits = ((PyLongObject*)x)->ob_digit;
+            switch (Py_SIZE(x)) {
+                case  0: return (int) 0;
+                case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, -(sdigit) digits[0])
+                case  1: __PYX_VERIFY_RETURN_INT(int,  digit, +digits[0])
+                case -2:
+                    if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) {
+                            return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])));
+                        }
+                    }
+                    break;
+                case 2:
+                    if (8 * sizeof(int) > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) {
+                            return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])));
+                        }
+                    }
+                    break;
+                case -3:
+                    if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) {
+                            return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])));
+                        }
+                    }
+                    break;
+                case 3:
+                    if (8 * sizeof(int) > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) {
+                            return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])));
+                        }
+                    }
+                    break;
+                case -4:
+                    if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) {
+                            return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])));
+                        }
+                    }
+                    break;
+                case 4:
+                    if (8 * sizeof(int) > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) {
+                            return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])));
+                        }
+                    }
+                    break;
+            }
+#endif
+            if (sizeof(int) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x))
+            } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) {
+                __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x))
             }
-            level = 0; /* try absolute import on failure */
         }
-        #endif
-        if (!module) {
-            PyObject *py_level = PyInt_FromLong(level);
-            if (!py_level)
-                goto bad;
-            module = PyObject_CallFunctionObjArgs(py_import,
-                name, global_dict, empty_dict, list, py_level, NULL);
-            Py_DECREF(py_level);
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            int val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (int) -1;
         }
+    } else {
+        int val;
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (int) -1;
+        val = __Pyx_PyInt_As_int(tmp);
+        Py_DECREF(tmp);
+        return val;
     }
-    #else
-    if (level>0) {
-        PyErr_SetString(PyExc_RuntimeError, "Relative import is not supported for Python <=2.4.");
-        goto bad;
-    }
-    module = PyObject_CallFunctionObjArgs(py_import,
-        name, global_dict, empty_dict, list, NULL);
-    #endif
-bad:
-    Py_XDECREF(empty_list);
-    Py_XDECREF(py_import);
-    Py_XDECREF(empty_dict);
-    return module;
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to int");
+    return (int) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to int");
+    return (int) -1;
 }
 
-static CYTHON_INLINE PyObject *__Pyx_PyInt_to_py_int64_t(int64_t val) {
-    const int64_t neg_one = (int64_t)-1, const_zero = (int64_t)0;
-    const int is_unsigned = const_zero < neg_one;
-    if ((sizeof(int64_t) == sizeof(char))  ||
-        (sizeof(int64_t) == sizeof(short))) {
-        return PyInt_FromLong((long)val);
-    } else if ((sizeof(int64_t) == sizeof(int)) ||
-               (sizeof(int64_t) == sizeof(long))) {
-        if (is_unsigned)
-            return PyLong_FromUnsignedLong((unsigned long)val);
-        else
-            return PyInt_FromLong((long)val);
-    } else if (sizeof(int64_t) == sizeof(PY_LONG_LONG)) {
-        if (is_unsigned)
-            return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)val);
-        else
-            return PyLong_FromLongLong((PY_LONG_LONG)val);
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_int64_t(int64_t value) {
+    const int64_t neg_one = (int64_t) -1, const_zero = (int64_t) 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(int64_t) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int64_t) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(int64_t) <= sizeof(unsigned PY_LONG_LONG)) {
+            return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value);
+        }
     } else {
+        if (sizeof(int64_t) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(int64_t) <= sizeof(PY_LONG_LONG)) {
+            return PyLong_FromLongLong((PY_LONG_LONG) value);
+        }
+    }
+    {
         int one = 1; int little = (int)*(unsigned char *)&one;
-        unsigned char *bytes = (unsigned char *)&val;
+        unsigned char *bytes = (unsigned char *)&value;
         return _PyLong_FromByteArray(bytes, sizeof(int64_t),
                                      little, !is_unsigned);
     }
 }
 
-static CYTHON_INLINE int64_t __Pyx_PyInt_from_py_int64_t(PyObject* x) {
-    const int64_t neg_one = (int64_t)-1, const_zero = (int64_t)0;
-    const int is_unsigned = const_zero < neg_one;
-    if (sizeof(int64_t) == sizeof(char)) {
-        if (is_unsigned)
-            return (int64_t)__Pyx_PyInt_AsUnsignedChar(x);
-        else
-            return (int64_t)__Pyx_PyInt_AsSignedChar(x);
-    } else if (sizeof(int64_t) == sizeof(short)) {
-        if (is_unsigned)
-            return (int64_t)__Pyx_PyInt_AsUnsignedShort(x);
-        else
-            return (int64_t)__Pyx_PyInt_AsSignedShort(x);
-    } else if (sizeof(int64_t) == sizeof(int)) {
-        if (is_unsigned)
-            return (int64_t)__Pyx_PyInt_AsUnsignedInt(x);
-        else
-            return (int64_t)__Pyx_PyInt_AsSignedInt(x);
-    } else if (sizeof(int64_t) == sizeof(long)) {
-        if (is_unsigned)
-            return (int64_t)__Pyx_PyInt_AsUnsignedLong(x);
-        else
-            return (int64_t)__Pyx_PyInt_AsSignedLong(x);
-    } else if (sizeof(int64_t) == sizeof(PY_LONG_LONG)) {
-        if (is_unsigned)
-            return (int64_t)__Pyx_PyInt_AsUnsignedLongLong(x);
-        else
-            return (int64_t)__Pyx_PyInt_AsSignedLongLong(x);
-    }  else {
-        #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
-        PyErr_SetString(PyExc_RuntimeError,
-                        "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
-        #else
+static CYTHON_INLINE int64_t __Pyx_PyInt_As_int64_t(PyObject *x) {
+    const int64_t neg_one = (int64_t) -1, const_zero = (int64_t) 0;
+    const int is_unsigned = neg_one > const_zero;
+#if PY_MAJOR_VERSION < 3
+    if (likely(PyInt_Check(x))) {
+        if (sizeof(int64_t) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(int64_t, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (int64_t) val;
+        }
+    } else
+#endif
+    if (likely(PyLong_Check(x))) {
+        if (is_unsigned) {
+#if CYTHON_USE_PYLONG_INTERNALS
+            const digit* digits = ((PyLongObject*)x)->ob_digit;
+            switch (Py_SIZE(x)) {
+                case  0: return (int64_t) 0;
+                case  1: __PYX_VERIFY_RETURN_INT(int64_t, digit, digits[0])
+                case 2:
+                    if (8 * sizeof(int64_t) > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int64_t) >= 2 * PyLong_SHIFT) {
+                            return (int64_t) (((((int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]));
+                        }
+                    }
+                    break;
+                case 3:
+                    if (8 * sizeof(int64_t) > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int64_t) >= 3 * PyLong_SHIFT) {
+                            return (int64_t) (((((((int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]));
+                        }
+                    }
+                    break;
+                case 4:
+                    if (8 * sizeof(int64_t) > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int64_t) >= 4 * PyLong_SHIFT) {
+                            return (int64_t) (((((((((int64_t)digits[3]) << PyLong_SHIFT) | (int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0]));
+                        }
+                    }
+                    break;
+            }
+#endif
+#if CYTHON_COMPILING_IN_CPYTHON
+            if (unlikely(Py_SIZE(x) < 0)) {
+                goto raise_neg_overflow;
+            }
+#else
+            {
+                int result = PyObject_RichCompareBool(x, Py_False, Py_LT);
+                if (unlikely(result < 0))
+                    return (int64_t) -1;
+                if (unlikely(result == 1))
+                    goto raise_neg_overflow;
+            }
+#endif
+            if (sizeof(int64_t) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT_EXC(int64_t, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(int64_t) <= sizeof(unsigned PY_LONG_LONG)) {
+                __PYX_VERIFY_RETURN_INT_EXC(int64_t, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x))
+            }
+        } else {
+#if CYTHON_USE_PYLONG_INTERNALS
+            const digit* digits = ((PyLongObject*)x)->ob_digit;
+            switch (Py_SIZE(x)) {
+                case  0: return (int64_t) 0;
+                case -1: __PYX_VERIFY_RETURN_INT(int64_t, sdigit, -(sdigit) digits[0])
+                case  1: __PYX_VERIFY_RETURN_INT(int64_t,  digit, +digits[0])
+                case -2:
+                    if (8 * sizeof(int64_t) - 1 > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int64_t, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int64_t) - 1 > 2 * PyLong_SHIFT) {
+                            return (int64_t) (((int64_t)-1)*(((((int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])));
+                        }
+                    }
+                    break;
+                case 2:
+                    if (8 * sizeof(int64_t) > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int64_t) - 1 > 2 * PyLong_SHIFT) {
+                            return (int64_t) ((((((int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])));
+                        }
+                    }
+                    break;
+                case -3:
+                    if (8 * sizeof(int64_t) - 1 > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int64_t, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int64_t) - 1 > 3 * PyLong_SHIFT) {
+                            return (int64_t) (((int64_t)-1)*(((((((int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])));
+                        }
+                    }
+                    break;
+                case 3:
+                    if (8 * sizeof(int64_t) > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int64_t) - 1 > 3 * PyLong_SHIFT) {
+                            return (int64_t) ((((((((int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])));
+                        }
+                    }
+                    break;
+                case -4:
+                    if (8 * sizeof(int64_t) - 1 > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int64_t, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int64_t) - 1 > 4 * PyLong_SHIFT) {
+                            return (int64_t) (((int64_t)-1)*(((((((((int64_t)digits[3]) << PyLong_SHIFT) | (int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])));
+                        }
+                    }
+                    break;
+                case 4:
+                    if (8 * sizeof(int64_t) > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(int64_t, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(int64_t) - 1 > 4 * PyLong_SHIFT) {
+                            return (int64_t) ((((((((((int64_t)digits[3]) << PyLong_SHIFT) | (int64_t)digits[2]) << PyLong_SHIFT) | (int64_t)digits[1]) << PyLong_SHIFT) | (int64_t)digits[0])));
+                        }
+                    }
+                    break;
+            }
+#endif
+            if (sizeof(int64_t) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT_EXC(int64_t, long, PyLong_AsLong(x))
+            } else if (sizeof(int64_t) <= sizeof(PY_LONG_LONG)) {
+                __PYX_VERIFY_RETURN_INT_EXC(int64_t, PY_LONG_LONG, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            int64_t val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (int64_t) -1;
+        }
+    } else {
         int64_t val;
-        PyObject *v = __Pyx_PyNumber_Int(x);
-        #if PY_VERSION_HEX < 0x03000000
-        if (likely(v) && !PyLong_Check(v)) {
-            PyObject *tmp = v;
-            v = PyNumber_Long(tmp);
-            Py_DECREF(tmp);
+        PyObject *tmp = __Pyx_PyNumber_Int(x);
+        if (!tmp) return (int64_t) -1;
+        val = __Pyx_PyInt_As_int64_t(tmp);
+        Py_DECREF(tmp);
+        return val;
+    }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to int64_t");
+    return (int64_t) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to int64_t");
+    return (int64_t) -1;
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) {
+    const long neg_one = (long) -1, const_zero = (long) 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(long) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) {
+            return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value);
         }
-        #endif
-        if (likely(v)) {
-            int one = 1; int is_little = (int)*(unsigned char *)&one;
-            unsigned char *bytes = (unsigned char *)&val;
-            int ret = _PyLong_AsByteArray((PyLongObject *)v,
-                                          bytes, sizeof(val),
-                                          is_little, !is_unsigned);
-            Py_DECREF(v);
-            if (likely(!ret))
-                return val;
+    } else {
+        if (sizeof(long) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) {
+            return PyLong_FromLongLong((PY_LONG_LONG) value);
         }
-        #endif
-        return (int64_t)-1;
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(long),
+                                     little, !is_unsigned);
+    }
+}
+
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_int(unsigned int value) {
+    const unsigned int neg_one = (unsigned int) -1, const_zero = (unsigned int) 0;
+    const int is_unsigned = neg_one > const_zero;
+    if (is_unsigned) {
+        if (sizeof(unsigned int) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned int) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(unsigned int) <= sizeof(unsigned PY_LONG_LONG)) {
+            return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value);
+        }
+    } else {
+        if (sizeof(unsigned int) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(unsigned int) <= sizeof(PY_LONG_LONG)) {
+            return PyLong_FromLongLong((PY_LONG_LONG) value);
+        }
+    }
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(unsigned int),
+                                     little, !is_unsigned);
     }
 }
 
@@ -15973,404 +21027,214 @@ static CYTHON_INLINE int64_t __Pyx_PyInt_from_py_int64_t(PyObject* x) {
     #endif
 #endif
 
-static CYTHON_INLINE unsigned char __Pyx_PyInt_AsUnsignedChar(PyObject* x) {
-    const unsigned char neg_one = (unsigned char)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (sizeof(unsigned char) < sizeof(long)) {
-        long val = __Pyx_PyInt_AsLong(x);
-        if (unlikely(val != (long)(unsigned char)val)) {
-            if (!unlikely(val == -1 && PyErr_Occurred())) {
-                PyErr_SetString(PyExc_OverflowError,
-                    (is_unsigned && unlikely(val < 0)) ?
-                    "can't convert negative value to unsigned char" :
-                    "value too large to convert to unsigned char");
-            }
-            return (unsigned char)-1;
-        }
-        return (unsigned char)val;
-    }
-    return (unsigned char)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE unsigned short __Pyx_PyInt_AsUnsignedShort(PyObject* x) {
-    const unsigned short neg_one = (unsigned short)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (sizeof(unsigned short) < sizeof(long)) {
-        long val = __Pyx_PyInt_AsLong(x);
-        if (unlikely(val != (long)(unsigned short)val)) {
-            if (!unlikely(val == -1 && PyErr_Occurred())) {
-                PyErr_SetString(PyExc_OverflowError,
-                    (is_unsigned && unlikely(val < 0)) ?
-                    "can't convert negative value to unsigned short" :
-                    "value too large to convert to unsigned short");
-            }
-            return (unsigned short)-1;
-        }
-        return (unsigned short)val;
-    }
-    return (unsigned short)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE unsigned int __Pyx_PyInt_AsUnsignedInt(PyObject* x) {
-    const unsigned int neg_one = (unsigned int)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (sizeof(unsigned int) < sizeof(long)) {
-        long val = __Pyx_PyInt_AsLong(x);
-        if (unlikely(val != (long)(unsigned int)val)) {
-            if (!unlikely(val == -1 && PyErr_Occurred())) {
-                PyErr_SetString(PyExc_OverflowError,
-                    (is_unsigned && unlikely(val < 0)) ?
-                    "can't convert negative value to unsigned int" :
-                    "value too large to convert to unsigned int");
-            }
-            return (unsigned int)-1;
-        }
-        return (unsigned int)val;
-    }
-    return (unsigned int)__Pyx_PyInt_AsUnsignedLong(x);
-}
-
-static CYTHON_INLINE char __Pyx_PyInt_AsChar(PyObject* x) {
-    const char neg_one = (char)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (sizeof(char) < sizeof(long)) {
-        long val = __Pyx_PyInt_AsLong(x);
-        if (unlikely(val != (long)(char)val)) {
-            if (!unlikely(val == -1 && PyErr_Occurred())) {
-                PyErr_SetString(PyExc_OverflowError,
-                    (is_unsigned && unlikely(val < 0)) ?
-                    "can't convert negative value to char" :
-                    "value too large to convert to char");
-            }
-            return (char)-1;
-        }
-        return (char)val;
-    }
-    return (char)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE short __Pyx_PyInt_AsShort(PyObject* x) {
-    const short neg_one = (short)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (sizeof(short) < sizeof(long)) {
-        long val = __Pyx_PyInt_AsLong(x);
-        if (unlikely(val != (long)(short)val)) {
-            if (!unlikely(val == -1 && PyErr_Occurred())) {
-                PyErr_SetString(PyExc_OverflowError,
-                    (is_unsigned && unlikely(val < 0)) ?
-                    "can't convert negative value to short" :
-                    "value too large to convert to short");
-            }
-            return (short)-1;
-        }
-        return (short)val;
-    }
-    return (short)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE int __Pyx_PyInt_AsInt(PyObject* x) {
-    const int neg_one = (int)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (sizeof(int) < sizeof(long)) {
-        long val = __Pyx_PyInt_AsLong(x);
-        if (unlikely(val != (long)(int)val)) {
-            if (!unlikely(val == -1 && PyErr_Occurred())) {
-                PyErr_SetString(PyExc_OverflowError,
-                    (is_unsigned && unlikely(val < 0)) ?
-                    "can't convert negative value to int" :
-                    "value too large to convert to int");
-            }
-            return (int)-1;
-        }
-        return (int)val;
-    }
-    return (int)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE signed char __Pyx_PyInt_AsSignedChar(PyObject* x) {
-    const signed char neg_one = (signed char)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (sizeof(signed char) < sizeof(long)) {
-        long val = __Pyx_PyInt_AsLong(x);
-        if (unlikely(val != (long)(signed char)val)) {
-            if (!unlikely(val == -1 && PyErr_Occurred())) {
-                PyErr_SetString(PyExc_OverflowError,
-                    (is_unsigned && unlikely(val < 0)) ?
-                    "can't convert negative value to signed char" :
-                    "value too large to convert to signed char");
-            }
-            return (signed char)-1;
-        }
-        return (signed char)val;
-    }
-    return (signed char)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE signed short __Pyx_PyInt_AsSignedShort(PyObject* x) {
-    const signed short neg_one = (signed short)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (sizeof(signed short) < sizeof(long)) {
-        long val = __Pyx_PyInt_AsLong(x);
-        if (unlikely(val != (long)(signed short)val)) {
-            if (!unlikely(val == -1 && PyErr_Occurred())) {
-                PyErr_SetString(PyExc_OverflowError,
-                    (is_unsigned && unlikely(val < 0)) ?
-                    "can't convert negative value to signed short" :
-                    "value too large to convert to signed short");
-            }
-            return (signed short)-1;
-        }
-        return (signed short)val;
-    }
-    return (signed short)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE signed int __Pyx_PyInt_AsSignedInt(PyObject* x) {
-    const signed int neg_one = (signed int)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (sizeof(signed int) < sizeof(long)) {
-        long val = __Pyx_PyInt_AsLong(x);
-        if (unlikely(val != (long)(signed int)val)) {
-            if (!unlikely(val == -1 && PyErr_Occurred())) {
-                PyErr_SetString(PyExc_OverflowError,
-                    (is_unsigned && unlikely(val < 0)) ?
-                    "can't convert negative value to signed int" :
-                    "value too large to convert to signed int");
-            }
-            return (signed int)-1;
-        }
-        return (signed int)val;
-    }
-    return (signed int)__Pyx_PyInt_AsSignedLong(x);
-}
-
-static CYTHON_INLINE int __Pyx_PyInt_AsLongDouble(PyObject* x) {
-    const int neg_one = (int)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-    if (sizeof(int) < sizeof(long)) {
-        long val = __Pyx_PyInt_AsLong(x);
-        if (unlikely(val != (long)(int)val)) {
-            if (!unlikely(val == -1 && PyErr_Occurred())) {
-                PyErr_SetString(PyExc_OverflowError,
-                    (is_unsigned && unlikely(val < 0)) ?
-                    "can't convert negative value to int" :
-                    "value too large to convert to int");
-            }
-            return (int)-1;
-        }
-        return (int)val;
-    }
-    return (int)__Pyx_PyInt_AsLong(x);
-}
-
-static CYTHON_INLINE unsigned long __Pyx_PyInt_AsUnsignedLong(PyObject* x) {
-    const unsigned long neg_one = (unsigned long)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
-    if (likely(PyInt_Check(x))) {
-        long val = PyInt_AS_LONG(x);
-        if (is_unsigned && unlikely(val < 0)) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "can't convert negative value to unsigned long");
-            return (unsigned long)-1;
-        }
-        return (unsigned long)val;
-    } else
-#endif
-    if (likely(PyLong_Check(x))) {
-        if (is_unsigned) {
-            if (unlikely(Py_SIZE(x) < 0)) {
-                PyErr_SetString(PyExc_OverflowError,
-                                "can't convert negative value to unsigned long");
-                return (unsigned long)-1;
-            }
-            return (unsigned long)PyLong_AsUnsignedLong(x);
-        } else {
-            return (unsigned long)PyLong_AsLong(x);
-        }
-    } else {
-        unsigned long val;
-        PyObject *tmp = __Pyx_PyNumber_Int(x);
-        if (!tmp) return (unsigned long)-1;
-        val = __Pyx_PyInt_AsUnsignedLong(tmp);
-        Py_DECREF(tmp);
-        return val;
-    }
-}
-
-static CYTHON_INLINE unsigned PY_LONG_LONG __Pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
-    const unsigned PY_LONG_LONG neg_one = (unsigned PY_LONG_LONG)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
-    if (likely(PyInt_Check(x))) {
-        long val = PyInt_AS_LONG(x);
-        if (is_unsigned && unlikely(val < 0)) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "can't convert negative value to unsigned PY_LONG_LONG");
-            return (unsigned PY_LONG_LONG)-1;
-        }
-        return (unsigned PY_LONG_LONG)val;
-    } else
-#endif
-    if (likely(PyLong_Check(x))) {
-        if (is_unsigned) {
-            if (unlikely(Py_SIZE(x) < 0)) {
-                PyErr_SetString(PyExc_OverflowError,
-                                "can't convert negative value to unsigned PY_LONG_LONG");
-                return (unsigned PY_LONG_LONG)-1;
-            }
-            return (unsigned PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
-        } else {
-            return (unsigned PY_LONG_LONG)PyLong_AsLongLong(x);
-        }
-    } else {
-        unsigned PY_LONG_LONG val;
-        PyObject *tmp = __Pyx_PyNumber_Int(x);
-        if (!tmp) return (unsigned PY_LONG_LONG)-1;
-        val = __Pyx_PyInt_AsUnsignedLongLong(tmp);
-        Py_DECREF(tmp);
-        return val;
-    }
-}
-
-static CYTHON_INLINE long __Pyx_PyInt_AsLong(PyObject* x) {
-    const long neg_one = (long)-1, const_zero = 0;
+static CYTHON_INLINE PyObject* __Pyx_PyInt_From_enum__NPY_TYPES(enum NPY_TYPES value) {
+    const enum NPY_TYPES neg_one = (enum NPY_TYPES) -1, const_zero = (enum NPY_TYPES) 0;
     const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
-    if (likely(PyInt_Check(x))) {
-        long val = PyInt_AS_LONG(x);
-        if (is_unsigned && unlikely(val < 0)) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "can't convert negative value to long");
-            return (long)-1;
-        }
-        return (long)val;
-    } else
-#endif
-    if (likely(PyLong_Check(x))) {
-        if (is_unsigned) {
-            if (unlikely(Py_SIZE(x) < 0)) {
-                PyErr_SetString(PyExc_OverflowError,
-                                "can't convert negative value to long");
-                return (long)-1;
-            }
-            return (long)PyLong_AsUnsignedLong(x);
-        } else {
-            return (long)PyLong_AsLong(x);
+    if (is_unsigned) {
+        if (sizeof(enum NPY_TYPES) < sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned long)) {
+            return PyLong_FromUnsignedLong((unsigned long) value);
+        } else if (sizeof(enum NPY_TYPES) <= sizeof(unsigned PY_LONG_LONG)) {
+            return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value);
         }
     } else {
-        long val;
-        PyObject *tmp = __Pyx_PyNumber_Int(x);
-        if (!tmp) return (long)-1;
-        val = __Pyx_PyInt_AsLong(tmp);
-        Py_DECREF(tmp);
-        return val;
-    }
-}
-
-static CYTHON_INLINE PY_LONG_LONG __Pyx_PyInt_AsLongLong(PyObject* x) {
-    const PY_LONG_LONG neg_one = (PY_LONG_LONG)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
-    if (likely(PyInt_Check(x))) {
-        long val = PyInt_AS_LONG(x);
-        if (is_unsigned && unlikely(val < 0)) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "can't convert negative value to PY_LONG_LONG");
-            return (PY_LONG_LONG)-1;
+        if (sizeof(enum NPY_TYPES) <= sizeof(long)) {
+            return PyInt_FromLong((long) value);
+        } else if (sizeof(enum NPY_TYPES) <= sizeof(PY_LONG_LONG)) {
+            return PyLong_FromLongLong((PY_LONG_LONG) value);
         }
-        return (PY_LONG_LONG)val;
-    } else
-#endif
-    if (likely(PyLong_Check(x))) {
-        if (is_unsigned) {
-            if (unlikely(Py_SIZE(x) < 0)) {
-                PyErr_SetString(PyExc_OverflowError,
-                                "can't convert negative value to PY_LONG_LONG");
-                return (PY_LONG_LONG)-1;
-            }
-            return (PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
-        } else {
-            return (PY_LONG_LONG)PyLong_AsLongLong(x);
-        }
-    } else {
-        PY_LONG_LONG val;
-        PyObject *tmp = __Pyx_PyNumber_Int(x);
-        if (!tmp) return (PY_LONG_LONG)-1;
-        val = __Pyx_PyInt_AsLongLong(tmp);
-        Py_DECREF(tmp);
-        return val;
     }
-}
-
-static CYTHON_INLINE signed long __Pyx_PyInt_AsSignedLong(PyObject* x) {
-    const signed long neg_one = (signed long)-1, const_zero = 0;
-    const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
-    if (likely(PyInt_Check(x))) {
-        long val = PyInt_AS_LONG(x);
-        if (is_unsigned && unlikely(val < 0)) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "can't convert negative value to signed long");
-            return (signed long)-1;
-        }
-        return (signed long)val;
-    } else
-#endif
-    if (likely(PyLong_Check(x))) {
-        if (is_unsigned) {
-            if (unlikely(Py_SIZE(x) < 0)) {
-                PyErr_SetString(PyExc_OverflowError,
-                                "can't convert negative value to signed long");
-                return (signed long)-1;
-            }
-            return (signed long)PyLong_AsUnsignedLong(x);
-        } else {
-            return (signed long)PyLong_AsLong(x);
-        }
-    } else {
-        signed long val;
-        PyObject *tmp = __Pyx_PyNumber_Int(x);
-        if (!tmp) return (signed long)-1;
-        val = __Pyx_PyInt_AsSignedLong(tmp);
-        Py_DECREF(tmp);
-        return val;
+    {
+        int one = 1; int little = (int)*(unsigned char *)&one;
+        unsigned char *bytes = (unsigned char *)&value;
+        return _PyLong_FromByteArray(bytes, sizeof(enum NPY_TYPES),
+                                     little, !is_unsigned);
     }
 }
 
-static CYTHON_INLINE signed PY_LONG_LONG __Pyx_PyInt_AsSignedLongLong(PyObject* x) {
-    const signed PY_LONG_LONG neg_one = (signed PY_LONG_LONG)-1, const_zero = 0;
+static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {
+    const long neg_one = (long) -1, const_zero = (long) 0;
     const int is_unsigned = neg_one > const_zero;
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
     if (likely(PyInt_Check(x))) {
-        long val = PyInt_AS_LONG(x);
-        if (is_unsigned && unlikely(val < 0)) {
-            PyErr_SetString(PyExc_OverflowError,
-                            "can't convert negative value to signed PY_LONG_LONG");
-            return (signed PY_LONG_LONG)-1;
+        if (sizeof(long) < sizeof(long)) {
+            __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x))
+        } else {
+            long val = PyInt_AS_LONG(x);
+            if (is_unsigned && unlikely(val < 0)) {
+                goto raise_neg_overflow;
+            }
+            return (long) val;
         }
-        return (signed PY_LONG_LONG)val;
     } else
 #endif
     if (likely(PyLong_Check(x))) {
         if (is_unsigned) {
+#if CYTHON_USE_PYLONG_INTERNALS
+            const digit* digits = ((PyLongObject*)x)->ob_digit;
+            switch (Py_SIZE(x)) {
+                case  0: return (long) 0;
+                case  1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0])
+                case 2:
+                    if (8 * sizeof(long) > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) {
+                            return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]));
+                        }
+                    }
+                    break;
+                case 3:
+                    if (8 * sizeof(long) > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) {
+                            return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]));
+                        }
+                    }
+                    break;
+                case 4:
+                    if (8 * sizeof(long) > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) {
+                            return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]));
+                        }
+                    }
+                    break;
+            }
+#endif
+#if CYTHON_COMPILING_IN_CPYTHON
             if (unlikely(Py_SIZE(x) < 0)) {
-                PyErr_SetString(PyExc_OverflowError,
-                                "can't convert negative value to signed PY_LONG_LONG");
-                return (signed PY_LONG_LONG)-1;
+                goto raise_neg_overflow;
+            }
+#else
+            {
+                int result = PyObject_RichCompareBool(x, Py_False, Py_LT);
+                if (unlikely(result < 0))
+                    return (long) -1;
+                if (unlikely(result == 1))
+                    goto raise_neg_overflow;
+            }
+#endif
+            if (sizeof(long) <= sizeof(unsigned long)) {
+                __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x))
+            } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) {
+                __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x))
             }
-            return (signed PY_LONG_LONG)PyLong_AsUnsignedLongLong(x);
         } else {
-            return (signed PY_LONG_LONG)PyLong_AsLongLong(x);
+#if CYTHON_USE_PYLONG_INTERNALS
+            const digit* digits = ((PyLongObject*)x)->ob_digit;
+            switch (Py_SIZE(x)) {
+                case  0: return (long) 0;
+                case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, -(sdigit) digits[0])
+                case  1: __PYX_VERIFY_RETURN_INT(long,  digit, +digits[0])
+                case -2:
+                    if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) {
+                            return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])));
+                        }
+                    }
+                    break;
+                case 2:
+                    if (8 * sizeof(long) > 1 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) {
+                            return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])));
+                        }
+                    }
+                    break;
+                case -3:
+                    if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) {
+                            return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])));
+                        }
+                    }
+                    break;
+                case 3:
+                    if (8 * sizeof(long) > 2 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) {
+                            return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])));
+                        }
+                    }
+                    break;
+                case -4:
+                    if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) {
+                            return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])));
+                        }
+                    }
+                    break;
+                case 4:
+                    if (8 * sizeof(long) > 3 * PyLong_SHIFT) {
+                        if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) {
+                            __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0])))
+                        } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) {
+                            return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])));
+                        }
+                    }
+                    break;
+            }
+#endif
+            if (sizeof(long) <= sizeof(long)) {
+                __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x))
+            } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) {
+                __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x))
+            }
+        }
+        {
+#if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray)
+            PyErr_SetString(PyExc_RuntimeError,
+                            "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers");
+#else
+            long val;
+            PyObject *v = __Pyx_PyNumber_Int(x);
+ #if PY_MAJOR_VERSION < 3
+            if (likely(v) && !PyLong_Check(v)) {
+                PyObject *tmp = v;
+                v = PyNumber_Long(tmp);
+                Py_DECREF(tmp);
+            }
+ #endif
+            if (likely(v)) {
+                int one = 1; int is_little = (int)*(unsigned char *)&one;
+                unsigned char *bytes = (unsigned char *)&val;
+                int ret = _PyLong_AsByteArray((PyLongObject *)v,
+                                              bytes, sizeof(val),
+                                              is_little, !is_unsigned);
+                Py_DECREF(v);
+                if (likely(!ret))
+                    return val;
+            }
+#endif
+            return (long) -1;
         }
     } else {
-        signed PY_LONG_LONG val;
+        long val;
         PyObject *tmp = __Pyx_PyNumber_Int(x);
-        if (!tmp) return (signed PY_LONG_LONG)-1;
-        val = __Pyx_PyInt_AsSignedLongLong(tmp);
+        if (!tmp) return (long) -1;
+        val = __Pyx_PyInt_As_long(tmp);
         Py_DECREF(tmp);
         return val;
     }
+raise_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "value too large to convert to long");
+    return (long) -1;
+raise_neg_overflow:
+    PyErr_SetString(PyExc_OverflowError,
+        "can't convert negative value to long");
+    return (long) -1;
 }
 
 static int __Pyx_check_binary_version(void) {
@@ -16383,32 +21247,11 @@ static int __Pyx_check_binary_version(void) {
                       "compiletime version %s of module '%.100s' "
                       "does not match runtime version %s",
                       ctversion, __Pyx_MODULE_NAME, rtversion);
-        #if PY_VERSION_HEX < 0x02050000
-        return PyErr_Warn(NULL, message);
-        #else
         return PyErr_WarnEx(NULL, message, 1);
-        #endif
     }
     return 0;
 }
 
-static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
-#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
-    PyObject *ob = PyCapsule_New(vtable, 0, 0);
-#else
-    PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
-#endif
-    if (!ob)
-        goto bad;
-    if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
-        goto bad;
-    Py_DECREF(ob);
-    return 0;
-bad:
-    Py_XDECREF(ob);
-    return -1;
-}
-
 #ifndef __PYX_HAVE_RT_ImportModule
 #define __PYX_HAVE_RT_ImportModule
 static PyObject *__Pyx_ImportModule(const char *name) {
@@ -16435,6 +21278,10 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class
     PyObject *result = 0;
     PyObject *py_name = 0;
     char warning[200];
+    Py_ssize_t basicsize;
+#ifdef Py_LIMITED_API
+    PyObject *py_basicsize;
+#endif
     py_module = __Pyx_ImportModule(module_name);
     if (!py_module)
         goto bad;
@@ -16450,23 +21297,31 @@ static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class
         goto bad;
     if (!PyType_Check(result)) {
         PyErr_Format(PyExc_TypeError,
-            "%s.%s is not a type object",
+            "%.200s.%.200s is not a type object",
             module_name, class_name);
         goto bad;
     }
-    if (!strict && (size_t)((PyTypeObject *)result)->tp_basicsize > size) {
+#ifndef Py_LIMITED_API
+    basicsize = ((PyTypeObject *)result)->tp_basicsize;
+#else
+    py_basicsize = PyObject_GetAttrString(result, "__basicsize__");
+    if (!py_basicsize)
+        goto bad;
+    basicsize = PyLong_AsSsize_t(py_basicsize);
+    Py_DECREF(py_basicsize);
+    py_basicsize = 0;
+    if (basicsize == (Py_ssize_t)-1 && PyErr_Occurred())
+        goto bad;
+#endif
+    if (!strict && (size_t)basicsize > size) {
         PyOS_snprintf(warning, sizeof(warning),
             "%s.%s size changed, may indicate binary incompatibility",
             module_name, class_name);
-        #if PY_VERSION_HEX < 0x02050000
-        if (PyErr_Warn(NULL, warning) < 0) goto bad;
-        #else
         if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
-        #endif
     }
-    else if ((size_t)((PyTypeObject *)result)->tp_basicsize != size) {
+    else if ((size_t)basicsize != size) {
         PyErr_Format(PyExc_ValueError,
-            "%s.%s has the wrong size, try recompiling",
+            "%.200s.%.200s has the wrong size, try recompiling",
             module_name, class_name);
         goto bad;
     }
@@ -16478,168 +21333,6 @@ bad:
 }
 #endif
 
-static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) {
-    int start = 0, mid = 0, end = count - 1;
-    if (end >= 0 && code_line > entries[end].code_line) {
-        return count;
-    }
-    while (start < end) {
-        mid = (start + end) / 2;
-        if (code_line < entries[mid].code_line) {
-            end = mid;
-        } else if (code_line > entries[mid].code_line) {
-             start = mid + 1;
-        } else {
-            return mid;
-        }
-    }
-    if (code_line <= entries[mid].code_line) {
-        return mid;
-    } else {
-        return mid + 1;
-    }
-}
-static PyCodeObject *__pyx_find_code_object(int code_line) {
-    PyCodeObject* code_object;
-    int pos;
-    if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) {
-        return NULL;
-    }
-    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
-    if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) {
-        return NULL;
-    }
-    code_object = __pyx_code_cache.entries[pos].code_object;
-    Py_INCREF(code_object);
-    return code_object;
-}
-static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
-    int pos, i;
-    __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries;
-    if (unlikely(!code_line)) {
-        return;
-    }
-    if (unlikely(!entries)) {
-        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry));
-        if (likely(entries)) {
-            __pyx_code_cache.entries = entries;
-            __pyx_code_cache.max_count = 64;
-            __pyx_code_cache.count = 1;
-            entries[0].code_line = code_line;
-            entries[0].code_object = code_object;
-            Py_INCREF(code_object);
-        }
-        return;
-    }
-    pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line);
-    if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) {
-        PyCodeObject* tmp = entries[pos].code_object;
-        entries[pos].code_object = code_object;
-        Py_DECREF(tmp);
-        return;
-    }
-    if (__pyx_code_cache.count == __pyx_code_cache.max_count) {
-        int new_max = __pyx_code_cache.max_count + 64;
-        entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc(
-            __pyx_code_cache.entries, new_max*sizeof(__Pyx_CodeObjectCacheEntry));
-        if (unlikely(!entries)) {
-            return;
-        }
-        __pyx_code_cache.entries = entries;
-        __pyx_code_cache.max_count = new_max;
-    }
-    for (i=__pyx_code_cache.count; i>pos; i--) {
-        entries[i] = entries[i-1];
-    }
-    entries[pos].code_line = code_line;
-    entries[pos].code_object = code_object;
-    __pyx_code_cache.count++;
-    Py_INCREF(code_object);
-}
-
-#include "compile.h"
-#include "frameobject.h"
-#include "traceback.h"
-static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
-            const char *funcname, int c_line,
-            int py_line, const char *filename) {
-    PyCodeObject *py_code = 0;
-    PyObject *py_srcfile = 0;
-    PyObject *py_funcname = 0;
-    #if PY_MAJOR_VERSION < 3
-    py_srcfile = PyString_FromString(filename);
-    #else
-    py_srcfile = PyUnicode_FromString(filename);
-    #endif
-    if (!py_srcfile) goto bad;
-    if (c_line) {
-        #if PY_MAJOR_VERSION < 3
-        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
-        #else
-        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
-        #endif
-    }
-    else {
-        #if PY_MAJOR_VERSION < 3
-        py_funcname = PyString_FromString(funcname);
-        #else
-        py_funcname = PyUnicode_FromString(funcname);
-        #endif
-    }
-    if (!py_funcname) goto bad;
-    py_code = __Pyx_PyCode_New(
-        0,            /*int argcount,*/
-        0,            /*int kwonlyargcount,*/
-        0,            /*int nlocals,*/
-        0,            /*int stacksize,*/
-        0,            /*int flags,*/
-        __pyx_empty_bytes, /*PyObject *code,*/
-        __pyx_empty_tuple, /*PyObject *consts,*/
-        __pyx_empty_tuple, /*PyObject *names,*/
-        __pyx_empty_tuple, /*PyObject *varnames,*/
-        __pyx_empty_tuple, /*PyObject *freevars,*/
-        __pyx_empty_tuple, /*PyObject *cellvars,*/
-        py_srcfile,   /*PyObject *filename,*/
-        py_funcname,  /*PyObject *name,*/
-        py_line,      /*int firstlineno,*/
-        __pyx_empty_bytes  /*PyObject *lnotab*/
-    );
-    Py_DECREF(py_srcfile);
-    Py_DECREF(py_funcname);
-    return py_code;
-bad:
-    Py_XDECREF(py_srcfile);
-    Py_XDECREF(py_funcname);
-    return NULL;
-}
-static void __Pyx_AddTraceback(const char *funcname, int c_line,
-                               int py_line, const char *filename) {
-    PyCodeObject *py_code = 0;
-    PyObject *py_globals = 0;
-    PyFrameObject *py_frame = 0;
-    py_code = __pyx_find_code_object(c_line ? c_line : py_line);
-    if (!py_code) {
-        py_code = __Pyx_CreateCodeObjectForTraceback(
-            funcname, c_line, py_line, filename);
-        if (!py_code) goto bad;
-        __pyx_insert_code_object(c_line ? c_line : py_line, py_code);
-    }
-    py_globals = PyModule_GetDict(__pyx_m);
-    if (!py_globals) goto bad;
-    py_frame = PyFrame_New(
-        PyThreadState_GET(), /*PyThreadState *tstate,*/
-        py_code,             /*PyCodeObject *code,*/
-        py_globals,          /*PyObject *globals,*/
-        0                    /*PyObject *locals*/
-    );
-    if (!py_frame) goto bad;
-    py_frame->f_lineno = py_line;
-    PyTraceBack_Here(py_frame);
-bad:
-    Py_XDECREF(py_code);
-    Py_XDECREF(py_frame);
-}
-
 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
     while (t->p) {
         #if PY_MAJOR_VERSION < 3
@@ -16650,7 +21343,7 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
         } else {
             *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
         }
-        #else  /* Python 3+ has unicode identifiers */
+        #else
         if (t->is_unicode | t->is_str) {
             if (t->intern) {
                 *t->p = PyUnicode_InternFromString(t->s);
@@ -16670,27 +21363,88 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
     return 0;
 }
 
-
-/* Type Conversion Functions */
-
+static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {
+    return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str));
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) {
+    Py_ssize_t ignore;
+    return __Pyx_PyObject_AsStringAndSize(o, &ignore);
+}
+static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) {
+#if CYTHON_COMPILING_IN_CPYTHON && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT)
+    if (
+#if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+            __Pyx_sys_getdefaultencoding_not_ascii &&
+#endif
+            PyUnicode_Check(o)) {
+#if PY_VERSION_HEX < 0x03030000
+        char* defenc_c;
+        PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL);
+        if (!defenc) return NULL;
+        defenc_c = PyBytes_AS_STRING(defenc);
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        {
+            char* end = defenc_c + PyBytes_GET_SIZE(defenc);
+            char* c;
+            for (c = defenc_c; c < end; c++) {
+                if ((unsigned char) (*c) >= 128) {
+                    PyUnicode_AsASCIIString(o);
+                    return NULL;
+                }
+            }
+        }
+#endif
+        *length = PyBytes_GET_SIZE(defenc);
+        return defenc_c;
+#else
+        if (__Pyx_PyUnicode_READY(o) == -1) return NULL;
+#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII
+        if (PyUnicode_IS_ASCII(o)) {
+            *length = PyUnicode_GET_LENGTH(o);
+            return PyUnicode_AsUTF8(o);
+        } else {
+            PyUnicode_AsASCIIString(o);
+            return NULL;
+        }
+#else
+        return PyUnicode_AsUTF8AndSize(o, length);
+#endif
+#endif
+    } else
+#endif
+#if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE))
+    if (PyByteArray_Check(o)) {
+        *length = PyByteArray_GET_SIZE(o);
+        return PyByteArray_AS_STRING(o);
+    } else
+#endif
+    {
+        char* result;
+        int r = PyBytes_AsStringAndSize(o, &result, length);
+        if (unlikely(r < 0)) {
+            return NULL;
+        } else {
+            return result;
+        }
+    }
+}
 static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
    int is_true = x == Py_True;
    if (is_true | (x == Py_False) | (x == Py_None)) return is_true;
    else return PyObject_IsTrue(x);
 }
-
 static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
   PyNumberMethods *m;
   const char *name = NULL;
   PyObject *res = NULL;
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
   if (PyInt_Check(x) || PyLong_Check(x))
 #else
   if (PyLong_Check(x))
 #endif
-    return Py_INCREF(x), x;
+    return __Pyx_NewRef(x);
   m = Py_TYPE(x)->tp_as_number;
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
   if (m && m->nb_int) {
     name = "int";
     res = PyNumber_Int(x);
@@ -16706,13 +21460,13 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
   }
 #endif
   if (res) {
-#if PY_VERSION_HEX < 0x03000000
+#if PY_MAJOR_VERSION < 3
     if (!PyInt_Check(res) && !PyLong_Check(res)) {
 #else
     if (!PyLong_Check(res)) {
 #endif
       PyErr_Format(PyExc_TypeError,
-                   "__%s__ returned non-%s (type %.200s)",
+                   "__%.4s__ returned non-%.4s (type %.200s)",
                    name, name, Py_TYPE(res)->tp_name);
       Py_DECREF(res);
       return NULL;
@@ -16724,40 +21478,70 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
   }
   return res;
 }
-
 static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
   Py_ssize_t ival;
-  PyObject* x = PyNumber_Index(b);
+  PyObject *x;
+#if PY_MAJOR_VERSION < 3
+  if (likely(PyInt_CheckExact(b))) {
+    if (sizeof(Py_ssize_t) >= sizeof(long))
+        return PyInt_AS_LONG(b);
+    else
+        return PyInt_AsSsize_t(x);
+  }
+#endif
+  if (likely(PyLong_CheckExact(b))) {
+    #if CYTHON_USE_PYLONG_INTERNALS
+    const digit* digits = ((PyLongObject*)b)->ob_digit;
+    const Py_ssize_t size = Py_SIZE(b);
+    if (likely(__Pyx_sst_abs(size) <= 1)) {
+        ival = likely(size) ? digits[0] : 0;
+        if (size == -1) ival = -ival;
+        return ival;
+    } else {
+      switch (size) {
+         case 2:
+           if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) {
+             return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]));
+           }
+           break;
+         case -2:
+           if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) {
+             return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]));
+           }
+           break;
+         case 3:
+           if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) {
+             return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]));
+           }
+           break;
+         case -3:
+           if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) {
+             return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]));
+           }
+           break;
+         case 4:
+           if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) {
+             return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]));
+           }
+           break;
+         case -4:
+           if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) {
+             return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0]));
+           }
+           break;
+      }
+    }
+    #endif
+    return PyLong_AsSsize_t(b);
+  }
+  x = PyNumber_Index(b);
   if (!x) return -1;
   ival = PyInt_AsSsize_t(x);
   Py_DECREF(x);
   return ival;
 }
-
 static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
-#if PY_VERSION_HEX < 0x02050000
-   if (ival <= LONG_MAX)
-       return PyInt_FromLong((long)ival);
-   else {
-       unsigned char *bytes = (unsigned char *) &ival;
-       int one = 1; int little = (int)*(unsigned char*)&one;
-       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
-   }
-#else
-   return PyInt_FromSize_t(ival);
-#endif
-}
-
-static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
-   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
-   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
-       return (size_t)-1;
-   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
-       PyErr_SetString(PyExc_OverflowError,
-                       "value too large to convert to size_t");
-       return (size_t)-1;
-   }
-   return (size_t)val;
+    return PyInt_FromSize_t(ival);
 }
 
 
diff --git a/pyfftw/pyfftw.pxd b/pyfftw/pyfftw.pxd
index 12cfd2f..0e80a76 100644
--- a/pyfftw/pyfftw.pxd
+++ b/pyfftw/pyfftw.pxd
@@ -1,20 +1,36 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 cimport numpy as np
 from libc.stdint cimport int64_t
@@ -63,63 +79,63 @@ cdef extern from 'fftw3.h':
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             cdouble *_in, cdouble *_out,
-            int sign, unsigned flags)
+            int sign, unsigned flags) nogil
     
     # Single precision complex planner
     fftwf_plan fftwf_plan_guru_dft(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             cfloat *_in, cfloat *_out,
-            int sign, unsigned flags)
+            int sign, unsigned flags) nogil
 
     # Single precision complex planner
     fftwl_plan fftwl_plan_guru_dft(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             clongdouble *_in, clongdouble *_out,
-            int sign, unsigned flags)
+            int sign, unsigned flags) nogil
     
     # Double precision real to complex planner
     fftw_plan fftw_plan_guru_dft_r2c(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             double *_in, cdouble *_out,
-            unsigned flags)
+            unsigned flags) nogil
     
     # Single precision real to complex planner
     fftwf_plan fftwf_plan_guru_dft_r2c(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             float *_in, cfloat *_out,
-            unsigned flags)
+            unsigned flags) nogil
 
     # Single precision real to complex planner
     fftwl_plan fftwl_plan_guru_dft_r2c(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             long double *_in, clongdouble *_out,
-            unsigned flags)
+            unsigned flags) nogil
 
     # Double precision complex to real planner
     fftw_plan fftw_plan_guru_dft_c2r(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             cdouble *_in, double *_out,
-            unsigned flags)
+            unsigned flags) nogil
     
     # Single precision complex to real planner
     fftwf_plan fftwf_plan_guru_dft_c2r(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             cfloat *_in, float *_out,
-            unsigned flags)
+            unsigned flags) nogil
 
     # Single precision complex to real planner
     fftwl_plan fftwl_plan_guru_dft_c2r(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             clongdouble *_in, long double *_out,
-            unsigned flags)
+            unsigned flags) nogil
 
     # Double precision complex new array execute
     void fftw_execute_dft(fftw_plan,
@@ -227,7 +243,7 @@ ctypedef void * (*fftw_generic_plan_guru)(
         int rank, fftw_iodim *dims,
         int howmany_rank, fftw_iodim *howmany_dims,
         void *_in, void *_out,
-        int sign, int flags)
+        int sign, unsigned flags) nogil
 
 ctypedef void (*fftw_generic_execute)(void *_plan, void *_in, void *_out) nogil
 
@@ -258,4 +274,4 @@ cdef enum:
     FFTW_PRESERVE_INPUT = 16
     FFTW_PATIENT = 32
     FFTW_ESTIMATE = 64
-
+    FFTW_WISDOM_ONLY = 2097152
diff --git a/pyfftw/pyfftw.pyx b/pyfftw/pyfftw.pyx
index 61d2407..1fd38bd 100644
--- a/pyfftw/pyfftw.pyx
+++ b/pyfftw/pyfftw.pyx
@@ -1,20 +1,36 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2015 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import numpy as np
 cimport numpy as np
@@ -22,6 +38,9 @@ from libc.stdlib cimport calloc, malloc, free
 from libc.stdint cimport intptr_t, int64_t
 from libc cimport limits
 
+import warnings
+import threading
+
 include 'utils.pxi'
 
 cdef extern from *:
@@ -31,16 +50,25 @@ cdef object directions
 directions = {'FFTW_FORWARD': FFTW_FORWARD,
         'FFTW_BACKWARD': FFTW_BACKWARD}
 
+cdef object directions_lookup
+directions_lookup = {FFTW_FORWARD: 'FFTW_FORWARD',
+        FFTW_BACKWARD: 'FFTW_BACKWARD'}
+
 cdef object flag_dict
 flag_dict = {'FFTW_MEASURE': FFTW_MEASURE,
         'FFTW_EXHAUSTIVE': FFTW_EXHAUSTIVE,
         'FFTW_PATIENT': FFTW_PATIENT,
         'FFTW_ESTIMATE': FFTW_ESTIMATE,
         'FFTW_UNALIGNED': FFTW_UNALIGNED,
-        'FFTW_DESTROY_INPUT': FFTW_DESTROY_INPUT}
+        'FFTW_DESTROY_INPUT': FFTW_DESTROY_INPUT,
+        'FFTW_WISDOM_ONLY': FFTW_WISDOM_ONLY}
 
 _flag_dict = flag_dict.copy()
 
+# Need a global lock to protect FFTW planning so that multiple Python threads
+# do not attempt to plan simultaneously.
+cdef object plan_lock = threading.Lock()
+
 # Function wrappers
 # =================
 # All of these have the same signature as the fftw_generic functions
@@ -58,7 +86,7 @@ cdef void* _fftw_plan_guru_dft(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             void *_in, void *_out,
-            int sign, int flags):
+            int sign, unsigned flags) nogil:
 
     return <void *>fftw_plan_guru_dft(rank, dims,
             howmany_rank, howmany_dims,
@@ -70,7 +98,7 @@ cdef void* _fftwf_plan_guru_dft(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             void *_in, void *_out,
-            int sign, int flags):
+            int sign, unsigned flags) nogil:
 
     return <void *>fftwf_plan_guru_dft(rank, dims,
             howmany_rank, howmany_dims,
@@ -82,7 +110,7 @@ cdef void* _fftwl_plan_guru_dft(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             void *_in, void *_out,
-            int sign, int flags):
+            int sign, unsigned flags) nogil:
 
     return <void *>fftwl_plan_guru_dft(rank, dims,
             howmany_rank, howmany_dims,
@@ -94,7 +122,7 @@ cdef void* _fftw_plan_guru_dft_r2c(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             void *_in, void *_out,
-            int sign, int flags):
+            int sign, unsigned flags) nogil:
 
     return <void *>fftw_plan_guru_dft_r2c(rank, dims,
             howmany_rank, howmany_dims,
@@ -106,7 +134,7 @@ cdef void* _fftwf_plan_guru_dft_r2c(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             void *_in, void *_out,
-            int sign, int flags):
+            int sign, unsigned flags) nogil:
 
     return <void *>fftwf_plan_guru_dft_r2c(rank, dims,
             howmany_rank, howmany_dims,
@@ -118,7 +146,7 @@ cdef void* _fftwl_plan_guru_dft_r2c(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             void *_in, void *_out,
-            int sign, int flags):
+            int sign, unsigned flags) nogil:
 
     return <void *>fftwl_plan_guru_dft_r2c(rank, dims,
             howmany_rank, howmany_dims,
@@ -130,7 +158,7 @@ cdef void* _fftw_plan_guru_dft_c2r(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             void *_in, void *_out,
-            int sign, int flags):
+            int sign, unsigned flags) nogil:
 
     return <void *>fftw_plan_guru_dft_c2r(rank, dims,
             howmany_rank, howmany_dims,
@@ -142,7 +170,7 @@ cdef void* _fftwf_plan_guru_dft_c2r(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             void *_in, void *_out,
-            int sign, int flags):
+            int sign, unsigned flags) nogil:
 
     return <void *>fftwf_plan_guru_dft_c2r(rank, dims,
             howmany_rank, howmany_dims,
@@ -154,7 +182,7 @@ cdef void* _fftwl_plan_guru_dft_c2r(
             int rank, fftw_iodim *dims,
             int howmany_rank, fftw_iodim *howmany_dims,
             void *_in, void *_out,
-            int sign, int flags):
+            int sign, unsigned flags) nogil:
 
     return <void *>fftwl_plan_guru_dft_c2r(rank, dims,
             howmany_rank, howmany_dims,
@@ -562,6 +590,7 @@ cdef void make_axes_unique(int64_t *axes, int64_t axes_length,
 
     return
 
+
 # The External Interface
 # ======================
 #
@@ -596,66 +625,65 @@ cdef class FFTW:
     '''
     # Each of these function pointers simply
     # points to a chosen fftw wrapper function
-    cdef fftw_generic_plan_guru __fftw_planner
-    cdef fftw_generic_execute __fftw_execute
-    cdef fftw_generic_destroy_plan __fftw_destroy
-    cdef fftw_generic_plan_with_nthreads __nthreads_plan_setter
+    cdef fftw_generic_plan_guru _fftw_planner
+    cdef fftw_generic_execute _fftw_execute
+    cdef fftw_generic_destroy_plan _fftw_destroy
+    cdef fftw_generic_plan_with_nthreads _nthreads_plan_setter
 
     # The plan is typecast when it is created or used
     # within the wrapper functions
-    cdef void *__plan
-
-    cdef np.ndarray __input_array
-    cdef np.ndarray __output_array
-    cdef int __direction
-    cdef int __flags
-
-    cdef bint __simd_allowed
-    cdef int __input_array_alignment
-    cdef int __output_array_alignment    
-    cdef bint __use_threads
-
-    cdef object __input_strides
-    cdef object __input_byte_strides
-    cdef object __output_strides
-    cdef object __output_byte_strides
-    cdef object __input_shape
-    cdef object __output_shape
-    cdef object __input_dtype
-    cdef object __output_dtype
-    cdef object __flags_used
-
-    cdef float __normalisation_scaling
-
-    cdef int __rank
-    cdef _fftw_iodim *__dims
-    cdef int __howmany_rank
-    cdef _fftw_iodim *__howmany_dims
-
-    cdef int64_t *__axes
-    cdef int64_t *__not_axes
-
-    cdef int __N
-    def __get_N(self):
+    cdef void *_plan
+
+    cdef np.ndarray _input_array
+    cdef np.ndarray _output_array
+    cdef int _direction
+    cdef unsigned _flags
+
+    cdef bint _simd_allowed
+    cdef int _input_array_alignment
+    cdef int _output_array_alignment    
+
+    cdef object _input_item_strides
+    cdef object _input_strides
+    cdef object _output_item_strides
+    cdef object _output_strides
+    cdef object _input_shape
+    cdef object _output_shape
+    cdef object _input_dtype
+    cdef object _output_dtype
+    cdef object _flags_used
+
+    cdef double _normalisation_scaling
+
+    cdef int _rank
+    cdef _fftw_iodim *_dims
+    cdef int _howmany_rank
+    cdef _fftw_iodim *_howmany_dims
+
+    cdef int64_t *_axes
+    cdef int64_t *_not_axes
+
+    cdef int64_t _N
+    def _get_N(self):
         '''
         The product of the lengths of the DFT over all DFT axes.
         1/N is the normalisation constant. For any input array A, 
         and for any set of axes, 1/N * ifft(fft(A)) = A
         '''
-        return self.__N
+        return self._N
 
-    N = property(__get_N)
+    N = property(_get_N)
 
-    def __get_simd_aligned(self):
+    def _get_simd_aligned(self):
         '''
         Return whether or not this FFTW object requires simd aligned
         input and output data.
         '''
-        return self.__simd_allowed
+        return self._simd_allowed
 
-    simd_aligned = property(__get_simd_aligned)
+    simd_aligned = property(_get_simd_aligned)
 
-    def __get_input_alignment(self):
+    def _get_input_alignment(self):
         '''
         Returns the byte alignment of the input arrays for which the
         :class:`~pyfftw.FFTW` object was created.
@@ -665,11 +693,11 @@ cdef class FFTW:
         a copy being made if the :meth:`~pyfftw.FFTW.__call__` 
         interface is used.
         '''
-        return self.__input_array_alignment
+        return self._input_array_alignment
 
-    input_alignment = property(__get_input_alignment)
+    input_alignment = property(_get_input_alignment)
 
-    def __get_output_alignment(self):
+    def _get_output_alignment(self):
         '''
         Returns the byte alignment of the output arrays for which the
         :class:`~pyfftw.FFTW` object was created.
@@ -677,32 +705,121 @@ cdef class FFTW:
         Output array updates with arrays that are not aligned on this
         byte boundary will result in a ValueError being raised.
         '''
-        return self.__output_array_alignment
+        return self._output_array_alignment
 
-    output_alignment = property(__get_output_alignment)
+    output_alignment = property(_get_output_alignment)
 
-    def __get_flags_used(self):
+    def _get_flags_used(self):
         '''
         Return which flags were used to construct the FFTW object.
         
         This includes flags that were added during initialisation.
         '''
-        return tuple(self.__flags_used)
+        return tuple(self._flags_used)
+
+    flags = property(_get_flags_used)
+
+    def _get_input_array(self):
+        '''
+        Return the input array that is associated with the FFTW 
+        instance.
+        '''
+        return self._input_array
+
+    input_array = property(_get_input_array)
+
+    def _get_output_array(self):
+        '''
+        Return the output array that is associated with the FFTW 
+        instance.
+        '''
+        return self._output_array
 
-    flags = property(__get_flags_used)
+    output_array = property(_get_output_array)
+
+    def _get_input_strides(self):
+        '''
+        Return the strides of the input array for which the FFT is planned.
+        '''
+        return self._input_strides
+    
+    input_strides = property(_get_input_strides)
+
+    def _get_output_strides(self):
+        '''
+        Return the strides of the output array for which the FFT is planned.
+        '''
+        return self._output_strides
+    
+    output_strides = property(_get_output_strides)
+
+    def _get_input_shape(self):
+        '''
+        Return the shape of the input array for which the FFT is planned.
+        '''
+        return self._input_shape
+    
+    input_shape = property(_get_input_shape)
+
+    def _get_output_shape(self):
+        '''
+        Return the shape of the output array for which the FFT is planned.
+        '''
+        return self._output_shape
+    
+    output_shape = property(_get_output_shape)
+
+    def _get_input_dtype(self):
+        '''
+        Return the dtype of the input array for which the FFT is planned.
+        '''
+        return self._input_dtype
+    
+    input_dtype = property(_get_input_dtype)
+
+    def _get_output_dtype(self):
+        '''
+        Return the shape of the output array for which the FFT is planned.
+        '''
+        return self._output_dtype
+    
+    output_dtype = property(_get_output_dtype)
+
+    def _get_direction(self):
+        '''
+        Return the planned FFT direction. Either `'FFTW_FORWARD'` or 
+        `'FFTW_BACKWARD'`.
+        '''
+        return directions_lookup[self._direction]
+    
+    direction = property(_get_direction)
+
+    def _get_axes(self):
+        '''
+        Return the axes for the planned FFT in canonical form. That is, as
+        a tuple of positive integers. The order in which they were passed
+        is maintained.
+        '''
+        axes = []
+        for i in range(self._rank):
+            axes.append(self._axes[i])
+
+        return tuple(axes)
+    
+    axes = property(_get_axes)
 
     def __cinit__(self, input_array, output_array, axes=(-1,),
-            direction='FFTW_FORWARD', flags=('FFTW_MEASURE',), 
-            unsigned int threads=1, planning_timelimit=None,
-            *args, **kwargs):
+                  direction='FFTW_FORWARD', flags=('FFTW_MEASURE',), 
+                  unsigned int threads=1, planning_timelimit=None,
+                  *args, **kwargs):
         
         # Initialise the pointers that need to be freed
-        self.__plan = NULL
-        self.__dims = NULL
-        self.__howmany_dims = NULL
+        self._plan = NULL
+        self._dims = NULL
+        self._howmany_dims = NULL
 
-        self.__axes = NULL
-        self.__not_axes = NULL
+        self._axes = NULL
+        self._not_axes = NULL
 
         flags = list(flags)
 
@@ -735,33 +852,40 @@ cdef class FFTW:
                     'The output array and input array dtypes '
                     'do not correspond to a valid fftw scheme.')
 
-        self.__input_dtype = input_dtype
-        self.__output_dtype = output_dtype
+        self._input_dtype = input_dtype
+        self._output_dtype = output_dtype
         
         functions = scheme_functions[scheme]
         
-        self.__fftw_planner = planners[functions['planner']]
-        self.__fftw_execute = executors[functions['executor']]
-        self.__fftw_destroy = destroyers[functions['generic_precision']]
+        self._fftw_planner = planners[functions['planner']]
+        self._fftw_execute = executors[functions['executor']]
+        self._fftw_destroy = destroyers[functions['generic_precision']]
 
-        self.__nthreads_plan_setter = (
+        self._nthreads_plan_setter = (
                 nthreads_plan_setters[functions['generic_precision']])
 
         cdef fftw_generic_set_timelimit set_timelimit_func = (
                 set_timelimit_funcs[functions['generic_precision']])
 
+        # We're interested in the natural alignment on the real type, not
+        # necessarily on the complex type At least one bug was found where
+        # numpy reported an alignment on a complex dtype that was different
+        # to that on the real type.
+        cdef int natural_input_alignment = input_array.real.dtype.alignment
+        cdef int natural_output_alignment = output_array.real.dtype.alignment
+
         # If either of the arrays is not aligned on a 16-byte boundary,
         # we set the FFTW_UNALIGNED flag. This disables SIMD.
         # (16 bytes is assumed to be the minimal alignment)
         if 'FFTW_UNALIGNED' in flags:
-            self.__simd_allowed = False
-            self.__input_array_alignment = self.__input_dtype.alignment
-            self.__output_array_alignment = self.__output_dtype.alignment
+            self._simd_allowed = False
+            self._input_array_alignment = natural_input_alignment
+            self._output_array_alignment = natural_output_alignment
 
         else:
 
-            self.__input_array_alignment = -1
-            self.__output_array_alignment = -1
+            self._input_array_alignment = -1
+            self._output_array_alignment = -1
 
             for each_alignment in _valid_simd_alignments:
                 if (<intptr_t>np.PyArray_DATA(input_array) % 
@@ -769,61 +893,61 @@ cdef class FFTW:
                         <intptr_t>np.PyArray_DATA(output_array) % 
                         each_alignment == 0):
 
-                    self.__simd_allowed = True
+                    self._simd_allowed = True
 
-                    self.__input_array_alignment = each_alignment
-                    self.__output_array_alignment = each_alignment
+                    self._input_array_alignment = each_alignment
+                    self._output_array_alignment = each_alignment
 
                     break
 
-            if (self.__input_array_alignment == -1 or
-                    self.__output_array_alignment == -1):
+            if (self._input_array_alignment == -1 or
+                    self._output_array_alignment == -1):
 
-                self.__simd_allowed = False
+                self._simd_allowed = False
 
-                self.__input_array_alignment = (
-                        self.__input_dtype.alignment)
-                self.__output_array_alignment = (
-                        self.__output_dtype.alignment)
+                self._input_array_alignment = (
+                        natural_input_alignment)
+                self._output_array_alignment = (
+                        natural_output_alignment)
                 flags.append('FFTW_UNALIGNED')
 
         if (not (<intptr_t>np.PyArray_DATA(input_array)
-            % self.__input_array_alignment == 0)):
+            % self._input_array_alignment == 0)):
             raise ValueError('Invalid input alignment: '
                     'The input array is expected to lie on a %d '
-                    'byte boundary.' % self.__input_array_alignment)
+                    'byte boundary.' % self._input_array_alignment)
 
         if (not (<intptr_t>np.PyArray_DATA(output_array)
-            % self.__output_array_alignment == 0)):
+            % self._output_array_alignment == 0)):
             raise ValueError('Invalid output alignment: '
                     'The output array is expected to lie on a %d '
-                    'byte boundary.' % self.__output_array_alignment)
+                    'byte boundary.' % self._output_array_alignment)
 
         if not direction in scheme_directions[scheme]:
             raise ValueError('Invalid direction: '
                     'The direction is not valid for the scheme. '
                     'Try setting it explicitly if it is not already.')
 
-        self.__direction = directions[direction]
-        self.__input_shape = input_array.shape
-        self.__output_shape = output_array.shape
+        self._direction = directions[direction]
+        self._input_shape = input_array.shape
+        self._output_shape = output_array.shape
         
-        self.__input_array = input_array
-        self.__output_array = output_array
+        self._input_array = input_array
+        self._output_array = output_array
 
-        self.__axes = <int64_t *>malloc(len(axes)*sizeof(int64_t))
+        self._axes = <int64_t *>malloc(len(axes)*sizeof(int64_t))
         for n in range(len(axes)):
-            self.__axes[n] = axes[n]
+            self._axes[n] = axes[n]
 
         # Set the negative entries to their actual index (use the size
         # of the shape array for this)
-        cdef int64_t array_dimension = len(self.__input_shape)
+        cdef int64_t array_dimension = len(self._input_shape)
 
         for n in range(len(axes)):
-            if self.__axes[n] < 0:
-                self.__axes[n] = self.__axes[n] + array_dimension
+            if self._axes[n] < 0:
+                self._axes[n] = self._axes[n] + array_dimension
 
-            if self.__axes[n] >= array_dimension or self.__axes[n] < 0:
+            if self._axes[n] >= array_dimension or self._axes[n] < 0:
                 raise IndexError('Invalid axes: '
                     'The axes list cannot contain invalid axes.')
 
@@ -831,28 +955,28 @@ cdef class FFTW:
         cdef int64_t *unique_axes
         cdef int64_t *not_axes
         
-        make_axes_unique(self.__axes, len(axes), &unique_axes,
+        make_axes_unique(self._axes, len(axes), &unique_axes,
                 &not_axes, array_dimension, &unique_axes_length)
 
         # and assign axes and not_axes to the filled arrays
-        free(self.__axes)
-        self.__axes = unique_axes
-        self.__not_axes = not_axes
+        free(self._axes)
+        self._axes = unique_axes
+        self._not_axes = not_axes
 
         total_N = 1
         for n in range(unique_axes_length):
-            if self.__input_shape[self.__axes[n]] == 0:
+            if self._input_shape[self._axes[n]] == 0:
                 raise ValueError('Zero length array: '
                     'The input array should have no zero length'
                     'axes over which the FFT is to be taken')
 
-            if self.__direction == FFTW_FORWARD:
-                total_N *= self.__input_shape[self.__axes[n]]
+            if self._direction == FFTW_FORWARD:
+                total_N *= self._input_shape[self._axes[n]]
             else:
-                total_N *= self.__output_shape[self.__axes[n]]
+                total_N *= self._output_shape[self._axes[n]]
 
-        self.__N = total_N
-        self.__normalisation_scaling = 1/float(self.N)
+        self._N = total_N
+        self._normalisation_scaling = 1/float(self.N)
 
         # Now we can validate the array shapes
         cdef validator _validator
@@ -865,120 +989,130 @@ cdef class FFTW:
         else:
             _validator = validators[functions['validator']]
             if not _validator(input_array, output_array, 
-                    self.__axes, self.__not_axes, unique_axes_length):
+                    self._axes, self._not_axes, unique_axes_length):
                 raise ValueError('Invalid shapes: '
                         'The input array and output array are invalid '
                         'complementary shapes for their dtypes.')
 
-        self.__rank = unique_axes_length
-        self.__howmany_rank = self.__input_array.ndim - unique_axes_length
+        self._rank = unique_axes_length
+        self._howmany_rank = self._input_array.ndim - unique_axes_length
         
-        self.__flags = 0
-        self.__flags_used = []
+        self._flags = 0
+        self._flags_used = []
         for each_flag in flags:
             try:
-                self.__flags |= flag_dict[each_flag]
-                self.__flags_used.append(each_flag)
+                self._flags |= flag_dict[each_flag]
+                self._flags_used.append(each_flag)
             except KeyError:
                 raise ValueError('Invalid flag: ' + '\'' + 
                         each_flag + '\' is not a valid planner flag.')
 
         
         if ('FFTW_DESTROY_INPUT' not in flags) and (
-                (scheme[0] != 'c2r') or not self.__rank > 1):
+                (scheme[0] != 'c2r') or not self._rank > 1):
             # The default in all possible cases is to preserve the input
             # This is not possible for r2c arrays with rank > 1
-            self.__flags |= FFTW_PRESERVE_INPUT
+            self._flags |= FFTW_PRESERVE_INPUT
 
         # Set up the arrays of structs for holding the stride shape 
         # information
-        self.__dims = <_fftw_iodim *>malloc(
-                self.__rank * sizeof(_fftw_iodim))
-        self.__howmany_dims = <_fftw_iodim *>malloc(
-                self.__howmany_rank * sizeof(_fftw_iodim))
+        self._dims = <_fftw_iodim *>malloc(
+                self._rank * sizeof(_fftw_iodim))
+        self._howmany_dims = <_fftw_iodim *>malloc(
+                self._howmany_rank * sizeof(_fftw_iodim))
 
-        if self.__dims == NULL or self.__howmany_dims == NULL:
+        if self._dims == NULL or self._howmany_dims == NULL:
             # Not much else to do than raise an exception
             raise MemoryError
 
         # Find the strides for all the axes of both arrays in terms of the 
-        # number of elements (as opposed to the number of bytes).
-        self.__input_byte_strides = input_array.strides        
-        self.__input_strides = tuple([stride/input_array.itemsize 
+        # number of items (as opposed to the number of bytes).
+        self._input_strides = input_array.strides        
+        self._input_item_strides = tuple([stride/input_array.itemsize 
             for stride in input_array.strides])
-        self.__output_byte_strides = output_array.strides
-        self.__output_strides = tuple([stride/output_array.itemsize 
+        self._output_strides = output_array.strides
+        self._output_item_strides = tuple([stride/output_array.itemsize 
             for stride in output_array.strides])
 
         # Make sure that the arrays are not too big for fftw
         # This is hard to test, so we cross our fingers and hope for the 
         # best (any suggestions, please get in touch).
         cdef int i
-        for i in range(0, len(self.__input_shape)):
-            if self.__input_shape[i] >= <Py_ssize_t> limits.INT_MAX:
+        for i in range(0, len(self._input_shape)):
+            if self._input_shape[i] >= <Py_ssize_t> limits.INT_MAX:
                 raise ValueError('Dimensions of the input array must be ' +
                         'less than ', str(limits.INT_MAX))
 
-            if self.__input_strides[i] >= <Py_ssize_t> limits.INT_MAX:
+            if self._input_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:
                 raise ValueError('Strides of the input array must be ' +
                         'less than ', str(limits.INT_MAX))
 
-        for i in range(0, len(self.__output_shape)):
-            if self.__output_shape[i] >= <Py_ssize_t> limits.INT_MAX:
+        for i in range(0, len(self._output_shape)):
+            if self._output_shape[i] >= <Py_ssize_t> limits.INT_MAX:
                 raise ValueError('Dimensions of the output array must be ' +
                         'less than ', str(limits.INT_MAX))
 
-            if self.__output_strides[i] >= <Py_ssize_t> limits.INT_MAX:
+            if self._output_item_strides[i] >= <Py_ssize_t> limits.INT_MAX:
                 raise ValueError('Strides of the output array must be ' +
                         'less than ', str(limits.INT_MAX))
 
         fft_shape_lookup = functions['fft_shape_lookup']
         if fft_shape_lookup == -1:
-            fft_shape = self.__input_shape
+            fft_shape = self._input_shape
         else:
             fft_shape = fft_shape_lookup(input_array, output_array)
 
         # Fill in the stride and shape information
-        input_strides_array = self.__input_strides
-        output_strides_array = self.__output_strides
-        for i in range(0, self.__rank):
-            self.__dims[i]._n = fft_shape[self.__axes[i]]
-            self.__dims[i]._is = input_strides_array[self.__axes[i]]
-            self.__dims[i]._os = output_strides_array[self.__axes[i]]
-
-        for i in range(0, self.__howmany_rank):
-            self.__howmany_dims[i]._n = fft_shape[self.__not_axes[i]]
-            self.__howmany_dims[i]._is = input_strides_array[self.__not_axes[i]]
-            self.__howmany_dims[i]._os = output_strides_array[self.__not_axes[i]]
+        input_strides_array = self._input_item_strides
+        output_strides_array = self._output_item_strides
+        for i in range(0, self._rank):
+            self._dims[i]._n = fft_shape[self._axes[i]]
+            self._dims[i]._is = input_strides_array[self._axes[i]]
+            self._dims[i]._os = output_strides_array[self._axes[i]]
+
+        for i in range(0, self._howmany_rank):
+            self._howmany_dims[i]._n = fft_shape[self._not_axes[i]]
+            self._howmany_dims[i]._is = input_strides_array[self._not_axes[i]]
+            self._howmany_dims[i]._os = output_strides_array[self._not_axes[i]]
 
         ## Point at which FFTW calls are made
         ## (and none should be made before this)
-        if threads > 1:
-            self.__use_threads = True
-            self.__nthreads_plan_setter(threads)
-        else:
-            self.__use_threads = False
-            self.__nthreads_plan_setter(1)
+        self._nthreads_plan_setter(threads)
 
         # Set the timelimit
         set_timelimit_func(_planning_timelimit)
 
-        # Finally, construct the plan
-        self.__plan = self.__fftw_planner(
-            self.__rank, <fftw_iodim *>self.__dims,
-            self.__howmany_rank, <fftw_iodim *>self.__howmany_dims,
-            <void *>np.PyArray_DATA(self.__input_array),
-            <void *>np.PyArray_DATA(self.__output_array),
-            self.__direction, self.__flags)
-
-        if self.__plan == NULL:
-            raise RuntimeError('The data has an uncaught error that led '+
+        # Finally, construct the plan, after acquiring the global planner lock
+        # (so that only one python thread can plan at a time, as the FFTW
+        # planning functions are not thread-safe)
+        
+        # no self-lookups allowed in nogil block, so must grab all these first
+        cdef void *plan
+        cdef fftw_generic_plan_guru fftw_planner = self._fftw_planner
+        cdef int rank = self._rank
+        cdef fftw_iodim *dims = <fftw_iodim *>self._dims
+        cdef int howmany_rank = self._howmany_rank
+        cdef fftw_iodim *howmany_dims = <fftw_iodim *>self._howmany_dims
+        cdef void *_in = <void *>np.PyArray_DATA(self._input_array)
+        cdef void *_out = <void *>np.PyArray_DATA(self._output_array)
+        cdef int sign = self._direction
+        cdef unsigned c_flags = self._flags
+
+        with plan_lock, nogil:
+            plan = fftw_planner(rank, dims, howmany_rank, howmany_dims,
+                                _in, _out, sign, c_flags)
+        self._plan = plan
+        
+        if self._plan == NULL:
+            if 'FFTW_WISDOM_ONLY' in flags:
+                raise RuntimeError('No FFTW wisdom is known for this plan.')
+            else:
+                raise RuntimeError('The data has an uncaught error that led '+
                     'to the planner returning NULL. This is a bug.')
 
     def __init__(self, input_array, output_array, axes=(-1,), 
             direction='FFTW_FORWARD', flags=('FFTW_MEASURE',), 
-            int threads=1, planning_timelimit=None, 
-            *args, **kwargs):
+            int threads=1, planning_timelimit=None):
         '''
         **Arguments**:
 
@@ -1034,6 +1168,23 @@ cdef class FFTW:
             possible to preserve the input, making this flag implicit
             in that case. A little more on this is given 
             :ref:`below<scheme_table>`.
+          * ``'FFTW_WISDOM_ONLY'`` is supported.
+            This tells FFTW to raise an error if no plan for this transform
+            and data type is already in the wisdom. It thus provides a method
+            to determine whether planning would require additional effor or the
+            cached wisdom can be used. This flag should be combined with the
+            various planning-effort flags (``'FFTW_ESTIMATE'``,
+            ``'FFTW_MEASURE'``, etc.); if so, then an error will be raised if
+            wisdom derived from that level of planning effort (or higher) is 
+            not present. If no planning-effort flag is used, the default of
+            ``'FFTW_ESTIMATE'`` is assumed.
+            Note that wisdom is specific to all the parameters, including the
+            data alignment. That is, if wisdom was generated with input/output
+            arrays with one specific alignment, using ``'FFTW_WISDOM_ONLY'``
+            to create a plan for arrays with any different alignment will 
+            cause the ``'FFTW_WISDOM_ONLY'`` planning to fail. Thus it is
+            important to specifically control the data alignment to make the
+            best use of ``'FFTW_WISDOM_ONLY'``.
 
           The `FFTW planner flags documentation 
           <http://www.fftw.org/fftw3_doc/Planner-Flags.html#Planner-Flags>`_
@@ -1041,9 +1192,7 @@ cdef class FFTW:
           Note that only the flags documented here are supported.
 
         * ``threads`` tells the wrapper how many threads to use
-          when invoking FFTW, with a default of 1. If the number
-          of threads is greater than 1, then the GIL is released
-          by necessity.
+          when invoking FFTW, with a default of 1.
 
         * ``planning_timelimit`` is a floating point number that 
           indicates to the underlying FFTW planner the maximum number of
@@ -1148,9 +1297,9 @@ cdef class FFTW:
         instructions can be explicitly disabled by setting the
         FFTW_UNALIGNED flags, to allow for updates with unaligned
         data.
-        
-        :func:`~pyfftw.n_byte_align` and 
-        :func:`~pyfftw.n_byte_align_empty` are two methods
+
+        :func:`~pyfftw.byte_align` and
+        :func:`~pyfftw.empty_aligned` are two methods
         included with this module for producing aligned arrays.
 
         The optimum alignment for the running platform is provided
@@ -1172,20 +1321,20 @@ cdef class FFTW:
 
     def __dealloc__(self):
 
-        if not self.__axes == NULL:
-            free(self.__axes)
+        if not self._axes == NULL:
+            free(self._axes)
 
-        if not self.__not_axes == NULL:
-            free(self.__not_axes)
+        if not self._not_axes == NULL:
+            free(self._not_axes)
 
-        if not self.__plan == NULL:
-            self.__fftw_destroy(self.__plan)
+        if not self._plan == NULL:
+            self._fftw_destroy(self._plan)
 
-        if not self.__dims == NULL:
-            free(self.__dims)
+        if not self._dims == NULL:
+            free(self._dims)
 
-        if not self.__howmany_dims == NULL:
-            free(self.__howmany_dims)
+        if not self._howmany_dims == NULL:
+            free(self._howmany_dims)
 
     def __call__(self, input_array=None, output_array=None, 
             normalise_idft=True):
@@ -1248,16 +1397,16 @@ cdef class FFTW:
         if input_array is not None or output_array is not None:
 
             if input_array is None:
-                input_array = self.__input_array
+                input_array = self._input_array
 
             if output_array is None:
-                output_array = self.__output_array
+                output_array = self._output_array
 
             if not isinstance(input_array, np.ndarray):
                 copy_needed = True
-            elif (not input_array.dtype == self.__input_dtype):
+            elif (not input_array.dtype == self._input_dtype):
                 copy_needed = True
-            elif (not input_array.strides == self.__input_byte_strides):
+            elif (not input_array.strides == self._input_strides):
                 copy_needed = True
             elif not (<intptr_t>np.PyArray_DATA(input_array) 
                     % self.input_alignment == 0):
@@ -1270,18 +1419,18 @@ cdef class FFTW:
                 if not isinstance(input_array, np.ndarray):
                     input_array = np.asanyarray(input_array)
 
-                if not input_array.shape == self.__input_shape:
+                if not input_array.shape == self._input_shape:
                     raise ValueError('Invalid input shape: '
                             'The new input array should be the same shape '
                             'as the input array used to instantiate the '
                             'object.')
                 
-                self.__input_array[:] = input_array
+                self._input_array[:] = input_array
                 
                 if output_array is not None:
                     # No point wasting time if no update is necessary
                     # (which the copy above may have avoided)
-                    input_array = self.__input_array
+                    input_array = self._input_array
                     self.update_arrays(input_array, output_array)
 
             else:
@@ -1289,10 +1438,10 @@ cdef class FFTW:
 
         self.execute()
 
-        if self.__direction == FFTW_BACKWARD and normalise_idft:
-            self.__output_array *= self.__normalisation_scaling
+        if self._direction == FFTW_BACKWARD and normalise_idft:
+            self._output_array *= self._normalisation_scaling
 
-        return self.__output_array
+        return self._output_array
 
     cpdef update_arrays(self, 
             new_input_array, new_output_array):
@@ -1341,12 +1490,12 @@ cdef class FFTW:
                     'necessary that the update output array is similarly '
                     'aligned.' % self.output_alignment)
 
-        if not new_input_array.dtype == self.__input_dtype:
+        if not new_input_array.dtype == self._input_dtype:
             raise ValueError('Invalid input dtype: '
                     'The new input array is not of the same '
                     'dtype as was originally planned for.')
 
-        if not new_output_array.dtype == self.__output_dtype:
+        if not new_output_array.dtype == self._output_dtype:
             raise ValueError('Invalid output dtype: '
                     'The new output array is not of the same '
                     'dtype as was originally planned for.')
@@ -1357,22 +1506,22 @@ cdef class FFTW:
         new_input_strides = new_input_array.strides
         new_output_strides = new_output_array.strides
 
-        if not new_input_shape == self.__input_shape:
+        if not new_input_shape == self._input_shape:
             raise ValueError('Invalid input shape: '
                     'The new input array should be the same shape as '
                     'the input array used to instantiate the object.')
 
-        if not new_output_shape == self.__output_shape:
+        if not new_output_shape == self._output_shape:
             raise ValueError('Invalid output shape: '
                     'The new output array should be the same shape as '
                     'the output array used to instantiate the object.')
         
-        if not new_input_strides == self.__input_byte_strides:
+        if not new_input_strides == self._input_strides:
             raise ValueError('Invalid input striding: '
                     'The strides should be identical for the new '
                     'input array as for the old.')
         
-        if not new_output_strides == self.__output_byte_strides:
+        if not new_output_strides == self._output_strides:
             raise ValueError('Invalid output striding: '
                     'The strides should be identical for the new '
                     'output array as for the old.')
@@ -1384,46 +1533,56 @@ cdef class FFTW:
         ''' A C interface to the update_arrays method that does not
         perform any checks on strides being correct and so on.
         '''
-        self.__input_array = new_input_array
-        self.__output_array = new_output_array
+        self._input_array = new_input_array
+        self._output_array = new_output_array
 
     def get_input_array(self):
         '''get_input_array()
 
         Return the input array that is associated with the FFTW 
         instance.
+
+        *Deprecated since 0.10. Consider using the* :attr:`FFTW.input_array` 
+        *property instead.*
         '''
-        return self.__input_array
+        warnings.warn('get_input_array is deprecated. '
+                'Consider using the input_array property instead.', 
+                DeprecationWarning)
+
+        return self._input_array
 
     def get_output_array(self):
         '''get_output_array()
 
         Return the output array that is associated with the FFTW
         instance.
+
+        *Deprecated since 0.10. Consider using the* :attr:`FFTW.output_array` 
+        *property instead.*
         '''
-        return self.__output_array
+        warnings.warn('get_output_array is deprecated. '
+                'Consider using the output_array property instead.', 
+                DeprecationWarning)
+        
+        return self._output_array
 
     cpdef execute(self):
         '''execute()
 
         Execute the planned operation, taking the correct kind of FFT of
-        the input array (what is returned by :meth:`get_input_array`), 
-        and putting the result in the output array (what is returned by
-        :meth:`get_output_array`).
+        the input array (i.e. :attr:`FFTW.input_array`), 
+        and putting the result in the output array (i.e.
+        :attr:`FFTW.output_array`).
         '''
         cdef void *input_pointer = (
-                <void *>np.PyArray_DATA(self.__input_array))
+                <void *>np.PyArray_DATA(self._input_array))
         cdef void *output_pointer = (
-                <void *>np.PyArray_DATA(self.__output_array))
+                <void *>np.PyArray_DATA(self._output_array))
         
-        cdef void *plan = self.__plan
-        cdef fftw_generic_execute fftw_execute = self.__fftw_execute
-        
-        if self.__use_threads:
-            with nogil:
-                fftw_execute(plan, input_pointer, output_pointer)
-        else:
-            fftw_execute(self.__plan, input_pointer, output_pointer)
+        cdef void *plan = self._plan
+        cdef fftw_generic_execute fftw_execute = self._fftw_execute
+        with nogil:
+            fftw_execute(plan, input_pointer, output_pointer)
 
 cdef void count_char(char c, void *counter_ptr):
     '''
diff --git a/pyfftw/utils.pxi b/pyfftw/utils.pxi
index 27359d4..f72c7aa 100644
--- a/pyfftw/utils.pxi
+++ b/pyfftw/utils.pxi
@@ -1,24 +1,44 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
-# 
+# Copyright 2014 Knowledge Economy Developments Ltd
+# Copyright 2014 David Wells
+#
 # Henry Gomersall
 # heng at kedevelopments.co.uk
+# David Wells
+# drwells <at> vt.edu
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 cimport numpy as np
 cimport cpu
 from libc.stdint cimport intptr_t
+import warnings
 
 
 cdef int _simd_alignment = cpu.simd_alignment()
@@ -38,56 +58,62 @@ else:
 
 cpdef n_byte_align_empty(shape, n, dtype='float64', order='C'):
     '''n_byte_align_empty(shape, n, dtype='float64', order='C')
+    **This function is deprecated:** ``empty_aligned`` **should be used
+    instead.**
 
-    Function that returns an empty numpy array
-    that is n-byte aligned.
+    Function that returns an empty numpy array that is n-byte aligned.
 
-    The alignment is given by the second argument, ``n``.
-    The rest of the arguments are as per :func:`numpy.empty`.
+    The alignment is given by the first optional argument, ``n``. If
+    ``n`` is not provided then this function will inspect the CPU to
+    determine alignment. The rest of the arguments are as per
+    :func:`numpy.empty`.
     '''
-    
-    itemsize = np.dtype(dtype).itemsize
+    warnings.warn('This function is deprecated in favour of'
+    '``empty_aligned``.', DeprecationWarning)
+    return empty_aligned(shape, dtype=dtype, order=order, n=n)
 
-    # Apparently there is an issue with numpy.prod wrapping around on 32-bits
-    # on Windows 64-bit. This shouldn't happen, but the following code 
-    # alleviates the problem.
-    if not isinstance(shape, (int, np.integer)):
-        array_length = 1
-        for each_dimension in shape:
-            array_length *= each_dimension
-    
-    else:
-        array_length = shape
 
-    # Allocate a new array that will contain the aligned data
-    _array_aligned = np.empty(array_length*itemsize+n, dtype='int8')
-    
-    # We now need to know how to offset _array_aligned 
-    # so it is correctly aligned
-    _array_aligned_offset = (n-<intptr_t>np.PyArray_DATA(_array_aligned))%n
+cpdef n_byte_align(array, n, dtype=None):
+    '''n_byte_align(array, n, dtype=None)
 
-    array = np.frombuffer(
-            _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,
-            dtype=dtype).reshape(shape, order=order)
-    
-    return array
+    **This function is deprecated:** ``byte_align`` **should be used instead.**
 
-cpdef n_byte_align(array, n, dtype=None):
-    ''' n_byte_align(array, n, dtype=None)
+    Function that takes a numpy array and checks it is aligned on an n-byte
+    boundary, where ``n`` is an optional parameter. If ``n`` is not provided
+    then this function will inspect the CPU to determine alignment. If the
+    array is aligned then it is returned without further ado.  If it is not
+    aligned then a new array is created and the data copied in, but aligned
+    on the n-byte boundary.
+
+    ``dtype`` is an optional argument that forces the resultant array to be
+    of that dtype.
+    '''
+    warnings.warn('This function is deprecated in favour of'
+    '``byte_align``.', DeprecationWarning)
+    return byte_align(array, n=n, dtype=dtype)
+
+
+cpdef byte_align(array, n=None, dtype=None):
+    '''byte_align(array, n=None, dtype=None)
 
     Function that takes a numpy array and checks it is aligned on an n-byte
-    boundary, where ``n`` is a passed parameter. If it is, the array is
-    returned without further ado.  If it is not, a new array is created and
-    the data copied in, but aligned on the n-byte boundary.
+    boundary, where ``n`` is an optional parameter. If ``n`` is not provided
+    then this function will inspect the CPU to determine alignment. If the
+    array is aligned then it is returned without further ado.  If it is not
+    aligned then a new array is created and the data copied in, but aligned
+    on the n-byte boundary.
 
     ``dtype`` is an optional argument that forces the resultant array to be
     of that dtype.
     '''
     
     if not isinstance(array, np.ndarray):
-        raise TypeError('Invalid array: n_byte_align requires a subclass '
+        raise TypeError('Invalid array: byte_align requires a subclass '
                 'of ndarray')
 
+    if n is None:
+        n = _simd_alignment
+
     if dtype is not None:
         if not array.dtype == dtype:
             update_dtype = True
@@ -101,7 +127,7 @@ cpdef n_byte_align(array, n, dtype=None):
 
     if offset is not 0 or update_dtype:
 
-        _array_aligned = n_byte_align_empty(array.shape, n, dtype)
+        _array_aligned = empty_aligned(array.shape, dtype, n=n)
 
         _array_aligned[:] = array
 
@@ -109,18 +135,111 @@ cpdef n_byte_align(array, n, dtype=None):
     
     return array
 
-cpdef is_n_byte_aligned(array, n):
-    ''' is_n_byte_aligned(array, n)
+
+cpdef is_byte_aligned(array, n=None):
+    ''' is_n_byte_aligned(array, n=None)
 
     Function that takes a numpy array and checks it is aligned on an n-byte
-    boundary, where ``n`` is a passed parameter, returning ``True`` if it is,
-    and ``False`` if it is not.
+    boundary, where ``n`` is an optional parameter, returning ``True`` if it is,
+    and ``False`` if it is not. If ``n`` is not provided then this function will
+    inspect the CPU to determine alignment.
     '''
     if not isinstance(array, np.ndarray):
         raise TypeError('Invalid array: is_n_byte_aligned requires a subclass '
                 'of ndarray')
 
+    if n is None:
+        n = _simd_alignment
+
     # See if we're n byte aligned.
     offset = <intptr_t>np.PyArray_DATA(array) %n
 
     return not bool(offset)
+
+
+cpdef is_n_byte_aligned(array, n):
+    ''' is_n_byte_aligned(array, n)
+    **This function is deprecated:** ``is_byte_aligned`` **should be used
+    instead.**
+
+    Function that takes a numpy array and checks it is aligned on an n-byte
+    boundary, where ``n`` is a passed parameter, returning ``True`` if it is,
+    and ``False`` if it is not.
+    '''
+    return is_byte_aligned(array, n=n)
+
+
+cpdef empty_aligned(shape, dtype='float64', order='C', n=None):
+    '''empty_aligned(shape, dtype='float64', order='C', n=None)
+
+    Function that returns an empty numpy array that is n-byte aligned,
+    where ``n`` is determined by inspecting the CPU if it is not
+    provided.
+
+    The alignment is given by the final optional argument, ``n``. If
+    ``n`` is not provided then this function will inspect the CPU to
+    determine alignment. The rest of the arguments are as per
+    :func:`numpy.empty`.
+    '''
+    if n is None:
+        n = _simd_alignment
+
+    itemsize = np.dtype(dtype).itemsize
+
+    # Apparently there is an issue with numpy.prod wrapping around on 32-bits
+    # on Windows 64-bit. This shouldn't happen, but the following code
+    # alleviates the problem.
+    if not isinstance(shape, (int, np.integer)):
+        array_length = 1
+        for each_dimension in shape:
+            array_length *= each_dimension
+
+    else:
+        array_length = shape
+
+    # Allocate a new array that will contain the aligned data
+    _array_aligned = np.empty(array_length*itemsize+n, dtype='int8')
+
+    # We now need to know how to offset _array_aligned
+    # so it is correctly aligned
+    _array_aligned_offset = (n-<intptr_t>np.PyArray_DATA(_array_aligned))%n
+
+    array = np.frombuffer(
+            _array_aligned[_array_aligned_offset:_array_aligned_offset-n].data,
+            dtype=dtype).reshape(shape, order=order)
+
+    return array
+
+
+cpdef zeros_aligned(shape, dtype='float64', order='C', n=None):
+    '''zeros_aligned(shape, dtype='float64', order='C', n=None)
+
+    Function that returns a numpy array of zeros that is n-byte aligned,
+    where ``n`` is determined by inspecting the CPU if it is not
+    provided.
+
+    The alignment is given by the final optional argument, ``n``. If
+    ``n`` is not provided then this function will inspect the CPU to
+    determine alignment. The rest of the arguments are as per
+    :func:`numpy.zeros`.
+    '''
+    array = empty_aligned(shape, dtype=dtype, order=order, n=n)
+    array.fill(0)
+    return array
+
+
+cpdef ones_aligned(shape, dtype='float64', order='C', n=None):
+    '''ones_aligned(shape, dtype='float64', order='C', n=None)
+
+    Function that returns a numpy array of ones that is n-byte aligned,
+    where ``n`` is determined by inspecting the CPU if it is not
+    provided.
+
+    The alignment is given by the final optional argument, ``n``. If
+    ``n`` is not provided then this function will inspect the CPU to
+    determine alignment. The rest of the arguments are as per
+    :func:`numpy.ones`.
+    '''
+    array = empty_aligned(shape, dtype=dtype, order=order, n=n)
+    array.fill(1)
+    return array
diff --git a/pyfftw/version.py b/pyfftw/version.py
new file mode 100644
index 0000000..37dae81
--- /dev/null
+++ b/pyfftw/version.py
@@ -0,0 +1,13 @@
+
+# THIS FILE IS GENERATED FROM SETUP.PY
+short_version = '0.10.1'
+version = '0.10.1'
+full_version = '0.10.1'
+git_revision = '43edd862150b910c58744f804ecd5e3543d31ed4'
+release = True
+if not release:
+    version = full_version
+
+if __name__ == "__main__":
+    print(short_version)
+    print(version)
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..861a9f5
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,5 @@
+[egg_info]
+tag_build = 
+tag_date = 0
+tag_svn_revision = 0
+
diff --git a/setup.py b/setup.py
index e024f62..562540c 100644
--- a/setup.py
+++ b/setup.py
@@ -1,106 +1,135 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2015 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from distutils.core import setup, Command
-from distutils.extension import Extension
-from distutils.util import get_platform
+try:
+    # use setuptools if we can
+    from setuptools import setup, Command, Extension
+    from setuptools.command.build_ext import build_ext
+    using_setuptools = True
+except ImportError:
+    from distutils.core import setup, Command, Extension
+    from distutils.command.build_ext import build_ext
+    using_setuptools = False
+
 from distutils.ccompiler import get_default_compiler
 
 import os
-import numpy
 import sys
 
-# Get the version string in rather a roundabout way.
-# We can't import it directly as the module may not yet be
-# built in pyfftw.
-import imp
-ver_file, ver_pathname, ver_description = imp.find_module(
-            '_version', ['pyfftw'])
-try:
-    _version = imp.load_module('version', ver_file, ver_pathname, 
-            ver_description)
-finally:
-    ver_file.close()
-
-version = _version.version
+MAJOR = 0
+MINOR = 10
+MICRO = 1
+ISRELEASED = True
+VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
 
-try:
-    from Cython.Distutils import build_ext as build_ext
-    sources = [os.path.join(os.getcwd(), 'pyfftw', 'pyfftw.pyx')]
-except ImportError as e:
-    sources = [os.path.join(os.getcwd(), 'pyfftw', 'pyfftw.c')]
-    if not os.path.exists(sources[0]):
-        raise ImportError(str(e) + '. ' +
-                'Cython is required to build the initial .c file.')
+def get_package_data():
+    from pkg_resources import get_build_platform
 
-    # We can't cythonize, but that's ok as it's been done already.
-    from distutils.command.build_ext import build_ext
+    package_data = {}
 
-include_dirs = [os.path.join(os.getcwd(), 'include'), 
-        os.path.join(os.getcwd(), 'pyfftw'),
-        numpy.get_include()]
-library_dirs = []
-package_data = {}
-
-if get_platform() in ('win32', 'win-amd64'):
-    libraries = ['libfftw3-3', 'libfftw3f-3', 'libfftw3l-3']
-    include_dirs.append(os.path.join(os.getcwd(), 'include', 'win'))
-    library_dirs.append(os.path.join(os.getcwd(), 'pyfftw'))
-    package_data['pyfftw'] = [
+    if get_build_platform() in ('win32', 'win-amd64'):
+        package_data['pyfftw'] = [
             'libfftw3-3.dll', 'libfftw3l-3.dll', 'libfftw3f-3.dll']
-else:
-    libraries = ['fftw3', 'fftw3f', 'fftw3l', 'fftw3_threads', 
-            'fftw3f_threads', 'fftw3l_threads']
 
-class custom_build_ext(build_ext):
-    def finalize_options(self):
+    return package_data
 
-        build_ext.finalize_options(self)
+def get_include_dirs():
+    import numpy
+    from pkg_resources import get_build_platform
 
-        if self.compiler is None:
-            compiler = get_default_compiler()
-        else:
-            compiler = self.compiler
+    include_dirs = [os.path.join(os.getcwd(), 'include'), 
+                    os.path.join(os.getcwd(), 'pyfftw'),
+                    numpy.get_include()]
 
-        if compiler == 'msvc':
-            # Add msvc specific hacks
-            
-            if (sys.version_info.major, sys.version_info.minor) < (3, 3):
-                # The check above is a nasty hack. We're using the python
-                # version as a proxy for the MSVC version. 2008 doesn't
-                # have stdint.h, so is needed. 2010 does.
-                #
-                # We need to add the path to msvc includes
-                include_dirs.append(os.path.join(os.getcwd(), 
-                    'include', 'msvc_2008'))
+    if get_build_platform() in ('win32', 'win-amd64'):
+        include_dirs.append(os.path.join(os.getcwd(), 'include', 'win'))
 
-            # We need to prepend lib to all the library names
-            _libraries = []
-            for each_lib in self.libraries:
-                _libraries.append('lib' + each_lib)
+    return include_dirs
 
-            self.libraries = _libraries
+def get_library_dirs():
+    from pkg_resources import get_build_platform
+
+    library_dirs = []
+    if get_build_platform() in ('win32', 'win-amd64'):
+        library_dirs.append(os.path.join(os.getcwd(), 'pyfftw'))
+
+    return library_dirs
+
+def get_libraries():
+    from pkg_resources import get_build_platform
+
+    if get_build_platform() in ('win32', 'win-amd64'):
+        libraries = ['libfftw3-3', 'libfftw3f-3', 'libfftw3l-3']
+
+    else:
+        libraries = ['fftw3', 'fftw3f', 'fftw3l', 'fftw3_threads', 
+                     'fftw3f_threads', 'fftw3l_threads']
+
+    return libraries
+
+def get_extensions():
+    from distutils.extension import Extension
 
-ext_modules = [Extension('pyfftw.pyfftw',
-    sources=sources,
-    libraries=libraries,
-    library_dirs=library_dirs,
-    include_dirs=include_dirs)]
+    common_extension_args = {
+        'include_dirs': get_include_dirs(),
+        'library_dirs': get_library_dirs(),
+        'libraries': get_libraries()}
+
+    try:
+        from Cython.Build import cythonize        
+        sources = [os.path.join(os.getcwd(), 'pyfftw', 'pyfftw.pyx')]
+        have_cython = True
+
+    except ImportError as e:
+        # no cython
+        sources = [os.path.join(os.getcwd(), 'pyfftw', 'pyfftw.c')]
+        if not os.path.exists(sources[0]):
+            raise ImportError(
+                str(e) + '. ' + 
+                'Cython is required to build the initial .c file.')
+        
+        have_cython = False
+
+    ext_modules = [
+        Extension('pyfftw.pyfftw', sources=sources, 
+                  **common_extension_args)]
+
+    if have_cython:
+        return cythonize(ext_modules)
+
+    else:
+        return ext_modules
 
 long_description = '''
 pyFFTW is a pythonic wrapper around `FFTW <http://www.fftw.org/>`_, the
@@ -133,6 +162,77 @@ The documentation can be found
 is on `github <https://github.com/hgomersall/pyFFTW>`_.
 '''
 
+class custom_build_ext(build_ext):
+    def finalize_options(self):
+
+        build_ext.finalize_options(self)
+
+        if self.compiler is None:
+            compiler = get_default_compiler()
+        else:
+            compiler = self.compiler
+
+        if compiler == 'msvc':
+            # Add msvc specific hacks
+            
+            if (sys.version_info.major, sys.version_info.minor) < (3, 3):
+                # The check above is a nasty hack. We're using the python
+                # version as a proxy for the MSVC version. 2008 doesn't
+                # have stdint.h, so is needed. 2010 does.
+                #
+                # We need to add the path to msvc includes
+
+                msvc_2008_path = (
+                    os.path.join(os.getcwd(), 'include', 'msvc_2008'))
+
+                if self.include_dirs is not None:
+                    self.include_dirs.append(msvc_2008_path)
+
+                else:
+                    self.include_dirs = [msvc_2008_path]
+
+            elif (sys.version_info.major, sys.version_info.minor) < (3, 5):
+                # Actually, it seems that appveyor doesn't have a stdint that
+                # works, so even for 2010 we use our own (hacked) version
+                # of stdint.
+                # This should be pretty safe in whatever case.
+                msvc_2010_path = (
+                    os.path.join(os.getcwd(), 'include', 'msvc_2010'))
+
+                if self.include_dirs is not None:
+                    self.include_dirs.append(msvc_2010_path)
+
+                else:
+                    self.include_dirs = [msvc_2010_path]
+
+            # We need to prepend lib to all the library names
+            _libraries = []
+            for each_lib in self.libraries:
+                _libraries.append('lib' + each_lib)
+
+            self.libraries = _libraries
+
+class CreateChangelogCommand(Command):
+    '''Depends on the ruby program github_changelog_generator. Install with
+    gem install gihub_changelog_generator.
+    '''
+    user_options = []
+
+    def initialize_options(self):
+        pass
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        import subprocess        
+        github_token_file = 'github_changelog_generator_token'
+
+        with open(github_token_file) as f:
+            github_token = f.readline().strip()
+
+        subprocess.call(['github_changelog_generator', '-t', github_token])
+
 class TestCommand(Command):
     user_options = []
 
@@ -143,38 +243,190 @@ class TestCommand(Command):
         pass
 
     def run(self):
-        import sys, subprocess
-        errno = subprocess.call([sys.executable, '-m', 'unittest', 
-            'discover'])
+        import subprocess
+        errno = subprocess.call([sys.executable, '-m', 
+            'unittest', 'discover'])
         raise SystemExit(errno)
 
-setup_args = {
+class QuickTestCommand(Command):
+    '''Runs a set of test cases that covers a limited set of the 
+    functionality. It is intended that this class be used as a sanity check
+    that everything is loaded and basically working as expected. It is not
+    meant to replace the comprehensive test suite.
+    '''
+    user_options = []
+
+    def initialize_options(self):
+        pass
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+
+        quick_test_cases = [
+            'test.test_pyfftw_complex.Complex64FFTWTest',
+            'test.test_pyfftw_complex.Complex128FFTWTest.test_2d',
+            'test.test_pyfftw_complex.ComplexLongDoubleFFTWTest.test_2d',
+            'test.test_pyfftw_real_forward.RealForwardSingleFFTWTest',
+            'test.test_pyfftw_real_forward.RealForwardDoubleFFTWTest.test_2d',
+            'test.test_pyfftw_real_forward.RealForwardLongDoubleFFTWTest.test_2d',
+            'test.test_pyfftw_real_backward.RealBackwardSingleFFTWTest',
+            'test.test_pyfftw_real_backward.RealBackwardDoubleFFTWTest.test_2d',
+            'test.test_pyfftw_real_backward.RealBackwardLongDoubleFFTWTest.test_2d',
+            'test.test_pyfftw_wisdom',
+            'test.test_pyfftw_utils',
+            'test.test_pyfftw_call',
+            'test.test_pyfftw_class_misc',
+            'test.test_pyfftw_nbyte_align',
+            'test.test_pyfftw_interfaces_cache',
+            'test.test_pyfftw_multithreaded',
+            'test.test_pyfftw_numpy_interface.InterfacesNumpyFFTTestModule',
+            'test.test_pyfftw_numpy_interface.InterfacesNumpyFFTTestFFT2',
+            'test.test_pyfftw_numpy_interface.InterfacesNumpyFFTTestIFFT2',            
+            'test.test_pyfftw_builders.BuildersTestFFTWWrapper',
+            'test.test_pyfftw_builders.BuildersTestFFT2',
+            'test.test_pyfftw_builders.BuildersTestIRFFT2',
+        ]
+
+        import subprocess
+        errno = subprocess.call([sys.executable, '-m', 
+            'unittest'] + quick_test_cases)
+        raise SystemExit(errno)
+
+
+# borrowed from scipy via pyNFFT
+def git_version():
+
+    import subprocess
+
+    def _minimal_ext_cmd(cmd):
+        # construct minimal environment
+        env = {}
+        for k in ['SYSTEMROOT', 'PATH']:
+            v = os.environ.get(k)
+            if v is not None:
+                env[k] = v
+        # LANGUAGE is used on win32
+        env['LANGUAGE'] = 'C'
+        env['LANG'] = 'C'
+        env['LC_ALL'] = 'C'
+        out = subprocess.Popen(cmd, stdout = subprocess.PIPE, env=env).communicate()[0]
+        return out
+
+    try:
+        out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD'])
+        GIT_REVISION = out.strip().decode('ascii')
+    except OSError:
+        GIT_REVISION = "Unknown"
+
+    return GIT_REVISION
+
+# borrowed from scipy via pyNFFT
+def get_version_info():
+    FULLVERSION = VERSION
+    if os.path.exists('.git'):
+        GIT_REVISION = git_version()
+    elif os.path.exists('pyfftw/version.py'):
+        # must be a source distribution, use existing version file
+        # load it as a separate module in order not to load __init__.py
+        import imp
+        version = imp.load_source('pyfftw.version', 'pyfftw/version.py')
+        GIT_REVISION = version.git_revision
+    else:
+        GIT_REVISION = "Unknown"
+
+    if not ISRELEASED:
+        FULLVERSION += '.dev0+' + GIT_REVISION[:7]
+
+    return FULLVERSION, GIT_REVISION
+
+# borrowed from scipy via pyNFFT
+def write_version_py(filename='pyfftw/version.py'):
+    cnt = """
+# THIS FILE IS GENERATED FROM SETUP.PY
+short_version = '%(version)s'
+version = '%(version)s'
+full_version = '%(full_version)s'
+git_revision = '%(git_revision)s'
+release = %(isrelease)s
+if not release:
+    version = full_version
+
+if __name__ == "__main__":
+    print(short_version)
+    print(version)
+"""
+    FULLVERSION, GIT_REVISION = get_version_info()
+
+    f = open(filename, 'w')
+    try:
+        f.write(cnt % {'version': VERSION,
+                       'full_version' : FULLVERSION,
+                       'git_revision' : GIT_REVISION,
+                       'isrelease': str(ISRELEASED)})
+    finally:
+        f.close()
+
+def setup_package():
+
+    # Get current version
+    FULLVERSION, GIT_REVISION = get_version_info()
+
+    # Refresh version file
+    write_version_py()
+
+    # Figure out whether to add ``*_requires = ['numpy']``.
+    build_requires = []
+    try:
+        import numpy
+    except ImportError:
+        build_requires = ['numpy>=1.6, <2.0']
+
+    setup_args = {
         'name': 'pyFFTW',
-        'version': version,
+        'version': FULLVERSION,
         'author': 'Henry Gomersall',
         'author_email': 'heng at kedevelopments.co.uk',
-        'description': 'A pythonic wrapper around FFTW, the FFT library, presenting a unified interface for all the supported transforms.',
+        'description': (
+            'A pythonic wrapper around FFTW, the FFT library, presenting a '
+            'unified interface for all the supported transforms.'),
         'url': 'http://hgomersall.github.com/pyFFTW/',
         'long_description': long_description,
         'classifiers': [
             'Programming Language :: Python',
             'Programming Language :: Python :: 3',
             'Development Status :: 4 - Beta',
-            'License :: OSI Approved :: GNU General Public License (GPL)',
+            'License :: OSI Approved :: BSD License',
             'Operating System :: OS Independent',
             'Intended Audience :: Developers',
             'Intended Audience :: Science/Research',
             'Topic :: Scientific/Engineering',
             'Topic :: Scientific/Engineering :: Mathematics',
-            'Topic :: Multimedia :: Sound/Audio :: Analysis',
-            ],
-        'packages':['pyfftw', 'pyfftw.builders', 'pyfftw.interfaces'],
-        'ext_modules': ext_modules,
-        'include_dirs': include_dirs,
-        'package_data': package_data,
+            'Topic :: Multimedia :: Sound/Audio :: Analysis'],
         'cmdclass': {'test': TestCommand,
-            'build_ext': custom_build_ext},
-  }
+                     'quick_test': QuickTestCommand,
+                     'build_ext': custom_build_ext,
+                     'create_changelog': CreateChangelogCommand}
+    }
+
+    if using_setuptools:
+        setup_args['setup_requires'] = build_requires
+        setup_args['install_requires'] = build_requires
+
+    if len(sys.argv) >= 2 and (
+        '--help' in sys.argv[1:] or
+        sys.argv[1] in ('--help-commands', 'egg_info', '--version',
+                        'clean')):
+        # For these actions, NumPy is not required.
+        pass
+    else:
+        setup_args['packages'] = [
+            'pyfftw', 'pyfftw.builders', 'pyfftw.interfaces']
+        setup_args['ext_modules'] = get_extensions()
+        setup_args['package_data'] = get_package_data()
 
-if __name__ == '__main__':
     setup(**setup_args)
+
+if __name__ == '__main__':
+    setup_package()
diff --git a/test/test_pyfftw_base.py b/test/test_pyfftw_base.py
index ec6aec5..cfd8517 100644
--- a/test/test_pyfftw_base.py
+++ b/test/test_pyfftw_base.py
@@ -1,22 +1,38 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from pyfftw import FFTW, n_byte_align, n_byte_align_empty
+from pyfftw import FFTW
 import numpy
 import struct
 from timeit import Timer
@@ -50,10 +66,10 @@ class FFTWBaseTest(unittest.TestCase):
         return
 
     def get_input_dtype_alignment(self):
-        return numpy.dtype(self.input_dtype).alignment
+        return self.input_dtype([]).real.dtype.alignment
 
     def get_output_dtype_alignment(self):
-        return numpy.dtype(self.output_dtype).alignment
+        return self.input_dtype([]).real.dtype.alignment
 
     def make_shapes(self):
         self.input_shapes = {
diff --git a/test/test_pyfftw_builders.py b/test/test_pyfftw_builders.py
index 844617e..2661924 100644
--- a/test/test_pyfftw_builders.py
+++ b/test/test_pyfftw_builders.py
@@ -1,30 +1,47 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2015 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from pyfftw import builders, n_byte_align_empty, n_byte_align, FFTW
+from pyfftw import builders, empty_aligned, byte_align, FFTW
 from pyfftw.builders import _utils as utils
 from .test_pyfftw_base import run_test_suites
+from ._get_default_args import get_default_args
 
 import unittest
 import numpy
+import numpy as np
 from numpy import fft as np_fft
 import copy
-import inspect
 import warnings
 warnings.filterwarnings('always')
 
@@ -32,31 +49,36 @@ complex_dtypes = (numpy.complex64, numpy.complex128, numpy.clongdouble)
 real_dtypes = (numpy.float32, numpy.float64, numpy.longdouble)
 
 def make_complex_data(shape, dtype):
-    ar, ai = dtype(numpy.random.randn(2, *shape))
+    ar, ai = numpy.random.randn(2, *shape).astype(dtype)
     return ar + 1j*ai
 
 def make_real_data(shape, dtype):
-    return dtype(numpy.random.randn(*shape))
+    return numpy.random.randn(*shape).astype(dtype)
 
 
-io_dtypes = {
+input_dtypes = {
     'complex': (complex_dtypes, make_complex_data),
     'r2c': (real_dtypes, make_real_data),
     'c2r': (complex_dtypes, make_complex_data)}
 
+output_dtypes = {
+    'complex': complex_dtypes,
+    'r2c': complex_dtypes,
+    'c2r': real_dtypes}
+
 functions = {
-        'fft': 'complex',
-        'ifft': 'complex', 
-        'rfft': 'r2c',
-        'irfft': 'c2r',
-        'rfftn': 'r2c',
-        'irfftn': 'c2r',
-        'rfft2': 'r2c',
-        'irfft2': 'c2r',
-        'fft2': 'complex',
-        'ifft2': 'complex',
-        'fftn': 'complex',
-        'ifftn': 'complex'}
+    'fft': 'complex',
+    'ifft': 'complex', 
+    'rfft': 'r2c',
+    'irfft': 'c2r',
+    'rfftn': 'r2c',
+    'irfftn': 'c2r',
+    'rfft2': 'r2c',
+    'irfft2': 'c2r',
+    'fft2': 'complex',
+    'ifft2': 'complex',
+    'fftn': 'complex',
+    'ifftn': 'complex'}
 
 
 class BuildersTestFFT(unittest.TestCase):
@@ -107,10 +129,11 @@ class BuildersTestFFT(unittest.TestCase):
 
         input_array = array_type(test_shape, dtype)
         
-        if input_array.dtype == 'clongdouble':
+        # Use char because of potential MSVC related bug.
+        if input_array.dtype.char == np.dtype('clongdouble').char:
             np_input_array = numpy.complex128(input_array)
 
-        elif input_array.dtype == 'longdouble':
+        elif input_array.dtype.char == np.dtype('longdouble').char:
             np_input_array = numpy.float64(input_array)
 
         else:
@@ -159,9 +182,7 @@ class BuildersTestFFT(unittest.TestCase):
 
     def axes_from_kwargs(self, kwargs):
         
-        argspec = inspect.getargspec(getattr(builders, self.func))
-        default_args = dict(list(zip(
-            argspec.args[-len(argspec.defaults):], argspec.defaults)))
+        default_args = get_default_args(getattr(builders, self.func))
 
         if 'axis' in kwargs:
             axes = (kwargs['axis'],)
@@ -188,9 +209,7 @@ class BuildersTestFFT(unittest.TestCase):
         ''' Return either a scalar s or a tuple depending on
         whether axis or axes is specified
         '''
-        argspec = inspect.getargspec(getattr(builders, self.func))
-        default_args = dict(list(zip(
-            argspec.args[-len(argspec.defaults):], argspec.defaults)))
+        default_args = get_default_args(getattr(builders, self.func))
 
         if 'axis' in kwargs:
             s = test_shape[kwargs['axis']]
@@ -226,7 +245,7 @@ class BuildersTestFFT(unittest.TestCase):
         return s
 
     def test_valid(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
@@ -237,8 +256,31 @@ class BuildersTestFFT(unittest.TestCase):
 
                 self.assertTrue(type(FFTW_object) == FFTW)
 
+    def test_output_dtype_correct(self):
+        '''The output dtype should be correct given the input dtype.
+
+        It was noted that this is a particular problem on windows 64
+        due longdouble being mapped to double, but the dtype().char attribute
+        still being different.
+        '''
+        inp_dtype_tuple = input_dtypes[functions[self.func]]
+        output_dtype_tuple = output_dtypes[functions[self.func]]
+
+        for input_dtype, output_dtype in zip(inp_dtype_tuple[0], 
+                                             output_dtype_tuple):
+
+            for test_shape, s, kwargs in self.test_data:
+                s = None
+
+                FFTW_object = self.validate_pyfftw_object(inp_dtype_tuple[1], 
+                        test_shape, input_dtype, s, kwargs)
+
+                self.assertTrue(
+                    FFTW_object.output_array.dtype.char == 
+                    np.dtype(output_dtype).char)
+
     def test_fail_on_invalid_s_or_axes(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         
         for dtype in dtype_tuple[0]:
 
@@ -251,7 +293,7 @@ class BuildersTestFFT(unittest.TestCase):
 
 
     def test_same_sized_s(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
 
@@ -263,7 +305,7 @@ class BuildersTestFFT(unittest.TestCase):
     def test_bigger_s_overwrite_input(self):
         '''Test that FFTWWrapper deals with a destroyed input properly.
         '''
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
 
@@ -286,7 +328,7 @@ class BuildersTestFFT(unittest.TestCase):
                         type(FFTW_object) == utils._FFTWWrapper)
     
     def test_bigger_s(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
 
@@ -303,7 +345,7 @@ class BuildersTestFFT(unittest.TestCase):
                         type(FFTW_object) == utils._FFTWWrapper)
 
     def test_smaller_s(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
 
@@ -320,7 +362,7 @@ class BuildersTestFFT(unittest.TestCase):
                         type(FFTW_object) == utils._FFTWWrapper)                
 
     def test_bigger_and_smaller_s(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             i = -1
             for test_shape, s, kwargs in self.test_data:
@@ -340,7 +382,7 @@ class BuildersTestFFT(unittest.TestCase):
                         type(FFTW_object) == utils._FFTWWrapper)
     
     def test_auto_contiguous_input(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
@@ -376,7 +418,7 @@ class BuildersTestFFT(unittest.TestCase):
                 FFTW_object = getattr(builders, self.func)(
                         input_array, s1, **_kwargs)
 
-                internal_input_array = FFTW_object.get_input_array()
+                internal_input_array = FFTW_object.input_array
                 flags = internal_input_array.flags
                 self.assertTrue(input_array is internal_input_array)
                 self.assertFalse(flags['C_CONTIGUOUS'] or 
@@ -385,7 +427,7 @@ class BuildersTestFFT(unittest.TestCase):
                 FFTW_object = getattr(builders, self.func)(
                         input_array, s2, **_kwargs)
 
-                internal_input_array = FFTW_object.get_input_array()
+                internal_input_array = FFTW_object.input_array
                 flags = internal_input_array.flags
                 # We actually expect the _FFTWWrapper to be C_CONTIGUOUS
                 self.assertTrue(flags['C_CONTIGUOUS'])
@@ -396,7 +438,7 @@ class BuildersTestFFT(unittest.TestCase):
                 FFTW_object = getattr(builders, self.func)(
                         input_array, s1, **_kwargs)
 
-                internal_input_array = FFTW_object.get_input_array()
+                internal_input_array = FFTW_object.input_array
                 flags = internal_input_array.flags
                 self.assertTrue(flags['C_CONTIGUOUS'] or 
                     flags['F_CONTIGUOUS'])
@@ -404,14 +446,14 @@ class BuildersTestFFT(unittest.TestCase):
                 FFTW_object = getattr(builders, self.func)(
                         input_array, s2, **_kwargs)
 
-                internal_input_array = FFTW_object.get_input_array()
+                internal_input_array = FFTW_object.input_array
                 flags = internal_input_array.flags
                 # as above
                 self.assertTrue(flags['C_CONTIGUOUS'])
 
 
     def test_auto_align_input(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
@@ -458,9 +500,9 @@ class BuildersTestFFT(unittest.TestCase):
     def test_dtype_coercian(self):
         # Make sure we input a dtype that needs to be coerced
         if functions[self.func] == 'r2c':
-            dtype_tuple = io_dtypes['complex']
+            dtype_tuple = input_dtypes['complex']
         else:
-            dtype_tuple = io_dtypes['r2c']
+            dtype_tuple = input_dtypes['r2c']
 
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
@@ -474,7 +516,7 @@ class BuildersTestFFT(unittest.TestCase):
     def test_persistent_padding(self):
         '''Test to confirm the padding it not touched after creation.
         '''
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
 
@@ -497,7 +539,7 @@ class BuildersTestFFT(unittest.TestCase):
                 FFTW_object = self.validate_pyfftw_object(dtype_tuple[1], 
                         test_shape, dtype, s, kwargs)
 
-                internal_array = FFTW_object.get_input_array()
+                internal_array = FFTW_object.input_array
                 padding = internal_array[padding_slicer]
 
                 # Fill the padding with garbage
@@ -508,14 +550,14 @@ class BuildersTestFFT(unittest.TestCase):
                 # Now confirm that nothing is done to the padding
                 FFTW_object()
 
-                final_padding = FFTW_object.get_input_array()[padding_slicer]
+                final_padding = FFTW_object.input_array[padding_slicer]
 
                 self.assertTrue(numpy.all(final_padding == initial_padding))
 
     def test_planner_effort(self):
         '''Test the planner effort arg
         '''
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         test_shape = (16,)
         
         for dtype in dtype_tuple[0]:
@@ -544,7 +586,7 @@ class BuildersTestFFT(unittest.TestCase):
     def test_threads_arg(self):
         '''Test the threads argument
         '''
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         test_shape = (16,)
         
         for dtype in dtype_tuple[0]:
@@ -571,7 +613,7 @@ class BuildersTestFFT(unittest.TestCase):
     def test_overwrite_input(self):
         '''Test the overwrite_input flag
         '''
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         
         for dtype in dtype_tuple[0]:
             for test_shape, s, _kwargs in self.test_data:
@@ -596,7 +638,7 @@ class BuildersTestFFT(unittest.TestCase):
     def test_input_maintained(self):
         '''Test to make sure the input is maintained
         '''
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
 
@@ -605,7 +647,7 @@ class BuildersTestFFT(unittest.TestCase):
                 FFTW_object = getattr(
                         builders, self.func)(input_array, s, **kwargs)
 
-                final_input_array = FFTW_object.get_input_array()
+                final_input_array = FFTW_object.input_array
 
                 self.assertTrue(
                         numpy.alltrue(input_array == final_input_array))
@@ -613,7 +655,7 @@ class BuildersTestFFT(unittest.TestCase):
     def test_avoid_copy(self):
         '''Test the avoid_copy flag
         '''
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = input_dtypes[functions[self.func]]
         
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
@@ -650,10 +692,10 @@ class BuildersTestFFT(unittest.TestCase):
 
                 # Offset by one from 16 byte aligned to guarantee it's not
                 # 16 byte aligned
-                _input_array = n_byte_align_empty(
-                        numpy.prod(test_shape)*input_array.itemsize+1, 
-                        16, dtype='int8')
-    
+                _input_array = empty_aligned(
+                        numpy.prod(test_shape)*input_array.itemsize+1,
+                        dtype='int8', n=16)
+
                 misaligned_input_array = _input_array[1:].view(
                          dtype=input_array.dtype).reshape(*test_shape)
 
@@ -662,13 +704,13 @@ class BuildersTestFFT(unittest.TestCase):
                         getattr(builders, self.func),
                         misaligned_input_array, s, **_kwargs)
 
-                _input_array = n_byte_align(input_array.copy(), 16)
+                _input_array = byte_align(input_array.copy())
                 FFTW_object = getattr(builders, self.func)(
                         _input_array, s, **_kwargs)
 
                 # A catch all to make sure the internal array
                 # is not a copy
-                self.assertTrue(FFTW_object.get_input_array() is
+                self.assertTrue(FFTW_object.input_array is
                         _input_array)
 
 
@@ -680,10 +722,10 @@ class BuildersTestRFFT(BuildersTestFFT):
 
 class BuildersTestIRFFT(BuildersTestFFT):
     func = 'irfft'
-    realinv = True    
+    realinv = True
 
 class BuildersTestFFT2(BuildersTestFFT):
-    axes_kw = 'axes'    
+    axes_kw = 'axes'
     func = 'ifft2'
     test_shapes = (
             ((128, 64), {'axes': None}),
@@ -693,7 +735,7 @@ class BuildersTestFFT2(BuildersTestFFT):
             ((64, 128, 16), {'axes': (0, 2)}),
             ((4, 6, 8, 4), {'axes': (0, 3)}),
             )
-    
+
     invalid_args = (
             ((100,), ((100, 200),), ValueError, 'Shape error'),
             ((100, 200), ((100, 200, 100),), ValueError, 'Shape error'),
@@ -711,7 +753,7 @@ class BuildersTestRFFT2(BuildersTestFFT2):
 
 class BuildersTestIRFFT2(BuildersTestFFT2):
     func = 'irfft2'
-    realinv = True    
+    realinv = True
 
 class BuildersTestFFTN(BuildersTestFFT2):
     func = 'ifftn'
@@ -730,7 +772,7 @@ class BuildersTestRFFTN(BuildersTestFFTN):
 
 class BuildersTestIRFFTN(BuildersTestFFTN):
     func = 'irfftn'
-    realinv = True    
+    realinv = True
 
 
 class BuildersTestFFTWWrapper(unittest.TestCase):
@@ -749,21 +791,18 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
 
         self.input_array_slicer = [slice(None), slice(256)]
         self.FFTW_array_slicer = [slice(128), slice(None)]
-        
-        self.input_array = n_byte_align_empty((128, 512), 16, 
-                dtype='complex128')
-        self.output_array = n_byte_align_empty((256, 256), 16,
-                dtype='complex128')
 
-        self.internal_array = n_byte_align_empty((256, 256), 16, 
-                dtype='complex128')
+        self.input_array = empty_aligned((128, 512), dtype='complex128')
+        self.output_array = empty_aligned((256, 256), dtype='complex128')
+
+        self.internal_array = empty_aligned((256, 256), dtype='complex128')
 
-        self.fft = utils._FFTWWrapper(self.internal_array, 
+        self.fft = utils._FFTWWrapper(self.internal_array,
                 self.output_array,
                 input_array_slicer=self.input_array_slicer,
                 FFTW_array_slicer=self.FFTW_array_slicer)
 
-        self.input_array[:] = (numpy.random.randn(*self.input_array.shape) 
+        self.input_array[:] = (numpy.random.randn(*self.input_array.shape)
                 + 1j*numpy.random.randn(*self.input_array.shape))
 
         self.internal_array[:] = 0
@@ -774,8 +813,8 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
         '''Does what the internal update arrays does for an FFTW
         object but with a reslicing.
         '''
-        internal_input_array = self.fft.get_input_array()
-        internal_output_array = self.fft.get_output_array()
+        internal_input_array = self.fft.input_array
+        internal_output_array = self.fft.output_array
 
         internal_input_array[self.FFTW_array_slicer] = (
                 input_array[self.input_array_slicer])
@@ -786,57 +825,58 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
         '''Test a call to an instance of the class.
         '''
 
-        self.input_array[:] = (numpy.random.randn(*self.input_array.shape) 
+        self.input_array[:] = (numpy.random.randn(*self.input_array.shape)
                 + 1j*numpy.random.randn(*self.input_array.shape))
 
         output_array = self.fft()
 
         self.assertTrue(numpy.alltrue(output_array == self.output_array))
 
-    
+
     def test_call_with_positional_input_update(self):
         '''Test the class call with a positional input update.
         '''
 
-        input_array = n_byte_align(
-                (numpy.random.randn(*self.input_array.shape) 
-                    + 1j*numpy.random.randn(*self.input_array.shape)), 16)
+        input_array = byte_align(
+                (numpy.random.randn(*self.input_array.shape)
+                    + 1j*numpy.random.randn(*self.input_array.shape)))
 
-        output_array = self.fft(n_byte_align(input_array.copy(), 16)).copy()
+        output_array = self.fft(
+                byte_align(input_array.copy())).copy()
 
         self.update_arrays(input_array, self.output_array)
         self.fft.execute()
 
         self.assertTrue(numpy.alltrue(output_array == self.output_array))
 
-        
+
     def test_call_with_keyword_input_update(self):
         '''Test the class call with a keyword input update.
         '''
-        input_array = n_byte_align(
-                numpy.random.randn(*self.input_array.shape) 
-                    + 1j*numpy.random.randn(*self.input_array.shape), 16)
+        input_array = byte_align(
+                numpy.random.randn(*self.input_array.shape)
+                    + 1j*numpy.random.randn(*self.input_array.shape))
 
         output_array = self.fft(
-            input_array=n_byte_align(input_array.copy(), 16)).copy()
+            input_array=byte_align(input_array.copy())).copy()
 
         self.update_arrays(input_array, self.output_array)
         self.fft.execute()
 
         self.assertTrue(numpy.alltrue(output_array == self.output_array))
-    
-        
+
+
     def test_call_with_keyword_output_update(self):
         '''Test the class call with a keyword output update.
         '''
-        output_array = n_byte_align(
-            (numpy.random.randn(*self.output_array.shape) 
-                + 1j*numpy.random.randn(*self.output_array.shape)), 16)
+        output_array = byte_align(
+            (numpy.random.randn(*self.output_array.shape)
+                + 1j*numpy.random.randn(*self.output_array.shape)))
 
         returned_output_array = self.fft(
-                output_array=n_byte_align(output_array.copy(), 16)).copy()
+                output_array=byte_align(output_array.copy())).copy()
+
 
-        
         self.update_arrays(self.input_array, output_array)
         self.fft.execute()
 
@@ -846,16 +886,16 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
     def test_call_with_positional_updates(self):
         '''Test the class call with a positional array updates.
         '''
-        
-        input_array = n_byte_align((numpy.random.randn(*self.input_array.shape) 
-            + 1j*numpy.random.randn(*self.input_array.shape)), 16)
 
-        output_array = n_byte_align((numpy.random.randn(*self.output_array.shape) 
-            + 1j*numpy.random.randn(*self.output_array.shape)), 16)
+        input_array = byte_align((numpy.random.randn(*self.input_array.shape)
+            + 1j*numpy.random.randn(*self.input_array.shape)))
+
+        output_array = byte_align((numpy.random.randn(*self.output_array.shape)
+            + 1j*numpy.random.randn(*self.output_array.shape)))
 
         returned_output_array = self.fft(
-            n_byte_align(input_array.copy(), 16),
-            n_byte_align(output_array.copy(), 16)).copy()
+            byte_align(input_array.copy()),
+            byte_align(output_array.copy())).copy()
 
         self.update_arrays(input_array, output_array)
         self.fft.execute()
@@ -865,32 +905,32 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
     def test_call_with_keyword_updates(self):
         '''Test the class call with a positional output update.
         '''
-        
-        input_array = n_byte_align(
-                (numpy.random.randn(*self.input_array.shape) 
-                    + 1j*numpy.random.randn(*self.input_array.shape)), 16)
 
-        output_array = n_byte_align(
+        input_array = byte_align(
+                (numpy.random.randn(*self.input_array.shape)
+                    + 1j*numpy.random.randn(*self.input_array.shape)))
+
+        output_array = byte_align(
                 (numpy.random.randn(*self.output_array.shape)
-                    + 1j*numpy.random.randn(*self.output_array.shape)), 16)
+                    + 1j*numpy.random.randn(*self.output_array.shape)))
 
         returned_output_array = self.fft(
-                output_array=n_byte_align(output_array.copy(), 16),
-                input_array=n_byte_align(input_array.copy(), 16)).copy()
+                output_array=byte_align(output_array.copy()),
+                input_array=byte_align(input_array.copy())).copy()
 
         self.update_arrays(input_array, output_array)
         self.fft.execute()
 
         self.assertTrue(numpy.alltrue(returned_output_array == output_array))
-    
+
     def test_call_with_different_input_dtype(self):
         '''Test the class call with an array with a different input dtype
         '''
-        input_array = n_byte_align(numpy.complex64(
-                numpy.random.randn(*self.input_array.shape) 
-                + 1j*numpy.random.randn(*self.input_array.shape)), 16)
+        input_array = byte_align(numpy.complex64(
+                numpy.random.randn(*self.input_array.shape)
+                + 1j*numpy.random.randn(*self.input_array.shape)))
 
-        output_array = self.fft(n_byte_align(input_array.copy(), 16)).copy()
+        output_array = self.fft(byte_align(input_array.copy())).copy()
 
         _input_array = numpy.asarray(input_array,
                 dtype=self.input_array.dtype)
@@ -899,7 +939,7 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
         self.fft.execute()
 
         self.assertTrue(numpy.alltrue(output_array == self.output_array))
-    
+
     def test_call_with_list_input(self):
         '''Test the class call with a list rather than an array
         '''
@@ -916,25 +956,25 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
         '''
 
         new_shape = self.input_array.shape + (2, )
-        invalid_array = (numpy.random.randn(*new_shape) 
+        invalid_array = (numpy.random.randn(*new_shape)
                 + 1j*numpy.random.randn(*new_shape))
-        
-        self.assertRaises(ValueError, self.fft, 
+
+        self.assertRaises(ValueError, self.fft,
                 *(),
                 **{'output_array':invalid_array})
 
-        self.assertRaises(ValueError, self.fft, 
+        self.assertRaises(ValueError, self.fft,
                 *(),
                 **{'input_array':invalid_array})
 
-    
+
     def test_call_with_invalid_output_striding(self):
         '''Test the class call with an invalid strided output update.
         '''
         # Add an extra dimension to bugger up the striding
         new_shape = self.output_array.shape + (2,)
-        output_array = n_byte_align(numpy.random.randn(*new_shape) 
-                + 1j*numpy.random.randn(*new_shape), 16)
+        output_array = byte_align(numpy.random.randn(*new_shape)
+                + 1j*numpy.random.randn(*new_shape))
 
         self.assertRaisesRegex(ValueError, 'Invalid output striding',
                 self.fft, **{'output_array': output_array[:,:,1]})
@@ -945,18 +985,18 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
         input_array_shape = self.input_array.shape + (2,)
         internal_array_shape = self.internal_array.shape
 
-        internal_array = n_byte_align(
-                numpy.random.randn(*internal_array_shape) 
-                + 1j*numpy.random.randn(*internal_array_shape), 16)
+        internal_array = byte_align(
+                numpy.random.randn(*internal_array_shape)
+                + 1j*numpy.random.randn(*internal_array_shape))
 
         fft =  utils._FFTWWrapper(internal_array, self.output_array,
                 input_array_slicer=self.input_array_slicer,
                 FFTW_array_slicer=self.FFTW_array_slicer)
-        
+
         test_output_array = fft().copy()
 
-        new_input_array = n_byte_align_empty(input_array_shape, 16,
-                dtype=internal_array.dtype)
+        new_input_array = empty_aligned(input_array_shape,
+                                        dtype=internal_array.dtype)
         new_input_array[:] = 0
 
         new_input_array[:,:,0][self.input_array_slicer] = (
@@ -976,17 +1016,17 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
         shape = list(self.input_array.shape + (2,))
         shape[0] += 1
 
-        input_array = n_byte_align(numpy.random.randn(*shape) 
-                + 1j*numpy.random.randn(*shape), 16)
+        input_array = byte_align(numpy.random.randn(*shape)
+                + 1j*numpy.random.randn(*shape))
 
         self.assertRaisesRegex(ValueError, 'Invalid input shape',
                 self.fft, **{'input_array': input_array[:,:,0]})
 
     def test_call_with_normalisation_on(self):
-        _input_array = n_byte_align_empty(self.internal_array.shape, 16,
-                dtype='complex128')
-        
-        ifft = utils._FFTWWrapper(self.output_array, _input_array, 
+        _input_array = empty_aligned(self.internal_array.shape,
+                                     dtype='complex128')
+
+        ifft = utils._FFTWWrapper(self.output_array, _input_array,
                 direction='FFTW_BACKWARD',
                 input_array_slicer=slice(None),
                 FFTW_array_slicer=slice(None))
@@ -995,15 +1035,15 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
         ifft(normalise_idft=True)
 
         self.assertTrue(numpy.allclose(
-            self.input_array[self.input_array_slicer], 
+            self.input_array[self.input_array_slicer],
             _input_array[self.FFTW_array_slicer]))
 
     def test_call_with_normalisation_off(self):
-        
-        _input_array = n_byte_align_empty(self.internal_array.shape, 16,
-                dtype='complex128')
 
-        ifft = utils._FFTWWrapper(self.output_array, _input_array, 
+        _input_array = empty_aligned(self.internal_array.shape,
+                                     dtype='complex128')
+
+        ifft = utils._FFTWWrapper(self.output_array, _input_array,
                 direction='FFTW_BACKWARD',
                 input_array_slicer=slice(None),
                 FFTW_array_slicer=slice(None))
@@ -1014,14 +1054,14 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
         _input_array /= ifft.N
 
         self.assertTrue(numpy.allclose(
-            self.input_array[self.input_array_slicer], 
+            self.input_array[self.input_array_slicer],
             _input_array[self.FFTW_array_slicer]))
 
     def test_call_with_normalisation_default(self):
-        _input_array = n_byte_align_empty(self.internal_array.shape, 16,
-                dtype='complex128')
+        _input_array = empty_aligned(self.internal_array.shape,
+                                     dtype='complex128')
 
-        ifft = utils._FFTWWrapper(self.output_array, _input_array, 
+        ifft = utils._FFTWWrapper(self.output_array, _input_array,
                 direction='FFTW_BACKWARD',
                 input_array_slicer=slice(None),
                 FFTW_array_slicer=slice(None))
@@ -1031,7 +1071,7 @@ class BuildersTestFFTWWrapper(unittest.TestCase):
 
         # Scaling is performed by default
         self.assertTrue(numpy.allclose(
-            self.input_array[self.input_array_slicer], 
+            self.input_array[self.input_array_slicer],
             _input_array[self.FFTW_array_slicer]))
 
 
@@ -1122,7 +1162,7 @@ class BuildersTestUtilities(unittest.TestCase):
         for each_axes in test_axes:
 
             args = (a, s, each_axes, False, False)
-            self.assertRaisesRegex(IndexError, 'Invalid axes', 
+            self.assertRaisesRegex(IndexError, 'Invalid axes',
                     utils._compute_array_shapes, *args)
 
     def _call_cook_nd_args(self, arg_tuple):
@@ -1162,7 +1202,7 @@ class BuildersTestUtilities(unittest.TestCase):
         for each_input, each_output in zip(inputs, outputs):
             self.assertEqual(self._call_cook_nd_args(each_input),
                     each_output)
-    
+
     def test_cook_nd_args_invreal(self):
 
         # inputs are (a.shape, s, axes, invreal)
@@ -1203,7 +1243,7 @@ class BuildersTestUtilities(unittest.TestCase):
 
         # all the inputs should yield an error
         for each_input in inputs:
-            self.assertRaisesRegex(ValueError, 'Shape error', 
+            self.assertRaisesRegex(ValueError, 'Shape error',
                     self._call_cook_nd_args, *(each_input,))
 
 test_cases = (
diff --git a/test/test_pyfftw_call.py b/test/test_pyfftw_call.py
index 7abd021..fba1bc7 100644
--- a/test/test_pyfftw_call.py
+++ b/test/test_pyfftw_call.py
@@ -1,23 +1,40 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
 
 from pyfftw import (
-        FFTW, n_byte_align_empty, n_byte_align)
+        FFTW, empty_aligned, byte_align)
 
 from .test_pyfftw_base import run_test_suites
 import numpy
@@ -34,10 +51,8 @@ class FFTWCallTest(unittest.TestCase):
    
     def setUp(self):
 
-        self.input_array = n_byte_align_empty((256, 512), 16, 
-                dtype='complex128')
-        self.output_array = n_byte_align_empty((256, 512), 16,
-                dtype='complex128')
+        self.input_array = empty_aligned((256, 512), dtype='complex128', n=16)
+        self.output_array = empty_aligned((256, 512), dtype='complex128', n=16)
 
         self.fft = FFTW(self.input_array, self.output_array)
 
@@ -61,11 +76,11 @@ class FFTWCallTest(unittest.TestCase):
         '''Test the class call with a positional input update.
         '''
 
-        input_array = n_byte_align(
-                (numpy.random.randn(*self.input_array.shape) 
-                    + 1j*numpy.random.randn(*self.input_array.shape)), 16)
+        input_array = byte_align(
+                (numpy.random.randn(*self.input_array.shape)
+                    + 1j*numpy.random.randn(*self.input_array.shape)), n=16)
 
-        output_array = self.fft(n_byte_align(input_array.copy(), 16)).copy()
+        output_array = self.fft(byte_align(input_array.copy(), n=16)).copy()
 
         self.fft.update_arrays(input_array, self.output_array)
         self.fft.execute()
@@ -75,12 +90,12 @@ class FFTWCallTest(unittest.TestCase):
     def test_call_with_keyword_input_update(self):
         '''Test the class call with a keyword input update.
         '''
-        input_array = n_byte_align(
-                numpy.random.randn(*self.input_array.shape) 
-                    + 1j*numpy.random.randn(*self.input_array.shape), 16)
+        input_array = byte_align(
+                numpy.random.randn(*self.input_array.shape)
+                    + 1j*numpy.random.randn(*self.input_array.shape), n=16)
 
         output_array = self.fft(
-            input_array=n_byte_align(input_array.copy(), 16)).copy()
+            input_array=byte_align(input_array.copy(), n=16)).copy()
 
         self.fft.update_arrays(input_array, self.output_array)
         self.fft.execute()
@@ -91,12 +106,12 @@ class FFTWCallTest(unittest.TestCase):
     def test_call_with_keyword_output_update(self):
         '''Test the class call with a keyword output update.
         '''
-        output_array = n_byte_align(
-            (numpy.random.randn(*self.output_array.shape) 
-                + 1j*numpy.random.randn(*self.output_array.shape)), 16)
+        output_array = byte_align(
+            (numpy.random.randn(*self.output_array.shape)
+                + 1j*numpy.random.randn(*self.output_array.shape)), n=16)
 
         returned_output_array = self.fft(
-                output_array=n_byte_align(output_array.copy(), 16)).copy()
+                output_array=byte_align(output_array.copy(), n=16)).copy()
 
         self.fft.update_arrays(self.input_array, output_array)
         self.fft.execute()
@@ -107,16 +122,16 @@ class FFTWCallTest(unittest.TestCase):
     def test_call_with_positional_updates(self):
         '''Test the class call with a positional array updates.
         '''
-        
-        input_array = n_byte_align((numpy.random.randn(*self.input_array.shape) 
-            + 1j*numpy.random.randn(*self.input_array.shape)), 16)
 
-        output_array = n_byte_align((numpy.random.randn(*self.output_array.shape) 
-            + 1j*numpy.random.randn(*self.output_array.shape)), 16)
+        input_array = byte_align((numpy.random.randn(*self.input_array.shape)
+            + 1j*numpy.random.randn(*self.input_array.shape)), n=16)
+
+        output_array = byte_align((numpy.random.randn(*self.output_array.shape)
+            + 1j*numpy.random.randn(*self.output_array.shape)), n=16)
 
         returned_output_array = self.fft(
-            n_byte_align(input_array.copy(), 16),
-            n_byte_align(output_array.copy(), 16)).copy()
+            byte_align(input_array.copy(), n=16),
+            byte_align(output_array.copy(), n=16)).copy()
 
         self.fft.update_arrays(input_array, output_array)
         self.fft.execute()
@@ -126,18 +141,18 @@ class FFTWCallTest(unittest.TestCase):
     def test_call_with_keyword_updates(self):
         '''Test the class call with a positional output update.
         '''
-        
-        input_array = n_byte_align(
-                (numpy.random.randn(*self.input_array.shape) 
-                    + 1j*numpy.random.randn(*self.input_array.shape)), 16)
 
-        output_array = n_byte_align(
+        input_array = byte_align(
+                (numpy.random.randn(*self.input_array.shape)
+                    + 1j*numpy.random.randn(*self.input_array.shape)), n=16)
+
+        output_array = byte_align(
                 (numpy.random.randn(*self.output_array.shape)
-                    + 1j*numpy.random.randn(*self.output_array.shape)), 16)
+                    + 1j*numpy.random.randn(*self.output_array.shape)), n=16)
 
         returned_output_array = self.fft(
-                output_array=n_byte_align(output_array.copy(), 16),
-                input_array=n_byte_align(input_array.copy(), 16)).copy()
+                output_array=byte_align(output_array.copy(), n=16),
+                input_array=byte_align(input_array.copy(), n=16)).copy()
 
         self.fft.update_arrays(input_array, output_array)
         self.fft.execute()
@@ -147,14 +162,14 @@ class FFTWCallTest(unittest.TestCase):
     def test_call_with_different_input_dtype(self):
         '''Test the class call with an array with a different input dtype
         '''
-        input_array = n_byte_align(numpy.complex64(
-                numpy.random.randn(*self.input_array.shape) 
-                + 1j*numpy.random.randn(*self.input_array.shape)), 16)
+        input_array = byte_align(numpy.complex64(
+                numpy.random.randn(*self.input_array.shape)
+                + 1j*numpy.random.randn(*self.input_array.shape)), n=16)
 
-        output_array = self.fft(n_byte_align(input_array.copy(), 16)).copy()
+        output_array = self.fft(byte_align(input_array.copy(), n=16)).copy()
 
-        _input_array = n_byte_align(numpy.asarray(input_array,
-                dtype=self.input_array.dtype), 16)
+        _input_array = byte_align(numpy.asarray(input_array,
+                dtype=self.input_array.dtype), n=16)
 
         self.assertTrue(_input_array.dtype != input_array.dtype)
 
@@ -197,14 +212,14 @@ class FFTWCallTest(unittest.TestCase):
                 + 1j*numpy.random.randn(*self.input_array.shape))
 
         output_array = self.fft(
-                input_array=n_byte_align(input_array.copy(), 16)).copy()
+                input_array=byte_align(input_array.copy(), n=16)).copy()
 
         # Offset by one from 16 byte aligned to guarantee it's not
         # 16 byte aligned
         a = input_array
-        a__ = n_byte_align_empty(
-                numpy.prod(a.shape)*a.itemsize+1, 16, dtype='int8')
-        
+        a__ = empty_aligned(numpy.prod(a.shape)*a.itemsize+1, dtype='int8',
+                            n=16)
+
         a_ = a__[1:].view(dtype=a.dtype).reshape(*a.shape)
         a_[:] = a
 
@@ -225,13 +240,13 @@ class FFTWCallTest(unittest.TestCase):
         a_size = len(a.ravel())*a.itemsize
 
         update_array = numpy.frombuffer(
-                numpy.zeros(a_size + 1, dtype='int8')[1:].data, 
+                numpy.zeros(a_size + 1, dtype='int8')[1:].data,
                 dtype=a.dtype).reshape(a.shape)
 
         fft = FFTW(a, b, flags=('FFTW_UNALIGNED',))
         # Confirm that a usual update will fail (it's not on the
         # byte boundary)
-        self.assertRaisesRegex(ValueError, 'Invalid input alignment', 
+        self.assertRaisesRegex(ValueError, 'Invalid input alignment',
                 fft.update_arrays, *(update_array, b))
 
         fft(update_array, b)
@@ -241,8 +256,8 @@ class FFTWCallTest(unittest.TestCase):
         '''
         # Add an extra dimension to bugger up the striding
         new_shape = self.output_array.shape + (2,)
-        output_array = n_byte_align(numpy.random.randn(*new_shape) 
-                + 1j*numpy.random.randn(*new_shape), 16)
+        output_array = byte_align(numpy.random.randn(*new_shape)
+                + 1j*numpy.random.randn(*new_shape), n=16)
 
         self.assertRaisesRegex(ValueError, 'Invalid output striding',
                 self.fft, **{'output_array': output_array[:,:,1]})
@@ -252,15 +267,15 @@ class FFTWCallTest(unittest.TestCase):
         '''
         shape = self.input_array.shape + (2,)
 
-        input_array = n_byte_align(numpy.random.randn(*shape) 
-                + 1j*numpy.random.randn(*shape), 16)
+        input_array = byte_align(numpy.random.randn(*shape)
+                + 1j*numpy.random.randn(*shape), n=16)
 
         fft = FFTW(input_array[:,:,0], self.output_array)
         
         test_output_array = fft().copy()
 
-        new_input_array = n_byte_align(
-                input_array[:, :, 0].copy(), 16)
+        new_input_array = byte_align(
+                input_array[:, :, 0].copy(), n=16)
 
         new_output = fft(new_input_array).copy()
 
@@ -275,8 +290,8 @@ class FFTWCallTest(unittest.TestCase):
         shape = list(self.input_array.shape + (2,))
         shape[0] += 1
 
-        input_array = n_byte_align(numpy.random.randn(*shape) 
-                + 1j*numpy.random.randn(*shape), 16)
+        input_array = byte_align(numpy.random.randn(*shape)
+                + 1j*numpy.random.randn(*shape), n=16)
 
         fft = FFTW(self.input_array, self.output_array)
         
@@ -290,25 +305,25 @@ class FFTWCallTest(unittest.TestCase):
                 + 1j*numpy.random.randn(*self.input_array.shape))
 
         output_array = self.fft(
-                input_array=n_byte_align(input_array.copy(), 16)).copy()
+                input_array=byte_align(input_array.copy(), n=16)).copy()
 
-        input_array = n_byte_align(input_array, 16)
-        output_array = n_byte_align(output_array, 16)
+        input_array = byte_align(input_array, n=16)
+        output_array = byte_align(output_array, n=16)
 
         # Offset by one from 16 byte aligned to guarantee it's not
         # 16 byte aligned
-        a = n_byte_align(input_array.copy(), 16)
-        a__ = n_byte_align_empty(
-                numpy.prod(a.shape)*a.itemsize+1, 16, dtype='int8')
-        
+        a = byte_align(input_array.copy(), n=16)
+        a__ = empty_aligned(numpy.prod(a.shape)*a.itemsize+1, dtype='int8',
+                            n=16)
+
         a_ = a__[1:].view(dtype=a.dtype).reshape(*a.shape)
         a_[:] = a
 
         # Create a different second array the same way
-        b = n_byte_align(output_array.copy(), 16)
-        b__ = n_byte_align_empty(
-                numpy.prod(b.shape)*a.itemsize+1, 16, dtype='int8')
-        
+        b = byte_align(output_array.copy(), n=16)
+        b__ = empty_aligned(numpy.prod(b.shape)*a.itemsize+1, dtype='int8',
+                            n=16)
+
         b_ = b__[1:].view(dtype=b.dtype).reshape(*b.shape)
         b_[:] = a
 
@@ -339,8 +354,7 @@ class FFTWCallTest(unittest.TestCase):
                 self.fft.update_arrays, *(input_array, b_))
 
     def test_call_with_normalisation_on(self):
-        _input_array = n_byte_align_empty((256, 512), 16,
-                dtype='complex128')
+        _input_array = empty_aligned((256, 512), dtype='complex128', n=16)
 
         ifft = FFTW(self.output_array, _input_array, 
                 direction='FFTW_BACKWARD')
@@ -351,10 +365,9 @@ class FFTWCallTest(unittest.TestCase):
         self.assertTrue(numpy.allclose(self.input_array, _input_array))
 
     def test_call_with_normalisation_off(self):
-        _input_array = n_byte_align_empty((256, 512), 16,
-                dtype='complex128')
+        _input_array = empty_aligned((256, 512), dtype='complex128', n=16)
 
-        ifft = FFTW(self.output_array, _input_array, 
+        ifft = FFTW(self.output_array, _input_array,
                 direction='FFTW_BACKWARD')
 
         self.fft(normalise_idft=True) # Shouldn't make any difference
@@ -365,8 +378,7 @@ class FFTWCallTest(unittest.TestCase):
         self.assertTrue(numpy.allclose(self.input_array, _input_array))
 
     def test_call_with_normalisation_default(self):
-        _input_array = n_byte_align_empty((256, 512), 16,
-                dtype='complex128')
+        _input_array = empty_aligned((256, 512), dtype='complex128', n=16)
 
         ifft = FFTW(self.output_array, _input_array, 
                 direction='FFTW_BACKWARD')
@@ -377,6 +389,32 @@ class FFTWCallTest(unittest.TestCase):
         # Scaling is performed by default
         self.assertTrue(numpy.allclose(self.input_array, _input_array))
 
+    def test_call_with_normalisation_precision(self):
+        '''The normalisation should use a double precision scaling.
+        '''
+        # Should be the case for double inputs...
+        _input_array = empty_aligned((256, 512), dtype='complex128', n=16)
+
+        ifft = FFTW(self.output_array, _input_array, 
+                direction='FFTW_BACKWARD')
+
+        ref_output = ifft(normalise_idft=False).copy()/numpy.float64(ifft.N)
+        test_output = ifft(normalise_idft=True).copy()
+
+        self.assertTrue(numpy.alltrue(ref_output == test_output))
+
+        # ... and single inputs.
+        _input_array = empty_aligned((256, 512), dtype='complex64', n=16)
+
+        ifft = FFTW(numpy.array(self.output_array, _input_array.dtype), 
+                    _input_array, 
+                    direction='FFTW_BACKWARD')
+
+        ref_output = ifft(normalise_idft=False).copy()/numpy.float64(ifft.N)
+        test_output = ifft(normalise_idft=True).copy()
+
+        self.assertTrue(numpy.alltrue(ref_output == test_output))
+
         
 test_cases = (
         FFTWCallTest,)
diff --git a/test/test_pyfftw_class_misc.py b/test/test_pyfftw_class_misc.py
index 535d0d8..b8f3e62 100644
--- a/test/test_pyfftw_class_misc.py
+++ b/test/test_pyfftw_class_misc.py
@@ -1,26 +1,46 @@
+# Copyright 2014 Knowledge Economy Developments Ltd
+# 
+# Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from pyfftw import (
-        FFTW, n_byte_align_empty, is_n_byte_aligned, simd_alignment)
+        FFTW, empty_aligned, is_byte_aligned, simd_alignment)
 import pyfftw
 
 from .test_pyfftw_base import run_test_suites
 
 import unittest
 import numpy
+import warnings
 
 # FFTW tests that don't seem to fit anywhere else
 
@@ -37,10 +57,8 @@ class FFTWMiscTest(unittest.TestCase):
 
     def setUp(self):
 
-        self.input_array = n_byte_align_empty((256, 512), 16, 
-                dtype='complex128')
-        self.output_array = n_byte_align_empty((256, 512), 16,
-                dtype='complex128')
+        self.input_array = empty_aligned((256, 512), dtype='complex128', n=16)
+        self.output_array = empty_aligned((256, 512), dtype='complex128', n=16)
 
         self.fft = FFTW(self.input_array, self.output_array)
 
@@ -69,8 +87,8 @@ class FFTWMiscTest(unittest.TestCase):
         self.assertEqual(fft.flags, ('FFTW_DESTROY_INPUT', 'FFTW_UNALIGNED'))
 
         # Test an implicit flag
-        _input_array = n_byte_align_empty(256, 16, dtype='complex64')
-        _output_array = n_byte_align_empty(256, 16, dtype='complex64')
+        _input_array = empty_aligned(256, dtype='complex64', n=16)
+        _output_array = empty_aligned(256, dtype='complex64', n=16)
 
         # These are guaranteed to be misaligned (due to dtype size == 8)
         input_array = _input_array[:-1]
@@ -93,12 +111,10 @@ class FFTWMiscTest(unittest.TestCase):
 
         # Start by creating arrays that are only on various byte 
         # alignments (4, 16 and 32)
-        _input_array = n_byte_align_empty(
-                len(self.input_array.ravel())*2+5,
-                32, dtype='float32')
-        _output_array = n_byte_align_empty(
-                len(self.output_array.ravel())*2+5,
-                32, dtype='float32')
+        _input_array = empty_aligned(len(self.input_array.ravel())*2+5,
+                                     dtype='float32', n=32)
+        _output_array = empty_aligned(len(self.output_array.ravel())*2+5,
+                                      dtype='float32', n=32)
 
         _input_array[:] = 0
         _output_array[:] = 0
@@ -135,20 +151,20 @@ class FFTWMiscTest(unittest.TestCase):
         alignments = (4, 16, 32)
 
         # Test the arrays are aligned on 4 bytes...
-        self.assertTrue(is_n_byte_aligned(input_arrays[4], 4))
-        self.assertTrue(is_n_byte_aligned(output_arrays[4], 4))
+        self.assertTrue(is_byte_aligned(input_arrays[4], n=4))
+        self.assertTrue(is_byte_aligned(output_arrays[4], n=4))
 
         # ...and on 16...
-        self.assertFalse(is_n_byte_aligned(input_arrays[4], 16))
-        self.assertFalse(is_n_byte_aligned(output_arrays[4], 16))
-        self.assertTrue(is_n_byte_aligned(input_arrays[16], 16))
-        self.assertTrue(is_n_byte_aligned(output_arrays[16], 16))
+        self.assertFalse(is_byte_aligned(input_arrays[4], n=16))
+        self.assertFalse(is_byte_aligned(output_arrays[4], n=16))
+        self.assertTrue(is_byte_aligned(input_arrays[16], n=16))
+        self.assertTrue(is_byte_aligned(output_arrays[16], n=16))
 
         # ...and on 32...
-        self.assertFalse(is_n_byte_aligned(input_arrays[16], 32))
-        self.assertFalse(is_n_byte_aligned(output_arrays[16], 32))
-        self.assertTrue(is_n_byte_aligned(input_arrays[32], 32))
-        self.assertTrue(is_n_byte_aligned(output_arrays[32], 32))
+        self.assertFalse(is_byte_aligned(input_arrays[16], n=32))
+        self.assertFalse(is_byte_aligned(output_arrays[16], n=32))
+        self.assertTrue(is_byte_aligned(input_arrays[32], n=32))
+        self.assertTrue(is_byte_aligned(output_arrays[32], n=32))
 
         if len(pyfftw.pyfftw._valid_simd_alignments) > 0:
             max_align = pyfftw.pyfftw._valid_simd_alignments[0]
@@ -191,14 +207,140 @@ class FFTWMiscTest(unittest.TestCase):
     def test_get_input_array(self):
         '''Test to see the get_input_array method returns the correct thing
         '''
+        with warnings.catch_warnings(record=True) as w:
+            # This method is deprecated, so check the deprecation warning
+            # is raised.
+            warnings.simplefilter("always")
+            input_array = self.fft.get_input_array()
+            self.assertEqual(len(w), 1)
+            self.assertTrue(issubclass(w[-1].category, DeprecationWarning))
 
-        self.assertIs(self.input_array, self.fft.get_input_array())
+        self.assertIs(self.input_array, input_array)
 
     def test_get_output_array(self):
         '''Test to see the get_output_array method returns the correct thing
         '''
+        with warnings.catch_warnings(record=True) as w:
+            # This method is deprecated, so check the deprecation warning
+            # is raised.
+            warnings.simplefilter("always")
+            output_array = self.fft.get_output_array()
+            self.assertEqual(len(w), 1)
+            self.assertTrue(issubclass(w[-1].category, DeprecationWarning))
+
+        self.assertIs(self.output_array, output_array)
+
+    def test_input_array(self):
+        '''Test to see the input_array property returns the correct thing
+        '''
+        self.assertIs(self.input_array, self.fft.input_array)
+
+    def test_output_array(self):
+        '''Test to see the output_array property returns the correct thing
+        '''
+        self.assertIs(self.output_array, self.fft.output_array)
+
+    def test_input_strides(self):
+        '''Test to see if the input_strides property returns the correct thing
+        '''
+        self.assertEqual(self.fft.input_strides, self.input_array.strides)
+
+        new_input_array = self.input_array[::2, ::4]
+        new_output_array = self.output_array[::2, ::4]
+
+        new_fft = FFTW(new_input_array, new_output_array)
+
+        self.assertEqual(new_fft.input_strides, new_input_array.strides)
+
+    def test_output_strides(self):
+        '''Test to see if the output_strides property returns the correct thing
+        '''
+        self.assertEqual(self.fft.output_strides, self.output_array.strides)
+
+        new_input_array = self.output_array[::2, ::4]
+        new_output_array = self.output_array[::2, ::4]
+
+        new_fft = FFTW(new_input_array, new_output_array)
+
+        self.assertEqual(new_fft.output_strides, new_output_array.strides)
+
+    def test_input_shape(self):
+        '''Test to see if the input_shape property returns the correct thing
+        '''
+        self.assertEqual(self.fft.input_shape, self.input_array.shape)
+
+        new_input_array = self.input_array[::2, ::4]
+        new_output_array = self.output_array[::2, ::4]
+
+        new_fft = FFTW(new_input_array, new_output_array)
+
+        self.assertEqual(new_fft.input_shape, new_input_array.shape)
+
+    def test_output_strides(self):
+        '''Test to see if the output_shape property returns the correct thing
+        '''
+        self.assertEqual(self.fft.output_shape, self.output_array.shape)
+
+        new_input_array = self.output_array[::2, ::4]
+        new_output_array = self.output_array[::2, ::4]
+
+        new_fft = FFTW(new_input_array, new_output_array)
+
+        self.assertEqual(new_fft.output_shape, new_output_array.shape)
+
+    def test_input_dtype(self):
+        '''Test to see if the input_dtype property returns the correct thing
+        '''
+        self.assertEqual(self.fft.input_dtype, self.input_array.dtype)
+
+        new_input_array = numpy.complex64(self.input_array)
+        new_output_array = numpy.complex64(self.output_array)
+
+        new_fft = FFTW(new_input_array, new_output_array)
+
+        self.assertEqual(new_fft.input_dtype, new_input_array.dtype)
+
+    def test_output_dtype(self):
+        '''Test to see if the output_dtype property returns the correct thing
+        '''
+        self.assertEqual(self.fft.output_dtype, self.output_array.dtype)
+
+        new_input_array = numpy.complex64(self.input_array)
+        new_output_array = numpy.complex64(self.output_array)
+
+        new_fft = FFTW(new_input_array, new_output_array)
+
+        self.assertEqual(new_fft.output_dtype, new_output_array.dtype)
+
+    def test_direction_property(self):
+        '''Test to see if the direction property returns the correct thing
+        '''
+        self.assertEqual(self.fft.direction, 'FFTW_FORWARD')
+
+        new_fft = FFTW(self.input_array, self.output_array, 
+                direction='FFTW_BACKWARD')
+
+        self.assertEqual(new_fft.direction, 'FFTW_BACKWARD')
+
+    def test_axes_property(self):
+        '''Test to see if the axes property returns the correct thing
+        '''
+        self.assertEqual(self.fft.axes, (1,))
+
+        new_fft = FFTW(self.input_array, self.output_array, axes=(-1, -2))
+        self.assertEqual(new_fft.axes, (1, 0))
+
+        new_fft = FFTW(self.input_array, self.output_array, axes=(-2, -1))
+        self.assertEqual(new_fft.axes, (0, 1))
+
+        new_fft = FFTW(self.input_array, self.output_array, axes=(1, 0))
+        self.assertEqual(new_fft.axes, (1, 0))
+
+        new_fft = FFTW(self.input_array, self.output_array, axes=(1,))
+        self.assertEqual(new_fft.axes, (1,))
 
-        self.assertIs(self.output_array, self.fft.get_output_array())
+        new_fft = FFTW(self.input_array, self.output_array, axes=(0,))
+        self.assertEqual(new_fft.axes, (0,))
 
 test_cases = (
         FFTWMiscTest,)
diff --git a/test/test_pyfftw_complex.py b/test/test_pyfftw_complex.py
index 258ddec..ef6f5d6 100644
--- a/test/test_pyfftw_complex.py
+++ b/test/test_pyfftw_complex.py
@@ -1,22 +1,39 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+#
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from pyfftw import FFTW, n_byte_align, n_byte_align_empty, forget_wisdom
+from pyfftw import FFTW, byte_align, empty_aligned, forget_wisdom
 import pyfftw
 import numpy
 from timeit import Timer
@@ -46,6 +63,17 @@ class Complex64FFTW1DTest(object):
                 lambda: self.np_fft_comparison(a))
         self.assertTrue(True)
 
+    def test_invalid_args_raise(self):
+
+        in_shape = self.input_shapes['1d']
+        out_shape = self.output_shapes['1d']
+        
+        axes=(-1,)
+        a, b = self.create_test_arrays(in_shape, out_shape)
+
+        # Note "thread" is incorrect, it should be "threads"
+        self.assertRaises(TypeError, FFTW, a, b, axes, thread=4)
+
     def test_1d(self):
         in_shape = self.input_shapes['1d']
         out_shape = self.output_shapes['1d']
@@ -121,9 +149,11 @@ class Complex64FFTW1DTest(object):
 
         import sys
         if sys.platform == 'win32':
-            # Give a 4x margin on windows. The timers are low
-            # precision and FFTW seems to take longer anyway
-            self.assertTrue(limited_time < time_limit*4)
+            # Give a 6x margin on windows. The timers are low
+            # precision and FFTW seems to take longer anyway.
+            # Also, we need to allow for processor contention which 
+            # Appveyor seems prone to.
+            self.assertTrue(limited_time < time_limit*6)
         else:
             # Otherwise have a 2x margin
             self.assertTrue(limited_time < time_limit*2)
@@ -148,6 +178,8 @@ class Complex64FFTW1DTest(object):
         a, b = self.create_test_arrays(in_shape, out_shape)
 
         for each_flag in pyfftw.pyfftw._flag_dict:
+            if each_flag == 'FFTW_WISDOM_ONLY':
+                continue
             fft, ifft = self.run_validate_fft(a, b, axes, 
                     flags=(each_flag,))
 
@@ -158,6 +190,30 @@ class Complex64FFTW1DTest(object):
         fft, ifft = self.run_validate_fft(a, b, axes, 
                     flags=())
 
+    def test_wisdom_only(self):
+        in_shape = self.input_shapes['small_1d']
+        out_shape = self.output_shapes['small_1d']
+
+        axes=(0,)
+        a, b = self.create_test_arrays(in_shape, out_shape)
+        forget_wisdom()
+        # with no wisdom, an error should be raised with FFTW_WISDOM_ONLY
+        # 
+        # NB: wisdom is specific to aligned/unaligned distinction, so we must
+        # ensure that the arrays don't get copied (and potentially
+        # switched between aligned and unaligned) by run_validate_fft()... 
+        self.assertRaisesRegex(RuntimeError, 'No FFTW wisdom', 
+                self.run_validate_fft, *(a, b, axes), 
+                **{'flags':('FFTW_ESTIMATE', 'FFTW_WISDOM_ONLY'), 
+                   'create_array_copies': False})
+        # now plan the FFT
+        self.run_validate_fft(a, b, axes, flags=('FFTW_ESTIMATE',),
+                create_array_copies=False)
+        # now FFTW_WISDOM_ONLY should not raise an error because the plan should
+        # be in the wisdom
+        self.run_validate_fft(a, b, axes, flags=('FFTW_ESTIMATE', 
+                'FFTW_WISDOM_ONLY'), create_array_copies=False)
+
     def test_destroy_input(self):
         '''Test the destroy input flag
         '''
@@ -198,34 +254,34 @@ class Complex64FFTW1DTest(object):
         axes=(-1,)
         a, b = self.create_test_arrays(in_shape, out_shape)
 
-        a = n_byte_align(a, 16)
-        b = n_byte_align(b, 16)
+        a = byte_align(a, n=16)
+        b = byte_align(b, n=16)
 
         fft, ifft = self.run_validate_fft(a, b, axes, 
                 force_unaligned_data=True)
 
         a, b = self.create_test_arrays(in_shape, out_shape)
 
-        a = n_byte_align(a, 16)
-        b = n_byte_align(b, 16)
+        a = byte_align(a, n=16)
+        b = byte_align(b, n=16)
 
         a_orig = a.copy()
         b_orig = b.copy()
 
         # Offset from 16 byte aligned to guarantee it's not
         # 16 byte aligned
-        a__ = n_byte_align_empty(
-                numpy.prod(in_shape)*a.itemsize + input_dtype_alignment, 
-                16, dtype='int8')
-        
+        a__ = empty_aligned(
+                numpy.prod(in_shape)*a.itemsize + input_dtype_alignment,
+                dtype='int8', n=16)
+
         a_ = (a__[input_dtype_alignment:]
                 .view(dtype=self.input_dtype).reshape(*in_shape))
-        a_[:] = a 
-        
-        b__ = n_byte_align_empty(
-                numpy.prod(out_shape)*b.itemsize + input_dtype_alignment, 
-                16, dtype='int8')
-        
+        a_[:] = a
+
+        b__ = empty_aligned(
+                numpy.prod(out_shape)*b.itemsize + input_dtype_alignment,
+                dtype='int8', n=16)
+
         b_ = (b__[input_dtype_alignment:]
                 .view(dtype=self.output_dtype).reshape(*out_shape))
         b_[:] = b
@@ -271,8 +327,8 @@ class Complex64FFTW1DTest(object):
         axes=(-1,)
         a, b = self.create_test_arrays(in_shape, out_shape)
 
-        a = n_byte_align(a, 16)
-        b = n_byte_align(b, 16)
+        a = byte_align(a, n=16)
+        b = byte_align(b, n=16)
 
         fft, ifft = self.run_validate_fft(a, b, axes, 
                 force_unaligned_data=True)
@@ -281,17 +337,17 @@ class Complex64FFTW1DTest(object):
 
         # Offset from 16 byte aligned to guarantee it's not
         # 16 byte aligned
-        a__ = n_byte_align_empty(
-                numpy.prod(in_shape)*a.itemsize + 1, 
-                16, dtype='int8')
-        
+        a__ = empty_aligned(
+                numpy.prod(in_shape)*a.itemsize + 1,
+                dtype='int8', n=16)
+
         a_ = a__[1:].view(dtype=self.input_dtype).reshape(*in_shape)
-        a_[:] = a 
-        
-        b__ = n_byte_align_empty(
-                numpy.prod(out_shape)*b.itemsize + 1, 
-                16, dtype='int8')
-        
+        a_[:] = a
+
+        b__ = empty_aligned(
+                numpy.prod(out_shape)*b.itemsize + 1,
+                dtype='int8', n=16)
+
         b_ = b__[1:].view(dtype=self.output_dtype).reshape(*out_shape)
         b_[:] = b
 
@@ -479,8 +535,8 @@ class Complex64FFTW1DTest(object):
         axes=(-1,)
         a, b = self.create_test_arrays(in_shape, out_shape)
 
-        a = n_byte_align(a, 16)
-        b = n_byte_align(b, 16)
+        a = byte_align(a, n=16)
+        b = byte_align(b, n=16)
 
         fft, ifft = self.run_validate_fft(a, b, axes, 
                 force_unaligned_data=True)
@@ -489,18 +545,18 @@ class Complex64FFTW1DTest(object):
 
         # Offset from 16 byte aligned to guarantee it's not
         # 16 byte aligned
-        a__ = n_byte_align_empty(
-                numpy.prod(in_shape)*a.itemsize + input_dtype_alignment, 
-                16, dtype='int8')
-        
+        a__ = empty_aligned(
+                numpy.prod(in_shape)*a.itemsize + input_dtype_alignment,
+                dtype='int8', n=16)
+
         a_ = (a__[input_dtype_alignment:]
                 .view(dtype=self.input_dtype).reshape(*in_shape))
-        a_[:] = a 
-        
-        b__ = n_byte_align_empty(
-                numpy.prod(out_shape)*b.itemsize + input_dtype_alignment, 
-                16, dtype='int8')
-        
+        a_[:] = a
+
+        b__ = empty_aligned(
+                numpy.prod(out_shape)*b.itemsize + input_dtype_alignment,
+                dtype='int8', n=16)
+
         b_ = (b__[input_dtype_alignment:]
                 .view(dtype=self.output_dtype).reshape(*out_shape))
         b_[:] = b
@@ -520,17 +576,17 @@ class Complex64FFTW1DTest(object):
 
         # Offset from 16 byte aligned to guarantee it's not
         # 16 byte aligned
-        a__ = n_byte_align_empty(
+        a__ = empty_aligned(
                 numpy.prod(in_shape)*a.itemsize + input_dtype_alignment,
-                16, dtype='int8')
-        
+                dtype='int8', n=16)
+
         a_ = a__[input_dtype_alignment:].view(dtype=self.input_dtype).reshape(*in_shape)
         a_[:] = a
-        
-        b__ = n_byte_align_empty(
-                numpy.prod(out_shape)*b.itemsize + input_dtype_alignment, 
-                16, dtype='int8')
-        
+
+        b__ = empty_aligned(
+                numpy.prod(out_shape)*b.itemsize + input_dtype_alignment,
+                dtype='int8', n=16)
+
         b_ = b__[input_dtype_alignment:].view(dtype=self.output_dtype).reshape(*out_shape)
         b_[:] = b
         
@@ -551,8 +607,8 @@ class Complex64FFTW1DTest(object):
         axes=(-1,)
         a, b = self.create_test_arrays(in_shape, out_shape)
 
-        a = n_byte_align(a, 16)
-        b = n_byte_align(b, 16)
+        a = byte_align(a, n=16)
+        b = byte_align(b, n=16)
 
         fft, ifft = self.run_validate_fft(a, b, axes)
         
@@ -560,18 +616,18 @@ class Complex64FFTW1DTest(object):
 
         # Offset from 16 byte aligned to guarantee it's not
         # 16 byte aligned
-        a__ = n_byte_align_empty(
-                numpy.prod(in_shape)*a.itemsize+byte_error, 
-                16, dtype='int8')
-        
+        a__ = empty_aligned(
+                numpy.prod(in_shape)*a.itemsize+byte_error,
+                dtype='int8', n=16)
+
         a_ = (a__[byte_error:]
                 .view(dtype=self.input_dtype).reshape(*in_shape))
-        a_[:] = a 
-        
-        b__ = n_byte_align_empty(
-                numpy.prod(out_shape)*b.itemsize+byte_error, 
-                16, dtype='int8')
-        
+        a_[:] = a
+
+        b__ = empty_aligned(
+                numpy.prod(out_shape)*b.itemsize+byte_error,
+                dtype='int8', n=16)
+
         b_ = (b__[byte_error:]
                 .view(dtype=self.output_dtype).reshape(*out_shape))
         b_[:] = b
diff --git a/test/test_pyfftw_interfaces_cache.py b/test/test_pyfftw_interfaces_cache.py
index 7281906..65fede5 100644
--- a/test/test_pyfftw_interfaces_cache.py
+++ b/test/test_pyfftw_interfaces_cache.py
@@ -1,20 +1,38 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+#
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
 
 from pyfftw import interfaces, builders
 import numpy
@@ -26,6 +44,8 @@ from .test_pyfftw_numpy_interface import InterfacesNumpyFFTTestFFT
 import threading
 import time
 
+import os
+
 '''Test the caching functionality of the interfaces package.
 '''
 
@@ -143,11 +163,15 @@ class CacheTest(unittest.TestCase):
     def test_cache_parent_thread_ended(self):
         '''Test ending cache parent thread ends cache thread.
         '''
+        # Firstly make sure we've exited any lingering threads from other
+        # tests.
+        time.sleep(0.1)                
+
         self.assertTrue(threading.active_count() == 1)
 
         def cache_parent_thread():
             cache = interfaces.cache._Cache()
-            time.sleep(0.2)
+            time.sleep(0.5)
 
         parent_t = threading.Thread(target=cache_parent_thread)
         parent_t.start()
@@ -164,14 +188,17 @@ class CacheTest(unittest.TestCase):
     def test_delete_cache_object(self):
         '''Test deleting a cache object ends cache thread.
         '''
+        # Firstly make sure we've exited any lingering threads from other
+        # tests.
+        time.sleep(0.2)
         self.assertTrue(threading.active_count() == 1)
 
         _cache = interfaces.cache._Cache()
-        time.sleep(0.1)
+        time.sleep(0.2)
         self.assertTrue(threading.active_count() == 2)
-
+        
         del _cache
-        time.sleep(0.1)
+        time.sleep(0.2)
         self.assertTrue(threading.active_count() == 1)
 
     def test_insert_and_lookup_item(self):
@@ -242,7 +269,15 @@ class CacheTest(unittest.TestCase):
 
         keepalive_time = _cache.keepalive_time
 
-        time.sleep(_cache.keepalive_time*3)
+        if os.name == 'nt':
+            # A hack to keep appveyor from falling over here. I suspect the 
+            # contention is too much to work properly. Either way, let's
+            # assume it's a windows problem for now...
+            time.sleep(keepalive_time * 8)
+        else:
+            # Relax a bit more otherwise
+            time.sleep(keepalive_time * 4)
+
         self.assertRaises(KeyError, _cache.lookup, key)
 
         _cache.insert(obj, key)
@@ -251,10 +286,16 @@ class CacheTest(unittest.TestCase):
 
         self.assertIs(_cache.lookup(key), obj)
 
-        time.sleep(old_keepalive_time * 3)
+        time.sleep(old_keepalive_time * 3.5)
+        # still should be there
         self.assertIs(_cache.lookup(key), obj)
 
-        time.sleep(old_keepalive_time * 8)
+        if os.name == 'nt':
+            # As above, but with a bit longer
+            time.sleep(old_keepalive_time * 16)
+        else:
+            time.sleep(old_keepalive_time * 8)
+
         self.assertRaises(KeyError, _cache.lookup, key)
 
 class InterfacesNumpyFFTCacheTestIFFT(InterfacesNumpyFFTCacheTestFFT):
diff --git a/test/test_pyfftw_multithreaded.py b/test/test_pyfftw_multithreaded.py
index c6c01f8..8970eac 100644
--- a/test/test_pyfftw_multithreaded.py
+++ b/test/test_pyfftw_multithreaded.py
@@ -1,22 +1,38 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from pyfftw import FFTW, n_byte_align, n_byte_align_empty
+from pyfftw import FFTW
 import numpy
 from timeit import Timer
 
diff --git a/test/test_pyfftw_nbyte_align.py b/test/test_pyfftw_nbyte_align.py
index d6dcbd1..e8991f2 100644
--- a/test/test_pyfftw_nbyte_align.py
+++ b/test/test_pyfftw_nbyte_align.py
@@ -1,21 +1,43 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
-# 
+# Copyright 2014 Knowledge Economy Developments Ltd
+# Copyright 2014 David Wells
+#
 # Henry Gomersall
 # heng at kedevelopments.co.uk
+# David Wells
+# drwells <at> vt.edu
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+from pyfftw import (byte_align, is_byte_aligned, ones_aligned,
+                    empty_aligned, zeros_aligned, simd_alignment,)
+# Test the deprecated functions.
 from pyfftw import n_byte_align, n_byte_align_empty, is_n_byte_aligned
 import numpy
 from timeit import Timer
@@ -23,12 +45,23 @@ from timeit import Timer
 from .test_pyfftw_base import run_test_suites
 
 import unittest
+import warnings
+
+
+def ignore_deprecation_warning(function):
+    def new_function(*args, **kwargs):
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            return function(*args, **kwargs)
 
-class NByteAlignTest(unittest.TestCase):
+    return new_function
+
+
+class ByteAlignTest(unittest.TestCase):
 
     def __init__(self, *args, **kwargs):
 
-        super(NByteAlignTest, self).__init__(*args, **kwargs)
+        super(ByteAlignTest, self).__init__(*args, **kwargs)
 
         if not hasattr(self, 'assertRaisesRegex'):
             self.assertRaisesRegex = self.assertRaisesRegexp
@@ -38,9 +71,65 @@ class NByteAlignTest(unittest.TestCase):
         return
 
     def tearDown(self):
-        
+
         return
 
+    def test_ones_aligned(self):
+        shape = (10,10)
+        # Test a few alignments and dtypes
+        for each in [(3, 'float64'),
+                (7, 'float64'),
+                (9, 'float32'),
+                (16, 'int64'),
+                (24, 'bool'),
+                (23, 'complex64'),
+                (63, 'complex128'),
+                (64, 'int8')]:
+
+            n = each[0]
+            a = numpy.ones(shape, dtype=each[1])
+            b = ones_aligned(shape, dtype=each[1], n=n)
+            self.assertTrue(b.ctypes.data%n == 0)
+            self.assertTrue(b.dtype == each[1])
+            self.assertTrue(numpy.array_equal(a, b))
+
+    def test_zeros_aligned(self):
+        shape = (10,10)
+        # Test a few alignments and dtypes
+        for each in [(3, 'float64'),
+                (7, 'float64'),
+                (9, 'float32'),
+                (16, 'int64'),
+                (24, 'bool'),
+                (23, 'complex64'),
+                (63, 'complex128'),
+                (64, 'int8')]:
+
+            n = each[0]
+            a = numpy.zeros(shape, dtype=each[1])
+            b = zeros_aligned(shape, dtype=each[1], n=n)
+            self.assertTrue(b.ctypes.data%n == 0)
+            self.assertTrue(b.dtype == each[1])
+            self.assertTrue(numpy.array_equal(a, b))
+
+    def test_empty_aligned(self):
+        shape = (10,10)
+        # Test a few alignments and dtypes
+        for each in [(3, 'float64'),
+                (7, 'float64'),
+                (9, 'float32'),
+                (16, 'int64'),
+                (24, 'bool'),
+                (23, 'complex64'),
+                (63, 'complex128'),
+                (64, 'int8')]:
+
+            n = each[0]
+            b = empty_aligned(shape, dtype=each[1], n=n)
+            self.assertTrue(b.ctypes.data%n == 0)
+            self.assertTrue(b.dtype == each[1])
+
+    @ignore_deprecation_warning
     def test_n_byte_align_empty(self):
         shape = (10,10)
         # Test a few alignments and dtypes
@@ -56,8 +145,18 @@ class NByteAlignTest(unittest.TestCase):
             n = each[0]
             b = n_byte_align_empty(shape, n, dtype=each[1])
             self.assertTrue(b.ctypes.data%n == 0)
-            self.assertTrue(b.dtype == each[1])            
+            self.assertTrue(b.dtype == each[1])
 
+    def test_byte_align(self):
+        shape = (10,10)
+        a = numpy.random.randn(*shape)
+        # Test a few alignments
+        for n in [None, 3, 7, 9, 16, 24, 23, 63, 64]:
+            expected_alignment = get_expected_alignment(n)
+            b = byte_align(a, n=n)
+            self.assertTrue(b.ctypes.data % expected_alignment == 0)
+
+    @ignore_deprecation_warning
     def test_n_byte_align(self):
         shape = (10,10)
         a = numpy.random.randn(*shape)
@@ -66,7 +165,17 @@ class NByteAlignTest(unittest.TestCase):
             b = n_byte_align(a, n)
             self.assertTrue(b.ctypes.data%n == 0)
 
-    def test_integer_shape(self):
+    def test_byte_align_integer_shape(self):
+        shape = 100
+        a = numpy.random.randn(shape)
+        # Test a few alignments
+        for n in [None, 3, 7, 9, 16, 24, 23, 63, 64]:
+            expected_alignment = get_expected_alignment(n)
+            b = byte_align(a, n=n)
+            self.assertTrue(b.ctypes.data % expected_alignment == 0)
+
+    @ignore_deprecation_warning
+    def test_n_byte_align_integer_shape(self):
         shape = 100
         a = numpy.random.randn(shape)
         # Test a few alignments
@@ -74,6 +183,21 @@ class NByteAlignTest(unittest.TestCase):
             b = n_byte_align(a, n)
             self.assertTrue(b.ctypes.data%n == 0)
 
+    def test_is_byte_aligned(self):
+        a = empty_aligned(100)
+        self.assertTrue(is_byte_aligned(a, get_expected_alignment(None)))
+
+        a = empty_aligned(100, n=16)
+        self.assertTrue(is_byte_aligned(a, n=16))
+
+        a = empty_aligned(100, n=5)
+        self.assertTrue(is_byte_aligned(a, n=5))
+
+        a = empty_aligned(100, dtype='float32', n=16)[1:]
+        self.assertFalse(is_byte_aligned(a, n=16))
+        self.assertTrue(is_byte_aligned(a, n=4))
+
+    @ignore_deprecation_warning
     def test_is_n_byte_aligned(self):
         a = n_byte_align_empty(100, 16)
         self.assertTrue(is_n_byte_aligned(a, 16))
@@ -85,18 +209,50 @@ class NByteAlignTest(unittest.TestCase):
         self.assertFalse(is_n_byte_aligned(a, 16))
         self.assertTrue(is_n_byte_aligned(a, 4))
 
+    def test_is_byte_aligned_fail_with_non_array(self):
+
+        a = [1, 2, 3, 4]
+        self.assertRaisesRegex(TypeError, 'Invalid array',
+                is_byte_aligned, a, n=16)
+
+    @ignore_deprecation_warning
     def test_is_n_byte_aligned_fail_with_non_array(self):
 
         a = [1, 2, 3, 4]
         self.assertRaisesRegex(TypeError, 'Invalid array',
                 is_n_byte_aligned, a, 16)
 
+    def test_byte_align_fail_with_non_array(self):
+
+        a = [1, 2, 3, 4]
+        self.assertRaisesRegex(TypeError, 'Invalid array',
+                byte_align, a, n=16)
+
+    @ignore_deprecation_warning
     def test_n_byte_align_fail_with_non_array(self):
 
         a = [1, 2, 3, 4]
         self.assertRaisesRegex(TypeError, 'Invalid array',
                 n_byte_align, a, 16)
 
+    def test_byte_align_consistent_data(self):
+        shape = (10,10)
+        a = numpy.int16(numpy.random.randn(*shape)*16000)
+        b = numpy.float64(numpy.random.randn(*shape))
+        c = numpy.int8(numpy.random.randn(*shape)*255)
+
+        # Test a few alignments
+        for n in [None, 3, 7, 9, 16, 24, 23, 63, 64]:
+            d = byte_align(a, n=n)
+            self.assertTrue(numpy.array_equal(a, d))
+
+            d = byte_align(b, n=n)
+            self.assertTrue(numpy.array_equal(b, d))
+
+            d = byte_align(c, n=n)
+            self.assertTrue(numpy.array_equal(c, d))
+
+    @ignore_deprecation_warning
     def test_n_byte_align_consistent_data(self):
         shape = (10,10)
         a = numpy.int16(numpy.random.randn(*shape)*16000)
@@ -114,6 +270,27 @@ class NByteAlignTest(unittest.TestCase):
             d = n_byte_align(c, n)
             self.assertTrue(numpy.array_equal(c, d))
 
+    def test_byte_align_different_dtypes(self):
+        shape = (10,10)
+        a = numpy.int16(numpy.random.randn(*shape)*16000)
+        b = numpy.float64(numpy.random.randn(*shape))
+        c = numpy.int8(numpy.random.randn(*shape)*255)
+        # Test a few alignments
+        for n in [None, 3, 7, 9, 16, 24, 23, 63, 64]:
+            expected_alignment = get_expected_alignment(n)
+            d = byte_align(a, n=n)
+            self.assertTrue(d.ctypes.data % expected_alignment == 0)
+            self.assertTrue(d.__class__ == a.__class__)
+
+            d = byte_align(b, n=n)
+            self.assertTrue(d.ctypes.data % expected_alignment == 0)
+            self.assertTrue(d.__class__ == b.__class__)
+
+            d = byte_align(c, n=n)
+            self.assertTrue(d.ctypes.data % expected_alignment == 0)
+            self.assertTrue(d.__class__ == c.__class__)
+
+    @ignore_deprecation_warning
     def test_n_byte_align_different_dtypes(self):
         shape = (10,10)
         a = numpy.int16(numpy.random.randn(*shape)*16000)
@@ -133,6 +310,27 @@ class NByteAlignTest(unittest.TestCase):
             self.assertTrue(d.ctypes.data%n == 0)
             self.assertTrue(d.__class__ == c.__class__)
 
+    def test_byte_align_set_dtype(self):
+        shape = (10,10)
+        a = numpy.int16(numpy.random.randn(*shape)*16000)
+        b = numpy.float64(numpy.random.randn(*shape))
+        c = numpy.int8(numpy.random.randn(*shape)*255)
+        # Test a few alignments
+        for n in [None, 3, 7, 9, 16, 24, 23, 63, 64]:
+            expected_alignment = get_expected_alignment(n)
+            d = byte_align(a, dtype='float32', n=n)
+            self.assertTrue(d.ctypes.data % expected_alignment == 0)
+            self.assertTrue(d.dtype == 'float32')
+
+            d = byte_align(b, dtype='float32', n=n)
+            self.assertTrue(d.ctypes.data % expected_alignment == 0)
+            self.assertTrue(d.dtype == 'float32')
+
+            d = byte_align(c, dtype='float64', n=n)
+            self.assertTrue(d.ctypes.data % expected_alignment == 0)
+            self.assertTrue(d.dtype == 'float64')
+
+    @ignore_deprecation_warning
     def test_n_byte_align_set_dtype(self):
         shape = (10,10)
         a = numpy.int16(numpy.random.randn(*shape)*16000)
@@ -153,8 +351,14 @@ class NByteAlignTest(unittest.TestCase):
             self.assertTrue(d.dtype == 'float64')
 
 
+def get_expected_alignment(n):
+    if n is None:
+        return simd_alignment
+    else:
+        return n
+
 test_cases = (
-        NByteAlignTest,)
+        ByteAlignTest,)
 
 test_set = None
 
diff --git a/test/test_pyfftw_numpy_interface.py b/test/test_pyfftw_numpy_interface.py
index c1016b3..3a501a6 100644
--- a/test/test_pyfftw_numpy_interface.py
+++ b/test/test_pyfftw_numpy_interface.py
@@ -1,32 +1,54 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2015 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from pyfftw import n_byte_align_empty, n_byte_align, interfaces
+from pyfftw import interfaces
 
 from .test_pyfftw_base import run_test_suites
+from ._get_default_args import get_default_args
 
 import unittest
 import numpy
 from numpy import fft as np_fft
-import inspect
 import warnings
+import copy
 warnings.filterwarnings('always')
 
+if numpy.version.version <= '1.6.2':
+    # We overwrite the broken _cook_nd_args with a fixed version.
+    from ._cook_nd_args import _cook_nd_args
+    numpy.fft.fftpack._cook_nd_args = _cook_nd_args
+
 complex_dtypes = (numpy.complex64, numpy.complex128, numpy.clongdouble)
 real_dtypes = (numpy.float32, numpy.float64, numpy.longdouble)
 
@@ -38,17 +60,14 @@ def make_real_data(shape, dtype):
     return dtype(numpy.random.randn(*shape))
 
 
-io_dtypes = {
-    'complex': (complex_dtypes, make_complex_data),
-    'r2c': (real_dtypes, make_real_data),
-    'c2r': (complex_dtypes, make_complex_data)}
-
 functions = {
         'fft': 'complex',
         'ifft': 'complex', 
         'rfft': 'r2c',
         'irfft': 'c2r',
         'rfftn': 'r2c',
+        'hfft': 'c2r',
+        'ihfft': 'r2c',
         'irfftn': 'c2r',
         'rfft2': 'r2c',
         'irfft2': 'c2r',
@@ -57,7 +76,7 @@ functions = {
         'fftn': 'complex',
         'ifftn': 'complex'}
 
-acquired_names = ('hfft', 'ihfft', 'fftfreq', 'fftshift', 'ifftshift')
+acquired_names = ('fftfreq', 'fftshift', 'ifftshift')
 
 class InterfacesNumpyFFTTestModule(unittest.TestCase):
     ''' A really simple test suite to check the module works as expected.
@@ -74,13 +93,25 @@ class InterfacesNumpyFFTTestModule(unittest.TestCase):
 
 class InterfacesNumpyFFTTestFFT(unittest.TestCase):
 
+    io_dtypes = {
+            'complex': (complex_dtypes, make_complex_data),
+            'r2c': (real_dtypes, make_real_data),
+            'c2r': (complex_dtypes, make_complex_data)}
+
+    validator_module = np_fft
+    test_interface = interfaces.numpy_fft
     func = 'fft'
     axes_kw = 'axis'
+    overwrite_input_flag = 'overwrite_input'
+    default_s_from_shape_slicer = slice(-1, None)
+
     test_shapes = (
             ((100,), {}),
             ((128, 64), {'axis': 0}),
             ((128, 32), {'axis': -1}),
             ((59, 100), {}),
+            ((59, 99), {'axis': -1}),
+            ((59, 99), {'axis': 0}),            
             ((32, 32, 4), {'axis': 1}),
             ((64, 128, 16), {}),
             )
@@ -125,28 +156,30 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
         interfaces.cache.disable()
         self._validate(array_type, test_shape, dtype, s, kwargs)
 
+    def munge_input_array(self, array, kwargs):
+        return array
+
     def _validate(self, array_type, test_shape, dtype, 
             s, kwargs):
 
-        input_array = array_type(test_shape, dtype)
-        orig_input_array = input_array.copy()
+        input_array = self.munge_input_array(
+                array_type(test_shape, dtype), kwargs)
 
-        if input_array.dtype == 'clongdouble':
+        orig_input_array = copy.copy(input_array)
+
+        np_input_array = numpy.asarray(input_array)
+        
+        if np_input_array.dtype == 'clongdouble':
             np_input_array = numpy.complex128(input_array)
 
-        elif input_array.dtype == 'longdouble':
+        elif np_input_array.dtype == 'longdouble':
             np_input_array = numpy.float64(input_array)
 
-        else:
-            np_input_array = input_array
 
         with warnings.catch_warnings(record=True) as w:
             # We catch the warnings so as to pick up on when
             # a complex array is turned into a real array
 
-            output_array = getattr(interfaces.numpy_fft, self.func)(
-                    input_array.copy(), s, **kwargs)
-
             if 'axes' in kwargs:
                 axes = {'axes': kwargs['axes']}
             elif 'axis' in kwargs:
@@ -154,8 +187,29 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
             else:
                 axes = {}
 
-            test_out_array = getattr(np_fft, self.func)(
-                    np_input_array.copy(), s, **axes)
+            try:
+                test_out_array = getattr(self.validator_module, self.func)(
+                        copy.copy(np_input_array), s, **axes)
+
+            except Exception as e:
+                interface_exception = None
+                try:
+                    getattr(self.test_interface, self.func)(
+                            copy.copy(input_array), s, **kwargs)
+                except Exception as _interface_exception:
+                    # It's necessary to assign the exception to the
+                    # already defined variable in Python 3.
+                    # See http://www.python.org/dev/peps/pep-3110/#semantic-changes
+                    interface_exception = _interface_exception
+
+                # If the test interface raised, so must this.
+                self.assertEqual(type(interface_exception), type(e),
+                        msg='Interface exception raised. ' + 
+                        'Testing for: ' + repr(e))
+                return
+
+            output_array = getattr(self.test_interface, self.func)(
+                    copy.copy(input_array), s, **kwargs)
 
             if (functions[self.func] == 'r2c'):
                 if numpy.iscomplexobj(input_array):
@@ -168,18 +222,21 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
                 numpy.allclose(output_array, test_out_array, 
                     rtol=1e-2, atol=1e-4))
 
-        if (not 'overwrite_input' in kwargs or 
-                not kwargs['overwrite_input']):
+        input_precision_dtype = numpy.asanyarray(input_array).real.dtype
+
+        self.assertEqual(input_precision_dtype, 
+                output_array.real.dtype)
+
+        if (not self.overwrite_input_flag in kwargs or 
+                not kwargs[self.overwrite_input_flag]):
             self.assertTrue(numpy.allclose(input_array,
                 orig_input_array))
 
         return output_array
 
     def axes_from_kwargs(self, kwargs):
-        
-        argspec = inspect.getargspec(getattr(interfaces.numpy_fft, self.func))
-        default_args = dict(list(zip(
-            argspec.args[-len(argspec.defaults):], argspec.defaults)))
+        default_args = get_default_args(
+            getattr(self.test_interface, self.func))
 
         if 'axis' in kwargs:
             axes = (kwargs['axis'],)
@@ -206,9 +263,8 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
         ''' Return either a scalar s or a tuple depending on
         whether axis or axes is specified
         '''
-        argspec = inspect.getargspec(getattr(interfaces.numpy_fft, self.func))
-        default_args = dict(list(zip(
-            argspec.args[-len(argspec.defaults):], argspec.defaults)))
+        default_args = get_default_args(
+            getattr(self.test_interface, self.func))
 
         if 'axis' in kwargs:
             s = test_shape[kwargs['axis']]
@@ -226,7 +282,13 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
                     for each_axis in default_args['axes']:
                         s.append(test_shape[each_axis])
                 except TypeError:
-                    s = [test_shape[-1]]
+                    try:
+                        s = list(test_shape[
+                            self.default_s_from_shape_slicer])
+                    except TypeError:
+                        # We had an integer as the default, so force
+                        # it to be a list
+                        s = [test_shape[self.default_s_from_shape_slicer]]
 
         else:
             if 'axis' in default_args:
@@ -244,7 +306,7 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
         return s
 
     def test_valid(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
         
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
@@ -253,9 +315,22 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
                 self.validate(dtype_tuple[1], 
                         test_shape, dtype, s, kwargs)
 
+    def test_on_non_numpy_array(self):
+        dtype_tuple = self.io_dtypes[functions[self.func]]
+        
+        array_type = (lambda test_shape, dtype: 
+                dtype_tuple[1](test_shape, dtype).tolist())
+
+        for dtype in dtype_tuple[0]:
+            for test_shape, s, kwargs in self.test_data:
+                s = None
+
+                self.validate(array_type, 
+                        test_shape, dtype, s, kwargs)
+
 
     def test_fail_on_invalid_s_or_axes(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
         
         for dtype in dtype_tuple[0]:
 
@@ -263,12 +338,12 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
                 input_array = dtype_tuple[1](test_shape, dtype)
                 
                 self.assertRaisesRegex(exception, e_str,
-                        getattr(interfaces.numpy_fft, self.func), 
+                        getattr(self.test_interface, self.func), 
                         *((input_array,) + args))
 
 
     def test_same_sized_s(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
 
@@ -276,7 +351,7 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
                         test_shape, dtype, s, kwargs)
 
     def test_bigger_s(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
 
@@ -291,7 +366,7 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
 
 
     def test_smaller_s(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
 
@@ -320,14 +395,14 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
         try:
 
             # Replace the function that is to be used
-            real_fft = getattr(interfaces.numpy_fft, self.func)
-            setattr(interfaces.numpy_fft, self.func, fake_fft)
+            real_fft = getattr(self.test_interface, self.func)
+            setattr(self.test_interface, self.func, fake_fft)
 
             _kwargs = kwargs.copy()
 
             for each_value in arg_test_values:
                 _kwargs[arg] = each_value
-                builder_args = getattr(interfaces.numpy_fft, self.func)(
+                builder_args = getattr(self.test_interface, self.func)(
                 input_array.copy(), s, **_kwargs)
                 
                 self.assertTrue(builder_args[1][arg] == each_value)
@@ -339,18 +414,18 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
         
         finally:
             # Make sure we set it back
-            setattr(interfaces.numpy_fft, self.func, real_fft)
+            setattr(self.test_interface, self.func, real_fft)
 
         # Validate it aswell        
         for each_value in arg_test_values:
             _kwargs[arg] = each_value
-            builder_args = getattr(interfaces.numpy_fft, self.func)(
+            builder_args = getattr(self.test_interface, self.func)(
             input_array.copy(), s, **_kwargs)
 
             self.validate(array_type, test_shape, dtype, s, _kwargs)
 
     def test_auto_align_input(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
 
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
@@ -358,7 +433,7 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
                         dtype_tuple[1], test_shape, dtype, s, kwargs)
 
     def test_auto_contiguous_input(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
 
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
@@ -366,7 +441,7 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
                         dtype_tuple[1], test_shape, dtype, s, kwargs)
 
     def test_bigger_and_smaller_s(self):
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             i = -1
             for test_shape, s, kwargs in self.test_data:
@@ -386,9 +461,9 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
     def test_dtype_coercian(self):
         # Make sure we input a dtype that needs to be coerced
         if functions[self.func] == 'r2c':
-            dtype_tuple = io_dtypes['complex']
+            dtype_tuple = self.io_dtypes['complex']
         else:
-            dtype_tuple = io_dtypes['r2c']
+            dtype_tuple = self.io_dtypes['r2c']
 
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
@@ -401,7 +476,7 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
     def test_planner_effort(self):
         '''Test the planner effort arg
         '''
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
         test_shape = (16,)
         
         for dtype in dtype_tuple[0]:
@@ -428,7 +503,7 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
     def test_threads_arg(self):
         '''Test the threads argument
         '''
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
         test_shape = (16,)
         
         for dtype in dtype_tuple[0]:
@@ -452,7 +527,7 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
     def test_overwrite_input(self):
         '''Test the overwrite_input flag
         '''
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
         
         for dtype in dtype_tuple[0]:
             for test_shape, s, _kwargs in self.test_data:
@@ -461,13 +536,13 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
                 kwargs = _kwargs.copy()
                 self.validate(dtype_tuple[1], test_shape, dtype, s, kwargs)
                 
-                self.check_arg('overwrite_input', (True, False),
+                self.check_arg(self.overwrite_input_flag, (True, False),
                         dtype_tuple[1], test_shape, dtype, s, kwargs)
 
     def test_input_maintained(self):
         '''Test to make sure the input is maintained by default.
         '''
-        dtype_tuple = io_dtypes[functions[self.func]]
+        dtype_tuple = self.io_dtypes[functions[self.func]]
         for dtype in dtype_tuple[0]:
             for test_shape, s, kwargs in self.test_data:
 
@@ -475,7 +550,7 @@ class InterfacesNumpyFFTTestFFT(unittest.TestCase):
 
                 orig_input_array = input_array.copy()
                 
-                getattr(interfaces.numpy_fft, self.func)(
+                getattr(self.test_interface, self.func)(
                         input_array, s, **kwargs)
 
                 self.assertTrue(
@@ -490,7 +565,14 @@ class InterfacesNumpyFFTTestRFFT(InterfacesNumpyFFTTestFFT):
 
 class InterfacesNumpyFFTTestIRFFT(InterfacesNumpyFFTTestFFT):
     func = 'irfft'
-    realinv = True    
+    realinv = True
+
+class InterfacesNumpyFFTTestHFFT(InterfacesNumpyFFTTestFFT):
+    func = 'hfft'
+    realinv = True
+
+class InterfacesNumpyFFTTestIHFFT(InterfacesNumpyFFTTestFFT):
+    func = 'ihfft'
 
 class InterfacesNumpyFFTTestFFT2(InterfacesNumpyFFTTestFFT):
     axes_kw = 'axes'    
@@ -512,6 +594,20 @@ class InterfacesNumpyFFTTestFFT2(InterfacesNumpyFFTTestFFT):
             ((100, 200), ((100, 200), (-3, -2)), IndexError, 'Invalid axes'),
             ((100, 200), ((100,), (-3,)), IndexError, 'Invalid axes'))
 
+    def test_shape_and_s_different_lengths(self):
+        dtype_tuple = self.io_dtypes[functions[self.func]]
+        for dtype in dtype_tuple[0]:
+            for test_shape, s, _kwargs in self.test_data:
+                kwargs = copy.copy(_kwargs)
+                try:
+                    s = s[1:]
+                except TypeError:
+                    self.skipTest('Not meaningful test on 1d arrays.')
+
+                del kwargs['axes']
+                self.validate(dtype_tuple[1], 
+                        test_shape, dtype, s, kwargs)
+
 
 class InterfacesNumpyFFTTestIFFT2(InterfacesNumpyFFTTestFFT2):
     func = 'ifft2'
@@ -542,13 +638,14 @@ class InterfacesNumpyFFTTestIRFFTN(InterfacesNumpyFFTTestFFTN):
     func = 'irfftn'
     realinv = True    
 
-
 test_cases = (
         InterfacesNumpyFFTTestModule,
         InterfacesNumpyFFTTestFFT,
         InterfacesNumpyFFTTestIFFT,
         InterfacesNumpyFFTTestRFFT,
         InterfacesNumpyFFTTestIRFFT,
+        InterfacesNumpyFFTTestHFFT,
+        InterfacesNumpyFFTTestIHFFT,
         InterfacesNumpyFFTTestFFT2,
         InterfacesNumpyFFTTestIFFT2,
         InterfacesNumpyFFTTestRFFT2,
@@ -556,9 +653,9 @@ test_cases = (
         InterfacesNumpyFFTTestFFTN,
         InterfacesNumpyFFTTestIFFTN,
         InterfacesNumpyFFTTestRFFTN,
-        InterfacesNumpyFFTTestIRFFTN)
+        InterfacesNumpyFFTTestIRFFTN,)
 
-#test_set = {'InterfacesNumpyFFTTestIRFFT2': ('test_bigger_s',)}
+#test_set = {'InterfacesNumpyFFTTestHFFT': ('test_valid',)}
 test_set = None
 
 if __name__ == '__main__':
diff --git a/test/test_pyfftw_real_backward.py b/test/test_pyfftw_real_backward.py
index 359fd42..2db26f1 100644
--- a/test/test_pyfftw_real_backward.py
+++ b/test/test_pyfftw_real_backward.py
@@ -1,22 +1,39 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from pyfftw import FFTW, n_byte_align, n_byte_align_empty, forget_wisdom
+
+from pyfftw import FFTW, forget_wisdom
 import numpy
 from timeit import Timer
 import time
@@ -51,6 +68,17 @@ class RealBackwardDoubleFFTWTest(Complex64FFTWTest):
                 '2d': (256, 2048),
                 '3d': (5, 256, 2048)}
 
+    def test_invalid_args_raise(self):
+        in_shape = self.input_shapes['1d']
+        out_shape = self.output_shapes['1d']
+        
+        axes=(-1,)
+        a, b = self.create_test_arrays(in_shape, out_shape)
+
+        # Note "thread" is incorrect, it should be "threads"
+        self.assertRaises(TypeError, FFTW, a, b, axes, 
+                          direction='FFTW_BACKWARD', thread=4)
+
     def create_test_arrays(self, input_shape, output_shape, axes=None):
 
         a = self.input_dtype(numpy.random.randn(*input_shape)
@@ -253,8 +281,6 @@ class RealBackwardDoubleFFTWTest(Complex64FFTWTest):
 
         self.run_validate_fft(a_sliced, b_sliced, axes, create_array_copies=False)
 
-    @unittest.skipIf(numpy.version.version <= '1.6.2',
-            'numpy.fft <= 1.6.2 has a bug that causes this test to fail.')
     def test_non_contiguous_2d_in_3d(self):
         in_shape = (256, 4, 1025)
         out_shape = (256, 4, 2048)
@@ -276,8 +302,6 @@ class RealBackwardDoubleFFTWTest(Complex64FFTWTest):
         
         self.run_validate_fft(a_sliced, b_sliced, axes, create_array_copies=False)
 
-    @unittest.skipIf(numpy.version.version <= '1.6.2',
-            'numpy.fft <= 1.6.2 has a bug that causes this test to fail.')
     def test_non_monotonic_increasing_axes(self):
         super(RealBackwardDoubleFFTWTest, 
                 self).test_non_monotonic_increasing_axes()
@@ -327,4 +351,3 @@ if __name__ == '__main__':
     run_test_suites(test_cases, test_set)
 
 del Complex64FFTWTest
-
diff --git a/test/test_pyfftw_real_forward.py b/test/test_pyfftw_real_forward.py
index c53d6f9..c2462d7 100644
--- a/test/test_pyfftw_real_forward.py
+++ b/test/test_pyfftw_real_forward.py
@@ -1,22 +1,38 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from pyfftw import FFTW, n_byte_align, n_byte_align_empty
+from pyfftw import FFTW
 import numpy
 from timeit import Timer
 
diff --git a/test/test_pyfftw_scipy_interface.py b/test/test_pyfftw_scipy_interface.py
index 293ca42..931889d 100644
--- a/test/test_pyfftw_scipy_interface.py
+++ b/test/test_pyfftw_scipy_interface.py
@@ -1,31 +1,55 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from pyfftw.interfaces import scipy_fftpack
 import pyfftw
 import numpy
-import scipy
-import scipy.fftpack
-import scipy.signal
+
+try:
+    import scipy
+    import scipy.fftpack
+    import scipy.signal
+
+except ImportError:
+    scipy_missing = True
+
+else:
+    scipy_missing = False
 
 import unittest
 from .test_pyfftw_base import run_test_suites
-
+from . import test_pyfftw_numpy_interface
 
 '''pyfftw.interfaces.scipy_fftpack just wraps pyfftw.interfaces.numpy_fft.
 
@@ -40,13 +64,35 @@ acquired_names = ('dct', 'idct', 'diff', 'tilbert', 'itilbert', 'hilbert',
         'fftshift', 'ifftshift', 'fftfreq', 'rfftfreq', 'convolve', 
         '_fftpack')
 
+def make_complex_data(shape, dtype):
+    ar, ai = dtype(numpy.random.randn(2, *shape))
+    return ar + 1j*ai
+
+def make_r2c_real_data(shape, dtype):
+    return dtype(numpy.random.randn(*shape))
+
+def make_c2r_real_data(shape, dtype):
+    return dtype(numpy.random.randn(*shape))
+
+make_complex_data = test_pyfftw_numpy_interface.make_complex_data
+
+complex_dtypes = test_pyfftw_numpy_interface.complex_dtypes
+real_dtypes = test_pyfftw_numpy_interface.real_dtypes
+
 def numpy_fft_replacement(a, s, axes, overwrite_input, planner_effort, 
         threads, auto_align_input, auto_contiguous):
 
     return (a, s, axes, overwrite_input, planner_effort, 
         threads, auto_align_input, auto_contiguous)
 
-class InterfacesScipyFFTPackTestFFT(unittest.TestCase):
+io_dtypes = {
+        'complex': (complex_dtypes, make_complex_data),
+        'r2c': (real_dtypes, make_r2c_real_data),
+        'c2r': (real_dtypes, make_c2r_real_data)}
+
+ at unittest.skipIf(scipy_missing, 'scipy is not installed, so this feature is'
+                 'unavailable')
+class InterfacesScipyFFTPackTestSimple(unittest.TestCase):
     ''' A really simple test suite to check simple implementation.
     '''
 
@@ -54,8 +100,8 @@ class InterfacesScipyFFTPackTestFFT(unittest.TestCase):
         scipy_fftn = scipy.signal.signaltools.fftn
         scipy_ifftn = scipy.signal.signaltools.ifftn
 
-        a = pyfftw.n_byte_align_empty((128, 64), 16, dtype='complex128')
-        b = pyfftw.n_byte_align_empty((128, 64), 16, dtype='complex128')
+        a = pyfftw.empty_aligned((128, 64), dtype='complex128', n=16)
+        b = pyfftw.empty_aligned((128, 64), dtype='complex128', n=16)
 
         a[:] = (numpy.random.randn(*a.shape) + 
                 1j*numpy.random.randn(*a.shape))
@@ -112,10 +158,34 @@ class InterfacesScipyFFTPackTestFFT(unittest.TestCase):
             self.assertIs(fftpack_attr, acquired_attr)
 
 
+# Construct all the test classes automatically.
+built_classes = []
+for each_func in funcs:
+
+    class_name = 'InterfacesScipyFFTPackTest' + each_func.upper()
+
+    parent_class_name = 'InterfacesNumpyFFTTest' + each_func.upper()
+    parent_class = getattr(test_pyfftw_numpy_interface, parent_class_name)
+
+    class_dict = {'validator_module': scipy.fftpack, 
+                'test_interface': scipy_fftpack,
+                'io_dtypes': io_dtypes,
+                'overwrite_input_flag': 'overwrite_x',
+                'default_s_from_shape_slicer': slice(None)}
+
+    globals()[class_name] = type(class_name,
+            (parent_class,), class_dict)
+
+    built_classes.append(globals()[class_name])
+
+built_classes = tuple(built_classes)
+
 test_cases = (
-        InterfacesScipyFFTPackTestFFT,)
+        InterfacesScipyFFTPackTestSimple,) + built_classes
 
 test_set = None
+#test_set = {'InterfacesScipyFFTPackTestIFFTN': ['test_auto_align_input']}
+
 
 if __name__ == '__main__':
 
diff --git a/test/test_pyfftw_utils.py b/test/test_pyfftw_utils.py
index e458a88..9013c5d 100644
--- a/test/test_pyfftw_utils.py
+++ b/test/test_pyfftw_utils.py
@@ -1,20 +1,36 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 from .test_pyfftw_base import run_test_suites
diff --git a/test/test_pyfftw_wisdom.py b/test/test_pyfftw_wisdom.py
index 849f2cc..7df0342 100644
--- a/test/test_pyfftw_wisdom.py
+++ b/test/test_pyfftw_wisdom.py
@@ -1,23 +1,39 @@
-# Copyright 2012 Knowledge Economy Developments Ltd
+# Copyright 2014 Knowledge Economy Developments Ltd
 # 
 # Henry Gomersall
 # heng at kedevelopments.co.uk
 #
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
+# All rights reserved.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice, this
+# list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# * Neither the name of the copyright holder nor the names of its contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
 #
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from pyfftw import (
-        FFTW, n_byte_align_empty, 
+        FFTW, empty_aligned,
         export_wisdom, import_wisdom, forget_wisdom)
 
 from .test_pyfftw_base import run_test_suites
@@ -33,8 +49,8 @@ class FFTWWisdomTest(unittest.TestCase):
         for each_dtype in (numpy.complex128, numpy.complex64, 
                 numpy.clongdouble):
 
-            a = n_byte_align_empty((1,1024), 16, each_dtype)
-            b = n_byte_align_empty(a.shape, 16, dtype=a.dtype)
+            a = empty_aligned((1,1024), each_dtype, n=16)
+            b = empty_aligned(a.shape, dtype=a.dtype, n=16)
             fft = FFTW(a,b)
 
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pyfftw.git



More information about the debian-science-commits mailing list