Я использую 64-битный Matlab с 32 г ОЗУ (просто так, чтобы вы знали).
У меня есть файл (вектор) из 1,3 миллиона чисел (целых). Я хочу сделать еще один вектор той же длины, где каждая точка является средневзвешенным значением всего первого вектора, взвешенным по обратному расстоянию от этой позиции (на самом деле это позиция ^-0,1, а не ^-1, но для примера) . Я не могу использовать функцию «фильтр» Matlab, потому что она может только усреднять вещи до текущей точки, верно? Чтобы объяснить более четко, вот пример из 3 элементов
data = [ 2 6 9 ]
weights = [ 1 1/2 1/3; 1/2 1 1/2; 1/3 1/2 1 ]
results=data*weights= [ 8 11.5 12.666 ]
i.e.
8 = 2*1 + 6*1/2 + 9*1/3
11.5 = 2*1/2 + 6*1 + 9*1/2
12.666 = 2*1/3 + 6*1/2 + 9*1
Таким образом, каждая точка в новом векторе является средневзвешенным значением всего первого вектора, взвешенным на 1/(расстояние от этой позиции + 1).
Я мог бы просто переделать вектор весов для каждой точки, а затем поэлементно вычислить вектор результатов, но для этого требуется 1,3 миллиона итераций цикла for, каждая из которых содержит 1,3 миллиона умножений. Я бы предпочел использовать прямое матричное умножение, умножая 1x1,3 мила на 1,3 мила x 1,3 мила, что теоретически работает, но я не могу загрузить матрицу такого размера.
Затем я пытаюсь создать матрицу с помощью сценария оболочки и проиндексировать ее в Matlab, чтобы одновременно вызывался только соответствующий столбец матрицы, но это также занимает очень много времени.
Мне не нужно делать это в Matlab, поэтому любые советы людей по поводу использования таких больших чисел и получения средних значений будут оценены. Поскольку я использую вес ^-0,1, а не ^-1, он не падает так быстро - миллионный балл по-прежнему имеет вес 0,25 по сравнению с исходным весом баллов 1, поэтому я не могу просто сократить его прочь, как он становится большим либо.
Надеюсь, это было достаточно ясно?
Вот код ответа ниже (так что его можно отформатировать?):
data = load('/Users/mmanary/Documents/test/insertion.txt');
data=data.';
total=length(data);
x=1:total;
datapad=[zeros(1,total) data];
weights = ([(total+1):-1:2 1:total]).^(-.4);
weights = weights/sum(weights);
Fdata = fft(datapad);
Fweights = fft(weights);
Fresults = Fdata .* Fweights;
results = ifft(Fresults);
results = results(1:total);
plot(x,results)