Hi Miles,

It would be easier for me to give some excerpts of the Julia sources I am 
working with. I think it would suffice to illustrate the  mechanic we are 
trying to implement. 

Say we have two abstract types:

abstract BasicUC
abstract CCModel<:BasicUC

These are declared in separate modules.  BasicUC stands for basic 
unit-commitment and types that derive it have access to functionalities 
such as:

function setLineCapa!(m::BasicUC)
        JuMP.@addConstraint(m.mip, _contraint1[l = keys(m.net.branch), t = 
m.timeIndex], 
        m.var[:flow][l,t] <= m.net.branch[l].Fmax)
        ...
end

CCModel stands for an extended unit-commitment formulation, where robust 
reserve requirement are implemented. Details are irrelevant. A type that 
derives CCModel has access to, say:

function setRobustReserve!(m::CCModel)
        ...
end

Extending the functionality specific to BasicUC - let a type “Model” such 
that

type Model{T<:BasicUC} <: CCModel    
    uc                # Hook to BasicUC
    # Proxies to BasicUC:
    demand       # exogenous stuff
    mip              # JuMP model 
    . . .
    function Model(net,scenario)
        this=new()
        this.uc=T(net,scenario)
        . . .
        # Delegation to BasicUC
        this.demand=this.uc.demand        
        this.mip=this.uc.mip                  
        this.var=this.uc.var                     
        . . .
        # Specific to CCModel
        this.contingencies=scenario[:contingencies]
        JuMP.@defVar(this.mip, _post_gen[keys(this.net.gen), 
keys(this.contingencies), 
                                this.timeIndex])
        this.var[:post_gen]= _post_gen
        . . .
        return this
    end
end

Now, let a concrete type "BasicModel" be defined in, say module 
"BasicUnitCommitment",  and such that :

BasicModel<:BasicUC

Type Model{T} above can then be instantiated and tailored, with:
 
    m=Model{BasicUnitCommitment.BaseModel}(net,scenario)
    # from the base model (BasicUC)
    setBalanceEq!(m)
    setLineCapa!(m)
    setInitRamping!(m)
    # these are overloaded by CCModel 
    setObjective!(m) 
    setGenCapa!(m)
    setRamping!(m)
    # these are specific to CCModel
    setPostBalanceEq!(m)
    setRobustReserve!(m)
    . . .

So that's the idea. Perhaps I am overdoing this, but I think having some 
kind of encapsulation is essential for developing larger applications. 
Emulating inheritance, as is done above, is rather straightforward, but 
perhaps a little laborious, and there might be a better way to go about 
it.   

François




Le mercredi 3 juin 2015 16:12:21 UTC-5, Miles Lubin a écrit :
>
> Hi Francois,
>
> Could you give an example of how you might organize this code in a more 
> namespace heavy language like C++ or Java? I think this is quite a general 
> question on how to structure large Julia applications, not really specific 
> to JuMP.
>
> Best,
> Miles
>
> On Wednesday, June 3, 2015 at 9:07:03 PM UTC+2, Francois Gilbert wrote:
>>
>> Hi all,
>>
>> Is  anyone aware of any effort building large OR applications?  I am 
>> currently working at organizing a relatively large code base making use of 
>> the JuMP libraries.  The  context is unit-commitment and transmission 
>> planning.  Flexibility and code re-use is among our priorities. 
>>
>> Here are some of the design choices we made so far:
>>
>> 1) JuMP models are encapsulated in types that hold: 
>> a) references to the variable names, constraints (when multipliers are 
>> needed) and indices.  These are otherwise difficult to extract directly 
>> from the JuMP object
>> b) data structure that are required for model specification (generator 
>> characteristics, transmission lines, etc) 
>> c) exogenous variable values (demand scenarios, initial conditions, etc)
>>
>> 2) Most models we use are derived from a basic unit commitment model. The 
>> derivation is implemented using 
>> composition: the derived type manages a reference to the base type, and 
>> provides a number of proxies to some of the base type data structure. 
>>
>> 3) The objective and constraints  are specified  through function calls, 
>> using polymorphism on the basis of an underlying abstract types hierarchy. 
>>
>> I also toyed for a while with submodules to incorporate functionality 
>> that only make sense within the scope of a given base module. But from the 
>> language point of view, I did not see much benefit in doing so. That is,  a 
>> Julia submodule does not see anything of the base module, unless it is 
>> explicitly use/imported, and is thus in the same position as any other 
>> module defined outside the scope of the base module.  Are there any Julia 
>> packages making use submodules? 
>>
>> Any suggestions/comments are very welcome,
>>
>> François
>>
>>

Reply via email to