-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathDCTOp.jl
More file actions
70 lines (59 loc) · 2.02 KB
/
DCTOp.jl
File metadata and controls
70 lines (59 loc) · 2.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
export DCTOpImpl
mutable struct DCTOpImpl{T, vecT, P} <: DCTOp{T}
const nrow :: Int
const ncol :: Int
const symmetric :: Bool
const hermitian :: Bool
const prod! :: Function
const tprod! :: Nothing
const ctprod! :: Function
nprod :: Int
ntprod :: Int
nctprod :: Int
Mv :: vecT
Mtu :: vecT
const plan :: P
const dcttype::Int
end
LinearOperators.storage_type(::DCTOpImpl{T, vecT}) where {T,vecT} = vecT
"""
DCTOpImpl(T::Type, shape::Tuple, dcttype=2)
returns a `DCTOpImpl <: AbstractLinearOperator` which performs a DCT on a given input array.
# Arguments:
* `T::Type` - type of the array to transform
* `shape::Tuple` - size of the array to transform
* `dcttype` - type of DCT (currently `2` and `4` are supported)
"""
function LinearOperatorCollection.DCTOp(T::Type; shape::Tuple, S = Array{T}, dcttype=2)
tmp=similar(S(undef, 0), shape...)
if dcttype == 2
plan = plan_dct!(tmp)
iplan = plan_idct!(tmp)
prod! = (res, x) -> dct_multiply2(res, plan, x, tmp)
tprod! = (res, x) -> dct_multiply2(res, iplan, x, tmp)
elseif dcttype == 4
factor = T(sqrt(1.0/(prod(shape)* 2^length(shape)) ))
plan = FFTW.plan_r2r!(tmp,FFTW.REDFT11)
prod! = (res, x) -> dct_multiply4(res, plan, x, tmp, factor)
tprod! = (res, x) -> dct_multiply4(res, plan, x, tmp, factor)
else
error("DCT type $(dcttype) not supported")
end
return DCTOpImpl{T, S, typeof(plan)}(prod(shape), prod(shape), false, false,
prod!, nothing, tprod!,
0, 0, 0, S(undef, 0), S(undef, 0),
plan, dcttype)
end
function dct_multiply2(res::AbstractVector{T}, plan::P, x::AbstractVector{T}, tmp::AbstractArray{T,D}) where {T,P,D}
tmp[:] .= x
plan * tmp
res .= vec(tmp)
end
function dct_multiply4(res::AbstractVector{T}, plan::P, x::AbstractVector{T}, tmp::AbstractArray{T,D}, factor::T) where {T,P,D}
tmp[:] .= x
plan * tmp
res .= factor.*vec(tmp)
end
function Base.copy(S::DCTOpImpl)
return DCTOpImpl(eltype(S), size(S.plan), S.dcttype)
end