Как найти параметры N-кратной свертки в Matlab? - PullRequest
0 голосов
/ 08 октября 2019

У меня есть интересная проблема, которая заключается в свертывании K векторов друг с другом. Все элементы векторов К-1 известны. Например:

v1,v2,...vk,...,vK

и все элементы всех векторов, кроме vk, известны, и только два соседних элемента vk являются параметрами. Например:

v1=[p1 p2 4 5];
v2=[1 4 2 3 2 1];
v3=[1 1 1 2];
v4=[2 2 1 3 4];

Вопрос заключается в следующем:

Пусть '' v '' будет сверткой v1, v2, v3, v4, т.е. (при условии, что conv работает символически)

v=conv(v1,v2); 
v=conv(v,v3);
v=conv(v,v4);

Тогда каждый элемент v можно записать следующим образом:

v(n)=a0(n)+a1(n)*p1+a2(n)*p2

Пример: пусть есть два вектора

v1=[1, 1,1]
v2=[p1,p2,1]

Тогда

v=[p1,p1+p2,p1+p2+1,p2+1,1]

В результате мы имеем

a0=[0,0,1,1,1], a1=[1,1,1,0,0], a2=[0,1,1,1,0]

Таким образом, a0 - константы каждого элемента v, a1 - мультипликаторы p1, a2 - мультипликаторы p2

Я хочу иметь эффективный алгоритм, который может вычислять a0 (n), a1 (n) и a2 (n). В следующей итерации у меня смещение параметров, но та же проблема. После одной смены у меня будет

v1=[3 p1 p2 5];
v2=[1 4 2 3 2 1];
v3=[1 1 1 2];
v4=[2 2 1 3 4];

после двух смен:

v1=[3 1 p1 p2];
v2=[1 4 2 3 2 1];
v3=[1 1 2 2];
v4=[2 2 1 3 4];

после трех смен:

v1=[3 1 4 5];
v2=[p1 p2 2 3 2 1];
v3=[1 1 1 2];
v4=[2 2 1 3 4];

это продолжается до

v1=[3 1 4 5];
v2=[1 4 2 3 2 1];
v3=[1 1 1 2];
v4=[2 2 1 p1 p2];

на каждой итерации мне нужно получить a0 (n), a1 (n) и a2 (n). Всего 15 итераций, и на каждой итерации я получу 3 вектора. Следовательно, в общей сложности мне нужно получить матрицу, которая имеет 15 строк и столбцы 3xlength (a0).

 i=1 -> a0_i,a1_i,a2_i, for i=1,...,15.

Моя идея состояла в том, чтобы определить все элементы всех векторов как параметры p1, ... pK. Затем сверните их всех один раз символически. Это дает v (p1, ..., pN). Затем на каждой итерации, за исключением двух интересующих соседних параметров, я могу указать все остальные значения и, например, оценить v:

v(p1,p2,1,3 4,....,2)

, после этого я могу проверять каждыйэлемент v для

v (n) = a0 (n) + a1 (n) * p1 + a2 (n) * p2

и извлечение a0 (n), a1 (n)и a2 (n).

Прежде всего, я не уверен, эффективно это или нет. Потому что на каждой итерации я должен оценивать всю символическую вещь v (p1, p2,1,3 4, ...., 2), что может быть ненужным, так как у меня есть простая итерация параметров. Во-вторых, я не знаю, как можно сделать символическую свертку векторов K символом, или это хорошая или плохая идея.

Другая идея состоит в том, чтобы видеть, что кроме одного вектора, все векторы не содержатлюбой параметр. Таким образом, можно сначала свернуть эти векторы с функцией conv и получить v *. Тогда a1 (n) и a2 (n) кажутся просто элементами v *, просто один сдвинут по отношению к другому. Вот что я сделал на бумаге в качестве примера (p1, p2 - параметры, p3, p4 известны, a1, .., a13 - результат свертки известных векторов):

enter image description here

Этот подход кажется более ясным, но на каждой итерации нужно сворачивать векторы K-1. Следовательно, кажется, что нужно сделать много вычислений, и, вероятно, многие вычисления совпадают с предыдущей итерацией. Поэтому, мне кажется, что это не так эффективно.

Вопрос: Учитывая K произвольных векторов, каждый из которых имеет произвольную длину, как можно эффективно рассчитать вышеупомянутые векторы?

1 Ответ

2 голосов
/ 08 октября 2019

conv не поддерживают символическую математику. Поэтому мы должны использовать другой метод.

Одним из решений может быть разделение вектора, содержащего два параметра, на три части.

Если у нас есть v1 = [p1 p2 4 5]

, мы могли быcreate v1_split:

 v1_split = [1 0 0 0;   %p1
             0 1 0 0;   %p2
             0 0 4 5];  

Тогда мы можем рекурсивно использовать conv2 для решения проблемы:

sol = conv2(conv2(conv2(v1_split,v2),v3),v4)

Он выведет вектор 3xlength(a), где первая строка a0, второй a1 и последний a2.

Конечно, вместо использования conv2(conv2(conv2(... мы можем использовать рекурсивную функцию:

function r = rconv2(x)
   if length(x) == 1 
      r = x{1};
   else
     r = conv2(x{1},rconv2(x(2:end)));
   end
 end

Так что теперь мы можем использовать что-то вроде:

%input vector for step 1
v ={[1 0 0 0; 0 1 0 0; 0 0 4 5],[1 4 2 3 2 1],[1 1 1 2],[2 2 1 3 4]} %{v1_split,v2,v3,v4}

%recursive convolution
sol = rconv2(v)

РЕДАКТИРОВАТЬ , улучшение согласно комментарию @Seyhmus:

%Initial cell array of vectors
v ={[1 3 4 5],[1 4 2 3 2 1],[1 1 1 2],[2 2 1 3 4]} %{v1,v2,v3,v4}

%recursive convolution (need to be run only once)
allconv = rconv2(v)

%Example for step 1
%Deconv allconv with v{1}
dec = deconv(allconv,v{1})

%Compute v1_split
...

%Getting the solution using 2D convolution with v1_split:
sol = conv2(dec,v1_split)
...