# ControlSystemIdentification

**URL:** <https://discourse.julialang.org/t/controlsystemidentification/95794>\
**Category:** Modelling & Simulations\
**Tags:** question, package, controlsystems\
**Created:** [March 9, 2023, 12:41pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794 "2023-03-09T12:41:19Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 9, 2023, 12:41pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/1 "2023-03-09T12:41:20Z")

</div>

Hello,  
I am trying out the package ControlSystemIdentification.

It looks very good, each step very well explained!

One question: In the example [Temperature control · ControlSystemIdentification Documentation](https://baggepinnen.github.io/ControlSystemIdentification.jl/stable/examples/temp/) you are using a chirp signal for identifying the system.

Isn’t it more common to use a pseudo-random sequence? How could I do the same task using a pseudo-random sequence?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [March 9, 2023, 1:17pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/2 "2023-03-09T13:17:37Z")

</div>

Thanks 🙂

> [@ufechner7](#):
>
> Isn’t it more common to use a pseudo-random sequence?

It depends on whom you’re asking. A PRBS signal works fine for the heating element in the example, but it would be a poor choice for anything mechanical. I usually prefer chirp signals for a lot of reasons.

1. It’s easy to select the frequency content
2. You can “see” the frequency response in the live data during the experiment, and abort early if you determine that the amplitude is too high or too low etc. This is particularly effective for mechanical systems.

> [@ufechner7](#):
>
> How could I do the same task using a pseudo-random sequence?

The input is just an array, you can let the array represent any signal. A PRBS signal can be obtained by `sign.(randn(1, 100))`, possibly with some filtering applied before the `sign` to shape the frequency contents.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 9, 2023, 5:18pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/3 "2023-03-09T17:18:02Z")

</div>

Extra question regarding the given example: Why are you using an adjoint for u?

```julia
u = sign.(sin.((0:0.01:20) .^ 2))' # sample a control input for identification

```

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [March 9, 2023, 5:26pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/4 "2023-03-09T17:26:03Z")

</div>

Time is in the second dimension by the convention of the JuliaControl ecosystem.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 9, 2023, 5:28pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/5 "2023-03-09T17:28:49Z")

</div>

```julia
julia> data.u
1×2001 adjoint(::Vector{Float64}) with eltype Float64:
 0.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 … 1.0 1.0 1.0 -1.0 -1.0 -1.0

julia> data.y
1×2001 Matrix{Float64}:
 0.188729 0.0570035 0.158437 0.118835 … 0.337283 0.171856 0.09693

```

u is an adjoint and y a Matrix… Why is not both a vector?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 9, 2023, 5:29pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/6 "2023-03-09T17:29:45Z")

</div>

> [@baggepinnen](#):
>
> convention of the JuliaControl ecosystem

Where is this convention defined or explained?

Here you do not mention any adjoint: [Identification data · ControlSystemIdentification Documentation](https://baggepinnen.github.io/ControlSystemIdentification.jl/stable/iddata/) . Is it important to use an adjoint for u?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [March 9, 2023, 5:44pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/7 "2023-03-09T17:44:14Z")

</div>

> [@ufechner7](#):
>
> Where is this convention defined or explained?

In the docs for [`iddata`](https://baggepinnen.github.io/ControlSystemIdentification.jl/dev/iddata/#ControlSystemIdentification.iddata)  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/7/1/71cd45a82c34ece94c5bdb9bbe7447ca138daf5a.png)

> If the time-series are multivariate, time is in the _last_ dimension.

> [@ufechner7](#):
>
> Is it important to use an adjoint for u?

No, in this case, you could have used `transpose, reshape` or `permutedims` as well.

> [@ufechner7](#):
>
> u is an adjoint and y a Matrix… Why is not both a vector?

It doesn’t matter for the internals of ControlSystemIdentification as long as the dimensions are correct.

* * *

In fact, this piece of information is available in a lot of places throughout the documentation

In the docs for [`lsim`](https://juliacontrol.github.io/ControlSystems.jl/dev/lib/timefreqresponse/#ControlSystemsBase.lsim-Tuple%7BAbstractStateSpace,%20AbstractVecOrMat,%20AbstractVector%7D):

 ![image](https://global.discourse-cdn.com/julialang/original/3X/e/b/ebf3866489e7a1618e8b668bf20f0da0fa2d82ad.png)  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/c/4/c4d3aa222047b5876ed6b69d253a6ed531ba3961.png)

At the page [Noteworthy Differences from other Languages](https://juliacontrol.github.io/ControlSystems.jl/dev/man/differences/#Noteworthy-Differences-from-other-Languages):

 ![image](https://global.discourse-cdn.com/julialang/original/3X/8/3/83ad50fefd00c318872052030441d4c1069850fe.png)

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 9, 2023, 5:57pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/8 "2023-03-09T17:57:19Z")

</div>

Well, I still do not understand why u has to be an adjoint… You say time has to be in the second dimension, but there is no time information in u …  
u is a vector with only one dimension…

I am only electrical engineer and no mathematician. Some more explanation for simple engineers would be nice…

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [March 9, 2023, 6:02pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/9 "2023-03-09T18:02:35Z")

</div>

![image](https://global.discourse-cdn.com/julialang/original/3X/5/1/51cbd25c162c3201cd831f158eabff1d90c2ef08.png)

this is interpreted as an input array with one input signal of 3 time steps.

> [@ufechner7](#):
>
> I still do not understand why u has to be an adjoint

It does not have to be, it just has to have the size `(num_input, num_timepoints)`

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 9, 2023, 6:05pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/10 "2023-03-09T18:05:59Z")

</div>

> [@baggepinnen](#):
>
> It does not have to be

But why do you make it an adjoint in the example if this is not required? That is confusing.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [March 9, 2023, 6:12pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/11 "2023-03-09T18:12:09Z")

</div>

I give it the right shape, as described by the documentation. The fact that Julia wraps it in an Adjoint wrapper is completely irrelevant. If you don’t want to use an adjoint, don’t, if you do, that’s also fine. I don’t see what the problem is here, the example works and produces the intended result.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 9, 2023, 6:32pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/12 "2023-03-09T18:32:58Z")

</div>

So you would say that in a 2 dimensional matrix rows are the first dimension and columns the second dimension?  
OK, you say it works, but I want to understand what you are doing and why.

I found this information online:  
" You take the number of rows from the first matrix (2) to find the first dimension, and **the number of columns from the second matrix** (2) to find the second dimension."

OK, taking this into account the vector u where each element differs in time should be a row vector. A default vector in Julia is a column vector, therefore you make it an adjoint.

OK, I start understand why you are doing this. 🙂  
I still not understand the difference between and adjoint and a row vector, but that would be a different topic.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [March 10, 2023, 1:18pm UTC](https://discourse.julialang.org/t/controlsystemidentification/95794/13 "2023-03-10T13:18:07Z")

</div>

Created a pull request: [Update types.jl by ufechner7 · Pull Request #120 · baggepinnen/ControlSystemIdentification.jl · GitHub](https://github.com/baggepinnen/ControlSystemIdentification.jl/pull/120)
