external function / constant matrices

Use this forum to post Vensim related questions.
Post Reply
etam

external function / constant matrices

Post by etam »

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...
Administrator
Super Administrator
Posts: 4605
Joined: Wed Mar 05, 2003 3:10 am

Post by Administrator »

If you mark the function down has having user managed loops (in this example, it would have to be 2), you can work out what subscript elements you are dealing with.
bob@vensim.com
Senior Member
Posts: 1107
Joined: Wed Mar 12, 2003 2:46 pm

Post by bob@vensim.com »

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.
etam

Post by etam »

Thanks Bob.
I thought that, but was hoping there is a nicer solution.
tomfid
Administrator
Posts: 3815
Joined: Wed May 24, 2006 4:54 am

Post by tomfid »

Why do you want to do this? If you specify the problem you're trying to solve, you might get more useful answers.

Tom
etam

Post by etam »

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!
tomfid
Administrator
Posts: 3815
Joined: Wed May 24, 2006 4:54 am

Post by tomfid »

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
etam

Post by etam »

It's a general library, both are possible.

We have good results, it is fast enough. Now we are working on making it more general (that's why I asked my questions).
etam

Post by etam »

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?
bob@vensim.com
Senior Member
Posts: 1107
Joined: Wed Mar 12, 2003 2:46 pm

Post by bob@vensim.com »

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.
etam

Post by etam »

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!
Post Reply