#matlab #computation
#matlab #вычисление
Вопрос:
Вступление: Мне нужно найти наибольшие/наименьшие возможные отклонения от среднего в некоторых заданных векторах Matlab. Проблема в том, что из-за больших размеров задействованных массивов я не могу явно построить такие векторы. Поэтому я задаюсь вопросом, есть ли более разумный способ действовать. Ниже я кратко излагаю процедуру, которую я бы реализовал, если бы не было ограничений по памяти, а затем задаю свой вопрос.
(1) Рассмотрим 28 матриц в Matlab A{1},..., A{28}
. Для каждого j=1,...,28
A{j}
из них есть 4 столбца. Количество строк A{j}
может быть разным j=1,..., 28
и хранится в векторе r
.
clear rng default A=cell(28,1); r=randi(10000,28,1) 10000; (x1 for j=1:28 A{j}=randn(r(j),4); %r(j)x4 end
(2) Для каждого j=1,...,28
пусть b{j}
будет r(j) x 1
вектор , полученный путем суммирования первых двух строк A{j}
и вычитания последних двух строк A{j}
:
b=cell(28,1); for j=1:28 b{j}=A{j}(:,1) A{j}(:,2)-A{j}(:,3)-A{j}(:,4); %r(j)x1 end
(3) Пусть B
R x 28
матрица, полученная в виде 28-D сетки из векторов b{1},...,b{28}
:
%[ca, cb, cc, cd, ce, ...] = ndgrid(b{1}, b{2}, b{3} , ..., b{28}); %B(:,1)=ca(:); %B(:,2)=cb(:); %... %B(:,28)=...; c=cell(28,1); [c{:}]=ndgrid(b{:}); c=cellfun(@(x)x(:),c,'UniformOutput',false); B=[c{:}];
Приношу извинения за неполный код. Как вы можете себе представить, на этом этапе у меня возникают проблемы, как описано ниже.
(4) Для каждой строки B
я вычисляю разницу между такой строкой и ее средним значением и сохраняю результаты в R x 28
матрице D
:
%R=size(B,1); %D=zeros(R,28); %for t=1:R % D(t,:)=B(t,:)-mean(B(t,:)); %end D=B-mean(B,2);
(5) Для каждого j=1,...,28
я вычисляю минимальное и максимальное значение D(:,j)
и сохраняю его в матрице F
F=zeros(2,28); for j=1:28 F(1,j)=min(D(:,j)); F(2,j)=max(D(:,j)); end
Вопрос: F
это та матрица, которую я хотел бы построить. Однако шаг (3) неосуществим из-за большого r(1),..., r(28)
. Даже петля заняла бы целую вечность. Следовательно, я спрашиваю: есть ли более разумный способ построения F
, который избавляет меня от явного получения B
?
Ответ №1:
Вот быстрое решение (без использования ndgrid
):
F = zeros(2,28); mx = cellfun(@max,b) mn = cellfun(@min,b) for k = 1: 28 F(1,k) = min(b{k}-(b{k} sum(mx)-mx(k))/28); F(2,k) = max(b{k}-(b{k} sum(mn)-mn(k))/28); end
Объяснение:
Предположим, что матрица B
:
B = 1 3 5 1 3 6 1 4 5 1 4 6 2 3 5 2 3 6 2 4 5 2 4 6
Итак, мы хотим вычислить MinB=min(B-mean(B,2))
. Есть 3 колонки и MinB = [MinB(1) MinB(2) MinB(3)]
.
Мы начинаем вычисления для первого столбца или MinB(1)
.
Мы можем разделить B
матрицу на основе значений первого столбца :
B1= 1 3 5 1 3 6 1 4 5 1 4 6 B2= 2 3 5 2 3 6 2 4 5 2 4 6
так MinB(1)
можно вычислить как min(MinB1(1), MinB2(1))
.
И MinB1(1)
может быть написано так: MinB1(1) = min(1 - mean(B1, 2))
.
Эквивалентно это может быть написано как: MinB1(1) = 1 - max(mean(B1, 2))
.
Мы можем написать mean
так sum
: max(mean(B1, 2))== gt; max(sum(B1,2)/3)
.
Рассмотрим все комбинации чисел. Какая комбинация имеет максимум mean
или максимум sum
? комбинация, содержащая максимум каждого вектора b
или mx=[2 4 6]
. Поэтому мы использовали cellfun
для вычисления max
для каждого вектора b
. Таким образом, нам не нужно вычислять среднее значение всех комбинаций, нам просто нужно вычислить max
для каждого вектора b
, а затем вычислить среднее значение этого вектора. Это ключевой момент для приведенного выше решения, и max
его также можно вычислить таким образом.
Комментарии:
1. Я на самом деле вычислил среднее значение -gt; gt;
sum/28
. Я должен дать объяснение.2. Спасибо за это объяснение! Теперь в этом есть большой смысл.