# Trouble with Measurements.jl and Bessel Functions

**URL:** https://discourse.julialang.org/t/trouble-with-measurements-jl-and-bessel-functions/4562
**Category:** New to Julia
**Tags:** question, measurements
**Created:** [June 30, 2017, 11:16am UTC](https://discourse.julialang.org/t/trouble-with-measurements-jl-and-bessel-functions/4562 "2017-06-30T11:16:04Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Jason\_Kilpatrick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jason_kilpatrick/32/7662_2.png) [@Jason\_Kilpatrick](https://discourse.julialang.org/u/Jason_Kilpatrick)
#### Post date: [June 30, 2017, 11:16am UTC](https://discourse.julialang.org/t/trouble-with-measurements-jl-and-bessel-functions/4562/1 "2017-06-30T11:16:04Z")

</div>

I am using Measurements.jl for error propagation in my code and have come across an error when trying to use it with a Bessel function with a complex input.

This works

```julia
using Measurements
x = 1 ± 0.5
y = besselk(1. , x)

```

and this works

```julia
y = besselk(1., complex(1.,1.))

```

But this does not

```julia
using Measurements
x = 1 ± 0.5
y = besselk(1. , complex(1. , x))

```

and gives the following error

> LoadError: MethodError: no method matching besselk(::Measurements.Measurement{Float64}, ::Complex{Measurements.Measurement{Float64}})  
> Closest candidates are:  
> besselk(::T\<:AbstractFloat, ::Complex{T\<:AbstractFloat}) where T\<:AbstractFloat at C:\Users\xxxxxx.julia\v0.6\SpecialFunctions\src\bessel.jl:457  
> besselk(::Real, ::Complex) at C:\Users\xxxxxx.julia\v0.6\SpecialFunctions\src\bessel.jl:454  
> besselk(::Any…; kwargs…) at deprecated.jl:1294  
> …  
> while loading TestCase.jl, in expression starting on line 7  
> in besselk at SpecialFunctions\src\bessel.jl:455

I was under the impression that Measurements.jl was compatible with Julia functions that used AbstractFloat data types?

Is there something I am missing?

---

<div class="post-metadata">

### Author: ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)
#### Post date: [June 30, 2017, 12:34pm UTC](https://discourse.julialang.org/t/trouble-with-measurements-jl-and-bessel-functions/4562/2 "2017-06-30T12:34:50Z")

</div>

`Measurements.jl` supports any function whose argument’s type is no more specific than `AbstractFloat` and internally calls functions already supported, which is not the case for special functions with complex argument. I added support only for special functions with real argument, I should do the same for complex arguments as well. Patches are welcome 🙂

---

<div class="post-metadata">

### Author: ![Jason\_Kilpatrick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jason_kilpatrick/32/7662_2.png) [@Jason\_Kilpatrick](https://discourse.julialang.org/u/Jason_Kilpatrick)
#### Post date: [June 30, 2017, 12:51pm UTC](https://discourse.julialang.org/t/trouble-with-measurements-jl-and-bessel-functions/4562/3 "2017-06-30T12:51:57Z")

</div>

Many thanks. If I can figure out a patch I will be sure to submit it.

---

<div class="post-metadata">

### Author: ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)
#### Post date: [June 30, 2017, 1:03pm UTC](https://discourse.julialang.org/t/trouble-with-measurements-jl-and-bessel-functions/4562/4 "2017-06-30T13:03:15Z")

</div>

Look to definition of besselh in [https://github.com/JuliaPhysics/Measurements.jl/blob/master/src/math.jl](https://github.com/JuliaPhysics/Measurements.jl/blob/master/src/math.jl). It’s a function of real argument, but the output is complex. The `result` function is extensively commented, at the beginning of the file. The first argument is the nominal value, the second is the derivative, the last one is the input argument

---

<div class="post-metadata">

### Author: ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)
#### Post date: [June 30, 2017, 1:20pm UTC](https://discourse.julialang.org/t/trouble-with-measurements-jl-and-bessel-functions/4562/5 "2017-06-30T13:20:48Z")

</div>

Uhm, looking better, I believe another `result` method should be defined to support this case 🙂 So far, I didn’t have to worry about functions of complex arguments because most of such functions works out of the box (because they internally call supported functions), the only problem are special functions of complex argument because they only wrap external C functions

---

<div class="post-metadata">

### Author: ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)
#### Post date: [July 2, 2017, 3:06pm UTC](https://discourse.julialang.org/t/trouble-with-measurements-jl-and-bessel-functions/4562/6 "2017-07-02T15:06:02Z")

</div>

@Jason_Kilpatrick I just [added](https://github.com/JuliaPhysics/Measurements.jl/commit/7463ade7d8c735b1b705dfb4fcdff0924d3de4bc) the missing method for `result` function. The arguments are described in the comments before the new method.

In order to be able to add support to `besselj0` you should compute the derivatives of the real and imaginary parts of the result with respect to the real and imaginary parts of the argument, so they’re 4 derivatives in total. If you find out those quantities, `besselj0` with complex argument can be readily defined.

In the meantime, you can propagate the uncertainty of `besselj0` with complex argument (or any complex-valued function of one complex argument) by using the following macro, similar to the [`@uncertain` macro](https://measurementsjl.readthedocs.io/en/latest/usage.html#propagate-uncertainty-for-arbitrary-functions) which works only for functions of real arguments:

```julia
julia> using Measurements

julia> macro uncertain_complex(expr::Expr)
           f = esc(expr.args[1]) # Function name
           a = esc(expr.args[2]) # Argument, of Complex{Measurement} type
           return :( Measurements.result($f(Measurements.value($a)),
                                         vcat(Calculus.gradient(x -> real($f(complex(x[1], x[2]))),
                                                                [reim(Measurements.value($a))...]),
                                              Calculus.gradient(x -> imag($f(complex(x[1], x[2]))),
                                                                [reim(Measurements.value($a))...])),
                                         $a) )
       end
@uncertain_complex (macro with 1 method)

julia> @uncertain_complex besselj0(complex(1, 1 ± 0.5))
(0.9376084768060292 ± 0.18251401441177362) - (0.4965299476091221 ± 0.30708016745937555)im

julia> @uncertain_complex besselj0(complex(1 ± 0.5))
(0.7651976865579666 ± 0.22002529286918884) + (0.0 ± 0.0)im

julia> besselj0(1 ± 0.5)
0.7651976865579666 ± 0.22002529287246675

```

The last two lines shows that the macro correctly works in the case of a complex measurement with null imaginary parts (within numerical accuracy of `Calculus.gradient`), which is a good test case. This macro requires checking out `master` branch of the package, but I’ll probably tag a new version next week.

---

<div class="post-metadata">

### Author: ![Jason\_Kilpatrick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jason_kilpatrick/32/7662_2.png) [@Jason\_Kilpatrick](https://discourse.julialang.org/u/Jason_Kilpatrick)
#### Post date: [July 2, 2017, 3:35pm UTC](https://discourse.julialang.org/t/trouble-with-measurements-jl-and-bessel-functions/4562/7 "2017-07-02T15:35:00Z")

</div>

Many thanks for the quick solution.

---

<div class="post-metadata">

### Author: ![amaurigmartins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amaurigmartins/32/218207_2.png) [@amaurigmartins](https://discourse.julialang.org/u/amaurigmartins)
#### Post date: [September 7, 2025, 4:02pm UTC](https://discourse.julialang.org/t/trouble-with-measurements-jl-and-bessel-functions/4562/8 "2025-09-07T16:02:47Z")

</div>

Hi, I also needed the scaled forms `besselix` and `besselkx` so I further tweaked your macro:

```julia-auto
macro uncertain_bessel(expr::Expr)
	f = esc(expr.args[1]) # Function name
	order = expr.args[2] # First argument (order), no need to escape this
	a = esc(expr.args[3]) # Second argument (complex number with uncertainties)

	return :(Measurements.result(
		$f($order, Measurements.value($a)),
		vcat(
			Calculus.gradient(
				x -> real($f($order, complex(x[1], x[2]))),
				[reim(Measurements.value($a))...],
			),
			Calculus.gradient(
				x -> imag($f($order, complex(x[1], x[2]))),
				[reim(Measurements.value($a))...],
			),
		),
		$a,
	))
end

```

so it runs as:

```julia-auto
x = complex(1, 1 ± 0.5)
@uncertain_bessel(besselj(0,x))
>> (0.937608 ± 0.182514) + (-0.496530 ± 0.307080)im # regular besselj0

# scaled form
@uncertain_bessel(besseljx(0,x))
>> (0.344927 ± 0.105320) + (-0.182663 ± 0.021637)im

# plug back the scaling factor
@uncertain_bessel(besseljx(0,x))/exp(-abs(imag(x)))
>> (0.937608 ± 0.182514) + (-0.496530 ± 0.307080)im # guess it works

```

And because I wanted a single entry-point to all Bessels in my codebase, irrespective of deterministic/uncertain arguments, I cooked this module:

> <https://github.com/Electa-Git/LineCableModels.jl/blob/main/src/uncertainbessels/UncertainBessels.jl>
