My aim is to write a Hamiltonian MCMC sampler that samples bound and drift parameter posteriors for bounded diffusion models while assuming some parametric form for how these bounds and the drift change over time. This requires the first and second derivative of the first-passage densities that are computed in https://github.com/jdrugo/DiffModels.jl/blob/master/src/fpt.jl#L153. For certain parametrization of drift and bound, partial derivatives will be one or zero, which would make some parts of the code computing the full derivatives drop out. To make this have an impact on performance, I thought of two approaches:
- Write specialised functions for different parameterizations. This is the safe approach but would introduce many functions, as there are many possible combinations of drift and bound parameterizations. Also, it would not handle cases that I haven't thought of. - Write a generic function that only evaluates the parts of the code that influence the final result. Currently, it seems that macros are the best way to achieve this. The advantages would be that it only requires me to write the function once, avoiding code replication and associated bugs. Also, it should be able to handle cases that I haven't thought of. Note that the code linked above currently does not compute the derivatives. Due to several exp(.), the code that computes the derivatives will be significantly longer, such that not evaluating parts of it should lead to faster execution (not in the big-O sense, but reducing the constant). Jan On Friday, 3 July 2015 01:51:19 UTC+2, Stefan Karpinski wrote: > > Can you elaborate on why that kind of code needs this unusual evaluation? > It looks pretty reasonable as is to me. > > On Thu, Jul 2, 2015 at 5:20 PM, Jan Drugowitsch <[email protected] > <javascript:>> wrote: > >> Is this a toy reduction of a concept that you want to apply in a much >>> more complex way? >>> >> >> Yes, it was just meant to illustrate the concept. >> >> It should be applied to a function that has roughly the complexity of >> https://github.com/jdrugo/DiffModels.jl/blob/master/src/fpt.jl#L153 >> (in fact, it would be the first and second derivative of this function >> with respect to parameters of drift and bounds). >> >> Jan >> >> On Thu, Jul 2, 2015 at 11:09 AM, Jan Drugowitsch <[email protected]> >>> wrote: >>> >>>> On Thursday, 2 July 2015 16:55:33 UTC+2, Yichao Yu wrote: >>>>> >>>>> On Thu, Jul 2, 2015 at 10:48 AM, Tom Breloff <[email protected]> >>>>> wrote: >>>>> > Just curious... is there a reason simply checking for non-zero isn't >>>>> enough? >>>>> > Readability? Performance? >>>>> > >>>>> > f(a,b,c) = (Bool(a) ? a * (b + c) : 0.0) >>>>> >>>>> I'm guessing he want all code that gets his type automatically gets >>>>> this behavior? If yes, I don't think there's anyway you can do that. >>>>> If not, then just writing the branch or having a macro to rewrite that >>>>> in your own code is probably the best solution. >>>>> >>>> >>>> Indeed, the reason why I don't want to check for zeros and ones >>>> explicitly is that some of these appear in inner loops and would reduce >>>> performance. >>>> >>>> I already thought of macros as a possible solution, but I was wondering >>>> if the same could be achieved in a more implicit/elegant way. >>>> >>>> Thanks, >>>> Jan >>>> >>>> >>>>> > On Thursday, July 2, 2015 at 9:47:59 AM UTC-4, Jan Drugowitsch >>>>> wrote: >>>>> >> >>>>> >> Dear Julia users, >>>>> >> >>>>> >> I am implementing an algorithm to solve a specific type of Volterra >>>>> >> integral equation, and that simplifies significantly if some of its >>>>> >> parameters are set to zero or one. The function implementing the >>>>> algorithm >>>>> >> takes quite a few arguments, such that writing specific versions >>>>> for >>>>> >> different arguments being zero/one would lead to too many different >>>>> >> functions, which I would like to avoid. What I would rather like to >>>>> do is to >>>>> >> write one generic function and let the compiler prune different >>>>> parts of the >>>>> >> function, depending on the argument types. >>>>> >> >>>>> >> A minimal example of what I would like to do is >>>>> >> >>>>> >> immutable Zero <: Number; end >>>>> >> >>>>> >> const _zero = Zero() >>>>> >> >>>>> >> Base.promote_rule{T<:Number}(::Type{Zero}, ::Type{T}) = T >>>>> >> Base.convert{T<:Number}(::Type{T}, ::Zero) = zero(T) >>>>> >> >>>>> >> *(::Zero, ::Zero) = _zero >>>>> >> *(::Zero, ::Bool) = _zero >>>>> >> *(::Bool, ::Zero) = _zero >>>>> >> *(::Zero, ::Number) = _zero >>>>> >> *(::Number, ::Zero) = _zero >>>>> >> >>>>> >> f(a, b, c) = a * (println("summing b + c"); b + c) >>>>> >> >>>>> >> println("Evaluating f(0, 1, 2)") >>>>> >> f(0, 1, 2) >>>>> >> println("Evaluating f(_zero, 1, 2)") >>>>> >> f(_zero, 1, 2) >>>>> >> >>>>> >> (with Zero defined similar to >>>>> >> https://groups.google.com/forum/#!topic/julia-users/0ab30bE8q6c) >>>>> >> Running the above results in >>>>> >> >>>>> >> Evaluating f(0, 1, 2) >>>>> >> summing b + c >>>>> >> Evaluating f(_zero, 1, 2) >>>>> >> summing b + c >>>>> >> >>>>> >> even though the result of the second "summing b + c" is discarded, >>>>> and >>>>> >> therefore wouldn't need to be evaluated. This is no surprise, as >>>>> *(.,.) is a >>>>> >> standard function that evaluates its operands before applying the >>>>> function. >>>>> >> Is there any way to change this behavior and turn *(.,.) into a >>>>> function >>>>> >> that performs short-circuit evaluation? If not, is there an >>>>> alternative >>>>> >> approach that achieves this without writing tons of specialized >>>>> functions? >>>>> >> >>>>> >> Thanks, >>>>> >> Jan >>>>> >>>> >>> >
