Переставить функцию распределения Matlab

У меня есть следующие данные, представляющие значения за 12-месячный период:

1. 0
2. 253
3. 168
4. 323
5. 556
6. 470
7. 225
8. 445
9. 98
10. 114
11. 381
12. 187

Как я могу сгладить эту линию вперед?

Мне нужно, чтобы при последовательном просмотре списка любое значение, превышающее среднее (268), было равномерно распределено между оставшимися месяцами, но таким образом, чтобы получалась как можно более гладкая линия. Мне нужно пройти с января по декабрь по порядку. Заглядывая вперед, я хочу сместить любые излишки (пики) в предстоящие месяцы, чтобы распределение было как можно более равномерным (таким, чтобы сначала заполнялись впадины). Таким образом, проблема состоит в том, чтобы в каждой точке определить, каков «избыток» для этого месяца, и, во-вторых, как распределить его между еще предстоящими месяцами.

я использовал

p = find(Diff>0);
n = find(Diff<=0);
POS = Diff(p,1);
NEG = Diff(n,1)

чтобы увидеть, где существует дефицит / превышение по сравнению со средним значением, но не знаете, как построить код, который будет перераспределять вперед, сначала выделяя «впадины» распределения. Аналогия в том, что эти числа представляют количество урожая, и я должен раздать урожай населению. Как мне перераспределить поступающий урожай в течение года, чтобы свести к минимуму избыточное/недостаточное предложение? Я, очевидно, не могу отдать что-либо, что я не получил в конкретном месяце, если я не сохранил какой-то урожай за предыдущие месяцы. например Я начинаю в январе и вижу, что не могу ничего дать месяцам с февраля по декабрь, поэтому значение для января равно 0. В феврале у меня 253 — мне скорректировать 253 вниз или выдать все? Если да, то насколько? и куда мне перераспределить излишки, которые я обрезаю с марта по декабрь? И т.д. и т.п. Как мне это сделать, чтобы получить как можно более гладкое (равномерное) распределение? Для любого месяца новое значение, присвоенное этому месяцу, не может превышать текущее значение. Сумма за 12 месяцев должна быть равна до и после сглаживания. В качестве первой позиции январь всегда будет равен 0.


person Mary    schedule 21.02.2014    source источник
comment
У вас есть набор инструментов для подгонки кривой? Возможно, вы захотите изучить функцию smooth.   -  person Rody Oldenhuis    schedule 21.02.2014


Ответы (3)


Простая версия, просто перебирает и, если следующий месяц меньше, чем текущий месяц, передает значение вперед, чтобы уравнять их.

for n = 1:11
    if y(n)>y(n+1);
       y(n:n+1)=(y(n)+y(n+1))/2;
    end
end

введите здесь описание изображения

person nkjt    schedule 21.02.2014
comment
Спасибо nkjt. Как мне заставить это повторяться до тех пор, пока сглаживание не станет возможным? Я думаю, что это дало бы мне дистрибутив, в котором я нуждался. - person Mary; 21.02.2014
comment
Вы можете просто добавить вокруг него цикл while: while any(diff(y)<-0.01). (не <0 из-за проблем с плавающей запятой). - person nkjt; 21.02.2014
comment
Спасибо nkjt. Это идеально. Прекрасно работает. - person Mary; 24.02.2014

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

y = [ 0 253 168 323 556 470 225 445 98 114 381 187 ].';
x = (0:numel(y)-1).';

A = [ones(size(x)) x];

plot(...
    x,       y, 'b.',...
    x, A*(A\y), 'r')
xlabel('Month'), ylabel('Data')
legend('original data', 'fit')

введите здесь описание изображения

person Rody Oldenhuis    schedule 21.02.2014
comment
Спасибо, Роди. Я думаю, что решающей частью является то, что для любого месяца новое значение, присвоенное этому месяцу, не может превышать текущее значение, поэтому в противном случае решением будет установка прямой линии. - person Mary; 21.02.2014

Я тоже не совсем понимаю, что вы хотите, может быть, что-то простое?

year= [0 253 168 323 556 470 225 445 98 114 381 187];
m= mean(year);
total_before = sum(year)
linear_year = linspace(0,m*2,12);
toal_after= sum(linear_year)

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

person ben    schedule 21.02.2014
comment
Спасибо, Бен. Мое намерение состоит в том, чтобы значения были как можно ближе друг к другу, чтобы обеспечить как можно более равномерное распределение. Это дает возрастающее значение от месяца к месяцу. Я снова отредактирую вопрос, чтобы уточнить. - person Mary; 21.02.2014