Dear all,
This summer we plan to add the possibility to use sets in the Dynare macro language. This would allow to write some codes in a more elegant manner, avoiding the use of more or less complex nested loops.
To initiate the discussion here are some first (unordered) ideas for the new features and interface to be implemented.
Suppose one wants to write something like:
GDP_US = ... GDP_FR = ... GDP_EU = ... CPI_US = ... CPI_FR = ... CPI_EU = ...
With the current implementation of the macroprocessor, this has to be done with two nested loops. If instead we could define sets and tuples in the macro language we could do it with one loop using a Cartesian product of sets for the variables (GDP and CPI) and the coluntries (US, FR, EU).
We may declare sets using the following syntax:
@#define VARIABLE={"GDP", "CPI"} @#define COUNTRY={"US", "FR", "EU"} @#define TOTO={1, 2, 3} @#define TITI={"A", 3, "C"} @#define TUTU={(1,1), (1,2), (2,1), (2,2)} @#define ZERO={}
A set, defined by using opening and closing curly braces, can be composed of strings (VARIABLE and COUNTRY), integers (TOTO), or tuples (TUTU). A set can be empty (ZERO), and can contain objects of different types (not as the arrays). A tuple defined by opening and closing parenthesis can also contain objects of different types. I am not sure that we need to create an interface to define tuples.
We need to define operations on these sets
[1] @{VARIABLE}+@{COUNTRY} could be the union of two sets
[2] @{TITI}-@{TOTO} could be the set difference
[3] We could add something for the intersection, but this can be emulated with the set difference and union: the intersection of sets A and B is equal to (A+B)-((B-A)+(A-B)).
[4] @{VARIABLE}*@{COUNTRY} could be the Cartesian product of two sets. This operation returns a set of tuples:
@{VARIABLE}*@{COUNTRY} = {("GDP", "US"), ("GDP", "FR"), ("GDP", "EU"), ("CPI", "FR"), ...}
We should also define calculus rules for these operations (for instance precedence rules).
And finally, it should be possible to iterate on tuples in a for loop (to avoid the nested loops). Something like:
@#for (v,c) in TUTU @{v}_@{c} = ... @endif
Best, Stéphane.
Current state of discussions (Houtan, Sébastien and myself).
- We do not need to introduce a new syntax for sets. We can recycle the notations for arrays.
- To do so we need to allow arrays of heterogenous types. ⇒ An array can be made of integers, strings, arrays and tuples.
- We still need to take a decision regarding the the binary operators for union and intersection. My preference is for | (union) and & (intersection). An alternative could be two use explicit function like union(A,B)!, but it's not pretty. Note that we already use && and || as logical operators in the macroprocessor.
- Reusing array notations may obfuscate the interpretation of some already defined operations. For instance, A+B would be an union with repetitions. Also an array is by nature ordered, this is not necessarily what we have in mind when we deal with sets.
- Add comprehension to create array of tuples. Something like:
@#define COUNTRIES = ["FR", "US", "DE"] @#define VARIABLES = ["X", "M"] @#define LIST = [(v, c, d); for (v, c, d) in @{VARIABLES}*@{COUNTRIES}*@{COUNTRIES} if c!=d ]
- Power of sets as a shortcut for the Cartesian product of a set with itself. For instance @{COUNTRIES}^2 instead of @{COUNTRIES}*@{COUNTRIES}.
- We also need to deal with the empty set, ∅.
- What about partitions? I don't see any application right now...
Best, Stéphane.
Stéphane Adjemian writes:
Dear all,
This summer we plan to add the possibility to use sets in the Dynare macro language. This would allow to write some codes in a more elegant manner, avoiding the use of more or less complex nested loops.
To initiate the discussion here are some first (unordered) ideas for the new features and interface to be implemented.
Suppose one wants to write something like:
GDP_US = ... GDP_FR = ... GDP_EU = ... CPI_US = ... CPI_FR = ... CPI_EU = ...
With the current implementation of the macroprocessor, this has to be done with two nested loops. If instead we could define sets and tuples in the macro language we could do it with one loop using a Cartesian product of sets for the variables (GDP and CPI) and the coluntries (US, FR, EU).
We may declare sets using the following syntax:
@#define VARIABLE={"GDP", "CPI"} @#define COUNTRY={"US", "FR", "EU"} @#define TOTO={1, 2, 3} @#define TITI={"A", 3, "C"} @#define TUTU={(1,1), (1,2), (2,1), (2,2)} @#define ZERO={}
A set, defined by using opening and closing curly braces, can be composed of strings (VARIABLE and COUNTRY), integers (TOTO), or tuples (TUTU). A set can be empty (ZERO), and can contain objects of different types (not as the arrays). A tuple defined by opening and closing parenthesis can also contain objects of different types. I am not sure that we need to create an interface to define tuples.
We need to define operations on these sets
[1] @{VARIABLE}+@{COUNTRY} could be the union of two sets
[2] @{TITI}-@{TOTO} could be the set difference
[3] We could add something for the intersection, but this can be emulated with the set difference and union: the intersection of sets A and B is equal to (A+B)-((B-A)+(A-B)).
[4] @{VARIABLE}*@{COUNTRY} could be the Cartesian product of two sets. This operation returns a set of tuples:
@{VARIABLE}*@{COUNTRY} = {("GDP", "US"), ("GDP", "FR"), ("GDP", "EU"), ("CPI", "FR"), ...}
We should also define calculus rules for these operations (for instance precedence rules).
And finally, it should be possible to iterate on tuples in a for loop (to avoid the nested loops). Something like:
@#for (v,c) in TUTU @{v}_@{c} = ... @endif
Best, Stéphane.