@@ -15,29 +15,34 @@ using ..Controls: t_mid
1515ampl = LockedAmplitude(shape)
1616```
1717
18- wraps around `shape`, which must be either a vector of values defined on the
19- midpoints of a time grid or a callable `shape(t)`.
18+ wraps around `shape`, which must be either a `Vector{Float64}` of values defined
19+ on the midpoints of a time grid or a callable `shape(t)`.
2020
2121```julia
2222ampl = LockedAmplitude(shape, tlist)
2323```
2424
2525discretizes `shape` to the midpoints of `tlist`.
2626"""
27- abstract type LockedAmplitude end
28-
29-
30- function LockedAmplitude (shape)
31- if shape isa Vector{Float64}
32- return LockedPulseAmplitude (shape)
33- else
34- return LockedContinuousAmplitude (shape)
27+ struct LockedAmplitude{ST}
28+ shape:: ST
29+
30+ function LockedAmplitude (shape:: ST ; check = true ) where {ST}
31+ if check && ! (shape isa Vector{Float64})
32+ try
33+ shape (0.0 )
34+ catch
35+ msg = " A LockedAmplitude shape must either be a Vector{Float64} or a callable"
36+ error (msg)
37+ end
38+ end
39+ return new {ST} (shape)
3540 end
3641end
3742
3843
3944function LockedAmplitude (shape, tlist)
40- return LockedPulseAmplitude (discretize_on_midpoints (shape, tlist))
45+ return LockedAmplitude (discretize_on_midpoints (shape, tlist); check = false )
4146end
4247
4348
@@ -46,53 +51,29 @@ function Base.show(io::IO, ampl::LockedAmplitude)
4651end
4752
4853
49- struct LockedPulseAmplitude <: LockedAmplitude
50- shape:: Vector{Float64}
51- end
52-
53-
54- Base. Array (ampl:: LockedPulseAmplitude ) = ampl. shape
55-
56-
57- struct LockedContinuousAmplitude <: LockedAmplitude
58-
59- shape
60-
61- function LockedContinuousAmplitude (shape)
62- try
63- S_t = shape (0.0 )
64- catch
65- error (" A LockedAmplitude shape must either be a vector of values or a callable" )
66- end
67- return new (shape)
68- end
69-
70- end
71-
72- (ampl:: LockedContinuousAmplitude )(t:: Float64 ) = ampl. shape (t)
54+ Base. Array (ampl:: LockedAmplitude{Vector{Float64}} ) = ampl. shape
7355
7456get_controls (ampl:: LockedAmplitude ) = ()
7557
7658function substitute (ampl:: LockedAmplitude , replacements)
7759 return get (replacements, ampl, ampl)
7860end
7961
80- function evaluate (ampl:: LockedPulseAmplitude , tlist, n; _... )
62+ function evaluate (ampl:: LockedAmplitude{Vector{Float64}} , tlist, n:: Int ; _... )
8163 return ampl. shape[n]
8264end
8365
84- function evaluate (ampl:: LockedPulseAmplitude , t; _... )
85- error (
86- " A LockedAmplitude initialized on a `tlist` can only be evaluated with arguments `tlist, n`."
87- )
66+ function evaluate (ampl:: LockedAmplitude{Vector{Float64}} , t:: Float64 ; _... )
67+ msg = " A LockedAmplitude initialized from a vector can only be evaluated with (tlist, n)."
68+ error (msg)
8869end
8970
90- function evaluate (ampl:: LockedContinuousAmplitude , tlist, n; _... )
91- return ampl (t_mid (tlist, n))
71+ function evaluate (ampl:: LockedAmplitude , tlist, n:: Int ; _... )
72+ return ampl. shape (t_mid (tlist, n))
9273end
9374
94- function evaluate (ampl:: LockedContinuousAmplitude , t; _... )
95- return ampl (t)
75+ function evaluate (ampl:: LockedAmplitude , t:: Float64 ; _... )
76+ return ampl. shape (t)
9677end
9778
9879
@@ -124,63 +105,122 @@ ampl = ShapedAmplitude(control; shape=shape)
124105```
125106
126107produces an amplitude ``a(t) = S(t) ϵ(t)``, where ``S(t)`` corresponds to
127- `shape` and ``ϵ(t)`` corresponds to `control`. Both `control` and `shape`
128- should be either a vector of values defined on the midpoints of a time grid or
129- a callable `control(t)`, respectively `shape(t)`. In the latter case, `ampl`
130- will also be callable.
108+ `shape` and ``ϵ(t)`` corresponds to `control`. Each of `control` and `shape`
109+ must be either a `Vector{Float64}` of values defined on the midpoints of a time
110+ grid or a callable `control(t)`, respectively `shape(t)`. If both are callables,
111+ `ampl` will also be callable. If both are vectors, they must have the same length .
131112
132113```julia
133114ampl = ShapedAmplitude(control, tlist; shape=shape)
134115```
135116
136117discretizes `control` and `shape` to the midpoints of `tlist`.
137118"""
138- abstract type ShapedAmplitude <: ControlAmplitude end
119+ struct ShapedAmplitude{CT,ST} <: ControlAmplitude
120+ control:: CT
121+ shape:: ST
122+ end
139123
140- function ShapedAmplitude (control; shape)
141- if (control isa Vector{Float64}) && ( shape isa Vector{Float64} )
142- return ShapedPulseAmplitude (control, shape)
143- else
144- try
145- ϵ_t = control (0.0 )
146- catch
147- error (
148- " A ShapedAmplitude control must either be a vector of values or a callable "
149- )
124+
125+ function ShapedAmplitude (control; shape, check = true )
126+ if check
127+ if ! (control isa Vector{Float64})
128+ try
129+ control (0.0 )
130+ catch
131+ msg = " A ShapedAmplitude control must either be a Vector{Float64} or a callable "
132+ error (msg)
133+ end
150134 end
151- try
152- S_t = shape (0.0 )
153- catch
154- error (" A ShapedAmplitude shape must either be a vector of values or a callable" )
135+ if ! (shape isa Vector{Float64})
136+ try
137+ shape (0.0 )
138+ catch
139+ msg = " A ShapedAmplitude shape must either be a Vector{Float64} or a callable"
140+ error (msg)
141+ end
142+ end
143+ if (control isa Vector{Float64}) && (shape isa Vector{Float64})
144+ if length (control) ≠ length (shape)
145+ msg = " ShapedAmplitude control and shape vectors must have the same length"
146+ error (msg)
147+ end
155148 end
156- return ShapedContinuousAmplitude (control, shape)
157149 end
150+ return ShapedAmplitude {typeof(control),typeof(shape)} (control, shape)
158151end
159152
153+
160154function Base. show (io:: IO , ampl:: ShapedAmplitude )
161155 print (io, " ShapedAmplitude(::$(typeof (ampl. control)) ; shape::$(typeof (ampl. shape)) )" )
162156end
163157
164- function ShapedAmplitude (control, tlist; shape)
158+
159+ function ShapedAmplitude (control, tlist:: Vector{Float64} ; shape)
165160 control = discretize_on_midpoints (control, tlist)
166161 shape = discretize_on_midpoints (shape, tlist)
167- return ShapedPulseAmplitude (control, shape)
162+ return ShapedAmplitude {typeof(control),typeof(shape)} (control, shape)
163+ end
164+
165+
166+ function substitute (ampl:: ShapedAmplitude , replacements)
167+ ampl in keys (replacements) && return replacements[ampl]
168+ control = substitute (ampl. control, replacements)
169+ return ShapedAmplitude (control; shape = ampl. shape, check = true )
170+ end
171+
172+
173+ Base. Array (ampl:: ShapedAmplitude{Vector{Float64},Vector{Float64}} ) =
174+ ampl. control .* ampl. shape
175+
176+ (ampl:: ShapedAmplitude )(t:: Float64 ) = ampl. shape (t) * ampl. control (t)
177+
178+
179+ # Vector shape: index directly; control may be vector or callable (evaluated via Controls.evaluate)
180+ function evaluate (
181+ ampl:: ShapedAmplitude{CT,Vector{Float64}} ,
182+ tlist:: Vector{Float64} ,
183+ n:: Int ;
184+ vals_dict = IdDict ()
185+ ) where {CT}
186+ S_t = ampl. shape[n]
187+ ϵ_t = evaluate (ampl. control, tlist, n; vals_dict)
188+ return S_t * ϵ_t
168189end
169190
170- struct ShapedPulseAmplitude <: ShapedAmplitude
171- control:: Vector{Float64}
172- shape:: Vector{Float64}
191+ # Callable shape: call directly with t_mid; control may be vector or callable
192+ function evaluate (
193+ ampl:: ShapedAmplitude ,
194+ tlist:: Vector{Float64} ,
195+ n:: Int ;
196+ vals_dict = IdDict ()
197+ )
198+ S_t = ampl. shape (t_mid (tlist, n))
199+ ϵ_t = evaluate (ampl. control, tlist, n; vals_dict)
200+ return S_t * ϵ_t
173201end
174202
175- Base. Array (ampl:: ShapedPulseAmplitude ) = ampl. control .* ampl. shape
203+ # Callable shape and callable control: call both directly at t
204+ function evaluate (ampl:: ShapedAmplitude , t:: Float64 ; vals_dict = IdDict ())
205+ S_t = ampl. shape (t)
206+ ϵ_t = evaluate (ampl. control, t; vals_dict)
207+ return S_t * ϵ_t
208+ end
176209
210+ function evaluate (ampl:: ShapedAmplitude{Vector{Float64},Vector{Float64}} , t:: Float64 ; _... )
211+ msg = " A ShapedAmplitude with vector control and shape can only be evaluated with (tlist, n)."
212+ error (msg)
213+ end
177214
178- struct ShapedContinuousAmplitude <: ShapedAmplitude
179- control
180- shape
215+ function evaluate (ampl :: ShapedAmplitude{Vector{Float64},ST} , t :: Float64 ; _ ... ) where {ST}
216+ msg = " A ShapedAmplitude with a vector control can only be evaluated with (tlist, n). "
217+ error (msg)
181218end
182219
183- (ampl:: ShapedContinuousAmplitude )(t:: Float64 ) = ampl. shape (t) * ampl. control (t)
220+ function evaluate (ampl:: ShapedAmplitude{CT,Vector{Float64}} , t:: Float64 ; _... ) where {CT}
221+ msg = " A ShapedAmplitude with a vector shape can only be evaluated with (tlist, n)."
222+ error (msg)
223+ end
184224
185225
186226function evaluate (ampl:: ShapedAmplitude , args... ; vals_dict = IdDict ())
0 commit comments