you can inspect the `.env` field of a method to get a reference to the
closure variables

On Wed, Oct 15, 2014 at 6:26 PM, Nikolas Tezak <[email protected]>
wrote:

> Hi Isaiah, thanks for your reply! Yeah, I figured my use case is probably
> a little exotic. I have thought very hard about using macros, but either I
> haven't quite understood them yet (likely!) or they aren't the best
> solution in this instance.
> Maybe some sort of symbolic approach could work where I only store
> Expression objects for each circuit element that get concatenated and
> compiled when a whole circuit is simulated.
>
> Anyway, thanks!
> Nik
>
> On Wednesday, October 15, 2014 11:11:42 AM UTC-7, Isaiah wrote:
>>
>> Given the constructed sys1_ode method is there someway to dynamically
>>> access the captured variables, i.e. those that come from its closure?
>>
>>
>> I'm not sure I entirely follow, but: you can use the variables p1 and p2
>> inside the inner function and it will Just Work (scoping rules). But it is
>> not possible to interrogate the closure environment from inside the
>> enclosed function.
>>
>> Also, have you considered macros? They won't help to interrogate the
>> closure environment, but are a much better option for AST rewriting than
>> using code_lowered.
>>
>> On Tue, Oct 14, 2014 at 2:14 PM, Nikolas Tezak <[email protected]>
>> wrote:
>>
>>> Hi all,
>>>
>>> in my research I run numerical simulations (ODEs and SDEs) for circuit
>>> models that can be composed, i.e.,
>>> each system has an ode that modifies in-place the elements of an output
>>> array based on the current state variable.
>>> Moreover, dimensionality of each system may vary.
>>>
>>> function sys1_ode(t, x, xdot)
>>>     xdot[1] = # some function of x, t
>>>     xdot[2] = # some other function of x, t
>>> end
>>>
>>>
>>> function sys2_ode(t, x, xdot)
>>>     xdot[1] = # some expression with x, t
>>>     xdot[2] = # some other expression with x, t
>>>     xdot[3] = # some other expression with x, t
>>> end
>>>
>>>
>>> What I would like to do is use metaprogramming to construct a combined
>>> ode for both systems where the state vectors are just stacked. For each
>>> system I compute the offset within the state vector (0 for sys1 and 2 for
>>> sys2) and then modify and recombine the function code as follows
>>>
>>> function sys12_ode(t, x, xdot)
>>>     xdot[1+0] = # some expression with x[1:2], t
>>>     xdot[2+0] = # some other expression with x[1:2], t
>>>     xdot[1+2] = # some expression with x[1+2:3+2], t
>>>
>>>     xdot[2+2] = # some expression with x[1+2:3+2], t
>>>     xdot[3+2] = # some expression with x[1+2:3+2], t
>>>
>>> end
>>>
>>>
>>> So far, that would seem to be quite straightforward and I think I could
>>> get this working by calling code_lowered(sys1_ode) and using the rewritten
>>> output to construct an AST for the combined function.
>>>
>>> The difficulty now arises when my sys1 and sys2 odes are defined with
>>> some internal parameters that are not passed as an argument but rather
>>> through a closure from the surrounding scope, i.e. I have some ode factory:
>>>
>>> funcion make_sys1_ode(p1, p2)
>>>     function sys1_ode(t, x, xdot)
>>>         xdot[1] = # some expression with x, t AND p1, p2
>>>         xdot[2] = # some expression with of x, t AND p1, p2
>>>     end
>>>     sys1_ode
>>> end
>>>
>>> Given the constructed sys1_ode method is there someway to dynamically
>>> access the captured variables, i.e. those that come from its closure?
>>> Otherwise, I suppose I could resort to passing parameters via an extra
>>> ODE argument, but it would be super nice if I could avoid this.
>>> The reason why I am trying to implement things this way is to speed up
>>> ODE evaluation for very large complex (i.e. nested) circuits by expanding
>>> out all ODE bodies into a single function.
>>>
>>> I hope this write-up makes sense.
>>> Thanks,
>>> Nik
>>>
>>>
>>

Reply via email to