# Less than approx equals? \<≈

**URL:** <https://discourse.julialang.org/t/less-than-approx-equals/45436>\
**Category:** New to Julia\
**Created:** [August 23, 2020, 11:41pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436 "2020-08-23T23:41:20Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [August 23, 2020, 11:41pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/1 "2020-08-23T23:41:20Z")

</div>

```julia
leaq(a,b) = (a <= b) || (a ≈ b)

leaq(a,b,c) = leaq(a,b) && leaq(b,c)

```

Is there a better way of doing this? The only alternative I can think of is to subtract some epsilon from the lesser part of the inequality based on machine precision? I feel like it should be in Base, but I’m sure there’s a good reason why it isn’t.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 24, 2020, 12:12am UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/2 "2020-08-24T00:12:34Z")

</div>

`isapprox` is mainly used for tests. What is approximate `<=` useful for? Without knowing the application, it’s hard to prescribe its behavior.

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [August 24, 2020, 12:15am UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/3 "2020-08-24T00:15:59Z")

</div>

Sure so I recently was doing point of intersection of 2 line segments.

![unit_test](https://global.discourse-cdn.com/julialang/original/3X/8/a/8a04bd5bee9150aaa27d3d3ebf2aa124ba17429d.gif)

in this case, we have a line that has the same Y value at both endpoints. So one might want to ensure that a given point of intersection is:  
A.y \<= PoI.y \<= B.y

So say A.y = 1.5000000000001 and B.y = 1.4999999999999999 and PoI.y = 1.5  
It will fail the check!  
but, A.y \<≈ PoI.y \<≈ B.y  
would work just fine.  
Does that make sense? Sorry if this is still unclear.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [August 24, 2020, 12:28am UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/4 "2020-08-24T00:28:15Z")

</div>

I saw [GitHub - lairez/ExactPredicates.jl: Fast and exact geometrical predicates in the Euclidean plane](https://github.com/lairez/ExactPredicates.jl) awhile ago which seems like it might be of interest to you

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [August 24, 2020, 12:38am UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/5 "2020-08-24T00:38:12Z")

</div>

Cool package! Unfortunately, it doesn’t have a lot of what I need. For example, the `meet` function doesn’t return the point of intersection. In this case, it was ~10 LOC to just write it myself.

Predominately interested in the OP though. This example is just for fun but I’ll be running into more of this as time progresses on this project.

---

<div class="post-metadata">

**Author:** ![mforets](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mforets/32/298_2.png) [@mforets](https://discourse.julialang.org/u/mforets)\
**Post date:** [August 24, 2020, 3:16am UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/6 "2020-08-24T03:16:34Z")

</div>

> Less than approx equals?

[LazySets.jl](https://github.com/JuliaReach/LazySets.jl) internally uses `LazySets._leq`; you can check the definition in `src/Utils/comparisons.jl`, and the approximate equality can be changed with the `set_x` functions where `x` is `atol`, `rtol` or `ztol`. For example:

```julia
# approximate membership test
julia> [1.5, 1.5] ∈ LineSegment([1.5, 1.50000000000001], [1.5, 2.0])
true

# change the default Float64 tolerance
julia> r = LazySets._rtol(Float64);

julia> LazySets.set_rtol(Float64, 1e-20)
1.0e-20

julia> [1.5, 1.5] ∈ LineSegment([1.5, 1.50000000000001], [1.5, 2.0])
false

julia> LazySets.set_rtol(Float64, r); # revert change

```

For the intersection of line segments,

```julia
using LazySets, Plots

α = 1.5000000000001
β = 1.4999999999999999
A = LineSegment([1.0, β], [2.0, β])
B = LineSegment([1.5, α], [1.5, 2])
plot(A, lab="A")
plot!(B, lab="B")

LazySets.set_rtol(Float64, 1e-12)
@show intersection(A, B)
LazySets.set_rtol(Float64, 1e-20)
@show intersection(A, B)

intersection(A, B) = Singleton{Float64,Array{Float64,1}}([1.5, 1.5])
intersection(A, B) = EmptySet{Float64}(2)

```

(Note: for these examples you’ll need to checkout the branch `mforets/robust_in_linesegment` until it’s been merged 😉 )

 ![Screenshot from 2020-08-24 01-11-43](https://global.discourse-cdn.com/julialang/original/3X/2/e/2ec63931420eb2e62b825d2455704738d1153ca2.png)

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [August 24, 2020, 8:14pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/7 "2020-08-24T20:14:43Z")

</div>

Cool mforets. So I checked for that branch and don’t see it in there, also checked your fork and didn’t see it in there, might still be local? But, that’s okay I’m happy with my code except how I handled \<≈. That being said, it’s probably the solution I’ll use at this point, otherwise, I’d have to deal with 100s of hrs of politics/PRs when I’m just messing around… For a hobby - that’s definitely not optimal on the fun scale. So no need to race to do stuff, I’m not making a package, flag-planting, or stepping on toes here…

I quickly looked at the code for \_leq in LazySets but I didn’t really understand it. Is it overloading from Base? Seems a little risque compared to just defining a new operator with different semantics. It seems like you’ve run into this issue as well though, so at least I’m not alone. What are your thoughts about introducing a \<≈ operator into Julia Base? Is it too specialized?

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [August 24, 2020, 8:30pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/8 "2020-08-24T20:30:58Z")

</div>

I don’t know, if it should actually be defined in Base, but I do think allowing `<≈` and `>≈` as operators might be useful.

---

<div class="post-metadata">

**Author:** ![anon37204545](https://avatars.discourse-cdn.com/v4/letter/a/439d5e/32.png) [@anon37204545](https://discourse.julialang.org/u/anon37204545)\
**Post date:** [August 24, 2020, 8:56pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/9 "2020-08-24T20:56:45Z")

</div>

> [@anon92994695](#):
>
> `leaq(a,b) = (a <= b) || (a ≈ b)`

The operator makes perfect sense to me, but why not just define it with `<` instead of `<=`:

```julia
(a < b) || (a ≈ b)

```

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [August 24, 2020, 8:58pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/10 "2020-08-24T20:58:39Z")

</div>

good point, that is more concise.

---

<div class="post-metadata">

**Author:** ![mforets](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mforets/32/298_2.png) [@mforets](https://discourse.julialang.org/u/mforets)\
**Post date:** [August 24, 2020, 8:59pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/11 "2020-08-24T20:59:01Z")

</div>

> [@anon92994695](#):
>
> So I checked for that branch and don’t see it in there, also checked your fork and didn’t see it in there, might still be local?

Oops, it’s already been merged, and the branch deleted. You can checkout the `master` branch or wait to the next patch release, probably tomorrow…

> I quickly looked at the code for \_leq in LazySets but I didn’t really understand it. Is it overloading from Base?

See [this function](https://github.com/JuliaReach/LazySets.jl/blob/master/src/Utils/comparisons.jl#L407), that I copy here for convenience:

```julia
function _leq(x::N, y::N;
              rtol::Real=_rtol(N),
              ztol::Real=_ztol(N),
              atol::Real=_atol(N)) where {N<:AbstractFloat}
    return x <= y || _isapprox(x, y, rtol=rtol, ztol=ztol, atol=atol)
end

```

It doesn’t overload functions from Base, it simply uses an internal `_isapprox` for approximate equality comparisons, with tolerances that can be set at once (globally) for all operations. Some problems require very small tolerances, for other problems you can work with bigger tolerances so it’s useful to be able to change everything with one command (like tests for disjointness, inclusion, membership, etc).

> What are your thoughts about introducing a \<≈ operator into Julia Base? Is it too specialized?

I think that’s not justified, the building blocks are already in Base, and the actual meaning of approximate `<=` depends a lot on the application (as suggested above).

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [August 24, 2020, 9:03pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/12 "2020-08-24T21:03:07Z")

</div>

Cool, well I may use this package for future stuff. For now, think I’ll go with the lightweight thing, but thank you for the discussion and the philosophy.

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [August 24, 2020, 10:15pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/13 "2020-08-24T22:15:59Z")

</div>

> [@anon37204545](#):
>
> The operator makes perfect sense to me, but why not just define it with `<` instead of `<=` :
> 
> ```julia
> (a < b) || (a ≈ b)
> 
> ```

I wouldn’t do that. Keep it `(a <= b) || (a ≈ b)` as there’s no downsides to it when the values are the same. Changing to \< only saves one byte in the source code, but not in the assembly, and will be slower when values are equal, then you need to call to long function (that you will not see in the assembly as not inlined):

```julia
julia> @code_native isapprox(1.0, 1.0)

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [August 25, 2020, 3:08am UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/14 "2020-08-25T03:08:34Z")

</div>

True, but if you are using `≈` this means that you already expect the values to not be exactly equal. If there is any noise involved, the chance of two floating points evaluating false for `<` but true for `<=` already get very low. Will be consistently faster only for people doing integer arithmetic on floating points.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 25, 2020, 4:31am UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/15 "2020-08-25T04:31:29Z")

</div>

You don’t know who will be calling code that potentially uses `<≈`, or why they do it.

> [@anon92994695](#):
>
> ```julia
> leaq(a,b) = (a <= b) || (a ≈ b)
> 
> ```

Will be no worse, and potentially better, in each case.

---

<div class="post-metadata">

**Author:** ![lostella](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lostella/32/356_2.png) [@lostella](https://discourse.julialang.org/u/lostella)\
**Post date:** [August 25, 2020, 10:32am UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/16 "2020-08-25T10:32:26Z")

</div>

I can think of checking approximate feasibility of a solution to a constrained problem, e.g. checking that Ax \<= b up to some tolerance.

---

<div class="post-metadata">

**Author:** ![lostella](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lostella/32/356_2.png) [@lostella](https://discourse.julialang.org/u/lostella)\
**Post date:** [August 25, 2020, 10:34am UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/17 "2020-08-25T10:34:13Z")

</div>

I would use something like this. But why not allowing additional kwargs?

```julia
leaq(a, b; kwargs...) = (a <= b) || isapprox(a, b; kwargs...)

```

Edit: added semicolon, thanks @mtsch

---

<div class="post-metadata">

**Author:** ![mtsch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mtsch/32/2072_2.png) [@mtsch](https://discourse.julialang.org/u/mtsch)\
**Post date:** [August 25, 2020, 9:14pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/18 "2020-08-25T21:14:38Z")

</div>

You need to use `;` when splatting kwargs.

```julia
leaq(a, b; kwargs...) = (a <= b) || isapprox(a, b; kwargs...)

```

What you wrote tres to splat `kwargs` as positional arguments.

---

<div class="post-metadata">

**Author:** ![anon92994695](https://avatars.discourse-cdn.com/v4/letter/a/ce7236/32.png) [@anon92994695](https://discourse.julialang.org/u/anon92994695)\
**Post date:** [September 16, 2020, 8:25pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/20 "2020-09-16T20:25:54Z")

</div>

It would be pretty awesome to be able to make functions from 2 or more symbols. I ran into this when I was trying to do approximate greater than and approximate lesser than functions. Something tells me the julia parser can’t handle this? Does anyone know differently?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 16, 2020, 8:31pm UTC](https://discourse.julialang.org/t/less-than-approx-equals/45436/21 "2020-09-16T20:31:25Z")

</div>

> [@anon92994695](#):
>
> It would be pretty awesome to be able to make functions from 2 or more symbols. I ran into this when I was trying to do approximate greater than and approximate lesser than functions

Why not use `≲` and `≳` or `⪅` and `⪆`, which are all valid infix comparison operators in Julia?

I suppose you mean _binary operators_ and not just “functions” — binary operators in Julia can’t be arbitrary combinations of symbols, but you have a huge list of Unicode operators to choose from — far more than in any other mainstream language — and can additionally suffix them in various ways (e.g. `<ᵃ` and `<′`). See also [this issue on custom infix operators](https://github.com/JuliaLang/julia/issues/16985).

[Next page](https://discourse.julialang.org/t/less-than-approx-equals/45436.md?page=2)
