# Behavior of Parameters in Different Timestep Length Models

**URL:** <https://forum.mimiframework.org/t/behavior-of-parameters-in-different-timestep-length-models/110>\
**Category:** Uncategorized\
**Created:** [January 22, 2020, 7:18pm UTC](https://forum.mimiframework.org/t/behavior-of-parameters-in-different-timestep-length-models/110 "2020-01-22T19:18:31Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![FrankErrickson](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.mimiframework.org/frankerrickson/32/13_2.png) [@FrankErrickson](https://forum.mimiframework.org/u/FrankErrickson)\
**Post date:** [January 22, 2020, 7:18pm UTC](https://forum.mimiframework.org/t/behavior-of-parameters-in-different-timestep-length-models/110/1 "2020-01-22T19:18:31Z")

</div>

I have a model that couples components with varying timestep lengths. If I create a connection between two of the shorter components, the array holding this parameter takes on the length of the longer component (with the timesteps the shorter component doesn’t cover = missing). If I also do a `set_param!()` within this shorter component for a time-varying parameter, the array holding it takes on the size of the shorter component.

Am I understanding this correctly, and if so is this the desired behavior? It was causing all kinds of errors in my model because I was inadvertently indexing into these components the wrong way and having a bunch of missing values pop up. I attached a working example of what I’m talking about below (In this case the error arises from using `[1]` to index the first value. I know there are ways around this, but the error could still occur in more complicated indexing cases).

Here’s a toy model where the period 15 temperature value is either calculated or missing depending on how I index.

```auto
using Mimi

# An economy component (the longer component).
@defcomp economy begin
	gdp = Variable(index=[time])

	function run_timestep(p, v, d, t)
    	if is_first(t)
    		v.gdp[t] = 10.0
    	else
    		v.gdp[t] = v.gdp[t-1] * 1.02
    	end
    end
end

# A shorter emissions component that switches on in period 15.
@defcomp co2_emissions begin
	gdp	= Parameter(index=[time])
	co2 = Variable(index=[time])

	function run_timestep(p, v, d, t)
		v.co2[t] = (0.1 * p.gdp[t])
    end
end

# A shorter climate component that switches on in period 15.
@defcomp climate begin
    co2 = Parameter(index=[time])
    other_ghg = Parameter(index=[time])
    temperature = Variable(index=[time])

	function run_timestep(p, v, d, t)
		if is_first(t)
			v.temperature[t] = (p.co2[1] + p.other_ghg[1]) ^ 2
		else
			v.temperature[t] = (p.co2[t] + p.other_ghg[t]) ^ 1.5
		end
	end
end

# Create the model for 20 time steps.
m = Model()
set_dimension!(m, :time, 20)

# Add components (emissions and climate turn on in period 15).
add_comp!(m, economy)
add_comp!(m, co2_emissions; first=15)
add_comp!(m, climate; first=15)

# Set exogenous gas scenario for periods 15-20.
set_param!(m, :climate, :other_ghg, ones(6))

# Create component connections.
connect_param!(m, :co2_emissions => :gdp, :economy => :gdp)
connect_param!(m, :climate, :co2, :co2_emissions, :co2)

run(m)

```

In this example, `m[:climate, :temperature][15]` is a missing value. But the temperature will be calculated If I change the initial temperature calculation to :

`v.temperature[t] = (p.co2[15] + p.other_ghg[1]) ^ 2`

because the connected `co2` parameter ends up in a 20x1 array while the external `other_ghg` parameter is in a 6x1 array. This can get really confusing with more complicated set ups.

---

<div class="post-metadata">

**Author:** ![FrankErrickson](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.mimiframework.org/frankerrickson/32/13_2.png) [@FrankErrickson](https://forum.mimiframework.org/u/FrankErrickson)\
**Post date:** [January 23, 2020, 2:54am UTC](https://forum.mimiframework.org/t/behavior-of-parameters-in-different-timestep-length-models/110/2 "2020-01-23T02:54:42Z")

</div>

And I should say, I don’t think this is an error with Mimi, but more of an inconsistency with how the variable timestep models behave.

For instance, in the above example this would work:

```auto
if is_first(t)
    v.temperature[t] = (p.co2[t] + p.other_ghg[t]) ^ 2
else...

```

If you checked the values of `t` using the `t.t` syntax, it would come back as t=1 in this case. But as I mentioned, trying:

```auto
if is_first(t)
    v.temperature[t] = (p.co2[1] + p.other_ghg[1]) ^ 2
else...

```

results in a missing value because of the different sized parameter arrays. So I got confused because setting `something[t]` works, and in that case `t.t = 1`… but setting `something[1]` will cause an error.

I think the current set up for the different time step models just doesn’t have a consistent, intuitive approach for how to deal with the different couplings. I had to sort this out by messing with these toy models for two days until I was able to figure out what was going on.

---

<div class="post-metadata">

**Author:** ![ckingdon95](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.mimiframework.org/ckingdon95/32/15_2.png) [@ckingdon95](https://forum.mimiframework.org/u/ckingdon95)\
**Post date:** [January 23, 2020, 4:44pm UTC](https://forum.mimiframework.org/t/behavior-of-parameters-in-different-timestep-length-models/110/3 "2020-01-23T16:44:17Z")

</div>

Hi Frank,

Sorry you toiled over this for so long! It can be pretty confusing. You’ve correctly figured out though how it’s all currently implemented. A while ago we decided that it was much clearer (from an implementing Mimi standpoint) to have the data storage arrays be the whole length of the model’s time index, as you’ve discovered.

As you’ve also discovered, this makes it very confusing if you use integer indexing, which we are trying to discourage and will be discontinued in version 1.0. So for now, you should use:

```auto
v.temperature[t] = (p.co2[t] + p.other_ghg[t]) ^ 2

```

Because `t` in this timestep is `t.t==1`, which means it’s the first timestep for _this_ component, so it will correctly index into the expected “first” position for this component. But since the data are being stored in a longer array, using the integer 1 returns a missing value.

---

<div class="post-metadata">

**Author:** ![FrankErrickson](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.mimiframework.org/frankerrickson/32/13_2.png) [@FrankErrickson](https://forum.mimiframework.org/u/FrankErrickson)\
**Post date:** [January 23, 2020, 5:09pm UTC](https://forum.mimiframework.org/t/behavior-of-parameters-in-different-timestep-length-models/110/4 "2020-01-23T17:09:12Z")

</div>

> [@ckingdon95](#):
>
> have the data storage arrays be the whole length of the model’s time index, as you’ve discovered.
> 
> As you’ve also discovered, this makes it very confusing if you use integer indexing, which we are trying to discourage and will be discontinued in vers

@ckingdon95 Thanks for the helpful reply! And yes, I know integer indexing isn’t robust, but was just an example. I still just find the entire different array size vs. different timestep values within different length components quite confusing.

The immediate example that comes to mind is if I couple a longer climate model to a shorter IAM. There could be a case where I’d want the first temperature value (from 1765) and the first GDP value (from 2010) within the same component. I’m sure there’s a clean Mimi way to set this up, but it isn’t immediately clear.

Probably plenty of design issues I’m not thinking of, but for me it would be much easier if everything was just stored in an array whose length is that of the longest component (with missing values filled in for years without coverage). This would apply to external parameters too. And then just have a universal time step. So in the example above, the climate model would start at `t=1`, and the IAM would start at `t=246`.

---

<div class="post-metadata">

**Author:** ![ckingdon95](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.mimiframework.org/ckingdon95/32/15_2.png) [@ckingdon95](https://forum.mimiframework.org/u/ckingdon95)\
**Post date:** [January 23, 2020, 5:29pm UTC](https://forum.mimiframework.org/t/behavior-of-parameters-in-different-timestep-length-models/110/5 "2020-01-23T17:29:51Z")

</div>

I think what you’ve just proposed is very similar to something @plevin recently proposed for how we can re-design this functionality to be easier/cleaner. I’ll bring it up in our next meeting and we will let you know what we decide, and we may want to loop you in to a design discussion at some point!

Thanks again for working through this, it’s very helpful to have real life users try this out 🙂 and it seems like it can/will be a very important functionality that we want to get right!

---

<div class="post-metadata">

**Author:** ![lrennels](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.mimiframework.org/lrennels/32/6_2.png) [@lrennels](https://forum.mimiframework.org/u/lrennels)\
**Post date:** [January 24, 2020, 12:32am UTC](https://forum.mimiframework.org/t/behavior-of-parameters-in-different-timestep-length-models/110/6 "2020-01-24T00:32:39Z")

</div>

@ckingdon95 thanks so much for working through this, that all looks right to me. @FrankErrickson we’ve also added some new types in the developing `v0.9.5` version to add more flexible ways to index without using integers, although of course the discussion above is the wider question about different model lengths that we do need to work through.

In terms of indexing, `0.9.5` and beyond has two more types as described in the User Guide and copied below:

* * *

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.

```auto
@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.

```auto
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.

```auto
v.A[t] = p.c + p.d[TimestepValue(2000)]

```

You may also use shorthand to create arrays of `TimestepIndex` using Colon syntax.

```auto
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.
