Last active
August 18, 2017 13:25
-
-
Save decatur/cdd2099bd7eb6cefbf3db259f3fbc34e to your computer and use it in GitHub Desktop.
Run-Length-Encode/Decode Parameters in GAMS (General Algebraic Modeling System)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$include rle.gms | |
Set T / 1*5 /; | |
* Test series without additional domain. | |
Parameter a(T), a_rle(T) / 1 1, 3 EPS, 5 2 / | |
a_expected(T) / 1 1, 2 1, 5 2 /; | |
a(T) = a_rle(T); | |
rle_decode_1(a, T); | |
display a, a_expected; | |
rle_encode_1(a, T); | |
display a, a_rle; | |
Parameter b(T), b_rle(T) / 1 EPS, 5 2 /, | |
b_expected(T) / 5 2 /; | |
b(T) = b_rle(T); | |
rle_decode_1(b, T); | |
display b, b_expected; | |
rle_encode_1(b, T) | |
display b, b_rle; | |
* Test series on a card=4 domain. | |
Set S / a*d /; | |
Parameter c(T, S); | |
Table c_rle(T, S) | |
a b c d | |
1 1 3 1 EPS | |
2 EPS | |
3 4 | |
4 | |
5 2 ; | |
Table c_expected(T, S) | |
a b c d | |
1 1 3 1 | |
2 3 1 | |
3 4 1 | |
4 4 1 | |
5 2 4 1 ; | |
c(T,S) = c_rle(T,S); | |
rle_decode_2(c, T, S); | |
display c, c_expected; | |
rle_encode_2(c, T, S); | |
display c, c_rle; | |
* Now we do some crazy GAMS stuff to clarify. | |
Scalar vv / NA /; | |
vv = (EPS=EPS); | |
display "EPS compares to EPS", vv; | |
vv = (0=EPS); | |
display "EPS compares to 0", vv; | |
vv = (not EPS); | |
display "not EPS is 0", vv; | |
vv = (1 and EPS); | |
display "1 and EPS is true", vv; | |
vv = NA; | |
vv = 1$EPS; | |
display "EPS is true", vv; | |
vv = (NA=NA); | |
display "NA compares to NA ", vv; | |
* Demo that GAMS is a sparse system | |
Set Q / a1*a1000000 /; | |
Parameter p(Q); | |
* Following line does not do anything. | |
p(Q) = 0; | |
* p(Q) = EPS would be devastating; | |
p('a1') = EPS; | |
p('a1000') = 100000; | |
* Only saves two entries | |
Execute_Unload 'foobar.gdx', p; | |
Parameter x(T) / 1 1 /; | |
x(T+1) = x(T) | |
display x; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ontext | |
RunLengthEncoding (RLE) Series: | |
A Series where only changes in value are recorded. | |
Example A | |
index = 1 2 3 4 5 6 | |
value = 6 6 0 0 7 7 | |
as RLE series is | |
index = 1 3 5 | |
value = 6 0 7 | |
Example B from demo_rle | |
RLE-Encoded | |
a b c d | |
1 1 3 1 EPS | |
2 EPS | |
3 4 | |
4 | |
5 2 ; | |
RLE-Decoded | |
a b c d | |
1 1 3 1 | |
2 3 1 | |
3 4 1 | |
4 4 1 | |
5 2 4 1 ; | |
Important: Since GAMS is a sparse system where 0 values simply are not recorded, | |
we use EPS as explained below. | |
Notes: | |
1. Macros may not contain other Dollar Control Options such as $load. | |
2. The statement p(t) = p(t-1) is skipped for ord(t) = 1. | |
3. EPS is the marker for the zero value. In Python EPS is gams.SV_EPS | |
4. EPS and 0 compare to each other, i.e. EPS=1. However, (not EPS) is 0, whereas (not 0) is 1. | |
So DO NOT use p(t)=0, use not p(t) | |
From the GAMS documentation: | |
Special attention needs to be given to the value of 0. | |
Since GAMS is a sparse system it does not store (parameter) records with a true 0. | |
If a record with numerical value of 0 is needed, EPS(SV_EPS) can help. | |
Macros rle_decode_x(parameter, time_set, other_domain, ...): | |
Roll out a DiffSparse series | |
$offtext | |
* if p(t) is missing then set to p(t-1), else keep value by setting EPS to 0: | |
* if ( not p(t), p(t)=p(t-1); else if ( p(t)=EPS, p(t)=0 ) ) | |
* Note that the term | |
* if ( p(t)=EPS, p(t)=0 ) | |
* can be written as | |
* p(t) = p(t)$(not(p(t)=0)). | |
* So we could write | |
* p(t) = ifthen( not p(t), p(t-1), p(t)$(not(p(t)=0)) ) | |
* or | |
* p(t) = p(t-1)$(not p(t)) + p(t)$not(p(t)=0) | |
* In the first round ( ord(t)=1 ) this happens: | |
* If p(t) is 0, then we jump to the true-expressen, where nothing happens because | |
* t-1 is skipped. | |
* If p(t) is not zero, then we jump to the false-expression, and p(t) is set to 0 | |
* if equal to EPS. | |
$macro rle_decode_1(p, t) \ | |
Loop(t, \ | |
if ( not p(t), p(t)=p(t-1); else if ( p(t)=EPS, p(t)=0 ) ) \ | |
) | |
$macro rle_decode_2(p, t, d) \ | |
Loop((t, d), \ | |
if ( not p(t,d), p(t,d) = p(t-1,d); else if ( p(t,d)=EPS, p(t,d)=0 ) ); \ | |
) | |
$ontext | |
Macros rollin_x(parameter, time_set, other_domain, ...): | |
Inverse of rollout_x | |
$offtext | |
Scalar prev_val_ / NA /; | |
Scalar val_ / NA /; | |
$macro rle_encode_1(p, t) \ | |
Loop(t, \ | |
val_ = round(p(t), 4); \ | |
if ( ord(t) > 1 and val_=prev_val_, p(t) = 0; else prev_val_=val_; p(t)=ifthen(val_=0, EPS, val_) ); \ | |
) | |
$macro rle_encode_2(p, t, d) \ | |
Loop((d,t), \ | |
val_ = round(p(t,d), 4); \ | |
if ( ord(t) > 1 and val_=prev_val_, p(t,d) = 0; else prev_val_=val_; p(t,d)=ifthen(val_=0, EPS, val_) ); \ | |
) | |
$macro rle_encode_3(p, t, d1, d2) \ | |
Loop((d1,d2,t), \ | |
val_ = round(p(t,d1,d2), 4); \ | |
if ( ord(t)>1 and val_=prev_val_, p(t,d1,d2) = 0; else prev_val_=val_; p(t,d1,d2)=ifthen(val_=0, EPS, val_) ); \ | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment