2015-07-27 5 views
0

У меня странное поведение в попытке кодировать NORMINV() в формате C. В качестве norminv() я принял функцию this от математика, это, вероятно, правильно, так как я также попробовали разные с тем же результатом. Вот код:Возрастающее среднее отклонение с увеличением размера выборки в Excel NORMINV()

double calculate_probability(double x0, double x1) 
{ 
    return x0 + (x1 - x0) * rand()/((double)RAND_MAX); 
} 

int main() { 

long double probability = 0.0; 
long double mean = 0.0; 
long double stddev = 0.001; 
long double change_percentage = 0.0; 
long double current_price = 100.0; 
srand(time(0)); 
int runs = 0; 
long double prob_sum = 0.0; 
long double price_sum = 0.0; 

while (runs < 100000) 
{ 
    probability = calculate_probability(0.00001, 0.99999); 
    change_percentage = mean + stddev * norminv(probability); //norminv(p, mu, sigma) = mu + sigma * norminv(p) 
    current_price = current_price * (1.0 + change_percentage); 
    runs++; 
    prob_sum += probability; 
    price_sum += current_price; 
} 
printf("\n\n%f %f\n", price_sum/runs, prob_sum/runs); 
return 0; 
} 

Теперь я хочу, чтобы имитировать NORMINV в Excel (RAND(), 0, 0.001), где рандов() является значение> 0 и < 1, 0 является средним значением и 0,001 будет стандартный отклонение.

С 1000 значений выглядит хорошо:

100,729780 0,501135

С 10000 значений она распространяется слишком много:

107,781909 0,502301

И с 100000 значений иногда распространяется еще больше:

87.876500 0.498738

Теперь я не знаю, почему это происходит. Мое предположение состоит в том, что генератор случайных чисел также должен быть нормально распределен. В моем случае probability рассчитывается отлично, так как среднее значение составляет почти 0,5 все время. Поэтому я не знаю, почему среднее отклонение возрастает. Может кто-нибудь мне помочь?

+1

Почему это распространяется «слишком много»? С помощью крошечного stddev вы используете то, что вы делаете, очень близко к аддитивному случайному блужданию с шагами со стандартным отклонением 0,1 (0,1 == 100,0 * 0,001). Если вы предпримете N шагов, я ожидаю, что окончательное значение будет иметь стандартное отклонение sqrt (N) * 0,1. Если что-нибудь, ответ на 1000 шагов выглядит удивительно близко к 100. –

ответ

1

Вы делаете что-то вдоль линий random walk, за исключением того, что ваши движения имеют мультипликативный масштабный коэффициент, а не аддитивные шаги.

Рассмотрите два последовательных шага, первый из которых дает 20% -ный уровень инфляции, второй - с дефляцией 20%. Начиная с базовой линии 100, после первого шага вам будет 120. Если вы сейчас возьмете 80% из 120, вы получите 96, а не оригинал 100. Другими словами, кажущиеся симметричными масштабирующими факторами на самом деле не симметричны. Хотя ваши коэффициенты масштабирования являются случайными, они все еще создаются симметрично вокруг 1, поэтому я не удивлен, увидев, что отложения накапливаются.

+0

Можете ли вы объяснить мне, где проблема в коде? Является ли norminv() само? calculate_probability() должно быть нормально, не так ли? Мне интересно, потому что в Excel нет такой вещи, как среднее отклонение, и на самом деле я делаю то же самое. Поскольку change_percentage отрицателен в 50% случаев, я не понимаю, что вы имеете в виду. – JohnnyFromBF

+0

Проблема заключается в том, что '100 * (1 + 0,2) * (1 - 0,2) = 96! = 100'. Когда «симметричные» отклонения добавляются или вычитаются в масштабный коэффициент и умножаются, они не являются симметричными. Два отклонения, которые вы, по-видимому, считали симметричными и вернули бы вас до ста, не балансируйте. – pjs

+0

Хорошо, я понимаю, что вы имеете в виду, просто задайтесь вопросом, как мой код отличается от реализации norminv() в excel, см. Здесь [https://www.youtube.com/watch?v=1ot7HOI3wQE). – JohnnyFromBF