void WP::maximize_hourly_pattern(){ const Mat &count(suf()->count()); const Mat &exposure(suf()->exposure()); const Vec &delta(day_of_week_pattern()); double lambda = average_daily_rate(); Vec eta_weekend(24, 0.0); Vec eta_weekday(24, 0.0); for(int h = 0; h < 24; ++h){ double total_count_weekday = 0; double total_exposure_weekday = 0; double total_count_weekend = 0; double total_exposure_weekend = 0; double *total_count; double *total_exposure; for(int d = 0; d < 7; ++d){ if(d==Sat || d==Sun){ total_exposure = &total_exposure_weekend; total_count = &total_count_weekend; }else{ total_exposure = &total_exposure_weekday; total_count = &total_count_weekday; } *total_count += count(d, h); *total_exposure += exposure(d, h) * lambda * delta[d]; } eta_weekend[h] = total_count_weekend / total_exposure_weekend; eta_weekday[h] = total_count_weekday / total_exposure_weekday; } set_weekday_hourly_pattern(eta_weekday); set_weekend_hourly_pattern(eta_weekend); }
double WP::expected_number_of_events(const DateTime &t0, const DateTime &t1)const{ double duration = t1 - t0; int weeks = lround(floor(duration / 7)); double lambda = average_daily_rate(); double ans = 7 * weeks * lambda; duration -= 7*weeks; const double one_hour = DateTime::hours_to_days(1.0); double time_to_next_hour = t0.time_to_next_hour(); if(time_to_next_hour == 0) time_to_next_hour = one_hour; DayNames day = t0.date().day_of_week(); int hour = t0.hour(); double dt = std::min<double>(time_to_next_hour, duration); while(duration > 0){ ans += dt * event_rate(day, hour); duration -= dt; ++hour; if(hour == 24){ hour = 0; day = next(day); } dt = std::min<double>(one_hour, duration); } return ans; }
void WP::mle() { double old_loglike = loglike( concatenate_params(average_daily_rate(), day_of_week_pattern(), weekday_hourly_pattern(), weekend_hourly_pattern())); double dloglike = 1.0; while (dloglike > 1e-5) { maximize_average_daily_rate(); maximize_daily_pattern(); maximize_hourly_pattern(); double new_loglike = loglike(concatenate_params( average_daily_rate(), day_of_week_pattern(), weekday_hourly_pattern(), weekend_hourly_pattern())); dloglike = new_loglike - old_loglike; old_loglike = new_loglike; } }
void WP::maximize_daily_pattern(){ const Mat &count(suf()->count()); const Mat &exposure(suf()->exposure()); Vec delta(7); double lambda = average_daily_rate(); for(int d = 0; d < 7; ++d){ const Vec &eta(hourly_pattern(d)); double total_count = 0; double total_exposure = 0; for(int h = 0; h < 24; ++h){ total_count += count(d, h); total_exposure += exposure(d, h) * lambda * eta[h]; } delta[d] = total_count / total_exposure; } set_day_of_week_pattern(delta); // TODO(stevescott): check that this enforces sum(delta) == 7 }
double WP::event_rate(const DayNames day, int hour)const{ return average_daily_rate() * day_of_week_pattern()[day] * hourly_pattern(day)[hour]; }