{"id":15358850,"url":"https://github.com/warrenweckesser/numtypes","last_synced_at":"2025-04-15T07:21:32.829Z","repository":{"id":141013618,"uuid":"207826082","full_name":"WarrenWeckesser/numtypes","owner":"WarrenWeckesser","description":"Custom data types for numpy","archived":false,"fork":false,"pushed_at":"2024-08-07T00:05:54.000Z","size":160,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T17:47:47.463Z","etag":null,"topics":["numpy","python"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WarrenWeckesser.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-09-11T13:59:29.000Z","updated_at":"2024-08-07T00:05:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"e9f25958-3f03-4722-9407-5e7f65f03f6f","html_url":"https://github.com/WarrenWeckesser/numtypes","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WarrenWeckesser%2Fnumtypes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WarrenWeckesser%2Fnumtypes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WarrenWeckesser%2Fnumtypes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WarrenWeckesser%2Fnumtypes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WarrenWeckesser","download_url":"https://codeload.github.com/WarrenWeckesser/numtypes/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249024028,"owners_count":21200013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["numpy","python"],"created_at":"2024-10-01T12:43:13.156Z","updated_at":"2025-04-15T07:21:32.807Z","avatar_url":"https://github.com/WarrenWeckesser.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"numtypes\n========\n\nCustom data types for NumPy.\n\nThe following data types are defined in this library:\n\n* `logfloat32` and `logfloat64` are nonnegative floating point values\n  that store the *logarithm* of the value instead of the value.  Arithmetic\n  operations and NumPy ufuncs are implemented to allow operations on these\n  types over a large range of values without overflow or underflow.\n* `nint32` is a 32 bit signed integer type that uses the most negative\n  value as `nan`.\n* `polarcomplex64` and `polarcomplex128` are complex numbers represented\n  in polar coordinates.  (The Python objects and NumPy data types have been\n  created, but the NumPy ufuncs are not implemented yet.)\n* `logfloat` is a Python type that represents nonnegative floating point\n  numbers.  The type works with the logarithm of the numbers internally,\n  so it can do elementary arithmetic with values such as exp(-1200).\n  This is a *Python* type only; the NumPy types are `logfloat32` and `logfloat64`.\n\nThis package is an experimental work in progress.  Use at your own risk!\n\nExamples\n--------\n\n### `logfloat32` and `logfloat64`\n\nThe following shows calculations involving floating point values that\nwould be too small to represent as standard IEEE-754 32 bit floating\npoint:\n\n    \u003e\u003e\u003e import numpy as np\n    \u003e\u003e\u003e from numtypes import logfloat32\n\nNote that `logfloat32(log=-1000)` represents the value whose log is\n-1000, which is approximately `5.0759588975e-435`.\n\n    \u003e\u003e\u003e x = np.array([logfloat32(log=-1000), logfloat32(log=-1001.5),\n    ...               logfloat32(log=-1002)])\n    ...\n    \u003e\u003e\u003e x\n    array([logfloat32(log=-1000.0), logfloat32(log=-1001.5),\n           logfloat32(log=-1002.0)], dtype=logfloat32)\n    \u003e\u003e\u003e 2*x\n    array([logfloat32(log=-999.3068), logfloat32(log=-1000.8068),\n           logfloat32(log=-1001.3068)], dtype=logfloat32)\n    \u003e\u003e\u003e np.sqrt(x)\n    array([logfloat32(log=-500.0), logfloat32(log=-500.75),\n           logfloat32(log=-501.0)], dtype=logfloat32)\n    \u003e\u003e\u003e c = np.full(len(x), fill_value=logfloat32(log=-999))\n    \u003e\u003e\u003e c\n    array([logfloat32(log=-999.0), logfloat32(log=-999.0),\n           logfloat32(log=-999.0)], dtype=logfloat32)\n    \u003e\u003e\u003e x + c\n    array([logfloat32(log=-998.68677), logfloat32(log=-998.9211),\n           logfloat32(log=-998.9514)], dtype=logfloat32)\n    \u003e\u003e\u003e x * c\n    array([logfloat32(log=-1999.0), logfloat32(log=-2000.5),\n           logfloat32(log=-2001.0)], dtype=logfloat32)\n    \u003e\u003e\u003e x / c\n    array([logfloat32(log=-1.0), logfloat32(log=-2.5), logfloat32(log=-3.0)],\n           dtype=logfloat32)\n\n\n### Integers with `nan`, `nint32`\n\nSome examples of `nint32`:\n\n    \u003e\u003e\u003e import numpy as np\n    \u003e\u003e\u003e from numtypes import nint32\n\n    \u003e\u003e\u003e a = np.array([10, -99, 0, 1234], dtype=nint32)\n    \u003e\u003e\u003e a\n    array([10, -99, 0, 1234], dtype=nint32)\n    \u003e\u003e\u003e a.sum(initial=nint32(0))\n    1145\n\n    \u003e\u003e\u003e b = np.array([9, np.nan, 100, -1], dtype=nint32)\n    \u003e\u003e\u003e b\n    array([9, nan, 100, -1], dtype=nint32)\n    \u003e\u003e\u003e b.sum(initial=nint32(0))\n    nan\n    \u003e\u003e\u003e b // nint32(5)                     # Preserves dtype\n    array([1, nan, 20, -1], dtype=nint32)\n    \u003e\u003e\u003e b / 5                              # True divide, casts to float64.\n    array([ 1.8,  nan, 20. , -0.2])\n\n    \u003e\u003e\u003e a + b\n    array([19, nan, 100, 1233], dtype=nint32)\n    \u003e\u003e\u003e a * b\n    array([90, nan, 0, -1234], dtype=nint32)\n    \u003e\u003e\u003e a / b\n    array([ 1.11111111e+00,             nan,  0.00000000e+00, -1.23400000e+03])\n\n    \u003e\u003e\u003e a.astype(np.int32)\n    array([  10,  -99,    0, 1234], dtype=int32)\n    \u003e\u003e\u003e b.astype(np.int32)  # Note that nint32('nan') casts to -2147483648.\n    array([          9, -2147483648,         100,          -1], dtype=int32)\n    \u003e\u003e\u003e b.astype(np.float32)\n    array([  9.,  nan, 100.,  -1.], dtype=float32)\n\n    \u003e\u003e\u003e np.isnan(b)\n    array([False,  True, False, False])\n\n\n### Polar complex types\n\nSome examples of `polarcomplex64` and `polarcomplex128`:\n\n    \u003e\u003e\u003e from numtypes import polarcomplex64, polarcomplex128\n\nA tuple given to the type holds the magnitude and angle of the complex number.\nThe attributes `r` and `theta` return these values.\n\n    \u003e\u003e\u003e pz1 = polarcomplex128((2, np.pi/3))\n    \u003e\u003e\u003e pz1\n    polarcomplex128((2, 1.0471976))\n    \u003e\u003e\u003e pz1.r\n    2.0\n    \u003e\u003e\u003e pz1.theta\n    1.0471975511965976\n\nThe `real` and `imag` attributes compute the real and imaginary parts of\nthe complex number.\n\n    \u003e\u003e\u003e pz1.real\n    1.0000000000000002\n    \u003e\u003e\u003e pz1.imag\n    1.7320508075688772\n\nThe `conj()` method returns the complex conjugate.  In polar coordinates,\nthis simply changes the sign of the angle.\n\n    \u003e\u003e\u003e pz1.conj()\n    polarcomplex128((2, -1.0471976))\n\nThe Python object implements the usual arithmetic operations.\n(This also demonstrates passing a Python complex number to the type.)\n\n    \u003e\u003e\u003e pz2 = polarcomplex128(5 + 12j)\n    \u003e\u003e\u003e pz2\n    polarcomplex128((13, 1.1760052))\n    \u003e\u003e\u003e -pz2\n    polarcomplex128((-13, 1.1760052))\n    \u003e\u003e\u003e abs(pz2)\n    13.0\n    \u003e\u003e\u003e pz2 / pz1\n    polarcomplex128((6.5, 0.12880766))\n    \u003e\u003e\u003e pz1 + pz2\n    polarcomplex128((14.985634, 1.158861))\n\nCheck that converting the values to Python complex numbers gives the same\nresult, whether we add before or after the conversion.\n\n    \u003e\u003e\u003e complex(pz1 + pz2)\n    (5.999999999999999+13.732050807568877j)\n    \u003e\u003e\u003e complex(pz1) + complex(pz2)\n    (6.000000000000001+13.732050807568877j)\n\nThe NumPy type `complex64` and `complex128` can be converted to the polar\ntypes.\n\n    \u003e\u003e\u003e a = np.array([1 + 2j, 3+4j, -5j])\n    \u003e\u003e\u003e a.astype(polarcomplex64)\n    array([polarcomplex64((2.236068, 1.1071488)),\n           polarcomplex64((5, 0.92729521)), polarcomplex64((5, -1.5707964))],\n          dtype=polarcomplex64)\n\n\n### `logfloat`\n\n`logfloat` represents a nonnegative floating point number. It stores the\nlogarithm of the number internally, so it can represent a much greater\nrange of values than the standard Python `float`.  The logarithm is displayed\nin the `repr`, and can be accessed with the `.log` attribute.  The basic\nPython arithmetic operators have been implemented.\n\n    \u003e\u003e\u003e from numtypes import logfloat\n    \u003e\u003e\u003e x = logfloat(log=-1000)\n    \u003e\u003e\u003e x\n    logfloat(log=-1000)\n\n`x` represents `exp(-1000)`.  The value is too small to be represented\nas a regular 64 bit `float`:\n\n    \u003e\u003e\u003e float(x)\n    0.0\n\nThe basic arithmetic operators are implemented for the `logfloat`\ntype:\n\n    \u003e\u003e\u003e x/2\n    logfloat(log=-1000.6931471805599)\n    \u003e\u003e\u003e 1/x\n    logfloat(log=1000)\n    \u003e\u003e\u003e x**0.5\n    logfloat(log=-500)\n\n`y` is another very small value:\n\n    \u003e\u003e\u003e y = logfloat(log=-1002)\n    \u003e\u003e\u003e x + y\n    logfloat(log=-999.873071988957)\n    \u003e\u003e\u003e x - y\n    logfloat(log=-1000.1454134578688)\n    \u003e\u003e\u003e x/y\n    logfloat(log=2)\n\n--------------------------------------------------------------------------\n\nRelated work and links\n----------------------\n\n* [quaternion](https://github.com/moble/quaternion)\n* [numpy-user-dtypes](https://github.com/numpy/numpy-user-dtypes):\n  Repository for example user DTypes using the new API.\n* [numpy-dtypes](https://github.com/numpy/numpy-dtypes)\n  - Includes rational and quaternion, but not actively maintained.\n    See moble's github repo for a maintained version of quaternions.\n* Jax [ml_dtypes](https://github.com/jax-ml/ml_dtypes): Several NumPy dtype\n  extensions used in machine learning.\n* Stéfan van der Walt's class notes from the 2013 \"Dive Into NumPy\" class,\n      https://github.com/stefanv/teaching/tree/master/2013_scipy_austin_dive_into_numpy\n  - The steps in examples/quad_dtype show how to add a dtype for the\n    quad precision floating point type provided by gcc.\n* NumPy:\n      https://github.com/numpy/numpy/blob/main/numpy/core/src/umath/_rational_tests.c\n  - This implements a rational dtype as a unit test.\n* NumPy documentation of [user-defined data types](https://numpy.org/doc/1.17/user/c-info.beyond-basics.html#user-defined-data-types)\n* [ora](https://github.com/alexhsamuel/ora) implements time and datetime data types.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwarrenweckesser%2Fnumtypes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwarrenweckesser%2Fnumtypes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwarrenweckesser%2Fnumtypes/lists"}