Skip to content

Commit baf499e

Browse files
authored
implement linearize using linearization_function (#129)
1 parent 31ab3da commit baf499e

File tree

1 file changed

+76
-56
lines changed

1 file changed

+76
-56
lines changed

src/Blocks/analysis_points.jl

Lines changed: 76 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -152,21 +152,7 @@ function Base.:(==)(ap1::AnalysisPoint, ap2::AnalysisPoint)
152152
return ap1.in == ap2.in && ap1.out == ap2.out # Name doesn't really matter if inputs and outputs are the same
153153
end
154154

155-
"""
156-
get_sensitivity(sys, ap::AnalysisPoint; kwargs)
157-
get_sensitivity(sys, ap_name::Symbol; kwargs)
158-
159-
Compute the sensitivity function in analysis point `ap`. The sensitivity function is obtained by introducing an infinitesimal perturbation `d` at the input of `ap`, linearizing the system and computing the transfer function between `d` and the output of `ap`.
160-
161-
!!! danger "Experimental"
162-
The analysis-point interface is currently experimental and at any time subject to breaking changes not respecting semantic versioning.
163-
164-
# Arguments:
165-
- `kwargs`: Are sent to `ModelingToolkit.linearize`
166-
167-
See also [`get_comp_sensitivity`](@ref), [`get_looptransfer`](@ref).
168-
"""
169-
function get_sensitivity(sys, ap_name::Symbol; kwargs...)
155+
function get_sensitivity_function(sys, ap_name::Symbol; kwargs...)
170156
find = function (x, ns)
171157
x isa AnalysisPoint || return false
172158
if ns === nothing
@@ -193,24 +179,10 @@ function get_sensitivity(sys, ap_name::Symbol; kwargs...)
193179
d = ModelingToolkit.renamespace(ns, d)
194180
u = ModelingToolkit.renamespace(ns, u)
195181
end
196-
ModelingToolkit.linearize(sys, [d], [u]; kwargs...)
182+
ModelingToolkit.linearization_function(sys, [d], [u]; kwargs...)
197183
end
198184

199-
"""
200-
get_comp_sensitivity(sys, ap::AnalysisPoint; kwargs)
201-
get_comp_sensitivity(sys, ap_name::Symbol; kwargs)
202-
203-
Compute the complementary sensitivity function in analysis point `ap`. The complementary sensitivity function is obtained by introducing an infinitesimal perturbation `d` at the output of `ap`, linearizing the system and computing the transfer function between `d` and the input of `ap`.
204-
205-
!!! danger "Experimental"
206-
The analysis-point interface is currently experimental and at any time subject to breaking changes not respecting semantic versioning.
207-
208-
# Arguments:
209-
- `kwargs`: Are sent to `ModelingToolkit.linearize`
210-
211-
See also [`get_sensitivity`](@ref), [`get_looptransfer`](@ref).
212-
"""
213-
function get_comp_sensitivity(sys, ap_name::Symbol; kwargs...)
185+
function get_comp_sensitivity_function(sys, ap_name::Symbol; kwargs...)
214186
find = function (x, ns)
215187
x isa AnalysisPoint || return false
216188
if ns === nothing
@@ -237,24 +209,10 @@ function get_comp_sensitivity(sys, ap_name::Symbol; kwargs...)
237209
d = ModelingToolkit.renamespace(ns, d)
238210
u = ModelingToolkit.renamespace(ns, u)
239211
end
240-
ModelingToolkit.linearize(sys, [d], [u]; kwargs...)
212+
ModelingToolkit.linearization_function(sys, [d], [u]; kwargs...)
241213
end
242214

243-
"""
244-
get_looptransfer(sys, ap::AnalysisPoint; kwargs)
245-
get_looptransfer(sys, ap_name::Symbol; kwargs)
246-
247-
Compute the (linearized) loop-transfer function in analysis point `ap`, from `ap.out` to `ap.in`.
248-
249-
!!! danger "Experimental"
250-
The analysis-point interface is currently experimental and at any time subject to breaking changes not respecting semantic versioning.
251-
252-
# Arguments:
253-
- `kwargs`: Are sent to `ModelingToolkit.linearize`
254-
255-
See also [`get_sensitivity`](@ref), [`get_comp_sensitivity`](@ref), [`open_loop`](@ref).
256-
"""
257-
function get_looptransfer(sys, ap_name::Symbol; kwargs...)
215+
function get_looptransfer_function(sys, ap_name::Symbol; kwargs...)
258216
find = function (x, ns)
259217
x isa AnalysisPoint || return false
260218
if ns === nothing
@@ -281,7 +239,7 @@ function get_looptransfer(sys, ap_name::Symbol; kwargs...)
281239
y = ModelingToolkit.renamespace(ns, y)
282240
u = ModelingToolkit.renamespace(ns, u)
283241
end
284-
ModelingToolkit.linearize(sys, [u], [y]; kwargs...)
242+
ModelingToolkit.linearization_function(sys, [u], [y]; kwargs...)
285243
end
286244

287245
"""
@@ -330,13 +288,9 @@ function open_loop(sys, ap_name::Symbol; kwargs...)
330288
sys
331289
end
332290

333-
"""
334-
ModelingToolkit.linearize(sys, input_name::Symbol, output_name::Symbol)
335-
336-
Linearize a system between two analysis points. To get a loop-transfer function, see [`get_looptransfer`](@ref)
337-
"""
338-
function ModelingToolkit.linearize(sys, input_name::Symbol, output_name::Symbol;
339-
kwargs...)
291+
function ModelingToolkit.linearization_function(sys::ModelingToolkit.AbstractSystem,
292+
input_name::Symbol, output_name::Symbol;
293+
kwargs...)
340294
find = function (x, ns)
341295
x isa AnalysisPoint || return false
342296
if ns === nothing
@@ -371,7 +325,7 @@ function ModelingToolkit.linearize(sys, input_name::Symbol, output_name::Symbol;
371325
y = ModelingToolkit.renamespace(ns, y)
372326
u = ModelingToolkit.renamespace(ns, u)
373327
end
374-
ModelingToolkit.linearize(sys, [u], [y]; kwargs...)
328+
ModelingToolkit.linearization_function(sys, [u], [y]; kwargs...)
375329
end
376330

377331
# Add a method to get_sensitivity that accepts the name of an AnalysisPoint
@@ -385,3 +339,69 @@ function ModelingToolkit.linearize(sys, input::AnalysisPoint, output::AnalysisPo
385339
kwargs...)
386340
ModelingToolkit.linearize(sys, nameof(input), nameof(output); kwargs...)
387341
end
342+
343+
# Methods above are implemented in terms of linearization_function, the method below creates wrappers for linearize
344+
for f in [:get_sensitivity, :get_comp_sensitivity, :get_looptransfer]
345+
@eval function $f(sys, ap::Symbol, args...; kwargs...)
346+
lin_fun, ssys = $(Symbol(string(f) * "_function"))(sys, ap, args...; kwargs...)
347+
ModelingToolkit.linearize(ssys, lin_fun; kwargs...), ssys
348+
end
349+
end
350+
351+
"""
352+
ModelingToolkit.linearize(sys, input_name::Symbol, output_name::Symbol; kwargs...)
353+
354+
Linearize a system between two analysis points. To get a loop-transfer function, see [`get_looptransfer`](@ref)
355+
"""
356+
function ModelingToolkit.linearize(sys, input_name::Symbol, output_name::Symbol; kwargs...)
357+
lin_fun, ssys = linearization_function(sys, input_name, output_name; kwargs...)
358+
ModelingToolkit.linearize(ssys, lin_fun; kwargs...), ssys
359+
end
360+
361+
"""
362+
get_sensitivity(sys, ap::AnalysisPoint; kwargs)
363+
get_sensitivity(sys, ap_name::Symbol; kwargs)
364+
365+
Compute the sensitivity function in analysis point `ap`. The sensitivity function is obtained by introducing an infinitesimal perturbation `d` at the input of `ap`, linearizing the system and computing the transfer function between `d` and the output of `ap`.
366+
367+
!!! danger "Experimental"
368+
The analysis-point interface is currently experimental and at any time subject to breaking changes not respecting semantic versioning.
369+
370+
# Arguments:
371+
- `kwargs`: Are sent to `ModelingToolkit.linearize`
372+
373+
See also [`get_comp_sensitivity`](@ref), [`get_looptransfer`](@ref).
374+
"""
375+
get_sensitivity
376+
377+
"""
378+
get_comp_sensitivity(sys, ap::AnalysisPoint; kwargs)
379+
get_comp_sensitivity(sys, ap_name::Symbol; kwargs)
380+
381+
Compute the complementary sensitivity function in analysis point `ap`. The complementary sensitivity function is obtained by introducing an infinitesimal perturbation `d` at the output of `ap`, linearizing the system and computing the transfer function between `d` and the input of `ap`.
382+
383+
!!! danger "Experimental"
384+
The analysis-point interface is currently experimental and at any time subject to breaking changes not respecting semantic versioning.
385+
386+
# Arguments:
387+
- `kwargs`: Are sent to `ModelingToolkit.linearize`
388+
389+
See also [`get_sensitivity`](@ref), [`get_looptransfer`](@ref).
390+
"""
391+
get_comp_sensitivity
392+
393+
"""
394+
get_looptransfer(sys, ap::AnalysisPoint; kwargs)
395+
get_looptransfer(sys, ap_name::Symbol; kwargs)
396+
397+
Compute the (linearized) loop-transfer function in analysis point `ap`, from `ap.out` to `ap.in`.
398+
399+
!!! danger "Experimental"
400+
The analysis-point interface is currently experimental and at any time subject to breaking changes not respecting semantic versioning.
401+
402+
# Arguments:
403+
- `kwargs`: Are sent to `ModelingToolkit.linearize`
404+
405+
See also [`get_sensitivity`](@ref), [`get_comp_sensitivity`](@ref), [`open_loop`](@ref).
406+
"""
407+
get_looptransfer

0 commit comments

Comments
 (0)