1
- export Affine , AffineTransform
1
+ export AffinePushfwd , AffineTransform
2
2
using LinearAlgebra
3
3
import Base
4
4
@@ -161,42 +161,42 @@ basemeasure(d::OrthoLebesgue) = d
161
161
162
162
logdensity_def (:: OrthoLebesgue , x) = static (0.0 )
163
163
164
- struct Affine {N,M,T} <: AbstractMeasure
164
+ struct AffinePushfwd {N,M,T} <: AbstractMeasure
165
165
f:: AffineTransform{N,T}
166
166
parent:: M
167
167
end
168
168
169
- function Pretty. tile (d:: Affine )
169
+ function Pretty. tile (d:: AffinePushfwd )
170
170
pars = Pretty. literal (sprint (show, params (d. f); context = :compact => true ))
171
171
172
- Pretty. list_layout ([pars, Pretty. tile (d. parent)]; prefix = :Affine )
172
+ Pretty. list_layout ([pars, Pretty. tile (d. parent)]; prefix = :AffinePushfwd )
173
173
end
174
174
175
- @inline function testvalue (d:: Affine )
175
+ @inline function testvalue (d:: AffinePushfwd )
176
176
f = getfield (d, :f )
177
177
z = testvalue (parent (d))
178
178
return f (z)
179
179
end
180
180
181
- Affine (nt:: NamedTuple , μ:: AbstractMeasure ) = affine (nt, μ)
181
+ AffinePushfwd (nt:: NamedTuple , μ:: AbstractMeasure ) = affine (nt, μ)
182
182
183
- Affine (nt:: NamedTuple ) = affine (nt)
183
+ AffinePushfwd (nt:: NamedTuple ) = affine (nt)
184
184
185
- Base. parent (d:: Affine ) = getfield (d, :parent )
185
+ Base. parent (d:: AffinePushfwd ) = getfield (d, :parent )
186
186
187
- function params (μ:: Affine )
187
+ function params (μ:: AffinePushfwd )
188
188
nt1 = getfield (getfield (μ, :f ), :par )
189
189
nt2 = params (parent (μ))
190
190
return merge (nt1, nt2)
191
191
end
192
192
193
- function paramnames (:: Type{A} ) where {N,M,A<: Affine {N,M} }
193
+ function paramnames (:: Type{A} ) where {N,M,A<: AffinePushfwd {N,M} }
194
194
tuple (union (N, paramnames (M))... )
195
195
end
196
196
197
- Base. propertynames (d:: Affine {N} ) where {N} = N ∪ (:parent , :f )
197
+ Base. propertynames (d:: AffinePushfwd {N} ) where {N} = N ∪ (:parent , :f )
198
198
199
- @inline function Base. getproperty (d:: Affine , s:: Symbol )
199
+ @inline function Base. getproperty (d:: AffinePushfwd , s:: Symbol )
200
200
if s === :parent
201
201
return getfield (d, :parent )
202
202
elseif s === :f
@@ -206,42 +206,42 @@ Base.propertynames(d::Affine{N}) where {N} = N ∪ (:parent, :f)
206
206
end
207
207
end
208
208
209
- Base. size (d:: Affine ) = size (d. μ)
210
- Base. size (d:: Affine {(:σ,)} ) = (size (d. σ, 1 ),)
211
- Base. size (d:: Affine {(:λ,)} ) = (size (d. λ, 2 ),)
209
+ Base. size (d:: AffinePushfwd ) = size (d. μ)
210
+ Base. size (d:: AffinePushfwd {(:σ,)} ) = (size (d. σ, 1 ),)
211
+ Base. size (d:: AffinePushfwd {(:λ,)} ) = (size (d. λ, 2 ),)
212
212
213
- @inline function logdensity_def (d:: Affine {(:σ,)} , x:: AbstractArray )
213
+ @inline function logdensity_def (d:: AffinePushfwd {(:σ,)} , x:: AbstractArray )
214
214
z = solve (d. σ, x)
215
215
MeasureBase. unsafe_logdensityof (d. parent, z)
216
216
end
217
217
218
- @inline function logdensity_def (d:: Affine {(:λ,)} , x:: AbstractArray )
218
+ @inline function logdensity_def (d:: AffinePushfwd {(:λ,)} , x:: AbstractArray )
219
219
z = d. λ * x
220
220
MeasureBase. unsafe_logdensityof (d. parent, z)
221
221
end
222
222
223
- @inline function logdensity_def (d:: Affine {(:μ,)} , x:: AbstractArray )
223
+ @inline function logdensity_def (d:: AffinePushfwd {(:μ,)} , x:: AbstractArray )
224
224
z = mappedarray (- , x, d. μ)
225
225
MeasureBase. unsafe_logdensityof (d. parent, z)
226
226
end
227
227
228
- @inline function logdensity_def (d:: Affine {(:μ, :σ)} , x:: AbstractArray )
228
+ @inline function logdensity_def (d:: AffinePushfwd {(:μ, :σ)} , x:: AbstractArray )
229
229
z = d. σ \ mappedarray (- , x, d. μ)
230
230
MeasureBase. unsafe_logdensityof (d. parent, z)
231
231
end
232
232
233
- @inline function logdensity_def (d:: Affine {(:μ, :λ)} , x:: AbstractArray )
233
+ @inline function logdensity_def (d:: AffinePushfwd {(:μ, :λ)} , x:: AbstractArray )
234
234
z = d. λ * mappedarray (- , x, d. μ)
235
235
MeasureBase. unsafe_logdensityof (d. parent, z)
236
236
end
237
237
238
- @inline function logdensity_def (d:: Affine , x)
238
+ @inline function logdensity_def (d:: AffinePushfwd , x)
239
239
z = inverse (d. f)(x)
240
240
logdensity_def (d. parent, z)
241
241
end
242
242
243
- # # # logdensity_def(d::Affine {(:μ,:λ)}, x) = logdensity_def(d.parent, d.σ \ (x - d.μ))
244
- # # @inline function logdensity_def(d::Affine {(:μ,:σ), P, Tuple{V,M}}, x) where {P, V<:AbstractVector, M<:AbstractMatrix}
243
+ # # # logdensity_def(d::AffinePushfwd {(:μ,:λ)}, x) = logdensity_def(d.parent, d.σ \ (x - d.μ))
244
+ # # @inline function logdensity_def(d::AffinePushfwd {(:μ,:σ), P, Tuple{V,M}}, x) where {P, V<:AbstractVector, M<:AbstractMatrix}
245
245
# # z = x - d.μ
246
246
# # σ = d.σ
247
247
# # if σ isa Factorization
@@ -252,45 +252,45 @@ end
252
252
# # sum(zⱼ -> logdensity_def(d.parent, zⱼ), z)
253
253
# # end
254
254
255
- # # # logdensity_def(d::Affine {(:μ,:λ)}, x) = logdensity_def(d.parent, d.λ * (x - d.μ))
256
- # # @inline function logdensity_def(d::Affine {(:μ,:λ), P,Tuple{V,M}}, x) where {P,V<:AbstractVector, M<:AbstractMatrix}
255
+ # # # logdensity_def(d::AffinePushfwd {(:μ,:λ)}, x) = logdensity_def(d.parent, d.λ * (x - d.μ))
256
+ # # @inline function logdensity_def(d::AffinePushfwd {(:μ,:λ), P,Tuple{V,M}}, x) where {P,V<:AbstractVector, M<:AbstractMatrix}
257
257
# # z = x - d.μ
258
258
# # lmul!(d.λ, z)
259
259
# # logdensity_def(d.parent, z)
260
260
# # end
261
261
262
- @inline function basemeasure (d:: Affine {N,M,Tuple{A}} ) where {N,M,A<: AbstractArray }
262
+ @inline function basemeasure (d:: AffinePushfwd {N,M,Tuple{A}} ) where {N,M,A<: AbstractArray }
263
263
weightedmeasure (- logjac (d), OrthoLebesgue (params (d)))
264
264
end
265
265
266
266
@inline function basemeasure (
267
- d:: MeasureTheory.Affine {N,L,Tuple{A}} ,
267
+ d:: MeasureTheory.AffinePushfwd {N,L,Tuple{A}} ,
268
268
) where {N,L<: MeasureBase.Lebesgue ,A<: AbstractArray }
269
269
weightedmeasure (- logjac (d), OrthoLebesgue (params (d)))
270
270
end
271
271
272
272
@inline function basemeasure (
273
- d:: Affine {N,M,Tuple{A1,A2}} ,
273
+ d:: AffinePushfwd {N,M,Tuple{A1,A2}} ,
274
274
) where {N,M,A1<: AbstractArray ,A2<: AbstractArray }
275
275
weightedmeasure (- logjac (d), OrthoLebesgue (params (d)))
276
276
end
277
277
278
- @inline basemeasure (d:: Affine ) = affine (getfield (d, :f ), basemeasure (d. parent))
278
+ @inline basemeasure (d:: AffinePushfwd ) = affine (getfield (d, :f ), basemeasure (d. parent))
279
279
280
280
# We can't do this until we know we're working with Lebesgue measure, since for
281
281
# example it wouldn't make sense to apply a log-Jacobian to a point measure
282
- @inline function basemeasure (d:: Affine {N,L} ) where {N,L<: Lebesgue }
282
+ @inline function basemeasure (d:: AffinePushfwd {N,L} ) where {N,L<: Lebesgue }
283
283
weightedmeasure (- logjac (d), d. parent)
284
284
end
285
- @inline function basemeasure (d:: Affine {N,L} ) where {N,L<: LebesgueMeasure }
285
+ @inline function basemeasure (d:: AffinePushfwd {N,L} ) where {N,L<: LebesgueMeasure }
286
286
weightedmeasure (- logjac (d), d. parent)
287
287
end
288
288
289
- logjac (d:: Affine ) = logjac (getfield (d, :f ))
289
+ logjac (d:: AffinePushfwd ) = logjac (getfield (d, :f ))
290
290
291
291
function Random. rand! (
292
292
rng:: Random.AbstractRNG ,
293
- d:: Affine ,
293
+ d:: AffinePushfwd ,
294
294
x:: AbstractVector{T} ,
295
295
z = Vector {T} (undef, size (getfield (d, :f ), 2 )),
296
296
) where {T}
@@ -300,42 +300,67 @@ function Random.rand!(
300
300
return x
301
301
end
302
302
303
- # function Base.rand(rng::Random.AbstractRNG, ::Type{T}, d::Affine ) where {T}
303
+ # function Base.rand(rng::Random.AbstractRNG, ::Type{T}, d::AffinePushfwd ) where {T}
304
304
# f = getfield(d, :f)
305
305
# z = rand(rng, T, parent(d))
306
306
# apply!(x, f, z)
307
307
# return z
308
308
# end
309
309
310
- supportdim (nt:: NamedTuple{(:μ, :σ)} ) = colsize (nt. σ)
311
- supportdim (nt:: NamedTuple{(:μ, :λ)} ) = rowsize (nt. λ)
312
- supportdim (nt:: NamedTuple{(:σ,)} ) = colsize (nt. σ)
313
- supportdim (nt:: NamedTuple{(:λ,)} ) = rowsize (nt. λ)
314
- supportdim (nt:: NamedTuple{(:μ,)} ) = size (nt. μ)
310
+ supportdim (nt:: NamedTuple{(:μ, :σ),T} ) where {T} = colsize (nt. σ)
311
+ supportdim (nt:: NamedTuple{(:μ, :λ),T} ) where {T} = rowsize (nt. λ)
312
+ supportdim (nt:: NamedTuple{(:σ,),T} ) where {T} = colsize (nt. σ)
313
+ supportdim (nt:: NamedTuple{(:λ,),T} ) where {T} = rowsize (nt. λ)
314
+ supportdim (nt:: NamedTuple{(:μ,),T} ) where {T} = size (nt. μ)
315
315
316
- asparams (:: Affine , :: StaticSymbol{:μ} ) = asℝ
317
- asparams (:: Affine , :: StaticSymbol{:σ} ) = asℝ₊
318
- asparams (:: Type{A} , :: StaticSymbol{:μ} ) where {A<: Affine } = asℝ
319
- asparams (:: Type{A} , :: StaticSymbol{:σ} ) where {A<: Affine } = asℝ₊
316
+ asparams (:: AffinePushfwd , :: StaticSymbol{:μ} ) = asℝ
317
+ asparams (:: AffinePushfwd , :: StaticSymbol{:σ} ) = asℝ₊
318
+ asparams (:: Type{A} , :: StaticSymbol{:μ} ) where {A<: AffinePushfwd } = asℝ
319
+ asparams (:: Type{A} , :: StaticSymbol{:σ} ) where {A<: AffinePushfwd } = asℝ₊
320
320
321
- function asparams (d:: Affine {N,M,T} , :: StaticSymbol{:μ} ) where {N,M,T<: AbstractArray }
321
+ function asparams (d:: AffinePushfwd {N,M,T} , :: StaticSymbol{:μ} ) where {N,M,T<: AbstractArray }
322
322
as (Array, asℝ, size (d. μ))
323
323
end
324
324
325
- function asparams (d:: Affine {N,M,T} , :: StaticSymbol{:σ} ) where {N,M,T<: AbstractArray }
325
+ function asparams (d:: AffinePushfwd {N,M,T} , :: StaticSymbol{:σ} ) where {N,M,T<: AbstractArray }
326
326
as (Array, asℝ, size (d. σ))
327
327
end
328
328
329
- function Base. rand (rng:: Random.AbstractRNG , :: Type{T} , d:: Affine ) where {T}
329
+ function Base. rand (rng:: Random.AbstractRNG , :: Type{T} , d:: AffinePushfwd ) where {T}
330
330
z = rand (rng, T, parent (d))
331
331
f = getfield (d, :f )
332
332
return f (z)
333
333
end
334
334
335
- @inline function insupport (d:: Affine , x)
335
+ @inline function insupport (d:: AffinePushfwd , x)
336
336
insupport (d. parent, inverse (d. f)(x))
337
337
end
338
338
339
- @inline function Distributions. cdf (d:: Affine , x)
339
+ @inline function Distributions. cdf (d:: AffinePushfwd , x)
340
340
cdf (parent (d), inverse (d. f)(x))
341
341
end
342
+
343
+ @inline function mean (d:: AffinePushfwd )
344
+ f = getfield (d, :f )
345
+ f (mean (parent (d)))
346
+ end
347
+
348
+ @inline function std (d:: AffinePushfwd{(:μ,)} )
349
+ std (parent (d))
350
+ end
351
+
352
+ @inline function std (d:: AffinePushfwd{(:μ, :σ)} )
353
+ d. σ * std (parent (d))
354
+ end
355
+
356
+ @inline function std (d:: AffinePushfwd{(:σ,)} )
357
+ d. σ * std (parent (d))
358
+ end
359
+
360
+ @inline function std (d:: AffinePushfwd{(:λ,)} )
361
+ std (parent (d)) / d. λ
362
+ end
363
+
364
+ @inline function std (d:: AffinePushfwd{(:μ, :λ)} )
365
+ std (parent (d)) / d. λ
366
+ end
0 commit comments