Hi,
Another question about external functions.
You can define a constant with an external function, which is great.
You can get any variable's subscripts with *VENGV->get_varattrib, fine.
But can I get the fix subscripts from a definition?
I mean:
In your example you use:
constant[area,climate] = MYCONSTDEF('string')
However, these are also valid definitions:
sub : element1, element2 ~~|
constant2[area, climate, element1] = MYCONSTDEF('string') ~~|
constant3[area, element2, climate] = MYCONSTDEF('string') ~~|
Can I somehow get which subscripts varying in constant2 and constant3 above?
I couldn't find any solution in the docs and in your codes, so I reckon I can't, but it's better to ask it...
external function / constant matrices
-
- Super Administrator
- Posts: 4605
- Joined: Wed Mar 05, 2003 3:10 am
-
- Senior Member
- Posts: 1107
- Joined: Wed Mar 12, 2003 2:46 pm
the CONSTANT_MATRIX structure has in it the number of rows and columns requested. If you look at the example you will see how these are filled in. You can only have 2 subscripts varying so use the 'string' to specify which block of numbers is being requested. This is actually the same as the way GET XLS CONSTANTS works.
Why do you want to do this? If you specify the problem you're trying to solve, you might get more useful answers.
Tom
Tom
/*
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
I've created a general GAMS-Vensim interface.
One of its component reads data from GDX files (which are similar to VDF files).
This component has a function, something like this:
ReadFromGDX(CONSTANT_MATRIX *cmat, char *GDXFileName);
It gets the subscripts of cmat as interface-dictionary and uses them to read data from the GDX, which means that both Vensim and GAMS must have similar structures.
Let's assume the GDX has values of a variable:
Elasticities(Sectors, TimeShifts)
In my Vensim model there are two contants:
ELASTICITY GENERAL(SECTORS, TIMESHIFTS)
ELASTICITY SPEC(REGIONS, SECTORS, TIMESHIFTS)
(countries, sectors and timeshifts are subscript ranges)
For some reason I want to use them as follows:
ELASTICITY GENERAL(SECTORS, TIMESHIFTS) = ReadFromGDX('general.gdx') ~~|
ELASTICITY GENERAL(AFRICA, SECTORS, TIMESHIFTS) = ReadFromGDX('africa.gdx') ~~|
ELASTICITY GENERAL(AMERICA, SECTORS, TIMESHIFTS) = ReadFromGDX('america.gdx') ~~|
...
Unfortunately I can write it only that way:
ELASTICITY GENERAL(SECTORS, TIMESHIFTS) = ReadFromGDX('general.gdx', '') ~~|
ELASTICITY GENERAL(AFRICA, SECTORS, TIMESHIFTS) = ReadFromGDX('africa.gdx', 'AFRICA') ~~|
ELASTICITY GENERAL(AMERICA, SECTORS, TIMESHIFTS) = ReadFromGDX('america.gdx','AMERICA') ~~|
...
That's my simplest problem, but as you can read in the first post, also ordering matters.
Anyway, as Bob answered, there is no other solution.
Btw, thanks for the quick replies, it's really amazing!
One of its component reads data from GDX files (which are similar to VDF files).
This component has a function, something like this:
ReadFromGDX(CONSTANT_MATRIX *cmat, char *GDXFileName);
It gets the subscripts of cmat as interface-dictionary and uses them to read data from the GDX, which means that both Vensim and GAMS must have similar structures.
Let's assume the GDX has values of a variable:
Elasticities(Sectors, TimeShifts)
In my Vensim model there are two contants:
ELASTICITY GENERAL(SECTORS, TIMESHIFTS)
ELASTICITY SPEC(REGIONS, SECTORS, TIMESHIFTS)
(countries, sectors and timeshifts are subscript ranges)
For some reason I want to use them as follows:
ELASTICITY GENERAL(SECTORS, TIMESHIFTS) = ReadFromGDX('general.gdx') ~~|
ELASTICITY GENERAL(AFRICA, SECTORS, TIMESHIFTS) = ReadFromGDX('africa.gdx') ~~|
ELASTICITY GENERAL(AMERICA, SECTORS, TIMESHIFTS) = ReadFromGDX('america.gdx') ~~|
...
Unfortunately I can write it only that way:
ELASTICITY GENERAL(SECTORS, TIMESHIFTS) = ReadFromGDX('general.gdx', '') ~~|
ELASTICITY GENERAL(AFRICA, SECTORS, TIMESHIFTS) = ReadFromGDX('africa.gdx', 'AFRICA') ~~|
ELASTICITY GENERAL(AMERICA, SECTORS, TIMESHIFTS) = ReadFromGDX('america.gdx','AMERICA') ~~|
...
That's my simplest problem, but as you can read in the first post, also ordering matters.
Anyway, as Bob answered, there is no other solution.
Btw, thanks for the quick replies, it's really amazing!
Cool. Unfortunately I don't have any further helpful suggestion.
Just to indulge my curiousity though ... is your Vensim model calling/running a live GAMS model at each iteration, or using the GAMS results as a kind of fixed library of inputs, or ... ?
Tom
Just to indulge my curiousity though ... is your Vensim model calling/running a live GAMS model at each iteration, or using the GAMS results as a kind of fixed library of inputs, or ... ?
Tom
/*
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
Advice to posters (it really helps us to help you)
http://www.ventanasystems.co.uk/forum/v ... f=2&t=4391
Blog: http://blog.metasd.com
Model library: http://models.metasd.com
Bookmarks: http://delicious.com/tomfid/SystemDynamics
*/
Btw, with vensim_get_varattrib I can get the equations:
constant2[area, climate, element1] = MYCONSTDEF('string')
constant3[area, element2, climate] = MYCONSTDEF('string')
Isn't there any function which could tell me which is currently used if vensim_external is called?
Or any undocumented feature or tag?
constant2[area, climate, element1] = MYCONSTDEF('string')
constant3[area, element2, climate] = MYCONSTDEF('string')
Isn't there any function which could tell me which is currently used if vensim_external is called?
Or any undocumented feature or tag?
-
- Senior Member
- Posts: 1107
- Joined: Wed Mar 12, 2003 2:46 pm
If you call vensim_get_varoff you can find the offset in the computational vector (VENGV->LEVEL) and you can compare this with the address passed by a self looping function to determine what variable is being computed. You can probably get this to work, but it will take some experimentation and effort.
Uhh, I'm afraid I can't follow you this time.
Based on constmat/datamat->varname I know what variable is being computed.
And for user loops I know what subscripts are skipped.
I have problems only with constant and data definitions.
But offset won't work for them, since they have different storage in the CONSTANT_MATRIX, DATA_MATRIX structure, haven't they?
Moreover, VENGV->get_varoff(val[0].constmat->varname) returns 0 for me (within func vensim_external). Does it need any special initialization which is not mentioned in the doc?
Anyway, it's not really important, it can be solved with the literals.
Thanks for suggestions!
Based on constmat/datamat->varname I know what variable is being computed.
And for user loops I know what subscripts are skipped.
I have problems only with constant and data definitions.
But offset won't work for them, since they have different storage in the CONSTANT_MATRIX, DATA_MATRIX structure, haven't they?
Moreover, VENGV->get_varoff(val[0].constmat->varname) returns 0 for me (within func vensim_external). Does it need any special initialization which is not mentioned in the doc?
Anyway, it's not really important, it can be solved with the literals.
Thanks for suggestions!