# Isapprox for array of tuples

My aim is to approximately compare two arrays of tuples for needs of regression tests. There should be a more simple way to do `isapprox(R,R2)` than the following

``````    R = [
(4.0, 75.96375653207353)
(6.0, 79.81178239308181)
(8.0, 81.19371107853809)
(9.0, 83.6598082540901)
(10.0, 81.8365732447175)
(12.0, 85.04173693954638)
(15.0, 85.6845991057258)
(16.0, 86.42366562500266)
(20.0, 87.06652779118207)
(25.0, 87.70938995736148)
];
R2 = [
(4.0, 82.8749836510982)
(6.0, 85.23635830927383)
(8.0, 86.42366562500266)
(9.0, 86.82016988013577)
(10.0, 87.13759477388825)
(12.0, 87.61405596961119)
(15.0, 88.09084756700362)
(16.0, 88.21008939175394)
(20.0, 88.56790381583535)
(25.0, 88.8542371618249)
];

@test all([ all(map( (i,j) -> isapprox(i,j), R[k], T[k])) for k in 1:length(first.(R)) ])
``````

Thanks!

``````all(all.(map((i,j) -> isapprox.(i,j), R, R2)))
``````

Broadcasting makes it a bit more concise, but I’ve always found handling nested data structures like this rather clunky.

Comprehension syntax might make it a bit less clunky seeming than `map`?

``````all(all.(isapprox.(i,j) for (i,j) in zip(R,R2)))
``````

EDIT: Actually, using `Base.Iterators` does provide a clean solution:

``````using Base.Iterators

all(isapprox.(flatten(R), flatten(R2)))
``````
3 Likes

Note that you may or may not want elementwise `isapprox`: you might want to set the tolerance based on the norm of the whole array.

For example, do you want `[(0.0,1.0)]` to be approximately equal to `[(1e-100,1.0)]`? Your comparison will return `false`, because `isapprox(0.0, 1e-100)` is `false`: see the documentation on `x ≈ 0`. However, if you look at the whole array at once, the other entry `1.0` sets a scale against which `1e-100` can be viewed as “small”.

The alternative would be to look at the whole array at a time, e.g. via:

``````isapprox(collect(Iterators.flatten(R)), collect(Iterators.flatten(R2)))
``````

or, even more simply:

``````isapprox(collect.(R), collect.(R2))
``````
4 Likes