7 day average daily max

Use this forum to post Vensim related questions.
Post Reply
billh
Member
Posts: 45
Joined: Tue Jan 10, 2017 11:48 pm
Vensim version: DSS

7 day average daily max

Post by billh »

I'm stuck on a "data processing" problem, and I suspect the answer is easier than I've been making it.

My task: calculate the "7 day average daily max" of a variable (auxiliary or level). More than that, I'd like to see each day when that value is greater than a certain (perhaps varying) upper limit. It's probably best if the 7DADM variable works like the output of a sample-and-hold: on each day, it takes on the 7 day average daily max for the appropriate range of 7 days and keeps that value until the start of the next day.

For example, today is December 17. The value for today is found by taking the max data values for each of December 14, ... through December 20, taking the average of those peak values, and then assigning the average of the peaks to December 17 (today). Yes, I know that doesn't sound like a causal system, except that I get to wait until December 21 to report the value for December 17.

I have an auxiliary representing the variable I want to track (it's a subscripted variable, as I'm tracking 5 or 6 variables at the same time), and I've got an integer variable that represents the number of days since the start of the simulation (units for time = hour).

I'll attach one attempt. "Peak Data" obviously shows the peak to date over the entire 4-week horizon. "Peak Daily Data Try 1" shows the same thing, even though I tried to condition both on the change of a day and the data (it obviously only triggers if a new cumulative peak happens at the start of a day). I tried a "Peak Daily Data Try 2", but the best I have come up with so far is

SAMPLE IF TRUE (:NOT: (Day = The Day from an Hour Ago)), SAMPLE IF TRUE (Data > Peak Daily Data Try 2, Data, Data), Data)

which Vensim doesn't like.

Of course, when that works, I need to average over 7 days to calculate 7DADM.

I've searched the archives and the help system, but I haven't seen a way to do that. Any ideas?
Attachments
7DADM.mdl
(2.43 KiB) Downloaded 228 times
tomfid
Administrator
Posts: 3806
Joined: Wed May 24, 2006 4:54 am

Re: 7 day average daily max

Post by tomfid »

Maintaining quantiles over moving windows is generally a hard problem - there are low-memory approximate solutions, but they're complicated.

I think the solution here is probably to create an array dimension for the seven days, and store daily values in it. Then you can retrieve the max value with VMAX, and update the array like a dynamo boxcar train - SHIFT IF TRUE might be easiest, but you could also store a pointer to the "head" element and update that like a level. I'll ponder.
Administrator
Super Administrator
Posts: 4573
Joined: Wed Mar 05, 2003 3:10 am

Re: 7 day average daily max

Post by Administrator »

This one might be easier done in an external function (if that is an option).
Advice to posters seeking help (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391

Units are important!
http://www.bbc.co.uk/news/magazine-27509559
billh
Member
Posts: 45
Joined: Tue Jan 10, 2017 11:48 pm
Vensim version: DSS

Re: 7 day average daily max

Post by billh »

@Administrator: I was beginning to come to that idea doing this outside of Vensim might be a more natural approach, too, although I hadn't considered Vensim's external functions (I've not done any of those yet) but rather putting out the raw data and then letting an external program such as R calculate the 7DADM vector.

While 7DADM sounds like a simple (supplementary) performance metric, it is really part of a performance / cost function for the optimizer (see my recent posting on MPC). That makes it awkward to do in R, I think; I would probably have to give up on Vensim's optimizer and do all the optimization in R with calls from R back to Vensim. That sounds slow to run and perhaps tedious to write with iterative creation of new CIN and COMMAND files and calls back to Vensim.

In theory, the 7DADM is a small part of the overall problem. With the remaining effort required for the dynamic part of the model, I'm a bit reluctant to commit to learning how to do external functions right now. As a result, I'm hoping for Tom's pondering to be successful. Still, I may start experimenting to see if Cygwin's gcc compiler can create the required DLLs (I think it can) or if I need to get a Microsoft compiler.
tomfid
Administrator
Posts: 3806
Joined: Wed May 24, 2006 4:54 am

Re: 7 day average daily max

Post by tomfid »

Actually, it sounds like what you want is weeklyAverage( dailyMax ) - I described weeklyMax( dailyAverage ). Should be similar though.
tomfid
Administrator
Posts: 3806
Joined: Wed May 24, 2006 4:54 am

Re: 7 day average daily max

Post by tomfid »

Try this:
moving max.mdl
(4.77 KiB) Downloaded 293 times
billh
Member
Posts: 45
Joined: Tue Jan 10, 2017 11:48 pm
Vensim version: DSS

Re: 7 day average daily max

Post by billh »

Thanks, Tom. It looks promising. Let me see if I can switch it to weeklyAverage(dailyMax) successfully.
billh
Member
Posts: 45
Joined: Tue Jan 10, 2017 11:48 pm
Vensim version: DSS

Re: 7 day average daily max

Post by billh »

That was close, Tom, and a big help. I made a few modifications that I think do what I need:
  • I changed Daily Max to sample the result one TIME STEP earlier.
  • I sampled record at midnight to get the result before it was cleared for a new day.
  • I sampled Average Daily Max at midnight to get 7DADM, the value I want.
Given that we associate 7DADM with the middle of the seven numbers, I'll probably have to create a delayed Time stream or otherwise compute the association between 7DADM and date.

I left your Max Daily Average computation in the attached example, although I don't need that anymore.
Attachments
moving max testbed.mdl
(5.63 KiB) Downloaded 203 times
billh
Member
Posts: 45
Joined: Tue Jan 10, 2017 11:48 pm
Vensim version: DSS

Re: 7 day average daily max

Post by billh »

Just a short follow-up note: the initial value may need to be customized for a particular application. In my case, the initial value of "Value" wasn't 0, and so I needed to initialize it to the equivalent of

Code: Select all

Value*Hours per Day*Days per Week*One Week
.
Post Reply