Две версии одного и того же кода возвращают разные результаты

#matlab #signal-processing #state-space #transfer-function

#matlab #обработка сигналов #пространство состояний #transfer-функция

Вопрос:

Я ожидаю получить одинаковые результаты при сжатии этих двух строк кода MATLAB в одну, но я этого не делаю!

Код в 2 строки:

 [b,a]= butter(2,[0.4 0.6]) % Transfer function coefficients of the filter  
[A,B,C,D] = tf2ss(b,a)  % State-space representation of the filter
  

Код в 1 строку:

 [A,B,C,D]= butter(2,[0.4 0.6]) % State-space representation of the filter
  

масло :

  • возвращает, transfer function coefficients когда b,a выводятся

  • возвращает, state-space matrices когда A,B,C,D выводятся

tf2ss :

  • Преобразовать transfer function filter parameters в state-space форму

Комментарии:

1. И что происходит при запуске [A,B,C,D] = tf2ss(butter(2,[0.4 0.6])) ?

2. для B я получаю [1;0;0;0] для первого кода и [0.58;0.19;-0.58;-0.19] для второго

3. @famansour какая у вас версия MATLAB? Я могу воспроизвести ваши результаты в 2018b

4. @Karls это недопустимый код.

5. @AnderBiguri моя версия — R2018b!

Ответ №1:

Два получаемых вами представления в пространстве состояний допустимы. Представление фильтра в пространстве состояний не уникально. Две дают одинаковые результаты при применении к входному сигналу.

Вероятная причина, по которой два представления пространства состояний не совпадают, заключается в том, что они получены по разным маршрутам:

  • В двухэтапной версии вашего кода вы получаете представление передаточной функции, а затем преобразуете в пространство состояний, используя tf2ss .

  • В одноэтапной версии butter внутренне получает представление нулевого полюса, а затем преобразует в пространство состояний, используя zp2ss (по крайней мере, это то, что он делает в R2018b).

Вот проверка того, что они действительно эквивалентны.

 [b,a]= butter(2,[0.4 0.6]);
[A2,B2,C2,D2] = tf2ss(b,a); % 2 steps

[A1,B1,C1,D1]= butter(2,[0.4 0.6]); % 1 step
  

Определите входной сигнал:

 x = rand(1,100);
  

Создайте два объекта фильтра из их представлений в пространстве состояний:

 Hd2 = dfilt.statespace(A2,B2,C2,D2);
Hd1 = dfilt.statespace(A1,B1,C1,D1);
  

Получаем два выходных:

 y2 = Hd2.filter(x);
y1 = Hd1.filter(x);
  

Сравните результаты. Разница порядка eps , то есть незначительная:

 max(abs(y1))
max(abs(y2))
max(abs(y1-y2))

ans =
   0.348561524872161
ans =
   0.348561524872160
ans =
     8.153200337090993e-16
  

Вы также можете проверить, что оба представления пространства состояний дают одинаковое представление передаточной функции:

 [b1,a1] = ss2tf(A1,B1,C1,D1)
[b2,a2] = ss2tf(A2,B2,C2,D2)

b1 =
0.067455273889072   0.000000000000000  -0.134910547778144   0.000000000000000   0.067455273889072
a1 =
1.000000000000000  -0.000000000000001   1.142980502539900  -0.000000000000001   0.412801598096187
b2 =
0.067455273889072   0.000000000000000  -0.134910547778144  -0.000000000000000   0.067455273889072
a2 =
1.000000000000000  -0.000000000000001   1.142980502539899  -0.000000000000002   0.412801598096187
  

Ответ №2:

На самом деле, код строки 1 следует изменить на приведенный ниже.

 [A,B,C,D]= tf2ss(butter(2,[0.4 0.6]));
  

Но это также не даст желаемого ответа, поскольку trf2ss требовал двух входных данных в качестве входных параметров. Приведенный выше код выдает только один входной сигнал, который представляет собой вектор с двумя значениями. В Matlab векторы являются отдельным типом переменных, следовательно, иногда они не будут работать так, как мы ожидаем.