@@ -21,8 +21,6 @@ Dual(::Number1, [1]) --> Dual(1, Partials([1,])) # fail Any
21
21
22
22
const NANSAFE_MODE_ENABLED = false
23
23
24
- const AMBIGUOUS_TYPES = (AbstractFloat, Irrational, Integer, Rational, Real, RoundingMode)
25
-
26
24
const UNARY_PREDICATES = Symbol[:isinf , :isnan , :isfinite , :iseven , :isodd , :isreal , :isinteger ]
27
25
28
26
const DEFAULT_CHUNK_THRESHOLD = 12
@@ -59,37 +57,11 @@ chunksize(::Chunk{N}) where {N} = N
59
57
# Dual #
60
58
# #######
61
59
62
- """
63
- ForwardDiff2.can_dual(V::Type)
64
-
65
- Determines whether the type V is allowed as the scalar type in a
66
- Dual. By default, only `<:Real` types are allowed.
67
- """
68
- can_dual (:: Type{<:Real} ) = true
69
- can_dual (:: Type ) = false
70
-
71
60
struct Dual{T,V,P} <: Real
72
61
value:: V
73
62
partials:: P
74
63
end
75
64
76
- # #############
77
- # Exceptions #
78
- # #############
79
-
80
- struct DualMismatchError{A,B} <: Exception
81
- a:: A
82
- b:: B
83
- end
84
-
85
- Base. showerror (io:: IO , e:: DualMismatchError{A,B} ) where {A,B} =
86
- print (io, " Cannot determine ordering of Dual tags $(e. a) and $(e. b) " )
87
-
88
- @noinline function throw_cannot_dual (V:: Type )
89
- throw (ArgumentError (" Cannot create a dual over scalar type $V ." *
90
- " If the type behaves as a scalar, define FowardDiff.can_dual." ))
91
- end
92
-
93
65
# ###############
94
66
# Constructors #
95
67
# ###############
98
70
# intercept calls to dualtag
99
71
dualtag () = nothing
100
72
101
- @inline function Dual {T} (value:: V , partials:: P ) where {T,V,P}
102
- Q = promote_type (bottomvaluetype (V), eltype (P))
103
- partials′ = convert .(Q, partials)
104
- Dual {T,V,typeof(partials′)} (value, partials′)
105
- end
73
+ @inline Dual {T} (value:: V , partials:: P ) where {T,V,P} = Dual {T,V,P} (value, partials)
74
+
106
75
# @inline Dual{T}(value::V, ::Chunk{N}, p::Val{i}) where {T,V,P,i} = Dual{T}(value, single_seed(Partials{N,V}, p))
107
76
@inline Dual (value, partials) = Dual {typeof(dualtag())} (value, partials)
108
77
109
- # we define these special cases so that the "constructor <--> convert" pun holds for `Dual`
110
- @inline Dual {T,V,P} (x:: Dual{T,V,P} ) where {T,V,P} = x
111
- @inline Dual {T,V,P} (x) where {T,V,P} = convert (Dual{T,V,P}, x)
112
- @inline Dual {T,V,P} (x:: Number ) where {T,V,P} = convert (Dual{T,V,P}, x)
113
- @inline Dual {T,V} (x) where {T,V} = convert (Dual{T,V}, x)
114
-
115
78
# #############################
116
79
# Utility/Accessor Functions #
117
80
# #############################
118
81
119
- @inline bottomvaluetype (:: Type{Dual{T,V,P}} ) where {T,V,P} = bottomvaluetype (V)
120
- @inline bottomvaluetype (:: Type{T} ) where {T<: Any } = T
121
82
@inline value (x) = x
122
83
@inline value (d:: Dual ) = d. value
123
84
124
- @inline partials (d:: Dual ) = d. partials
125
- @inline Base. @propagate_inbounds partials (d:: Dual , i) = d. partials[i]
126
- @inline Base. @propagate_inbounds partials (d:: Dual , i, j) = partials (d, i). partials[j]
127
- @inline Base. @propagate_inbounds partials (d:: Dual , i, j, k... ) = partials (partials (d, i, j), k... )
128
-
129
- @inline npartials (d:: Dual ) = length (d. partials)
130
-
131
- @inline order (:: Type{V} ) where {V} = 0
132
- @inline order (:: Type{Dual{T,V,P}} ) where {T,V,P} = 1 + order (V)
133
-
134
85
@inline valtype (:: V ) where {V} = V
135
86
@inline valtype (:: Type{V} ) where {V} = V
136
87
@inline valtype (:: Dual{T,V} ) where {T,V} = V
137
88
@inline valtype (:: Type{Dual{T,V,P}} ) where {T,V,P} = V
138
89
139
- @inline tagtype (:: V ) where {V} = Nothing
140
- @inline tagtype (:: Type{V} ) where {V} = Nothing
141
- @inline tagtype (:: Dual{T} ) where {T} = T
142
- @inline tagtype (:: Type{Dual{T,V,P}} ) where {T,V,P} = T
90
+ @inline partials (d:: Dual ) = d. partials
91
+
92
+ @inline npartials (d:: Dual ) = (ps = d. partials) isa Wirtinger ? 1 : length (ps)
143
93
144
94
# ####################
145
95
# Generic Functions #
@@ -152,16 +102,16 @@ Base.eps(::Type{D}) where {D<:Dual} = eps(valtype(D))
152
102
153
103
Base. rtoldefault (:: Type{D} ) where {D<: Dual } = Base. rtoldefault (valtype (D))
154
104
155
- Base. floor (:: Type{R} , d:: Dual ) where {R<: Real } = floor (R, value (d))
105
+ Base. floor (:: Type{R} , d:: Dual ) where {R<: Number } = floor (R, value (d))
156
106
Base. floor (d:: Dual ) = floor (value (d))
157
107
158
- Base. ceil (:: Type{R} , d:: Dual ) where {R<: Real } = ceil (R, value (d))
108
+ Base. ceil (:: Type{R} , d:: Dual ) where {R<: Number } = ceil (R, value (d))
159
109
Base. ceil (d:: Dual ) = ceil (value (d))
160
110
161
- Base. trunc (:: Type{R} , d:: Dual ) where {R<: Real } = trunc (R, value (d))
111
+ Base. trunc (:: Type{R} , d:: Dual ) where {R<: Number } = trunc (R, value (d))
162
112
Base. trunc (d:: Dual ) = trunc (value (d))
163
113
164
- Base. round (:: Type{R} , d:: Dual ) where {R<: Real } = round (R, value (d))
114
+ Base. round (:: Type{R} , d:: Dual ) where {R<: Number } = round (R, value (d))
165
115
Base. round (d:: Dual ) = round (value (d))
166
116
167
117
Base. hash (d:: Dual ) = hash (value (d))
@@ -205,49 +155,11 @@ end
205
155
# Promotion/Conversion #
206
156
# #######################
207
157
208
- function Base. promote_rule (:: Type{Dual{T1,V1,P1}} ,
209
- :: Type{Dual{T2,V2,P2}} ) where {T1,V1,P1,T2,V2,P2}
210
- # V1 and V2 might themselves be Dual types
211
- if T2 ≺ T1
212
- Dual{T1,promote_type (V1,Dual{T2,V2,P2}),P1}
213
- else
214
- Dual{T2,promote_type (V2,Dual{T1,V1,P1}),P2}
215
- end
216
- end
217
-
218
- function Base. promote_rule (:: Type{Dual{T,A,P}} ,
219
- :: Type{Dual{T,B,P}} ) where {T,A,B,P}
220
- return Dual{T,promote_type (A, B),P}
221
- end
222
-
223
- for R in (Irrational, Real, BigFloat, Bool)
224
- if isconcretetype (R) # issue #322
225
- @eval begin
226
- Base. promote_rule (:: Type{$R} , :: Type{Dual{T,V,P}} ) where {T,V,P} = Dual{T,promote_type ($ R, V),P}
227
- Base. promote_rule (:: Type{Dual{T,V,P}} , :: Type{$R} ) where {T,V,P} = Dual{T,promote_type (V, $ R),P}
228
- end
229
- else
230
- @eval begin
231
- Base. promote_rule (:: Type{R} , :: Type{Dual{T,V,P}} ) where {R<: $R ,T,V,P} = Dual{T,promote_type (R, V),P}
232
- Base. promote_rule (:: Type{Dual{T,V,P}} , :: Type{R} ) where {T,V,P,R<: $R } = Dual{T,promote_type (V, R),P}
233
- end
234
- end
235
- end
236
-
237
158
Base. convert (:: Type{Dual{T,V,P}} , d:: Dual{T} ) where {T,V,P} = Dual {T} (convert (V, value (d)), convert (P, partials (d)))
238
159
Base. convert (:: Type{Dual{T,V,P}} , x) where {T,V,P} = Dual {T} (convert (V, x), zero (P))
239
160
Base. convert (:: Type{Dual{T,V,P}} , x:: Number ) where {T,V,P} = Dual {T} (convert (V, x), zero (P))
240
161
Base. convert (:: Type{D} , d:: D ) where {D<: Dual } = d
241
162
242
- Base. float (d:: Dual{T} ) where {T} = Dual {T} (value (d), map (float, partials (d)))
243
- Base. AbstractFloat (d:: Dual{T} ) where {T} = Dual {T} (convert (AbstractFloat, value (d)), map (x-> convert (AbstractFloat, x), partials (d)))
244
-
245
- # ##################################
246
- # General Mathematical Operations #
247
- # ##################################
248
-
249
- @inline Base. conj (d:: Dual ) = d
250
-
251
163
# ##################
252
164
# Pretty Printing #
253
165
# ##################
@@ -258,7 +170,7 @@ function tag_show(t, n=0)
258
170
if t isa Nothing
259
171
return subscript_num (n)
260
172
elseif t isa Tag
261
- tag_show (innertag (t), n+ 1 )
173
+ tag_show (oldertag (t), n+ 1 )
262
174
else
263
175
return " {" * repr (t) * " }" * subscript_num (n)
264
176
end
0 commit comments