Slightly relevant, I have a small finite element program where I want to be
able to give a function f(x,y,z,t) that represents the values of the
dirichlet boundary conditions on a set of degrees of freedom.
What I do (using FastAnonymous) is enter the function as a string, f_string,
then create the anonymous function like this
f_exp = "f = @anon (x,y,z,t) -> " * f_string
eval(parse(f_exp))
DirichletBC([0], f)
to create the type:
type DirichletBC{T}
dofs::Vector{Int}
f::T
end
eval(bc::DirichletBC, x, y, z, t) = bc.f(x,y,z,t)
In this case I don't mind having the function inside a type because the
function is in this case what defines the type, it is a part of the data,
not the functionality.
On Wednesday, May 27, 2015 at 3:58:46 PM UTC+2, Scott T wrote:
>
> 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
>>>>
>>>