Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
ada02e3
Add types and arithmetic functions
lrennels Oct 16, 2019
362b769
Add getindex methods
lrennels Oct 16, 2019
14e7045
Export types; Add deprecation warnings; Fix constructor; Add tests
lrennels Oct 17, 2019
57ffc08
Fix TimstepValue constructor
lrennels Oct 17, 2019
7219739
Fix TimstepValue constructor
lrennels Oct 17, 2019
c3b6b87
Fix type parameterization of TimestepValue
lrennels Oct 17, 2019
a59ed18
Add index error check function
lrennels Oct 17, 2019
19b2b64
Add tests and corner case errors
lrennels Oct 17, 2019
39edfe0
Deprecate setindex with an integer
lrennels Oct 17, 2019
e11d700
Work on _param_indices and set_param! for TimeIndex
lrennels Oct 18, 2019
e12ea67
Merge branch 'master' into timestepindex
lrennels Oct 18, 2019
6daac9e
Enhance warning message
lrennels Oct 18, 2019
5b7deb9
Merge master
lrennels Oct 23, 2019
502d77c
Merge branch 'master' into timestepindex
lrennels Oct 29, 2019
6a50856
Fix tests
lrennels Oct 29, 2019
1a5d4c5
Add setindex methods for TimestepValue
lrennels Oct 29, 2019
e5752de
Add getindex and setindex for indexing with arrays of timesteps
lrennels Oct 29, 2019
b8e57c3
Add Colon support
lrennels Oct 29, 2019
fd7b2ca
Add some Colon support for TimestepIndex; clean up
lrennels Oct 29, 2019
174a68a
Improve warning message with stacktrace; mute logging for dependency …
lrennels Oct 29, 2019
7d56cd6
Remove tests for timestep array int indexing
lrennels Oct 29, 2019
5afe427
Fix logging bug in dependency tests
lrennels Oct 29, 2019
aaf9cb8
Add docs
lrennels Oct 29, 2019
f997e93
Use depwarn to reduce logging output
lrennels Oct 30, 2019
1e387d1
Change colon indexing methods
lrennels Oct 30, 2019
bb11ece
Add TimestepValue array indexing and tests
lrennels Oct 30, 2019
69d8e76
Fix typos; simplify functions
lrennels Oct 30, 2019
c19ac92
Fix typo
lrennels Oct 30, 2019
24d9535
Add tests; fix bugs in array colon methods
lrennels Oct 31, 2019
4b67102
Add more tests
lrennels Oct 31, 2019
031f79b
Add more tests of deprecated functions
lrennels Oct 31, 2019
539b1a7
Clean up colon support in get and set index methods
lrennels Oct 31, 2019
753d99c
Clean up and add tests to test_timesteparrays
lrennels Oct 31, 2019
417869d
Add tests to improve coverage
lrennels Nov 1, 2019
3729377
Merge branch 'master' into timestepindex
lrennels Nov 1, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/src/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ replace_comp!
set_dimension!
set_leftover_params!
set_param!
TimestepIndex
TimestepValue
variable_dimensions
variable_names
update_param!
Expand Down
46 changes: 43 additions & 3 deletions docs/src/userguide.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ In order to invoke the explorer UI and explore all of the variables and paramete

```julia
run(mymodel)
explore(mymodel, title = "run1 results")
explore(mymodel, title = "run1 results")
```

![Explorer Model Example](figs/explorer_model_example.png)
Expand Down Expand Up @@ -183,8 +183,8 @@ In the `run_timestep` functions which the user defines, it may be useful to use
is_first(t) # returns true or false, true if t is the first timestep to be run
is_last(t) # returns true or false, true if t is the last timestep to be run
gettime(t) # returns the year represented by timestep t
is_time(t, s) # Return true or false, true if the current time (year) for t is y
is_timestep(t, y) # rReturn true or false, true if t timestep is step s.
is_time(t, y) # Return true or false, true if the current time (year) for t is y
is_timestep(t, s) # Return true or false, true if t timestep is step s.
```

The API details for AbstractTimestep object `t` are as follows:
Expand All @@ -194,6 +194,46 @@ The API details for AbstractTimestep object `t` are as follows:
- useful functions for commonly used conditionals are `is_first(t)`,`is_last(t)`, `is_time(t, s)`, and `is_timestep(t, y)` as listed above
- to access the index value of `t` as a `Number` representing the position in the time array, use `t.t`. Users are encouraged to avoid this access, and instead use the options listed above or a separate counter variable. each time the function gets called.

Indexing into a variable or parameter's `time` dimension with an `Integer` is deprecated and will soon error. Instead, users should take advantage of the `TimestepIndex` and `TimestepValue` types. For examples we will refer back to our component definition above, and repeated below.
```julia
@defcomp MyComponentName begin
regions = Index()

A = Variable(index = [time])
B = Variable(index = [time, regions])

c = Parameter()
d = Parameter(index = [time])
e = Parameter(index = [time, regions])
f = Parameter(index = [regions])

function run_timestep(p, v, d, t)
v.A[t] = p.c + p.d[t]
for r in d.regions
v.B[t, r] = p.f[r] * p.e[t, r]
end
end

end
```
`TimestepIndex` has one field, `index`, which refers to the absolute index in the parameter or variable array's `time` dimension. Thus, constructing a `TimestepIndex` is done by simply writing `TimestepIndex(index::Int)`. Looking back at our original component example
one could modify the first line of `run_timestep` to always refer to the first timestep of `p.d` with the following. One may index into the `time` dimension with a single `TimestepIndex`, or an `Array` of them.
```julia
v.A[t] = p.c + p.d[TimestepIndex(1)]
```
`TimestepValue` has two fields, `value` and `offset`, referring to the value within the `time` dimension and an optional `offset` from that `value`. Thus, constructing a `TimestepValue` is done either by writing `TimestepValue(value)`, with an implied offset of 0, or `TimestepValue(value, offset = i::Int)`, with an explicit offset of i. One may index into the `time` dimension with a single `TimestepValue`, or an `Array` of them. For example, you can use a `TimestepValue` to keep track of a baseline year.
```julia
v.A[t] = p.c + p.d[TimestepValue(2000)]
```
You may also use shorthand to create arrays of `TimestepIndex` using Colon syntax.
```julia
TimestepIndex(1):TimestepIndex(10) # implicit step size of 1
TimestepIndex(1):2:TimestepIndex(10) # explicit step of type Int
```
Both `TimestepIndex` and `TimestepArray` have methods to support addition and subtraction of integers. Note that the addition or subtraction is relative to the definition of the `time` dimension, so while `TimestepIndex(1) + 1 == TimestepIndex(2)`, `TimestepValue(2000) + 1` could be equivalent to `TimestepValue(2001)` **if** 2001 is the next year in the time dimension, or `TimestepValue(2005)` if the array has a step size of 5. Hence adding or subtracting is relative to the definition of the `time` dimension.



### Parameter connections between different length components

As mentioned earlier, it is possible for some components to start later or end sooner than the full length of the model. This presents potential complications for connecting their parameters. If you are setting the parameters to external values, then the provided values just need to be the right size for that component's parameter. If you are making an internal connection, this can happen in one of two ways:
Expand Down
2 changes: 2 additions & 0 deletions src/Mimi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export
set_dimension!,
set_leftover_params!,
set_param!,
TimestepIndex,
TimestepValue,
update_param!,
update_params!,
# variables,
Expand Down
29 changes: 27 additions & 2 deletions src/core/time.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,21 @@ function Base.:-(ts::VariableTimestep{TIMES}, val::Int) where {TIMES}
return VariableTimestep{TIMES}(ts.t - val)
end

function Base.:-(ts::TimestepValue, val::Int)
return TimestepValue(ts.value; offset = ts.offset - val)
end

function Base.:-(ts::TimestepIndex, val::Int)
return TimestepIndex(ts.index - val)
end

function Base.:+(ts::FixedTimestep{FIRST, STEP, LAST}, val::Int) where {FIRST, STEP, LAST}
if finished(ts)
error("Cannot get next timestep, this is last timestep.")
elseif gettime(ts) + val > LAST + 1
error("Cannot get requested timestep, exceeds last timestep.")
end
new_ts = FixedTimestep{FIRST, STEP, LAST}(ts.t + val)

return FixedTimestep{FIRST, STEP, LAST}(ts.t + val)
end

function Base.:+(ts::VariableTimestep{TIMES}, val::Int) where {TIMES}
Expand All @@ -125,6 +132,24 @@ function Base.:+(ts::VariableTimestep{TIMES}, val::Int) where {TIMES}
new_ts = VariableTimestep{TIMES}(ts.t + val)
end

function Base.:+(ts::TimestepValue, val::Int)
return TimestepValue(ts.value; offset = ts.offset + val)
end

function Base.:+(ts::TimestepIndex, val::Int)
return TimestepIndex(ts.index + val)
end

# Colon support
function Base.:(:)(start::T, step::Int, stop::T) where {T<:TimestepIndex}
indices = [start.index:step:stop.index...]
return TimestepIndex.(indices)
end

function Base.:(:)(start::T, stop::T) where {T<:TimestepIndex}
return Base.:(:)(start, 1, stop)
end

#
# CLOCK
#
Expand Down
Loading