Thanks - I had already split out the constant heat capacities into a
separate type, but for some reason hadn't thought to continue by subtyping
the non-constant ones to follow through with that abstraction.
Cheers,
Scott
On Friday, 22 May 2015 19:53:57 UTC+1, Tomas Lycken wrote:
>
> The best way is probably to introduce a small type hierarchy for your heat
> capacity specification, some of which interpolate and some of which don't.
> For example,
>
> ```
> abstract HeatCapacity
> immutable ConstantHeatCapacity{T} <: HeatCapacity
> C::T
> end
> heatcapacity(c::ConstantHeatCapacity, x) = c.C # will most likely be
> inlined
>
> immutable InterpolatedHeatCapacity{T<:Interpolation} <: HeatCapacity
> itp::T
> end
> heatcapacity(c::InterpolatedHeatCapacity, x) = itp[x] # or however you
> interpolate the heat capacity with your implementation
>
> function SomeFunction(hc::HeatCapacity, otherparams...)
> # do your calculations here
> # whenever you need the heat capacity at x, you can use
> C = heatcapacity(hc, x)
> # which will be type-stable
> end
> ```
>
> What we've done is to introduce an abstraction barrier between the
> calculation and the representation of the heat capacity, in order to keep
> everything type-stable and performant while letting `SomeFunction` be
> agnostic of how the heat capacity is calculated.
>
> // T
>
> On Friday, May 22, 2015 at 7:39:26 PM UTC+2, Scott T wrote:
>>
>> Second code block should have
>>
>> call(rsf::RunsSomeFunction, x) = rsf.f(x)
>>
>> instead and, if it's not obvious from the `call` functions, I'm using 0.4
>> - would be happy to hear about what the plans are for making higher-order
>> functions faster so I can pass them around as arguments without worrying so
>> much about speed.
>>
>>
>> On Friday, 22 May 2015 18:34:27 UTC+1, Scott T wrote:
>>>
>>> I'm aware of the fact that higher-order functions will currently be
>>> slow, and you can get around this by using a package like FastAnonymous or
>>> by using custom types:
>>>
>>> function SomeFunction(value, par)
>>> # do stuff with value based on parameter
>>> end
>>>
>>> type RunsSomeFunction
>>> par1
>>> end
>>>
>>> call(rsf::RunsSomeFunction, x) = SomeFunction(x, rsf.par)
>>>
>>> How should I deal with a situation where I have a function passed from
>>> somewhere else - say, an interpolation routine - and I need to access this
>>> function when using such a type? The function isn't known at compile-time,
>>> so I can't use the above trick. But I also feel like writing out something
>>> similar to the below code
>>>
>>> type RunsSomeFunction
>>> f::Function
>>> end
>>>
>>> call(rsf::RunsSomeFunction, x) = RunsSomeFunction.f(x)
>>>
>>> mytype = RunsSomeFunction(make_interpolant_from(file))
>>>
>>> isn't good, since I'm including a function inside a type (very OO-ish).
>>>
>>> The context is that I've got some types which represent heat capacities,
>>> varying across temperature and pressure, and these are later included in an
>>> integration routine. Making the heat capacities constant or a simple
>>> function of P/T is easy - they can be included directly in the body of the
>>> code. Interpolating from a file isn't so easy, and slows things down a lot
>>> more than I thought it would. Any ideas? Am I asking too much at the moment?
>>>
>>> Cheers,
>>>
>>> Scott
>>>
>>