daamath 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- daamath/__init__.py +23 -0
- daamath/aliases.py +125 -0
- daamath/context.py +16 -0
- daamath/domains.py +93 -0
- daamath/enums.py +11 -0
- daamath/exceptions.py +53 -0
- daamath/functions/__init__.py +27 -0
- daamath/functions/arithmetic.py +228 -0
- daamath/functions/arithmetic_extra.py +120 -0
- daamath/functions/combinatoric.py +15 -0
- daamath/functions/complex.py +16 -0
- daamath/functions/complex_extra.py +4 -0
- daamath/functions/interval.py +100 -0
- daamath/functions/logic.py +132 -0
- daamath/functions/mapping.py +239 -0
- daamath/functions/miscellaneous.py +196 -0
- daamath/functions/old_functions.py +726 -0
- daamath/functions/quantization.py +99 -0
- daamath/functions/sigmoids.py +32 -0
- daamath/functions/solvers.py +26 -0
- daamath/functions/tensor.py +70 -0
- daamath/functions/trigonometry.py +141 -0
- daamath/functions/trigonometry_extra.py +22 -0
- daamath/functions/variadic.py +79 -0
- daamath/numbers/__init__.py +21 -0
- daamath/numbers/constants.py +53 -0
- daamath/numbers/conversion_angle.py +44 -0
- daamath/numbers/derived.py +34 -0
- daamath/numbers/floating.py +14 -0
- daamath/strings/__init__.py +504 -0
- daamath/strings/arrow.py +34 -0
- daamath/strings/ascii.py +7 -0
- daamath/strings/bracket.py +103 -0
- daamath/strings/digit.py +17 -0
- daamath/strings/greek.py +31 -0
- daamath/strings/latin.py +38 -0
- daamath/strings/square.py +107 -0
- daamath/strings/utilities/__init__.py +2 -0
- daamath/strings/utilities/case.py +6 -0
- daamath/strings/utilities/lookup.py +37 -0
- daamath-0.2.0.dist-info/METADATA +9 -0
- daamath-0.2.0.dist-info/RECORD +44 -0
- daamath-0.2.0.dist-info/WHEEL +5 -0
- daamath-0.2.0.dist-info/top_level.txt +1 -0
daamath/__init__.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from .context import Context
|
|
2
|
+
|
|
3
|
+
from . import functions, numbers, strings, domains
|
|
4
|
+
from .functions import *
|
|
5
|
+
from .numbers import *
|
|
6
|
+
from .strings import *
|
|
7
|
+
from .domains import *
|
|
8
|
+
from . import enums
|
|
9
|
+
|
|
10
|
+
from . import aliases
|
|
11
|
+
from .aliases import *
|
|
12
|
+
|
|
13
|
+
from . import exceptions
|
|
14
|
+
|
|
15
|
+
context = Context(
|
|
16
|
+
functions = '',
|
|
17
|
+
datatypes = ''
|
|
18
|
+
# check_input_domain = True,
|
|
19
|
+
# check_output_domain = True,
|
|
20
|
+
# domain = REAL,
|
|
21
|
+
# error_policy = enums.ErrorPolicy.FLAG_RAISE_HALT,
|
|
22
|
+
# rounding = roundeven,
|
|
23
|
+
)
|
daamath/aliases.py
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import daamath as dm
|
|
2
|
+
|
|
3
|
+
# hyperoperation
|
|
4
|
+
succ = dm.h0c # hyperoperation of 0th order, solving for c in the equation a ? b = c
|
|
5
|
+
pred = dm.h0b
|
|
6
|
+
add = dm.h1c
|
|
7
|
+
sub = dm.h1b
|
|
8
|
+
mul = dm.h2c
|
|
9
|
+
div = dm.h2b
|
|
10
|
+
pow = dm.h3c
|
|
11
|
+
log = dm.h3b
|
|
12
|
+
root = dm.h3a
|
|
13
|
+
spow = dm.h4c
|
|
14
|
+
slog = dm.h4b
|
|
15
|
+
sroot = dm.h4a
|
|
16
|
+
|
|
17
|
+
# hyperoperation extra
|
|
18
|
+
ainv = dm.h1b_0 # sub with first argument fixed to 0
|
|
19
|
+
minv = dm.h2b_1
|
|
20
|
+
exp = dm.h3c_e
|
|
21
|
+
exp2 = dm.h3c_2
|
|
22
|
+
exp10 = dm.h3c_10
|
|
23
|
+
ln = dm.h3b__e # log with second argument fixed to e
|
|
24
|
+
log2 = dm.h3b__2
|
|
25
|
+
log10 = dm.h3b__10
|
|
26
|
+
square = dm.h3c__2
|
|
27
|
+
cube = dm.h3c__3
|
|
28
|
+
sqrt = dm.h3a__2
|
|
29
|
+
cbrt = dm.h3a__3
|
|
30
|
+
rsquare = dm.h2b_1_h3c__2 # minv of square of x
|
|
31
|
+
rcube = dm.h2b_1_h3c__3
|
|
32
|
+
rsqrt = dm.h2b_1_h3a__2
|
|
33
|
+
rcbrt = dm.h2b_1_h3a__3
|
|
34
|
+
fma = dm.h1c_h2c # dm.add_mul
|
|
35
|
+
expm1 = dm.h1b_h3c_e__1 # dm.sub_pow_e__1
|
|
36
|
+
ln1p = dm.h3b_h1c_1__e # dm.log_add_1__e
|
|
37
|
+
|
|
38
|
+
# trigonometry
|
|
39
|
+
sin = dm.croh # circular ratio from opposite and hypotenuse
|
|
40
|
+
cos = dm.crah
|
|
41
|
+
tan = dm.croa
|
|
42
|
+
cot = dm.crao
|
|
43
|
+
sec = dm.crha
|
|
44
|
+
csc = dm.crho
|
|
45
|
+
asin = dm.csoh
|
|
46
|
+
acos = dm.csah
|
|
47
|
+
atan = dm.csoa
|
|
48
|
+
acot = dm.csao
|
|
49
|
+
asec = dm.csha
|
|
50
|
+
acsc = dm.csho
|
|
51
|
+
sinh = dm.hroh
|
|
52
|
+
cosh = dm.hrah
|
|
53
|
+
tanh = dm.hroa
|
|
54
|
+
coth = dm.hrao
|
|
55
|
+
sech = dm.hrha
|
|
56
|
+
csch = dm.hrho
|
|
57
|
+
asinh = dm.hsoh
|
|
58
|
+
acosh = dm.hsah # hyperbolic semiarea from adjacent and hypotenuse
|
|
59
|
+
atanh = dm.hsoa
|
|
60
|
+
acoth = dm.hsao
|
|
61
|
+
asech = dm.hsha
|
|
62
|
+
acsch = dm.hsho
|
|
63
|
+
|
|
64
|
+
# trigonometry extra
|
|
65
|
+
asin2 = dm.csoh2 # 2-argument version of dm.csoh
|
|
66
|
+
acos2 = dm.csah2
|
|
67
|
+
atan2 = dm.csoa2
|
|
68
|
+
acot2 = dm.csao2
|
|
69
|
+
asec2 = dm.csha2
|
|
70
|
+
acsc2 = dm.csho2
|
|
71
|
+
sinc = dm.h2b_croh_S_S # dm.div_sin_S_S
|
|
72
|
+
|
|
73
|
+
# boolean
|
|
74
|
+
not_ = dm.tf # F, T → T, F
|
|
75
|
+
and_ = dm.ffft # FF, FT, TF, TT → F, F, F, T
|
|
76
|
+
or_ = dm.fttt
|
|
77
|
+
xor = dm.fttf
|
|
78
|
+
imp = dm.ttft
|
|
79
|
+
con = dm.tftt
|
|
80
|
+
nand = dm.tttf
|
|
81
|
+
nor = dm.tfff
|
|
82
|
+
nxor = dm.tfft # NOTE: nxor, not xnor
|
|
83
|
+
nimp = dm.fftf
|
|
84
|
+
ncon = dm.ftff
|
|
85
|
+
|
|
86
|
+
# interval
|
|
87
|
+
lt = dm.iee # A |B| C → include exclude exclude
|
|
88
|
+
le = dm.iie
|
|
89
|
+
eq = dm.eie
|
|
90
|
+
ne = dm.iei
|
|
91
|
+
ge = dm.eii
|
|
92
|
+
gt = dm.eei
|
|
93
|
+
oo = dm.eeiee # A |B| C |D| E → exclude exclude include exclude exclude
|
|
94
|
+
oc = dm.eeiie
|
|
95
|
+
co = dm.eiiee
|
|
96
|
+
cc = dm.eiiie
|
|
97
|
+
|
|
98
|
+
# variadic
|
|
99
|
+
sum = dm.vh1c
|
|
100
|
+
prod = dm.vh2c
|
|
101
|
+
all = dm.vffft
|
|
102
|
+
any = dm.vfttt
|
|
103
|
+
min = dm.mean__h1b_0_inf
|
|
104
|
+
hmean = dm.mean__h1b_0_1
|
|
105
|
+
gmean = dm.mean__0
|
|
106
|
+
amean = dm.mean__1
|
|
107
|
+
rms = dm.mean__2
|
|
108
|
+
cmean = dm.mean__3
|
|
109
|
+
max = dm.mean__inf
|
|
110
|
+
|
|
111
|
+
# idk bro
|
|
112
|
+
abs = dm.norm__2
|
|
113
|
+
sgn = dm.normalize__2
|
|
114
|
+
|
|
115
|
+
# quantization
|
|
116
|
+
floor = dm.round__true_floor
|
|
117
|
+
ceil = dm.round__true_ceil
|
|
118
|
+
trunc = dm.round__true_trunc
|
|
119
|
+
away = dm.round__true_away
|
|
120
|
+
roundfloor = dm.round__false_floor
|
|
121
|
+
roundceil = dm.round__false_ceil
|
|
122
|
+
roundtrunc = dm.round__false_trunc
|
|
123
|
+
roundaway = dm.round__false_away
|
|
124
|
+
roundeven = dm.round__false_even
|
|
125
|
+
roundodd = dm.round__false_odd
|
daamath/context.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
|
|
4
|
+
@dataclass
|
|
5
|
+
class Functions:
|
|
6
|
+
...
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class DataTypes:
|
|
10
|
+
...
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class Context:
|
|
14
|
+
"a collection of variables that define daamath's behaviour"
|
|
15
|
+
functions: Functions
|
|
16
|
+
datatypes: DataTypes
|
daamath/domains.py
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# a domain is a function with special UPPERCASE naming, because it is treated as both an object and also as a function
|
|
2
|
+
|
|
3
|
+
from typing import Any, Callable
|
|
4
|
+
import numbers
|
|
5
|
+
|
|
6
|
+
# 1st order domains (indicator functions):
|
|
7
|
+
def THING(fish: Any) -> bool:
|
|
8
|
+
'the base domain of anything. everything is a thing. even nothing is a thing. the indicator function simply returns `true`'
|
|
9
|
+
return True
|
|
10
|
+
|
|
11
|
+
def TRUTH(fish: Any) -> bool:
|
|
12
|
+
'idk'
|
|
13
|
+
return True
|
|
14
|
+
|
|
15
|
+
def BOOLEAN(fish: Any) -> bool:
|
|
16
|
+
'idk'
|
|
17
|
+
return True
|
|
18
|
+
|
|
19
|
+
def NUMBER(fish: Any) -> bool:
|
|
20
|
+
return isinstance(fish, numbers.Number)
|
|
21
|
+
|
|
22
|
+
def HYPERCOMPLEX(fish: Any) -> bool:
|
|
23
|
+
'idk'
|
|
24
|
+
return NUMBER(fish)
|
|
25
|
+
|
|
26
|
+
def OCTONION(fish: Any) -> bool:
|
|
27
|
+
'fish is HYPERCOMPLEX and fish has non-zero octonion vector part'
|
|
28
|
+
return HYPERCOMPLEX(fish)
|
|
29
|
+
|
|
30
|
+
def QUATERNION(fish: Any) -> bool:
|
|
31
|
+
'fish is OCTONION and fish has non-zero quaternion vector part'
|
|
32
|
+
return OCTONION(fish)
|
|
33
|
+
|
|
34
|
+
def COMPLEX(fish: Any) -> bool:
|
|
35
|
+
'fish is QUATERNION and fish has non-zero imaginary part'
|
|
36
|
+
return OCTONION(fish) and fish.imag == 0
|
|
37
|
+
|
|
38
|
+
def IMAGINARY(fish: Any) -> bool:
|
|
39
|
+
'fish is COMPLEX and real part is zero'
|
|
40
|
+
return COMPLEX(fish) and fish.real == 0
|
|
41
|
+
|
|
42
|
+
def REAL(fish: Any) -> bool:
|
|
43
|
+
'fish is COMPLEX and imaginary part is zero'
|
|
44
|
+
return COMPLEX(fish) and fish.imag == 0
|
|
45
|
+
|
|
46
|
+
def RATIONAL(fish: Any) -> bool:
|
|
47
|
+
'fish is REAL and fish can be represented as p / q where q ≠ 0'
|
|
48
|
+
return REAL(fish) and isinstance(fish, numbers.Rational)
|
|
49
|
+
|
|
50
|
+
def INTEGER(fish: Any) -> bool:
|
|
51
|
+
'fish is RATIONAL and fish is divisible by 1'
|
|
52
|
+
return RATIONAL(fish) and fish % 1 == 0
|
|
53
|
+
|
|
54
|
+
def IRRATIONAL(fish: Any) -> bool:
|
|
55
|
+
'fish is REAL and fish is not RATIONAL'
|
|
56
|
+
return REAL(fish) and not RATIONAL(fish)
|
|
57
|
+
|
|
58
|
+
def PRIME(fish: Any) -> bool:
|
|
59
|
+
'fish is NATURALSTART_2 and fish has two prime divisors'
|
|
60
|
+
raise NotImplementedError('developer hasnt defined this yet')
|
|
61
|
+
return NATURALSTART
|
|
62
|
+
|
|
63
|
+
def COMPOSITE(fish: Any) -> bool:
|
|
64
|
+
'fish is NATURAL_1 and fish has more than two prime divisors'
|
|
65
|
+
raise NotImplementedError('developer hasnt defined this yet')
|
|
66
|
+
return NATURALSTART_1(fish)
|
|
67
|
+
|
|
68
|
+
# 2nd order domains (domain constructors):
|
|
69
|
+
|
|
70
|
+
def NATURALFROM(start: int) -> Callable[[Any], bool]:
|
|
71
|
+
'natural numbers starting from N'
|
|
72
|
+
if not INTEGER(start) or start < 0:
|
|
73
|
+
raise ValueError('start must be non-negative integer')
|
|
74
|
+
|
|
75
|
+
def NATURALFROM(fish: Any) -> bool:
|
|
76
|
+
return INTEGER(fish) and fish >= start
|
|
77
|
+
return NATURALFROM
|
|
78
|
+
|
|
79
|
+
NATURALFROM_0: Callable[[Any], bool] = NATURALFROM(0)
|
|
80
|
+
NATURALFROM_1: Callable[[Any], bool] = NATURALFROM(1)
|
|
81
|
+
NATURALFROM_2: Callable[[Any], bool] = NATURALFROM(2)
|
|
82
|
+
|
|
83
|
+
def INTEGERMODULO(mod: int) -> Callable[[Any], bool]:
|
|
84
|
+
'integers modulo N, like in modular arithmetic'
|
|
85
|
+
if mod == 0:
|
|
86
|
+
return INTEGER
|
|
87
|
+
if not INTEGER(mod) or mod < 0:
|
|
88
|
+
raise ValueError(f'sorry, but i want mod to be a non-negative integer. i dont know what integers modulo {mod} would mean')
|
|
89
|
+
def INTEGERMODULO_N(fish: Any) -> bool:
|
|
90
|
+
return INTEGER(fish) and fish // mod == 0
|
|
91
|
+
return INTEGERMODULO
|
|
92
|
+
|
|
93
|
+
INTEGERMODULO_2: Callable[[Any], bool] = INTEGERMODULO(2)
|
daamath/enums.py
ADDED
daamath/exceptions.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from .context import Context
|
|
2
|
+
from collections.abc import Callable
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
class Error(Exception):
|
|
6
|
+
'the base class of any exception in daamath'
|
|
7
|
+
|
|
8
|
+
class DomainError(Error, ArithmeticError):
|
|
9
|
+
'this occurs when something related to the domain goes wrong'
|
|
10
|
+
|
|
11
|
+
class DataTypeError(Error, TypeError):
|
|
12
|
+
'this occurs when something related to the datatype goes wrong'
|
|
13
|
+
|
|
14
|
+
class OutOfDomainError(DomainError):
|
|
15
|
+
'this occurs when something is unexpectedly not in a domain'
|
|
16
|
+
|
|
17
|
+
def __init__(self, function_or_str: Callable | str, args: tuple[...] = None, kwargs: dict[str, Any] = None, output: Any = None, context: Context = None):
|
|
18
|
+
'the arguments here are entirely optional. these are just here to help you format the error message neater'
|
|
19
|
+
if args is None and kwargs is None and output is None:
|
|
20
|
+
super().__init__(function_or_str)
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
if args is None or kwargs is None or output is None:
|
|
24
|
+
raise ValueError('developer! lazy developer! give args, kwargs, output for this function')
|
|
25
|
+
|
|
26
|
+
raise NotImplementedError
|
|
27
|
+
|
|
28
|
+
args: str = ', '.join(f'{type(input).__name__} {input}' for arg in args)
|
|
29
|
+
kwargs: str = ', '.join(f'{key}={val!r}' for key, val in kwargs)
|
|
30
|
+
|
|
31
|
+
function: str = function_or_str.__name__
|
|
32
|
+
inputs: list[Any] = [f'{type(input).__name__} {input}' for arg in args] + []
|
|
33
|
+
input_types: list[Any] = [f'{type(input).__name__} {input}' for arg in args] + []
|
|
34
|
+
input_domains: list[Any] = []
|
|
35
|
+
output_type: str = type(output).__name__
|
|
36
|
+
output_domain: str = str(getattr(context.functions, function.__name__))
|
|
37
|
+
|
|
38
|
+
super().__init__(f'{function}{output_type} {output} which is not {output_domain}')
|
|
39
|
+
|
|
40
|
+
# this cheeky hack allows it to show things like:
|
|
41
|
+
# ClosureError: float INTEGER div(float INTEGER 1.0, float INTEGER 2.0) returned float 0.5 which is not INTEGER
|
|
42
|
+
# instead of:
|
|
43
|
+
# dm.exceptions.ClosureError: float INTEGER div(float INTEGER 1.0, float INTEGER 2.0) returned float 0.5 which is not INTEGER
|
|
44
|
+
__module__ = 'builtins'
|
|
45
|
+
|
|
46
|
+
class FidelityError(DataTypeError):
|
|
47
|
+
'this occurs when a datatype cannot represent something accurately'
|
|
48
|
+
|
|
49
|
+
# this cheeky hack allows it to show things like:
|
|
50
|
+
# RepresentationError: int REAL div(int REAL 1.0, int REAL 2.0) returned REAL 0.5 which cannot be accurately represented by int
|
|
51
|
+
# instead of:
|
|
52
|
+
# dm.exceptions.RepresentationError: int REAL div(int REAL 1.0, int REAL 2.0) returned REAL 0.5 which cannot be accurately represented by int
|
|
53
|
+
__module__ = 'builtins'
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# hey! you! yeah, you! daa!
|
|
2
|
+
#
|
|
3
|
+
# also, implement vector products like dot product, cross product (just a compositon of wedge product and hodge star. also, in 3D and 7D only! because they tie with quaternions and octonions, but none higher. no more normed algebrae after that), wedge product,
|
|
4
|
+
|
|
5
|
+
from . import arithmetic, arithmetic_extra, complex, complex_extra, trigonometry, trigonometry_extra, logic, interval, combinatoric, variadic, quantization, sigmoids, mapping, tensor, miscellaneous
|
|
6
|
+
|
|
7
|
+
from .arithmetic import h0c, h0b, h1c, h1b, h2c, h2b, h3c, h3b, h3a, h4c, h4b, h4a
|
|
8
|
+
from .arithmetic_extra import h1b_0, h2b_1, h3c_e, h3c_2, h3c_10, h3b__e, h3b__2, h3b__10, h3c__2, h3c__3, h3a__2, h3a__3, h2b_1_h3c__2, h2b_1_h3c__3, h2b_1_h3a__2, h2b_1_h3a__3, h1c_h2c, h1b_h3c_e__1, h3b_h1c_1__e
|
|
9
|
+
|
|
10
|
+
from .complex import real, imag, arg, rect, polar, conj
|
|
11
|
+
from .complex_extra import cis
|
|
12
|
+
|
|
13
|
+
from .trigonometry import croh, crah, croa, crao, crha, crho, csoh, csah, csoa, csao, csha, csho, hroh, hrah, hroa, hrao, hrha, hrho, hsoh, hsah, hsoa, hsao, hsha, hsho
|
|
14
|
+
from .trigonometry_extra import csoh2, csah2, csoa2, csao2, csha2, csho2, h2b_croh_S_S
|
|
15
|
+
|
|
16
|
+
from .logic import tf, ffft, fttt, fttf, ttft, tftt, tttf, tfff, tfft, fftf, ftff
|
|
17
|
+
from .interval import iee, iie, eie, iei, eii, eei, eeiee, eeiie, eiiee, eiiie
|
|
18
|
+
|
|
19
|
+
from .variadic import vffft, vfttt, vh1c, vh2c, mean, mean__h1b_0_inf, mean__h1b_0_1, mean__0, mean__1, mean__2, mean__3, mean__inf, vparallel
|
|
20
|
+
from .combinatoric import fact, sumt, comb, perm, gcd, lcm
|
|
21
|
+
from .quantization import round, round__true_floor, round__true_ceil, round__true_trunc, round__true_away, round__false_floor, round__false_ceil, round__false_trunc, round__false_away, round__false_even, round__false_odd, quot, rem, quotrem
|
|
22
|
+
from .sigmoids import sigmoid_tan, sigmoid_tanh
|
|
23
|
+
from .mapping import lerp, unlerp, map, fixed_log, fixed_exp, soft_log, soft_exp
|
|
24
|
+
from .tensor import norm, normalize, clamp, norm__2, normalize__2
|
|
25
|
+
from .miscellaneous import ifelse
|
|
26
|
+
|
|
27
|
+
from .solvers import roots, coeffs
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# these operators dont treat nested lists as tensors. do you know why?
|
|
2
|
+
# because the tensor object should know itself how to do basic math ops. an operator is an operator.. an object should know what to do with an operator.
|
|
3
|
+
# its also because this tensor mechanism is hard to scale across languages
|
|
4
|
+
|
|
5
|
+
'''
|
|
6
|
+
instead of:
|
|
7
|
+
root sroot
|
|
8
|
+
| |
|
|
9
|
+
pow -- spow -- …
|
|
10
|
+
/
|
|
11
|
+
succ -- add -- mul
|
|
12
|
+
| | | \
|
|
13
|
+
pred sub div exp -- sexp -- …
|
|
14
|
+
| |
|
|
15
|
+
log slog
|
|
16
|
+
|
|
17
|
+
we should have:
|
|
18
|
+
X h0X h1X h2X h3X h4X h5X …
|
|
19
|
+
c ++b a + b a * b a ^ b a ↑ b a ⇑ b …
|
|
20
|
+
b --c c - a c / a c L b … … …
|
|
21
|
+
a N/A c - b c / b c √ b … … …
|
|
22
|
+
|
|
23
|
+
where we X is the variable we solve for in the equation a ? b = c
|
|
24
|
+
'''
|
|
25
|
+
|
|
26
|
+
# NOTE: i expect these function signatures:
|
|
27
|
+
# hXc(a, b)
|
|
28
|
+
# hXb(c, a)
|
|
29
|
+
# hXa(c, b)
|
|
30
|
+
#
|
|
31
|
+
# i could make it a cycle of variables like so:
|
|
32
|
+
# hXc(a, b)
|
|
33
|
+
# hXb(c, a)
|
|
34
|
+
# hXa(b, c)
|
|
35
|
+
#
|
|
36
|
+
# but this would imply that the three variables are involved in a cyclic relation a → b → c → a when, really, they are involved in a 2 → 1 relation a, b → c. thats why when solving for b and a, we make it intentionally asymmetric
|
|
37
|
+
|
|
38
|
+
import math, cmath, functools
|
|
39
|
+
from numbers import Number, Real, Integral
|
|
40
|
+
from typing import Literal
|
|
41
|
+
from ..exceptions import DomainError
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
#h0c = functools.partial(h1c, a = 1)
|
|
45
|
+
def h0c(b: Integral) -> Integral:
|
|
46
|
+
'c = ++b, successor. the 0th hyperoperation'
|
|
47
|
+
if not isinstance(b, Integral):
|
|
48
|
+
raise DomainError('')
|
|
49
|
+
c = b + 1
|
|
50
|
+
|
|
51
|
+
if type(c) != type(b):
|
|
52
|
+
raise DomainError(succ, (b, ), c)
|
|
53
|
+
|
|
54
|
+
return c
|
|
55
|
+
|
|
56
|
+
#h0b = functools.partial(h1b, x = 1)
|
|
57
|
+
def h0b(c):
|
|
58
|
+
'b = --c, predecessor. the inverse of the 0th hyperoperation'
|
|
59
|
+
b = c - 1
|
|
60
|
+
|
|
61
|
+
if type(b) != type(c):
|
|
62
|
+
raise DomainError(pred, (c, ), b)
|
|
63
|
+
|
|
64
|
+
return b
|
|
65
|
+
|
|
66
|
+
def h1c(a, b):
|
|
67
|
+
'c = a + b, addition. the 1st hyperoperation'
|
|
68
|
+
if type(a) != type(b):
|
|
69
|
+
raise TypeError(f'{a} and {b} must be same type')
|
|
70
|
+
|
|
71
|
+
c = a + b
|
|
72
|
+
|
|
73
|
+
if type(a) != type(c):
|
|
74
|
+
raise DomainError(add, (a, b), c)
|
|
75
|
+
|
|
76
|
+
return c
|
|
77
|
+
|
|
78
|
+
def h1b(c, a):
|
|
79
|
+
'b = c - a, left subtraction. the inverse of the 1st hyperoperation'
|
|
80
|
+
if type(c) != type(a):
|
|
81
|
+
raise TypeError(f'{c} and {a} must be same type')
|
|
82
|
+
|
|
83
|
+
b = c - a
|
|
84
|
+
|
|
85
|
+
if type(b) != type(c):
|
|
86
|
+
raise DomainError(sub, (c, a), b)
|
|
87
|
+
|
|
88
|
+
return b
|
|
89
|
+
|
|
90
|
+
def h2c(a, b):
|
|
91
|
+
'c = a * b, multiplication. the 2nd hyperoperation'
|
|
92
|
+
if type(a) != type(b):
|
|
93
|
+
raise TypeError(f'{a} and {b} must be same type')
|
|
94
|
+
|
|
95
|
+
c = a * b
|
|
96
|
+
|
|
97
|
+
if type(c) != type(a):
|
|
98
|
+
raise DomainError(mul, (a, b), c)
|
|
99
|
+
|
|
100
|
+
return c
|
|
101
|
+
|
|
102
|
+
def h2b(c, a):
|
|
103
|
+
'b = c / a, left division. the inverse of the 2nd hyperoperation'
|
|
104
|
+
if type(c) != type(a):
|
|
105
|
+
raise TypeError(f'{c} and {a} must be same type')
|
|
106
|
+
|
|
107
|
+
if isinstance(a, int) and a % b != 0:
|
|
108
|
+
raise DomainError
|
|
109
|
+
b = c / a
|
|
110
|
+
|
|
111
|
+
if type(b) != type(c):
|
|
112
|
+
raise DomainError(div, (c, a), b)
|
|
113
|
+
|
|
114
|
+
return b
|
|
115
|
+
|
|
116
|
+
def h3c(a, b):
|
|
117
|
+
'c = a ^ b, power, exponentiation. the 3rd hyperoperation'
|
|
118
|
+
if type(a) != type(b):
|
|
119
|
+
raise TypeError(f'{a} and {b} must be same type')
|
|
120
|
+
|
|
121
|
+
c = a ** b
|
|
122
|
+
|
|
123
|
+
if type(c) != type(a):
|
|
124
|
+
raise DomainError(pow, (a, b), c)
|
|
125
|
+
|
|
126
|
+
return c
|
|
127
|
+
|
|
128
|
+
def h3b(a, c):
|
|
129
|
+
'b = log_a(c), logarithm. the inverse of the 3rd hyperoperation that solves for b'
|
|
130
|
+
# c = a ^ b
|
|
131
|
+
if type(a) != type(c):
|
|
132
|
+
raise TypeError(f'{a} and {c} must be same type')
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
b = math.log(c, a)
|
|
136
|
+
except:
|
|
137
|
+
b = cmath.log(c, a)
|
|
138
|
+
|
|
139
|
+
if type(b) != type(a):
|
|
140
|
+
raise DomainError(log, (a, c), b)
|
|
141
|
+
|
|
142
|
+
return b
|
|
143
|
+
|
|
144
|
+
def h3a(b, c):
|
|
145
|
+
'a = b √ c, n-th root. the inverse of the 3rd hyperoperation that solves for a'
|
|
146
|
+
if type(b) != type(c):
|
|
147
|
+
raise TypeError(f'{b} and {c} must be same type')
|
|
148
|
+
# c = a ^ b
|
|
149
|
+
a = c ** (1 / b)
|
|
150
|
+
|
|
151
|
+
if type(a) != type(b):
|
|
152
|
+
raise DomainError(root, (b, c), a)
|
|
153
|
+
|
|
154
|
+
return a
|
|
155
|
+
|
|
156
|
+
def h4c(a, b):
|
|
157
|
+
'c = a ↑ b, tetration, superexponentiation, the 4th hyperoperation'
|
|
158
|
+
if type(a) != type(b):
|
|
159
|
+
raise TypeError(f'{a} and {b} must be same type')
|
|
160
|
+
|
|
161
|
+
raise NotImplementedError
|
|
162
|
+
|
|
163
|
+
if type(c) != type(a):
|
|
164
|
+
raise DomainError(spow, (a, b), c)
|
|
165
|
+
|
|
166
|
+
return c
|
|
167
|
+
|
|
168
|
+
def h4b(a, c):
|
|
169
|
+
'b = slog_a(c), superlogarithm, the inverse of the 4th hyperoperation'
|
|
170
|
+
if type(a) != type(c):
|
|
171
|
+
raise TypeError(f'{a} and {c} must be same type')
|
|
172
|
+
|
|
173
|
+
raise NotImplementedError
|
|
174
|
+
|
|
175
|
+
if type(b) != type(a):
|
|
176
|
+
raise DomainError(slog, (a, c), b)
|
|
177
|
+
|
|
178
|
+
return b
|
|
179
|
+
|
|
180
|
+
def h4a(b, c):
|
|
181
|
+
'superroot. idfk what this is supposed to be in terms of code'
|
|
182
|
+
if type(b) != type(c):
|
|
183
|
+
raise TypeError(f'{b} and {c} must be same type')
|
|
184
|
+
|
|
185
|
+
raise NotImplementedError
|
|
186
|
+
|
|
187
|
+
if type(b) != type(a):
|
|
188
|
+
raise DomainError(slog, (b, c), a)
|
|
189
|
+
|
|
190
|
+
return a
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
'''
|
|
194
|
+
# this thing is just a novelty
|
|
195
|
+
def hyper(
|
|
196
|
+
left: Number,
|
|
197
|
+
right: Number,
|
|
198
|
+
n: int,
|
|
199
|
+
solve: Literal['a', 'b', 'c'] = 'c',
|
|
200
|
+
) -> Number:
|
|
201
|
+
match solve:
|
|
202
|
+
case 'a':
|
|
203
|
+
match n:
|
|
204
|
+
case 0: raise ArithmeticError('this operation simply does not exist in mathematics')
|
|
205
|
+
case 1: return h1a(left, right)
|
|
206
|
+
case 2: return h2a(left, right)
|
|
207
|
+
case 3: return h3a(left, right)
|
|
208
|
+
case 4: return h4a(left, right)
|
|
209
|
+
case _: raise NotImplementedError
|
|
210
|
+
case 'b':
|
|
211
|
+
match n:
|
|
212
|
+
case 0: return h0b(right)
|
|
213
|
+
case 1: return h1b(left, right)
|
|
214
|
+
case 2: return h2b(left, right)
|
|
215
|
+
case 3: return h3b(left, right)
|
|
216
|
+
case 4: return h4b(left, right)
|
|
217
|
+
case _: raise NotImplementedError
|
|
218
|
+
case 'c':
|
|
219
|
+
match n:
|
|
220
|
+
case 0: return h0c(right)
|
|
221
|
+
case 1: return h1c(left, right)
|
|
222
|
+
case 2: return h2c(left, right)
|
|
223
|
+
case 3: return h3c(left, right)
|
|
224
|
+
case 4: return h4c(left, right)
|
|
225
|
+
case _: raise NotImplementedError
|
|
226
|
+
case _:
|
|
227
|
+
raise ValueError("invalid solve parameter. must be one of {'a', 'b', 'c'}")
|
|
228
|
+
'''
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import math, cmath
|
|
2
|
+
from numbers import Number, Real
|
|
3
|
+
from ..exceptions import DomainError
|
|
4
|
+
|
|
5
|
+
def h1b_0(a: Number) -> Number:
|
|
6
|
+
'sub(0, a), additive inverse'
|
|
7
|
+
|
|
8
|
+
b = -a
|
|
9
|
+
|
|
10
|
+
if type(a) != type(b):
|
|
11
|
+
raise DomainError(ainv, (a, ), b)
|
|
12
|
+
|
|
13
|
+
return b
|
|
14
|
+
|
|
15
|
+
def h2b_1(a: Number) -> Number:
|
|
16
|
+
'div(1, a), multiplicative inverse'
|
|
17
|
+
b = 1 / a
|
|
18
|
+
|
|
19
|
+
if type(a) != type(b):
|
|
20
|
+
raise DomainError(minv, (a, ), b)
|
|
21
|
+
|
|
22
|
+
return b
|
|
23
|
+
|
|
24
|
+
'''
|
|
25
|
+
def abs_sq(a: Number) -> Real:
|
|
26
|
+
if isinstance(x, Complex):
|
|
27
|
+
return x.real * x.real + x.imag * x.imag
|
|
28
|
+
else:
|
|
29
|
+
return abs(a) ** 2
|
|
30
|
+
'''
|
|
31
|
+
|
|
32
|
+
def h3c__2(a: Number) -> Number:
|
|
33
|
+
'pow(a, 2), inverse of sqrt'
|
|
34
|
+
return a * a
|
|
35
|
+
|
|
36
|
+
def h3c__3(a: Number) -> Number:
|
|
37
|
+
'pow(a, 3), inverse of cbrt'
|
|
38
|
+
return a * a * a
|
|
39
|
+
|
|
40
|
+
def h3a__2(c: Number) -> Number:
|
|
41
|
+
'root(2, a). inverse of square'
|
|
42
|
+
try: return math.sqrt(c)
|
|
43
|
+
except: return cmath.sqrt(c)
|
|
44
|
+
|
|
45
|
+
def h3a__3(c: Number) -> Number:
|
|
46
|
+
'root(3, a). inverse of cube'
|
|
47
|
+
try: return math.cbrt(c)
|
|
48
|
+
except: return c ** (1 / 3)
|
|
49
|
+
|
|
50
|
+
def h2b_1_h3c__2(a: Number) -> Number:
|
|
51
|
+
'reciprocal square. inverse of rsqrt'
|
|
52
|
+
return a ** -2
|
|
53
|
+
|
|
54
|
+
def h2b_1_h3c__3(a: Number) -> Number:
|
|
55
|
+
'reciprocal cube. inverse of rcbrt'
|
|
56
|
+
return a ** -2
|
|
57
|
+
|
|
58
|
+
def h2b_1_h3a__2(c: Number) -> Number:
|
|
59
|
+
'reciprocal square root. inverse of rsquare'
|
|
60
|
+
return c ** -0.5
|
|
61
|
+
|
|
62
|
+
def h2b_1_h3a__3(c: Number) -> Number:
|
|
63
|
+
'reciprocal cube root. inverse of rcube'
|
|
64
|
+
return a ** -3
|
|
65
|
+
|
|
66
|
+
def h3c_e(b: Number) -> Number:
|
|
67
|
+
'e ^ b'
|
|
68
|
+
try: return math.exp(b)
|
|
69
|
+
except: return cmath.exp(b)
|
|
70
|
+
|
|
71
|
+
def h3c_2(b: Number) -> Number:
|
|
72
|
+
'pow(2, b), inverse of log_2'
|
|
73
|
+
try: return math.exp2(b)
|
|
74
|
+
except: return 2 ** b
|
|
75
|
+
|
|
76
|
+
def h3c_10(b: Number) -> Number:
|
|
77
|
+
'pow(10, b), inverse of log_10'
|
|
78
|
+
return 10 ** b
|
|
79
|
+
|
|
80
|
+
def h3b__e(c: Number) -> Number:
|
|
81
|
+
'log_e(c)'
|
|
82
|
+
try: return math.log(c)
|
|
83
|
+
except: return cmath.log(c)
|
|
84
|
+
|
|
85
|
+
def h3b__2(a: Number) -> Number:
|
|
86
|
+
'log(2, a), inverse of pow_2'
|
|
87
|
+
try: return math.log2(a)
|
|
88
|
+
except: return cmath.log(a, 2)
|
|
89
|
+
|
|
90
|
+
def h3b__10(a: Number) -> Number:
|
|
91
|
+
'log(10, a), inverse of pow_10'
|
|
92
|
+
try: return math.log10(a)
|
|
93
|
+
except: return cmath.log10(a)
|
|
94
|
+
|
|
95
|
+
#def pow_m1(a: Number, b: Number) -> Number:
|
|
96
|
+
# return math.expm1(math.log(a) * b)
|
|
97
|
+
|
|
98
|
+
#def root_1p(a: Number, b: Number) -> Number:
|
|
99
|
+
# return math.exp(math.log1p(a) / b)
|
|
100
|
+
|
|
101
|
+
def h1b_h3c_e__1(b: Number) -> Number:
|
|
102
|
+
'exp(b) - 1'
|
|
103
|
+
return e ** b - 1
|
|
104
|
+
|
|
105
|
+
def h3b_h1c_1__e(c: Number) -> Number:
|
|
106
|
+
'ln(1 + c)'
|
|
107
|
+
try:
|
|
108
|
+
try:
|
|
109
|
+
return math.log1p(c)
|
|
110
|
+
except:
|
|
111
|
+
return math.log(1 + c)
|
|
112
|
+
except:
|
|
113
|
+
return cmath.log(1 + c)
|
|
114
|
+
|
|
115
|
+
try:
|
|
116
|
+
from math import fma as h1c_h2c
|
|
117
|
+
except ImportError:
|
|
118
|
+
def h1c_h2c(a: float, b: float, c: float) -> float:
|
|
119
|
+
'a * b + c, fused multiply add'
|
|
120
|
+
return a * b + c
|