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
Laporan Proyek Machine Learning - Azhar Rizki Zulma

Laporan Proyek Machine Learning - Azhar Rizki Zulma Project Overview Domain proyek yang dipilih dalam proyek machine learning ini adalah mengenai hibu

Azhar Rizki Zulma 6 Mar 12, 2022
A statistical library designed to fill the void in Python's time series analysis capabilities, including the equivalent of R's auto.arima function.

pmdarima Pmdarima (originally pyramid-arima, for the anagram of 'py' + 'arima') is a statistical library designed to fill the void in Python's time se

alkaline-ml 1.3k Dec 22, 2022
A Collection of Conference & School Notes in Machine Learning 🦄📝🎉

Machine Learning Conference & Summer School Notes. 🦄📝🎉

558 Dec 28, 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
A linear equation solver using gaussian elimination. Implemented for fun and learning/teaching.

A linear equation solver using gaussian elimination. Implemented for fun and learning/teaching. The solver will solve equations of the type: A can be

Sanjeet N. Dasharath 3 Feb 15, 2022
The project's goal is to show a real world application of image segmentation using k means algorithm

The project's goal is to show a real world application of image segmentation using k means algorithm

2 Jan 22, 2022
CinnaMon is a Python library which offers a number of tools to detect, explain, and correct data drift in a machine learning system

CinnaMon is a Python library which offers a number of tools to detect, explain, and correct data drift in a machine learning system

Zelros 67 Dec 28, 2022
We have a dataset of user performances. The project is to develop a machine learning model that will predict the salaries of baseball players.

Salary-Prediction-with-Machine-Learning 1. Business Problem Can a machine learning project be implemented to estimate the salaries of baseball players

Ayşe Nur Türkaslan 9 Oct 14, 2022
Pandas Machine Learning and Quant Finance Library Collection

Pandas Machine Learning and Quant Finance Library Collection

148 Dec 07, 2022
A Streamlit demo to interactively visualize Uber pickups in New York City

Streamlit Demo: Uber Pickups in New York City A Streamlit demo written in pure Python to interactively visualize Uber pickups in New York City. View t

Streamlit 230 Dec 28, 2022
A visual dataflow programming language for sklearn

Persimmon What is it? Persimmon is a visual dataflow language for creating sklearn pipelines. It represents functions as blocks, inputs and outputs ar

Álvaro Bermejo 194 Jan 04, 2023
Coursera Machine Learning - Python code

Coursera Machine Learning This repository contains python implementations of certain exercises from the course by Andrew Ng. For a number of assignmen

Jordi Warmenhoven 859 Dec 10, 2022
ML Optimizers from scratch using JAX

Toy implementations of some popular ML optimizers using Python/JAX

Shreyansh Singh 38 Jul 29, 2022
CobraML: Completely Customizable A python ML library designed to give the end user full control

CobraML: Completely Customizable What is it? CobraML is a python library built on both numpy and numba. Unlike other ML libraries CobraML gives the us

Sriram Govindan 14 Dec 19, 2021
Winning solution for the Galaxy Challenge on Kaggle

Winning solution for the Galaxy Challenge on Kaggle

Sander Dieleman 483 Jan 02, 2023
Automated Machine Learning with scikit-learn

auto-sklearn auto-sklearn is an automated machine learning toolkit and a drop-in replacement for a scikit-learn estimator. Find the documentation here

AutoML-Freiburg-Hannover 6.7k Jan 07, 2023
using Machine Learning Algorithm to classification AppleStore application

AppleStore-classification-with-Machine-learning-Algo- using Machine Learning Algorithm to classification AppleStore application. the first step : 1: p

Mohammed Hussien 2 May 02, 2022
A library of extension and helper modules for Python's data analysis and machine learning libraries.

Mlxtend (machine learning extensions) is a Python library of useful tools for the day-to-day data science tasks. Sebastian Raschka 2014-2021 Links Doc

Sebastian Raschka 4.2k Dec 29, 2022
ELI5 is a Python package which helps to debug machine learning classifiers and explain their predictions

A library for debugging/inspecting machine learning classifiers and explaining their predictions

154 Dec 17, 2022
My project contrasts K-Nearest Neighbors and Random Forrest Regressors on Real World data

kNN-vs-RFR My project contrasts K-Nearest Neighbors and Random Forrest Regressors on Real World data In many areas, rental bikes have been launched to

1 Oct 28, 2021