Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion architecture_post_pr116_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestPostPR116CrossSeamConversionMetadataRationalAndFRD(t *testing.T) {
t.Fatalf("discrete metadata InputName=%v OutputName=%v", disc.InputName, disc.OutputName)
}

back, err := disc.D2C("zoh")
back, err := disc.D2C(C2DMethodZOH)
if err != nil {
t.Fatal(err)
}
Expand Down
4 changes: 2 additions & 2 deletions architecture_prd103_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func TestPRD103DelayConversionPolicyPublicWorkflows(t *testing.T) {
t.Fatal(err)
}

disc, err := cont.DiscretizeWithOpts(0.1, C2DOptions{Method: "zoh", ThiranOrder: 3})
disc, err := cont.DiscretizeWithOpts(0.1, C2DOptions{Method: C2DMethodZOH, ThiranOrder: 3})
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -200,7 +200,7 @@ func TestPRD103FrequencyAnalysisSampledResponseParity(t *testing.T) {
if _, err := Margin(delayed); err != nil {
t.Fatalf("delayed SISO Margin failed: %v", err)
}
if _, err := Pidtune(delayed, "PI"); err != nil {
if _, err := Pidtune(delayed, PidtunePI); err != nil {
t.Fatalf("delayed SISO Pidtune failed: %v", err)
}
}
Expand Down
4 changes: 2 additions & 2 deletions architecture_prd95_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestPRD95DelayBankPublicWorkflowsShareRules(t *testing.T) {
t.Fatal(err)
}

disc, err := plant.DiscretizeWithOpts(0.1, C2DOptions{Method: "zoh", ThiranOrder: 3})
disc, err := plant.DiscretizeWithOpts(0.1, C2DOptions{Method: C2DMethodZOH, ThiranOrder: 3})
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -279,7 +279,7 @@ func TestPRD95FrequencyResponseLayoutPublicWorkflowsAgree(t *testing.T) {
u.Set(0, k, math.Sin(0.17*float64(k)))
u.Set(1, k, math.Cos(0.11*float64(k)))
}
disc, err := sys.D2D(dt, C2DOptions{Method: "tustin"})
disc, err := sys.D2D(dt, C2DOptions{Method: C2DMethodTustin})
if err != nil {
t.Fatal(err)
}
Expand Down
10 changes: 5 additions & 5 deletions architecture_remaining_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func TestRemainingArchitectureConversionPlannerBehavior(t *testing.T) {
if err != nil {
t.Fatal(err)
}
discZOH, err := sys.DiscretizeWithOpts(0.1, C2DOptions{Method: "zoh"})
discZOH, err := sys.DiscretizeWithOpts(0.1, C2DOptions{Method: C2DMethodZOH})
if err != nil {
t.Fatal(err)
}
Expand All @@ -169,7 +169,7 @@ func TestRemainingArchitectureConversionPlannerBehavior(t *testing.T) {
t.Fatalf("InputDelay = %v, want [2 3]", discDefault.InputDelay)
}

resampled, err := discDefault.D2D(0.05, C2DOptions{Method: "tustin"})
resampled, err := discDefault.D2D(0.05, C2DOptions{Method: C2DMethodTustin})
if err != nil {
t.Fatal(err)
}
Expand All @@ -180,10 +180,10 @@ func TestRemainingArchitectureConversionPlannerBehavior(t *testing.T) {
t.Fatalf("state names = %v, want %v", resampled.StateName, sys.StateName)
}

if _, err := sys.DiscretizeWithOpts(0.1, C2DOptions{Method: "unknown"}); err == nil {
if _, err := sys.DiscretizeWithOpts(0.1, C2DOptions{Method: C2DMethod("unknown")}); err == nil {
t.Fatal("expected unknown C2D method to fail")
}
if _, err := discDefault.D2C("unknown"); err == nil {
if _, err := discDefault.D2C(C2DMethod("unknown")); err == nil {
t.Fatal("expected unknown D2C method to fail")
}
}
Expand Down Expand Up @@ -222,7 +222,7 @@ func TestRemainingArchitectureTimeDomainPolicyPublicConsumers(t *testing.T) {
}
}

contAgain, err := disc.D2C("tustin")
contAgain, err := disc.D2C(C2DMethodTustin)
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion architecture_runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func TestRuntimeArchitectureSISOLoopAnalysisRejectsMIMOConsistently(t *testing.T
return err
}},
{name: "Pidtune", run: func() error {
_, err := Pidtune(sys, "PI")
_, err := Pidtune(sys, PidtunePI)
return err
}},
}
Expand Down
14 changes: 7 additions & 7 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ func BenchmarkDiscretizeWithOpts_Thiran(b *testing.B) {
sys.InputDelay = []float64{0.35}
b.ResetTimer()
for i := 0; i < b.N; i++ {
sys.DiscretizeWithOpts(0.1, C2DOptions{Method: "zoh", ThiranOrder: 3})
sys.DiscretizeWithOpts(0.1, C2DOptions{Method: C2DMethodZOH, ThiranOrder: 3})
}
}

Expand All @@ -489,7 +489,7 @@ func BenchmarkDiscretizeWithOpts_IODelayThiran(b *testing.B) {
sys.Delay = mat.NewDense(1, 1, []float64{0.35})
b.ResetTimer()
for i := 0; i < b.N; i++ {
sys.DiscretizeWithOpts(0.1, C2DOptions{Method: "zoh", ThiranOrder: 3})
sys.DiscretizeWithOpts(0.1, C2DOptions{Method: C2DMethodZOH, ThiranOrder: 3})
}
}

Expand Down Expand Up @@ -1364,39 +1364,39 @@ func BenchmarkD2C_ZOH_N2(b *testing.B) {
sys := benchD2CSystem(2, 1, 0.05)
b.ResetTimer()
for i := 0; i < b.N; i++ {
sys.D2C("zoh")
sys.D2C(C2DMethodZOH)
}
}

func BenchmarkD2C_ZOH_N5(b *testing.B) {
sys := benchD2CSystem(5, 2, 0.05)
b.ResetTimer()
for i := 0; i < b.N; i++ {
sys.D2C("zoh")
sys.D2C(C2DMethodZOH)
}
}

func BenchmarkD2C_ZOH_N20(b *testing.B) {
sys := benchD2CSystem(20, 5, 0.01)
b.ResetTimer()
for i := 0; i < b.N; i++ {
sys.D2C("zoh")
sys.D2C(C2DMethodZOH)
}
}

func BenchmarkD2C_ZOH_N50(b *testing.B) {
sys := benchD2CSystem(50, 10, 0.01)
b.ResetTimer()
for i := 0; i < b.N; i++ {
sys.D2C("zoh")
sys.D2C(C2DMethodZOH)
}
}

func BenchmarkD2C_Tustin_N20(b *testing.B) {
sys := benchD2CSystem(20, 5, 0.01)
b.ResetTimer()
for i := 0; i < b.N; i++ {
sys.D2C("tustin")
sys.D2C(C2DMethodTustin)
}
}

Expand Down
6 changes: 3 additions & 3 deletions benchmark_hotspots_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -811,22 +811,22 @@ func BenchmarkPidtune_PI(b *testing.B) {
sys := benchSysNonSym(4, 1, 1)
b.ResetTimer()
for i := 0; i < b.N; i++ {
Pidtune(sys, "PI")
Pidtune(sys, PidtunePI)
}
}

func BenchmarkPidtune_PID(b *testing.B) {
sys := benchSysNonSym(4, 1, 1)
b.ResetTimer()
for i := 0; i < b.N; i++ {
Pidtune(sys, "PID")
Pidtune(sys, PidtunePID)
}
}

func BenchmarkPidtune_PIDF(b *testing.B) {
sys := benchSysNonSym(4, 1, 1)
b.ResetTimer()
for i := 0; i < b.N; i++ {
Pidtune(sys, "PIDF")
Pidtune(sys, PidtunePIDF)
}
}
28 changes: 14 additions & 14 deletions conversion_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ type c2dPlan struct {
sys *System
dt float64
opts C2DOptions
method string
delayModeling string
method C2DMethod
delayModeling C2DDelayModeling
contInputDelay []float64
contOutputDelay []float64
workSys *System
Expand All @@ -26,21 +26,21 @@ func newC2DPlan(sys *System, dt float64, opts C2DOptions) (c2dPlan, error) {

method := opts.Method
if method == "" {
method = "zoh"
method = C2DMethodZOH
}
switch method {
case "zoh", "tustin", "foh", "impulse", "matched":
case C2DMethodZOH, C2DMethodTustin, C2DMethodFOH, C2DMethodImpulse, C2DMethodMatched:
default:
return c2dPlan{}, fmt.Errorf("DiscretizeWithOpts: unknown method %q", method)
}
opts.Method = method

delayModeling := opts.DelayModeling
if delayModeling == "" {
delayModeling = "state"
delayModeling = C2DDelayModelingState
}
switch delayModeling {
case "state", "internal":
case C2DDelayModelingState, C2DDelayModelingInternal:
default:
return c2dPlan{}, fmt.Errorf("DiscretizeWithOpts: unknown DelayModeling %q", delayModeling)
}
Expand All @@ -58,7 +58,7 @@ func newC2DPlan(sys *System, dt float64, opts C2DOptions) (c2dPlan, error) {
}
plan.workSys.InputDelay = nil
plan.workSys.OutputDelay = nil
if sys.Delay != nil && (opts.ThiranOrder > 0 || delayModeling == "internal") {
if sys.Delay != nil && (opts.ThiranOrder > 0 || delayModeling == C2DDelayModelingInternal) {
decomp := decomposedDelayMatrix(sys.Delay)
if decomp.hasResidual() {
plan.workSys.Delay = decomp.residual
Expand All @@ -82,7 +82,7 @@ func (p c2dPlan) run() (*System, error) {
return nil, err
}

if p.delayModeling == "internal" {
if p.delayModeling == C2DDelayModelingInternal {
return discretizeDelaysAsInternal(disc, p.contInputDelay, p.contOutputDelay, p.dt)
}
return p.applyExternalDelays(disc)
Expand Down Expand Up @@ -120,18 +120,18 @@ func (p c2dPlan) applyExternalDelays(disc *System) (*System, error) {

type d2cPlan struct {
sys *System
method string
method C2DMethod
}

func newD2CPlan(sys *System, method string) (d2cPlan, error) {
func newD2CPlan(sys *System, method C2DMethod) (d2cPlan, error) {
if sys.IsContinuous() {
return d2cPlan{}, fmt.Errorf("D2C: system already continuous: %w", ErrWrongDomain)
}
if method == "" {
method = "zoh"
method = C2DMethodZOH
}
switch method {
case "zoh", "tustin":
case C2DMethodZOH, C2DMethodTustin:
return d2cPlan{sys: sys, method: method}, nil
default:
return d2cPlan{}, fmt.Errorf("D2C: unknown method %q (supported: \"tustin\", \"zoh\")", method)
Expand All @@ -140,9 +140,9 @@ func newD2CPlan(sys *System, method string) (d2cPlan, error) {

func (p d2cPlan) run() (*System, error) {
switch p.method {
case "zoh":
case C2DMethodZOH:
return p.sys.d2cZOH()
case "tustin":
case C2DMethodTustin:
return p.sys.Undiscretize()
default:
panic("unvalidated D2C method")
Expand Down
24 changes: 12 additions & 12 deletions convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (sys *System) Discretize(dt float64) (*System, error) {
}

if sys.HasInternalDelay() {
return discretizeWithInternalDelay(sys, dt, C2DOptions{Method: "tustin"})
return discretizeWithInternalDelay(sys, dt, C2DOptions{Method: C2DMethodTustin})
}

beta := 2.0 / dt
Expand Down Expand Up @@ -147,9 +147,9 @@ func bilinear(sys *System, palpha, pbeta, alpha, beta float64) (*System, error)
}

type C2DOptions struct {
Method string
Method C2DMethod
ThiranOrder int
DelayModeling string
DelayModeling C2DDelayModeling
}

type C2DMethod string
Expand Down Expand Up @@ -404,7 +404,7 @@ func (sys *System) DiscretizeZOH(dt float64) (*System, error) {
}

if sys.HasInternalDelay() {
return discretizeWithInternalDelay(sys, dt, C2DOptions{Method: "zoh"})
return discretizeWithInternalDelay(sys, dt, C2DOptions{Method: C2DMethodZOH})
}

n, m, _ := sys.Dims()
Expand Down Expand Up @@ -483,7 +483,7 @@ func discretizeWithInternalDelay(sys *System, dt float64, opts C2DOptions) (*Sys

method := opts.Method
if method == "" {
method = "zoh"
method = C2DMethodZOH
}

n, _, _ := sys.Dims()
Expand All @@ -499,13 +499,13 @@ func discretizeWithInternalDelay(sys *System, dt float64, opts C2DOptions) (*Sys
var Bd2 *mat.Dense

switch method {
case "zoh":
case C2DMethodZOH:
disc, Bd2, err = discretizeZOHAugmented(sys, dt)
case "tustin":
case C2DMethodTustin:
disc, Bd2, err = discretizeTustinAugmented(sys, dt)
case "foh":
case C2DMethodFOH:
disc, Bd2, err = discretizeFOHAugmented(sys, dt)
case "impulse":
case C2DMethodImpulse:
disc, Bd2, err = discretizeImpulseAugmented(sys, dt)
default:
return nil, fmt.Errorf("DiscretizeWithOpts: unknown method %q", method)
Expand Down Expand Up @@ -695,7 +695,7 @@ func (sys *System) DiscretizeImpulse(dt float64) (*System, error) {
}

if sys.HasInternalDelay() {
return discretizeWithInternalDelay(sys, dt, C2DOptions{Method: "impulse"})
return discretizeWithInternalDelay(sys, dt, C2DOptions{Method: C2DMethodImpulse})
}

n, m, _ := sys.Dims()
Expand Down Expand Up @@ -788,7 +788,7 @@ func (sys *System) DiscretizeFOH(dt float64) (*System, error) {
}

if sys.HasInternalDelay() {
return discretizeWithInternalDelay(sys, dt, C2DOptions{Method: "foh"})
return discretizeWithInternalDelay(sys, dt, C2DOptions{Method: C2DMethodFOH})
}

n, m, p := sys.Dims()
Expand Down Expand Up @@ -1150,7 +1150,7 @@ func matchedGainFallback(num, den Poly, discZeros, discPoles []complex128, dt fl
// axis and A_d − I non-singular (no eigenvalue exactly at 1).
//
// Delay fields are converted back to continuous (τ_c = τ_d · Dt).
func (sys *System) D2C(method string) (*System, error) {
func (sys *System) D2C(method C2DMethod) (*System, error) {
plan, err := newD2CPlan(sys, method)
if err != nil {
return nil, err
Expand Down
Loading
Loading