5
5
6
6
Inverse of `sqrt(x)` for non-negative `x`.
7
7
"""
8
- square (x) = x^ 2
9
- function square (x:: Real )
10
- x < zero (x) && throw (DomainError (x, " `square` is defined as the inverse of `sqrt` and can only be evaluated for non-negative values" ))
8
+ function square (x)
9
+ if is_real_type (typeof (x)) && x < zero (x)
10
+ throw (DomainError (x, " `square` is defined as the inverse of `sqrt` and can only be evaluated for non-negative values" ))
11
+ end
11
12
return x^ 2
12
13
end
13
14
14
15
15
- function invpow2 (x:: Real , p:: Integer )
16
- if x ≥ zero (x) || isodd (p)
17
- copysign (abs (x)^ inv (p), x)
16
+ function invpow_arg2 (x:: Number , p:: Real )
17
+ if is_real_type (typeof (x))
18
+ x ≥ zero (x) ? x^ inv (p) : # x > 0 - trivially invertible
19
+ isinteger (p) && isodd (Integer (p)) ? copysign (abs (x)^ inv (p), x) : # p odd - invertible even for x < 0
20
+ throw (DomainError (x, " inverse for x^$p is not defined at $x " ))
18
21
else
19
- throw (DomainError (x, " inverse for x^$p is not defined at $x " ))
20
- end
21
- end
22
- function invpow2 (x:: Real , p:: Real )
23
- if x ≥ zero (x)
24
- x^ inv (p)
25
- else
26
- throw (DomainError (x, " inverse for x^$p is not defined at $x " ))
27
- end
28
- end
29
- function invpow2 (x, p:: Real )
30
- # complex x^p is only invertible for p = 1/n
31
- if isinteger (inv (p))
32
- x^ inv (p)
33
- else
34
- throw (DomainError (x, " inverse for x^$p is not defined at $x " ))
22
+ # complex x^p is invertible only for p = 1/n
23
+ isinteger (inv (p)) ? x^ inv (p) : throw (DomainError (x, " inverse for x^$p is not defined at $x " ))
35
24
end
36
25
end
37
26
38
- function invpow1 (b:: Real , x:: Real )
27
+ function invpow_arg1 (b:: Real , x:: Real )
39
28
if b ≥ zero (b) && x ≥ zero (x)
40
29
log (b, x)
41
30
else
42
31
throw (DomainError (x, " inverse for $b ^x is not defined at $x " ))
43
32
end
44
33
end
45
34
46
- function invlog1 (b:: Real , x:: Real )
35
+ function invlog_arg1 (b:: Real , x:: Real )
47
36
if b ≥ zero (b)
48
37
b^ x
49
38
else
50
39
throw (DomainError (x, " inverse for log($b , x) is not defined at $x " ))
51
40
end
52
41
end
53
- invlog1 (b , x) = b^ x
42
+ invlog_arg1 (b :: Number , x:: Number ) = b^ x
54
43
55
- invlog2 (b , x) = x^ inv (b)
44
+ invlog_arg2 (b :: Number , x:: Number ) = x^ inv (b)
56
45
57
46
58
- function invdivrem ((q, r), divisor)
47
+ function invdivrem ((q, r):: NTuple{2,Number} , divisor:: Number )
59
48
res = muladd (q, divisor, r)
60
49
if abs (r) ≤ abs (divisor) && (iszero (r) || sign (r) == sign (res))
61
50
res
@@ -64,10 +53,18 @@ function invdivrem((q, r), divisor)
64
53
end
65
54
end
66
55
67
- function invfldmod ((q, r), divisor)
56
+ function invfldmod ((q, r):: NTuple{2,Number} , divisor:: Number )
68
57
if abs (r) ≤ abs (divisor) && (iszero (r) || sign (r) == sign (divisor))
69
58
muladd (q, divisor, r)
70
59
else
71
60
throw (DomainError ((q, r), " inverse for fldmod(x) is not defined at this point" ))
72
61
end
73
62
end
63
+
64
+
65
+ # check if T is a real-Number type
66
+ # this is not the same as T <: Real which immediately excludes custom Number subtypes such as unitful numbers
67
+ # also, isreal(x) != is_real_type(typeof(x)): the former is true for complex numbers with zero imaginary part
68
+ @inline is_real_type (@nospecialize _:: Type{<:Real} ) = true
69
+ @inline is_real_type (:: Type{T} ) where {T<: Number } = real (T) == T
70
+ @inline is_real_type (@nospecialize _:: Type ) = false
0 commit comments