Add built-in support for quaternions to numpy

Overview

Test Status Documentation Status PyPI Version Conda Version MIT License DOI

Quaternions in numpy

This Python module adds a quaternion dtype to NumPy.

The code was originally based on code by Martin Ling (which he wrote with help from Mark Wiebe), but has been rewritten with ideas from rational to work with both python 2.x and 3.x (and to fix a few bugs), and greatly expands the applications of quaternions.

See also the pure-python package quaternionic.

Quickstart

conda install -c conda-forge quaternion

or

python -m pip install --upgrade --force-reinstall numpy-quaternion

Optionally add --user after install in the second command if you're not using a python environment — though you should start.

Dependencies

The basic requirements for this code are reasonably current versions of python and numpy. In particular, python versions 3.6 through 3.10 are routinely tested. Python 2.7 might still work, but even numpy no longer supports this version, so your mileage may vary. Also, any numpy version greater than 1.13.0 should work, but the tests are run on the most recent release at the time of the test.

However, certain advanced functions in this package (including squad, mean_rotor_in_intrinsic_metric, integrate_angular_velocity, and related functions) require scipy and can automatically use numba. Scipy is a standard python package for scientific computation, and implements interfaces to C and Fortran codes for optimization (among other things) need for finding mean and optimal rotors. Numba uses LLVM to compile python code to machine code, accelerating many numerical functions by factors of anywhere from 2 to 2000. It is possible to run all the code without numba, but these particular functions can be anywhere from 4 to 400 times slower without it.

Both scipy and numba can be installed with pip or conda. However, because conda is specifically geared toward scientific python, it is generally more robust for these more complicated packages. In fact, the main anaconda package comes with both numba and scipy. If you prefer the smaller download size of miniconda (which comes with minimal extras), you'll also have to run this command:

conda install numpy scipy numba

Installation

Assuming you use conda to manage your python installation (which is currently the preferred choice for science and engineering with python), you can install this package simply as

conda install -c conda-forge quaternion

If you prefer to use pip, you can instead do

python -m pip install --upgrade --force-reinstall numpy-quaternion

(See here for a veteran python core contributor's explanation of why you should always use python -m pip instead of just pip or pip3.) The --upgrade --force-reinstall options are not always necessary, but will ensure that pip will update numpy if it has to.

If you refuse to use conda, you might want to install inside your home directory without root privileges. (Conda does this by default anyway.) This is done by adding --user to the above command:

python -m pip install --user --upgrade --force-reinstall numpy-quaternion

Note that pip will attempt to compile the code — which requires a working C compiler.

Finally, there's also the fully manual option of just downloading the code, changing to the code directory, and running

python -m pip install --upgrade --force-reinstall .

This should work regardless of the installation method, as long as you have a compiler hanging around.

Basic usage

The full documentation can be found on Read the Docs, and most functions have docstrings that should explain the relevant points. The following are mostly for the purposes of example.

>>> import numpy as np
>>> import quaternion
>>> np.quaternion(1,0,0,0)
quaternion(1, 0, 0, 0)
>>> q1 = np.quaternion(1,2,3,4)
>>> q2 = np.quaternion(5,6,7,8)
>>> q1 * q2
quaternion(-60, 12, 30, 24)
>>> a = np.array([q1, q2])
>>> a
array([quaternion(1, 2, 3, 4), quaternion(5, 6, 7, 8)], dtype=quaternion)
>>> np.exp(a)
array([quaternion(1.69392, -0.78956, -1.18434, -1.57912),
       quaternion(138.909, -25.6861, -29.9671, -34.2481)], dtype=quaternion)

Note that this package represents a quaternion as a scalar, followed by the x component of the vector part, followed by y, followed by z. These components can be accessed directly:

>>> q1.w, q1.x, q1.y, q1.z
(1.0, 2.0, 3.0, 4.0)

However, this only works on an individual quaternion; for arrays it is better to use "vectorized" operations like as_float_array.

The following ufuncs are implemented (which means they run fast on numpy arrays):

add, subtract, multiply, divide, log, exp, power, negative, conjugate,
copysign, equal, not_equal, less, less_equal, isnan, isinf, isfinite, absolute

Quaternion components are stored as double-precision floating point numbers — floats, in python language, or float64 in more precise numpy language. Numpy arrays with dtype=quaternion can be accessed as arrays of doubles without any (slow, memory-consuming) copying of data; rather, a view of the exact same memory space can be created within a microsecond, regardless of the shape or size of the quaternion array.

Comparison operations follow the same lexicographic ordering as tuples.

The unary tests isnan and isinf return true if they would return true for any individual component; isfinite returns true if it would return true for all components.

Real types may be cast to quaternions, giving quaternions with zero for all three imaginary components. Complex types may also be cast to quaternions, with their single imaginary component becoming the first imaginary component of the quaternion. Quaternions may not be cast to real or complex types.

Several array-conversion functions are also included. For example, to convert an Nx4 array of floats to an N-dimensional array of quaternions, use as_quat_array:

>>> import numpy as np
>>> import quaternion
>>> a = np.random.rand(7, 4)
>>> a
array([[ 0.93138726,  0.46972279,  0.18706385,  0.86605021],
       [ 0.70633523,  0.69982741,  0.93303559,  0.61440879],
       [ 0.79334456,  0.65912598,  0.0711557 ,  0.46622885],
       [ 0.88185987,  0.9391296 ,  0.73670503,  0.27115149],
       [ 0.49176628,  0.56688076,  0.13216632,  0.33309146],
       [ 0.11951624,  0.86804078,  0.77968826,  0.37229404],
       [ 0.33187593,  0.53391165,  0.8577846 ,  0.18336855]])
>>> qs = quaternion.as_quat_array(a)
>>> qs
array([ quaternion(0.931387262880247, 0.469722787598354, 0.187063852060487, 0.866050210100621),
       quaternion(0.706335233363319, 0.69982740767353, 0.933035590130247, 0.614408786768725),
       quaternion(0.793344561317281, 0.659125976566815, 0.0711557025000925, 0.466228847713644),
       quaternion(0.881859869074069, 0.939129602918467, 0.736705031709562, 0.271151494174001),
       quaternion(0.491766284854505, 0.566880763189927, 0.132166320200012, 0.333091463422536),
       quaternion(0.119516238634238, 0.86804077992676, 0.779688263524229, 0.372294043850009),
       quaternion(0.331875925159073, 0.533911652483908, 0.857784598617977, 0.183368547490701)], dtype=quaternion)

[Note that quaternions are printed with full precision, unlike floats, which is why you see extra digits above. But the actual data is identical in the two cases.] To convert an N-dimensional array of quaternions to an Nx4 array of floats, use as_float_array:

>>> b = quaternion.as_float_array(qs)
>>> b
array([[ 0.93138726,  0.46972279,  0.18706385,  0.86605021],
       [ 0.70633523,  0.69982741,  0.93303559,  0.61440879],
       [ 0.79334456,  0.65912598,  0.0711557 ,  0.46622885],
       [ 0.88185987,  0.9391296 ,  0.73670503,  0.27115149],
       [ 0.49176628,  0.56688076,  0.13216632,  0.33309146],
       [ 0.11951624,  0.86804078,  0.77968826,  0.37229404],
       [ 0.33187593,  0.53391165,  0.8577846 ,  0.18336855]])

It is also possible to convert a quaternion to or from a 3x3 array of floats representing a rotation matrix, or an array of N quaternions to or from an Nx3x3 array of floats representing N rotation matrices, using as_rotation_matrix and from_rotation_matrix. Similar conversions are possible for rotation vectors using as_rotation_vector and from_rotation_vector, and for spherical coordinates using as_spherical_coords and from_spherical_coords. Finally, it is possible to derive the Euler angles from a quaternion using as_euler_angles, or create a quaternion from Euler angles using from_euler_angles — though be aware that Euler angles are basically the worst things ever.1 Before you complain about those functions using something other than your favorite conventions, please read this page.

Bug reports and feature requests

Bug reports and feature requests are entirely welcome (with very few exceptions). The best way to do this is to open an issue on this code's github page. For bug reports, please try to include a minimal working example demonstrating the problem.

Pull requests are also entirely welcome, of course, if you have an idea where the code is going wrong, or have an idea for a new feature that you know how to implement.

This code is routinely tested on recent versions of both python (3.6 though 3.9) and numpy (>=1.13). But the test coverage is not necessarily as complete as it could be, so bugs may certainly be present, especially in the higher-level functions like mean_rotor_....

Acknowledgments

This code is, of course, hosted on github. Because it is an open-source project, the hosting is free, and all the wonderful features of github are available, including free wiki space and web page hosting, pull requests, a nice interface to the git logs, etc. Github user Hannes Ovrén (hovren) pointed out some errors in a previous version of this code and suggested some nice utility functions for rotation matrices, etc. Github user Stijn van Drongelen (rhymoid) contributed some code that makes compilation work with MSVC++. Github user Jon Long (longjon) has provided some elegant contributions to substantially improve several tricky parts of this code. Rebecca Turner (9999years) and Leo Stein (duetosymmetry) did all the work in getting the documentation onto Read the Docs.

Every change in this code is automatically tested on Travis-CI. This service integrates beautifully with github, detecting each commit and automatically re-running the tests. The code is downloaded and installed fresh each time, and then tested, on each of the five different versions of python. This ensures that no change I make to the code breaks either installation or any of the features that I have written tests for. Travis-CI also automatically builds the conda and pip versions of the code hosted on anaconda.org and pypi respectively. These are all free services for open-source projects like this one.

The work of creating this code was supported in part by the Sherman Fairchild Foundation and by NSF Grants No. PHY-1306125 and AST-1333129.



1 Euler angles are awful

Euler angles are pretty much the worst things ever and it makes me feel bad even supporting them. Quaternions are faster, more accurate, basically free of singularities, more intuitive, and generally easier to understand. You can work entirely without Euler angles (I certainly do). You absolutely never need them. But if you really can't give them up, they are mildly supported.

Comments
  • Understanding the conversion operations and generating the rotation quaternion from a 3d cuboid.

    Understanding the conversion operations and generating the rotation quaternion from a 3d cuboid.

    First of all, thanks for this amazing package!

    The TL;DR is that I would like to understand why converting a quaternion to a rotation matrix, then back to a quaternion does not reproduce the input. Here is a working example:

    import numpy as np
    import quaternion
    
    # Starting point: a float array
    float_quat = np.array([0.70033807, 0.0014434, -0.00209336, 0.71380675], dtype=np.float32)
    
    # Make the quaternion object
    q = quaternion.from_float_array(float_quat)
    # print(q) ->   quaternion(0.700338065624237, 0.00144340004771948, -0.00209336006082594, 0.713806748390198)
    
    # Generate the rotation matrix
    rot = quaternion.as_rotation_matrix(q)
    # print(rot)
    # array([[-1.90489677e-02, -9.99818172e-01, -8.71502129e-04],
    #        [ 9.99806086e-01, -1.90443702e-02, -5.01024534e-03],
    #        [ 4.99273713e-03, -9.66773134e-04,  9.99987069e-01]])
    
    # Go back to the quaternion representation
    q_from_rot = quaternion.from_rotation_matrix(rot)
    # print(q_from_rot)
    # quaternion(-0.700338084614, -0.00144340008685747, 0.00209336011758765, -0.713806767745166)
    

    The only difference is that all the signs have been reversed (neglecting difference due to precision).


    I am working on a problem whereby I receive 3d objects of the form: centroids (x, y, z), dimensions (length, width, height) and quaternion-rotation (w, x, y, z). For my purposes, I must represent these objects as 3d cuboids and (for speed) rotation matrices. After the processing, I need to once again restore a representation of centroids and quaternions, based on the 8 points of the 3d cuboid.

    I thought if I can manually create the rotation matrix from the final cuboid, I could use quaternion.from_rotation_matrix() to get the final quaternion representation (note that I don't actually expect the same quaternion that I began with, as the object may have been rotated). I started out by testing the conversions as in the code above, from a rotation matrix to quaternion.

    Is there another way to achieve this that I am overlooking?

    Thanks in advance for any help!

    opened by Nicholas-Mitchell 12
  • ValueError: size must be a divisor of the total size in bytes of the last axis of the array

    ValueError: size must be a divisor of the total size in bytes of the last axis of the array

    I have a numpy array with dimensions (4, 364, 3969), and try to convert it into a quat_array, e.g.,

    quat.as_quat_array(np.random.rand(4, 364, 3969) )

    and get the error

    ------------------------------------------------------------
    ValueError                 Traceback (most recent call last)
    <ipython-input-35-79d845f77eba> in <module>()
    ----> 1 quat.as_quat_array(testarray)
    
    ~/miniconda3/lib/python3.6/site-packages/quaternion/__init__.py in as_quat_array(a)
         90     if not a.flags['C_CONTIGUOUS'] or a.strides[-1] != a.itemsize:
         91         a = a.copy(order='C')
    ---> 92     av = a.view(np.quaternion)
         93 
         94     # special case - don't create an axis for a single quaternion, to match
    
    ValueError: When changing to a larger dtype, its size must be a divisor of the total size in bytes of the last axis of the array.
    

    Interestingly,

    quat.as_quat_array(np.random.rand(4, 364, 3968) ) works, (4, 364, 3964) does also, quat.as_quat_array(np.random.rand(4, 364, 3967) ) does not, so it seems that the last dimension must ba divisible by 4.

    The same applies for larger arrays, e.g.

    quat.as_quat_array(np.random.rand(4, 364, 3964,16) ) works

    quat.as_quat_array(np.random.rand(4, 364, 3964,15) ) does not.

    The workaround would probably be to design only arrays with last dimensions divisible by 4 (as the error suggests, "its size must be a divisor of the total size in bytes of the last axis of the array.").

    Is there another way to handle this behavior? Thank you!

    opened by BEpresent 12
  • as_quat_array is not working for huge volume of data:

    as_quat_array is not working for huge volume of data:

    When I tried to convert numpy array of size (2510792,4) to quaternion, I am not able to do the same. But the functionality is working for small size arrays

    opened by Srinivsankrishnan27 12
  • Memory leak when multiplying or adding quaternion array

    Memory leak when multiplying or adding quaternion array

    Describe the bug Multiplying (and adding, haven't tried the other ops) causes a memory leak. Memory usage does not go down over time after multiplying or adding. This occurs on an older version, and on the most up to date version of the quaternion library.

    To Reproduce The script below will print out the memory used, you should see that x = q * qa consumes a ton of memory that is not reclaimed. Running free should also show that memory is not returned until the program is killed.

    Note the program below loops forever so you have time to check into its memory usage.

    import numpy as np
    import quaternion
    import tracemalloc # requires python 3.6
    
    tracemalloc.start()
    
    def doit():
        q = np.quaternion(0.1, 0.1, 0.1, 0.1)
        qa = quaternion.as_quat_array([1.0] * 100000000)
        x = q * qa # THIS IS THE PROBLEMATIC LINE.
    
    def snapshot_trace():
        snapshot = tracemalloc.take_snapshot()
        top_stats = snapshot.statistics('lineno')
    
        print("[ Top 10 ]")
        for stat in top_stats[:10]:
            print(stat)
    
    snapshot_trace()
    doit()
    snapshot_trace()
    doit()
    snapshot_trace()
    
    # just here so you can check memory usage while this runs.
    while True:
        pass
    

    Sample output, not the first line is (1526MiB) used.

    [ Top 10 ]
    minimal.py:13: size=1526 MiB, count=4, average=381 MiB
    /home/brett/miniconda3/lib/python3.6/tracemalloc.py:65: size=1584 B, count=22, average=72 B
    /home/brett/miniconda3/lib/python3.6/tracemalloc.py:499: size=1488 B, count=4, average=372 B
    /home/brett/miniconda3/lib/python3.6/tracemalloc.py:207: size=896 B, count=2, average=448 B
    /home/brett/miniconda3/lib/python3.6/tracemalloc.py:165: size=864 B, count=2, average=432 B
    /home/brett/miniconda3/lib/python3.6/tracemalloc.py:497: size=680 B, count=1, average=680 B
    minimal.py:12: size=584 B, count=1, average=584 B
    /home/brett/miniconda3/lib/python3.6/tracemalloc.py:469: size=528 B, count=2, average=264 B
    minimal.py:18: size=480 B, count=1, average=480 B
    

    Expected behavior After each doit() call, memory usage should go back down and not climb as more and more calls are made, but instead we see that the memory is not reclaimed:

    Environment (please complete the following information):

    • OS, including version: Distributor ID: Ubuntu Description: Ubuntu 16.04.5 LTS Release: 16.04 Codename: xenial
    • Python version: Python 3.6.3 :: Anaconda, Inc.
    • Installation method: pip
    • Numpy version: '1.15.1'
    • Quaternion version: '2018.7.5.21.55.13'
    bug 
    opened by ctrlbrett 10
  • pickling quaternions fails

    pickling quaternions fails

    import quaternion
    import pickle
    
    a = quaternion.from_rotation_vector([0, 0, np.pi/3])
    
    pickle.dumps(a)
    

    produces:

    ---------------------------------------------------------------------------
    PicklingError                             Traceback (most recent call last)
    <ipython-input-47-143f409b05ff> in <module>()
          5 a = quaternion.from_rotation_vector([0, 0, np.pi/3])
          6 
    ----> 7 pickle.dumps(a)
    
    PicklingError: Can't pickle <class 'quaternion'>: attribute lookup quaternion on builtins failed
    

    I would like to use quaternions inside an application using dask, [http://dask.pydata.org/en/latest/] and dask distributed which seems to rely on cloudpickle to distribute work to workers on a cluster.

    How hard would it be to get this working?

    Thanks!

    opened by ulijh 10
  • from_rotation_matrix improved algorithms

    from_rotation_matrix improved algorithms

    According to the results of this survey paper

    A Survey on the Computation of Quaternions from Rotation Matrices Soheil Sarabandi and Federico Thomas, October 2018 Journal of Mechanisms and Robotics 11(2)

    the preferred algorithm for an orthonormal input matrix should be Cayley’s method (section 3.5 page 14).

    • Cayley’s method, besides being the simplest one, is superior in terms of accuracy and speed. Among the numerical methods, the second version of Bar-Itzhack’s method is the only one that deserves some attention as it can be used to obtain the quaternion corresponding to a non-perfectly orthogonal rotation matrix [48]. 20 In this case, the quaternion corresponds to the nearest orthogonal matrix to the input non-orthogonal matrix, where closeness is expressed in the Frobenius norm [52].

    I'd be interested to review and test the implementation of the Bar-Itzhack algorithm.

    If you'd like then I can attempt to contribute PRs:

    1. Change from Markley to Cayley for orthonormal case
    2. Tests of Bar-Itzhack implementation for speed and accuracy 2.1 Improve Bar-Itzhack speed and/or accuracy
    opened by willwray 8
  • Install via pip requirements.txt error

    Install via pip requirements.txt error

    I was trying to do a pip install using a requirements.txt file and it failed. Details:

    1. The pip command used: python -m pip install -r requirements.txt. Python==3.6.5, pip==9.0.3;
    2. The requirements.txt contained two lines: line 1: numpy==1.15.0, line 2: numpy-quaternion==2018.11.3.1.0.41.

    The error was:

    Collecting numpy-quaternion==2018.11.3.1.0.41 (from -r requirements.txt (line 25)) Using cached https://files.pythonhosted.org/packages/3c/5d/e58d67cd579061aa2c392dfeef510ba35b89d208d8ec689b0b0438c3632c/numpy-quaternion-2018.11.3.1.0.41.tar.gz Complete output from command python setup.py egg_info: The variable 'package_version' was not present in the environment Setup.py using strftime version='2018.12.12.21.45.36' Traceback (most recent call last): File "", line 1, in File "/tmp/pip-build-0iuc7nb6/numpy-quaternion/setup.py", line 54, in import numpy ModuleNotFoundError: No module named 'numpy'

    ----------------------------------------
    

    Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-0iuc7nb6/numpy-quaternion/

    Environment

    • Ubuntu 16.04

    I know I could install them one at a time (numpy first and numpy-quaternion second) and it worked. But it would be more convenient if I could use the requirements.txt method.

    opened by rowanxyt 8
  • Kernel never returns from `np.prod()` on quaternions

    Kernel never returns from `np.prod()` on quaternions

    Performing the prod NumPy operation over an array of quaternions results in kernel becoming unresponsive and producing a 100% CPU load. Only restarting the kernel would bring the notebook back to life.

    Example code:

    np.prod([np.quaternion(1, 0, 0, 0), np.quaternion(0, 0, 0, 1)])
    
    opened by noncom 8
  • Versioning fails when 'CI' is 'true'

    Versioning fails when 'CI' is 'true'

    I have written a package and would like to use quaternion as a dependency. On my local machine I installed it fine using pip and got everything working the way I wanted to and the tests passing. Then I pushed the new code to GitHub and started a TravisCI build, which failed with errors something like this:

    Collecting numpy-quaternion (from suspect==0.3.0a0)
      Downloading numpy-quaternion-2017.03.16.21.51.57.dev242408302.tar.gz (42kB)
        100% |████████████████████████████████| 51kB 11.6MB/s 
        Complete output from command python setup.py egg_info:
        fatal: Not a git repository (or any of the parent directories): .git
        /tmp/pip-build-n4nfx3tp/numpy-quaternion/auto_version/__init__.py:87: UserWarning:
        The 'calculate_version' function failed to get the git version.Maybe your version of python (<2.7?) is too old.  Here's the exception:
        Command 'git show -s --format="%ci %h" HEAD' returned non-zero exit status 128
          warn(warning)
        Traceback (most recent call last):
          File "<string>", line 1, in <module>
          File "/tmp/pip-build-n4nfx3tp/numpy-quaternion/setup.py", line 35, in <module>
            version=calculate_version(validate, error_on_invalid),
          File "/tmp/pip-build-n4nfx3tp/numpy-quaternion/auto_version/__init__.py", line 91, in calculate_version
            raise e
          File "/tmp/pip-build-n4nfx3tp/numpy-quaternion/auto_version/__init__.py", line 57, in calculate_version
            git_revision = subprocess.check_output("""git show -s --format="%ci %h" HEAD""", shell=use_shell).decode('ascii').rstrip()
          File "/opt/python/3.5.2/lib/python3.5/subprocess.py", line 626, in check_output
            **kwargs).stdout
          File "/opt/python/3.5.2/lib/python3.5/subprocess.py", line 708, in run
            output=stdout, stderr=stderr)
        subprocess.CalledProcessError: Command 'git show -s --format="%ci %h" HEAD' returned non-zero exit status 128
        Raising exception because environment variable 'CI' is "true"
        
        ----------------------------------------
    Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-n4nfx3tp/numpy-quaternion/
    The command "pip install ." failed and exited with 1 during .
    

    I am not sure but I think this might be because the auto_version assumes that if it is being installed on CI then it is being tested itself and so must be a git repo, whereas it is actually only a dependency without a repo of its own.

    enhancement 
    opened by bennyrowland 8
  • When using latest releases: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared

    When using latest releases: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared

    I'm not sure anything needs done here, just wanted to alert people having the same issue. If you have this error just revert to a previous version with python -m pip install numpy-quaternion==2021.3.11.10.32.22, or use python3 instead.

    When reverting to a past release with: python -m pip install numpy-quaternion==2021.3.11.10.32.22 it installs fine, but anything after that (starting with python -m pip install numpy-quaternion==2021.3.17.7.29.41), it errors out with the below error message. Using python 2.7 with pip 19.2.1.

    Full error log:

    Building wheels for collected packages: numpy-quaternion
      Building wheel for numpy-quaternion (PEP 517) ... error
      ERROR: Command errored out with exit status 1:
       command: /usr/bin/python /usr/local/lib/python2.7/dist-packages/pip/_vendor/pep517/_in_process.py build_wheel /tmp/tmpLaK6lg
           cwd: /tmp/pip-install-YApnml/numpy-quaternion
      Complete output (127 lines):
      running bdist_wheel
      running build
      running build_py
      creating build
      creating build/lib.linux-x86_64-2.7
      creating build/lib.linux-x86_64-2.7/quaternion
      copying src/quaternion/calculus.py -> build/lib.linux-x86_64-2.7/quaternion
      copying src/quaternion/numba_wrapper.py -> build/lib.linux-x86_64-2.7/quaternion
      copying src/quaternion/__init__.py -> build/lib.linux-x86_64-2.7/quaternion
      copying src/quaternion/quaternion_time_series.py -> build/lib.linux-x86_64-2.7/quaternion
      copying src/quaternion/means.py -> build/lib.linux-x86_64-2.7/quaternion
      running build_ext
      building 'quaternion.numpy_quaternion' extension
      creating build/temp.linux-x86_64-2.7
      creating build/temp.linux-x86_64-2.7/src
      x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-gnDdqE/python2.7-2.7.17=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I/tmp/pip-build-env-P0Q61t/overlay/lib/python2.7/site-packages/numpy/core/include -Isrc -I/usr/include/python2.7 -c src/quaternion.c -o build/temp.linux-x86_64-2.7/src/quaternion.o -O3 -w
      x86_64-linux-gnu-gcc -pthread -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fdebug-prefix-map=/build/python2.7-gnDdqE/python2.7-2.7.17=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I/tmp/pip-build-env-P0Q61t/overlay/lib/python2.7/site-packages/numpy/core/include -Isrc -I/usr/include/python2.7 -c src/numpy_quaternion.c -o build/temp.linux-x86_64-2.7/src/numpy_quaternion.o -O3 -w
      src/numpy_quaternion.c: In function ‘pyquaternion_add’:
      src/numpy_quaternion.c:318:3: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared (first use in this function); did you mean ‘Py_RETURN_NONE’?
         Py_RETURN_NOTIMPLEMENTED; \
         ^
      src/numpy_quaternion.c:320:51: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL’
       #define QQ_QS_SQ_BINARY_QUATERNION_RETURNER(name) QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL(name, name)
                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      src/numpy_quaternion.c:321:1: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER’
       QQ_QS_SQ_BINARY_QUATERNION_RETURNER(add)
       ^
      src/numpy_quaternion.c:318:3: note: each undeclared identifier is reported only once for each function it appears in
         Py_RETURN_NOTIMPLEMENTED; \
         ^
      src/numpy_quaternion.c:320:51: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL’
       #define QQ_QS_SQ_BINARY_QUATERNION_RETURNER(name) QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL(name, name)
                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      src/numpy_quaternion.c:321:1: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER’
       QQ_QS_SQ_BINARY_QUATERNION_RETURNER(add)
       ^
      src/numpy_quaternion.c: In function ‘pyquaternion_subtract’:
      src/numpy_quaternion.c:318:3: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared (first use in this function); did you mean ‘Py_RETURN_NONE’?
         Py_RETURN_NOTIMPLEMENTED; \
         ^
      src/numpy_quaternion.c:320:51: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL’
       #define QQ_QS_SQ_BINARY_QUATERNION_RETURNER(name) QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL(name, name)
                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      src/numpy_quaternion.c:322:1: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER’
       QQ_QS_SQ_BINARY_QUATERNION_RETURNER(subtract)
       ^
      src/numpy_quaternion.c: In function ‘pyquaternion_multiply’:
      src/numpy_quaternion.c:318:3: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared (first use in this function); did you mean ‘Py_RETURN_NONE’?
         Py_RETURN_NOTIMPLEMENTED; \
         ^
      src/numpy_quaternion.c:320:51: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL’
       #define QQ_QS_SQ_BINARY_QUATERNION_RETURNER(name) QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL(name, name)
                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      src/numpy_quaternion.c:323:1: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER’
       QQ_QS_SQ_BINARY_QUATERNION_RETURNER(multiply)
       ^
      src/numpy_quaternion.c: In function ‘pyquaternion_divide’:
      src/numpy_quaternion.c:318:3: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared (first use in this function); did you mean ‘Py_RETURN_NONE’?
         Py_RETURN_NOTIMPLEMENTED; \
         ^
      src/numpy_quaternion.c:320:51: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL’
       #define QQ_QS_SQ_BINARY_QUATERNION_RETURNER(name) QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL(name, name)
                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      src/numpy_quaternion.c:324:1: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER’
       QQ_QS_SQ_BINARY_QUATERNION_RETURNER(divide)
       ^
      src/numpy_quaternion.c: In function ‘pyquaternion_power’:
      src/numpy_quaternion.c:318:3: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared (first use in this function); did you mean ‘Py_RETURN_NONE’?
         Py_RETURN_NOTIMPLEMENTED; \
         ^
      src/numpy_quaternion.c:320:51: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL’
       #define QQ_QS_SQ_BINARY_QUATERNION_RETURNER(name) QQ_QS_SQ_BINARY_QUATERNION_RETURNER_FULL(name, name)
                                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      src/numpy_quaternion.c:327:1: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_RETURNER’
       QQ_QS_SQ_BINARY_QUATERNION_RETURNER(power)
       ^
      src/numpy_quaternion.c: In function ‘pyquaternion_inplace_add’:
      src/numpy_quaternion.c:352:5: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared (first use in this function); did you mean ‘Py_RETURN_NONE’?
           Py_RETURN_NOTIMPLEMENTED; \
           ^
      src/numpy_quaternion.c:354:50: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_INPLACE_FULL’
       #define QQ_QS_SQ_BINARY_QUATERNION_INPLACE(name) QQ_QS_SQ_BINARY_QUATERNION_INPLACE_FULL(name, name)
                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      src/numpy_quaternion.c:355:1: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_INPLACE’
       QQ_QS_SQ_BINARY_QUATERNION_INPLACE(add)
       ^
      src/numpy_quaternion.c: In function ‘pyquaternion_inplace_subtract’:
      src/numpy_quaternion.c:352:5: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared (first use in this function); did you mean ‘Py_RETURN_NONE’?
           Py_RETURN_NOTIMPLEMENTED; \
           ^
      src/numpy_quaternion.c:354:50: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_INPLACE_FULL’
       #define QQ_QS_SQ_BINARY_QUATERNION_INPLACE(name) QQ_QS_SQ_BINARY_QUATERNION_INPLACE_FULL(name, name)
                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      src/numpy_quaternion.c:356:1: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_INPLACE’
       QQ_QS_SQ_BINARY_QUATERNION_INPLACE(subtract)
       ^
      src/numpy_quaternion.c: In function ‘pyquaternion_inplace_multiply’:
      src/numpy_quaternion.c:352:5: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared (first use in this function); did you mean ‘Py_RETURN_NONE’?
           Py_RETURN_NOTIMPLEMENTED; \
           ^
      src/numpy_quaternion.c:354:50: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_INPLACE_FULL’
       #define QQ_QS_SQ_BINARY_QUATERNION_INPLACE(name) QQ_QS_SQ_BINARY_QUATERNION_INPLACE_FULL(name, name)
                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      src/numpy_quaternion.c:357:1: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_INPLACE’
       QQ_QS_SQ_BINARY_QUATERNION_INPLACE(multiply)
       ^
      src/numpy_quaternion.c: In function ‘pyquaternion_inplace_divide’:
      src/numpy_quaternion.c:352:5: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared (first use in this function); did you mean ‘Py_RETURN_NONE’?
           Py_RETURN_NOTIMPLEMENTED; \
           ^
      src/numpy_quaternion.c:354:50: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_INPLACE_FULL’
       #define QQ_QS_SQ_BINARY_QUATERNION_INPLACE(name) QQ_QS_SQ_BINARY_QUATERNION_INPLACE_FULL(name, name)
                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      src/numpy_quaternion.c:358:1: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_INPLACE’
       QQ_QS_SQ_BINARY_QUATERNION_INPLACE(divide)
       ^
      src/numpy_quaternion.c: In function ‘pyquaternion_inplace_power’:
      src/numpy_quaternion.c:352:5: error: ‘Py_RETURN_NOTIMPLEMENTED’ undeclared (first use in this function); did you mean ‘Py_RETURN_NONE’?
           Py_RETURN_NOTIMPLEMENTED; \
           ^
      src/numpy_quaternion.c:354:50: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_INPLACE_FULL’
       #define QQ_QS_SQ_BINARY_QUATERNION_INPLACE(name) QQ_QS_SQ_BINARY_QUATERNION_INPLACE_FULL(name, name)
                                                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      src/numpy_quaternion.c:361:1: note: in expansion of macro ‘QQ_QS_SQ_BINARY_QUATERNION_INPLACE’
       QQ_QS_SQ_BINARY_QUATERNION_INPLACE(power)
       ^
      error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
      ----------------------------------------
      ERROR: Failed building wheel for numpy-quaternion
      Running setup.py clean for numpy-quaternion
    Failed to build numpy-quaternion
    ERROR: Could not build wheels for numpy-quaternion which use PEP 517 and cannot be installed directly
    WARNING: You are using pip version 19.2.1, however version 20.3.4 is available.
    You should consider upgrading via the 'pip install --upgrade pip' command.
    
    opened by DanielArnett 7
  • Implementation of mean_rotor_in_intrinsic_metric

    Implementation of mean_rotor_in_intrinsic_metric

    mean_rotor_in_intrinsic_metric is currently not implemented. I am fairly new to the language of quaternions, but it seems like the algorithm in Markley, F. Landis, Yang Chen, John Lucas Crassidis, and Yaakov Oshman. "Average Quaternions." Journal of Guidance, Control, and Dynamics. Vol. 30, Issue 4, 2007, pp. 1193-1197 would be relevant here. Would you like for me to submit a PR? I would be happy to do so. My initial thought was to make yet another home-grown quaternion package, but I really like how you built the infrastructure here.

    opened by madphysicist 7
  • Add `assert(PyGILState_Check());` in `QUATERNION_copyswapn()`

    Add `assert(PyGILState_Check());` in `QUATERNION_copyswapn()`

    I'm working on a systematic cleanup of the extended Google codebase, which imports this github project. Using the patch below in the Google environment, I found a GIL check failure when running test_quaternion.py.

    I have not tried this outside the Google environment. Creating this PR to see if that reproduces the failure. (If not I'll explain more.)

    --- python_runtime/v3_9/Include/object.h
    +++ python_runtime/v3_9/Include/object.h
    @@ -417,8 +417,11 @@ PyAPI_FUNC(void) _Py_NegativeRefcount(co
    
     PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
    
    +PyAPI_FUNC(int) PyGILState_Check(void); /* Include/cpython/pystate.h */
    +
     static inline void _Py_INCREF(PyObject *op)
     {
    +    assert(PyGILState_Check());
     #ifdef Py_REF_DEBUG
         _Py_RefTotal++;
     #endif
    @@ -433,6 +436,7 @@ static inline void _Py_DECREF(
     #endif
         PyObject *op)
     {
    +    assert(PyGILState_Check());
     #ifdef Py_REF_DEBUG
         _Py_RefTotal--;
     #endif
    
    opened by rwgk 15
  • Build musl aarch64 wheels

    Build musl aarch64 wheels

    I added a line to skip musl builds on aarch64 in #187, because it takes ~50 minutes to build numpy for each python version in those runs. But numpy/numpy#20089 and numpy/numpy#20102 suggest that they might soon be available as wheels, so I could remove that skip.

    Alternatively, whatever numpy chooses to go with in its new cibuildwheels approach, I could restrict to with this package, since anyone who can't just use a numpy wheel will have to build numpy, which means they could just as easily build this package.

    opened by moble 0
  • array attributes for  scalar, vector,

    array attributes for scalar, vector,

    would it be possible to do array attributes for things like scalar part, and vector part, (or x,y,z, w parts too) like the way complex arrays do .real and .imag?

    opened by arsenovic 0
Releases(v2022.4.2)
Owner
Mike Boyle
Mike Boyle
Databricks Certified Associate Spark Developer preparation toolkit to setup single node Standalone Spark Cluster along with material in the form of Jupyter Notebooks.

Databricks Certification Spark Databricks Certified Associate Spark Developer preparation toolkit to setup single node Standalone Spark Cluster along

19 Dec 13, 2022
Python bindings for MPI

MPI for Python Overview Welcome to MPI for Python. This package provides Python bindings for the Message Passing Interface (MPI) standard. It is imple

MPI for Python 604 Dec 29, 2022
Implementation of different ML Algorithms from scratch, written in Python 3.x

Implementation of different ML Algorithms from scratch, written in Python 3.x

Gautam J 393 Nov 29, 2022
A repository to work on Machine Learning course. Select an algorithm to classify writer's gender, of Hebrew texts.

MachineLearning A repository to work on Machine Learning course. Select an algorithm to classify writer's gender, of Hebrew texts. Tested algorithms:

Haim Adrian 1 Feb 01, 2022
Simulate & classify transient absorption spectroscopy (TAS) spectral features for bulk semiconducting materials (Post-DFT)

PyTASER PyTASER is a Python (3.9+) library and set of command-line tools for classifying spectral features in bulk materials, post-DFT. The goal of th

Materials Design Group 4 Dec 27, 2022
🌊 River is a Python library for online machine learning.

River is a Python library for online machine learning. It is the result of a merger between creme and scikit-multiflow. River's ambition is to be the go-to library for doing machine learning on strea

OnlineML 4k Jan 03, 2023
Tribuo - A Java machine learning library

Tribuo - A Java prediction library (v4.1) Tribuo is a machine learning library in Java that provides multi-class classification, regression, clusterin

Oracle 1.1k Dec 28, 2022
Automatic extraction of relevant features from time series:

tsfresh This repository contains the TSFRESH python package. The abbreviation stands for "Time Series Feature extraction based on scalable hypothesis

Blue Yonder GmbH 7k Jan 06, 2023
Mesh TensorFlow: Model Parallelism Made Easier

Mesh TensorFlow - Model Parallelism Made Easier Introduction Mesh TensorFlow (mtf) is a language for distributed deep learning, capable of specifying

1.3k Dec 26, 2022
Decision Weights in Prospect Theory

Decision Weights in Prospect Theory It's clear that humans are irrational, but how irrational are they? After some research into behavourial economics

Cameron Davidson-Pilon 32 Nov 08, 2021
A Powerful Serverless Analysis Toolkit That Takes Trial And Error Out of Machine Learning Projects

KXY: A Seemless API to 10x The Productivity of Machine Learning Engineers Documentation https://www.kxy.ai/reference/ Installation From PyPi: pip inst

KXY Technologies, Inc. 35 Jan 02, 2023
Official code for HH-VAEM

HH-VAEM This repository contains the official Pytorch implementation of the Hierarchical Hamiltonian VAE for Mixed-type Data (HH-VAEM) model and the s

Ignacio Peis 8 Nov 30, 2022
Feature-engine is a Python library with multiple transformers to engineer and select features for use in machine learning models.

Feature-engine is a Python library with multiple transformers to engineer and select features for use in machine learning models. Feature-engine's transformers follow scikit-learn's functionality wit

Soledad Galli 33 Dec 27, 2022
Mosec is a high-performance and flexible model serving framework for building ML model-enabled backend and microservices

Mosec is a high-performance and flexible model serving framework for building ML model-enabled backend and microservices. It bridges the gap between any machine learning models you just trained and t

164 Jan 04, 2023
A handy tool for common machine learning models' hyper-parameter tuning.

Common machine learning models' hyperparameter tuning This repo is for a collection of hyper-parameter tuning for "common" machine learning models, in

Kevin Hu 2 Jan 27, 2022
Bottleneck a collection of fast, NaN-aware NumPy array functions written in C.

Bottleneck Bottleneck is a collection of fast, NaN-aware NumPy array functions written in C. As one example, to check if a np.array has any NaNs using

Python for Data 835 Dec 27, 2022
Management of exclusive GPU access for distributed machine learning workloads

TensorHive is an open source tool for managing computing resources used by multiple users across distributed hosts. It focuses on granting

Paweł Rościszewski 131 Dec 12, 2022
The code from the Machine Learning Bookcamp book and a free course based on the book

The code from the Machine Learning Bookcamp book and a free course based on the book

Alexey Grigorev 5.5k Jan 09, 2023
My capstone project for Udacity's Machine Learning Nanodegree

MLND-Capstone My capstone project for Udacity's Machine Learning Nanodegree Lane Detection with Deep Learning In this project, I use a deep learning-b

Michael Virgo 407 Dec 12, 2022
Sequence learning toolkit for Python

seqlearn seqlearn is a sequence classification toolkit for Python. It is designed to extend scikit-learn and offer as similar as possible an API. Comp

Lars 653 Dec 27, 2022