Code Monkey home page Code Monkey logo

Comments (24)

dlfivefifty avatar dlfivefifty commented on September 25, 2024 1

Here's a speculative thought: how should an "uncountable iterator" work? Following Riemann integration, one approach would be to have a function partitions(::Domain) that gives an iterator of partitions of the domain that become increasingly small. Then Riemann integration would look something like:

function arclength(d::Domain)
   ret = Inf
   for p in partitions(d)
      new_ret = 0
      for (x, Δx) in p
          new_ret += norm(Δx)
      end
      new_ret  ret && break
      ret = new_ret
   end
   return ret
end

from domainsets.jl.

MikaelSlevinsky avatar MikaelSlevinsky commented on September 25, 2024 1

What about the old notions of length or arclength being lebesguemeasure?

  • No one would call that method out of confusion!
  • It's the same for open and closed intervals.

from domainsets.jl.

marcusdavidwebb avatar marcusdavidwebb commented on September 25, 2024 1

Or A -> hausdorffmeasure(A,1)? And area being A -> hausdorffmeasure(A,2)...?

from domainsets.jl.

marcusdavidwebb avatar marcusdavidwebb commented on September 25, 2024 1

No, because the integral for arclength is of a positive function.

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

This might actually be a case where Domain should be <: AbstractSet, and Set(::Domain) should throw an error.

from domainsets.jl.

daanhb avatar daanhb commented on September 25, 2024

Are there other examples of AbstractSet's that are non-iterable? If not, let's not inherit from AbstractSet.

How about ptype instead of eltype, short for pointtype?

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

You could in theory make domains iterable using nextfloat ...

from domainsets.jl.

daanhb avatar daanhb commented on September 25, 2024

Also, currently nothing prevents you from making a domain of Ints, which could be iterable efficiently, though that may be hard to implement with any kind of generality

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

Hm, I'm having second thoughts about this issue:

  1. The reason Set(1) returns Set([1]) is because 1 is a 1-element iterator, so we have for example
julia> for x in 1 print("$x") end
1

But I do not think interval(0,1) should act like a 1-element iterator, so Set(interval(0,1)) should not work.
2. In the example above, Set([interval(0,1)]) gives the right thing.

So I think eltype(::Domain) should be left as is.

If we wanted to be crazy, we could add this:

Base.start(d::Interval{:closed}) = d.a
Base.start(d::Interval{:open,R,<:AbstractFloat}) where R = nextfloat(d.a)
Base.next(d::ClosedInterval{<:AbstractFloat}, st) = st, nextfloat(st)
Base.done(d::Interval{R,:open,<:AbstractFloat}, st) where R = st  d.b
Base.done(d::Interval{R,:closed,<:AbstractFloat}, st) where R = st > d.b

function num_floats(d)
    k = 0
    for x in d
        k += 1
    end
    k
end

num_floats(interval(0,1E-316)) # 20240226,   in 0.062868s 

from domainsets.jl.

daanhb avatar daanhb commented on September 25, 2024

Hey, that takes 0.11 seconds on my desktop! The fact that such code is even possible makes me want to add it.

Okay, let's keep using eltype for the time being.

from domainsets.jl.

daanhb avatar daanhb commented on September 25, 2024

See 53c81f8.

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

Shouldn't cardinality be called length?

julia> Set([1,2,3]) |> length
3

from domainsets.jl.

daanhb avatar daanhb commented on September 25, 2024

True, that is a logical consequence. Okay, that is the reason this iteration is a bad idea. The question is whether we see an interval as the collection of all floating point numbers in between it, or as an approximation to a set of real numbers. Of course it is the latter, because we want the length of an interval to return what you would expect (b-a).

Yet, what is the length of the open interval (10,15) as a subset of the natural numbers? Is it 5 or 3? We may want to avoid using length altogether.

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

length should not return b-a as it causes numerous other issues in Base.

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

This is why at some point I changed from length to arclength for domains in ApproxFun.

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

The question comes down to is 0.5 in Interval{Int}(0,1)?

from domainsets.jl.

daanhb avatar daanhb commented on September 25, 2024

Okay, let's say we are not touching length, unless it agrees with what Base expects (the number of elements in an iterable sequence).

About the question: yes, this is a key point. My first reaction was that it would be hard to argue that 0.5 is in ClosedInterval{Int}(0,1), since the user has explicitly created the interval as a subset of integers. Yet, it currently is, due to the promotion rules in in. Then again, for the same promotion reason we have that nextfloat(big(0.5)) is in ClosedInterval{Float64}(0,1), even though this value can't be represented by the Float64 type. This case quite clearly is more desirable.

The simplest conceptual definition of a Domain{T} would be such that in returns false for any variable that is not of type T. But that goes against the promotion system in Julia, since for example big(0.5) == 0.5 is true. In fact, even convert(Float64, (big(0.5)+big(nextfloat(0.5)))/2) == 0.5 is true, so convert has a tolerance. (Following up on this logic, one could make a case for letting in be "fuzzy" up to some eps-related tolerance, which it currently isn't except in some cases.)

An alternative is to distinguish between "discrete" and "continuous" types (for which an eps can be meaningfully defined, say), and to disallow mixed promotion in the in function.

The third option is to let Julia's promotion system decide, as in the current implementation. So, 0.5 is in the interval because the interval can be promoted to Domain{Float64}.

Regardless, any interpretation of an interval as an absurdly large but discrete set of floating point values is bound to break at some point in practice.

I wasn't before, but I am currently in favour of the fuzzy in: that means 0.5 is in the Int interval - because Julia says so: leftendpoint(d) <= 0.5 <= rightendpoint(d) represents the interval. It is a matter of what you define things to be.

Perhaps slightly better is to let the domain decide when implementing in. This way we leave the decision in the hand of the user, who could still choose to implement a sequence of integers (though said user is probably better off using a UnitRange). That would mean the promotion logic currently in in would have to be implemented conditionally, somehow. Perhaps in by default can call approx_in with promoted arguments, and domains can choose to override approx_in or in itself.

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

I think the domain already decides itself when you call convert(Domain{T}, d). That is, 0.5 in ClosedInterval{Int}(0,1) because convert(Domain{Float64}, ClosedInterval{Int}(0,1)) returns ClosedInterval{Float64}(0,1).

from domainsets.jl.

daanhb avatar daanhb commented on September 25, 2024

Fair enough. This throws an error when the conversion fails, rather than returning false, but then again so does in in Base at times.

So, should in also be "fuzzy" or approximate everywhere? It currently isn't. That would make the distinction between open and closed domains conceptual, captured in their type perhaps but not in in, but in practice that is mostly the case anyway.

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

The current behaviour is not "fuzzy" and is precise to infinite-precision:

a in d                          # true
prevfloat(a) in d               # false
nextfloat(a) in d               # true

BigFloat(a) in d                # true
prevfloat(BigFloat(a)) in d     # false
nextfloat(BigFloat(a)) in d     # true

b in d                          # false
prevfloat(b) in d               # true
nextfloat(b) in d               # false

BigFloat(b) in d                # false
prevfloat(BigFloat(b)) in d     # true
nextfloat(BigFloat(b)) in d     # false

That is, It's the infinite-dimensional interval [a,b) where the endpoints are exactly expressible as floating point numbers. No matter what x is, a and b are expressible exactly as T = promote_type(typeof(x), Float64), and so there is no fuzzyness introduced by convert(T, a) and convert(T,b).

This precision is desirable and should be maintained.

Note this interpretation makes the sets truly infinite: x in d if x in convert(Domain{T}, d) for any T, which means it actually represents the mathematical interval [a,b). In other words, my for x in interval(0,1) is a bad idea.

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

What does this mean for Circle <: Domain{Complex128}? It means almost no floating Complex128s are in the domain, but if I make my own type: RadialComplex(r, θ) then RadialComplex(1.0, θ) will be in Circle(0.0, 1.0) for all θ provided convert(Domain{RadialComplex}, ::Circle) is overriden.

EDIT: we would actually need to support promote_type(RadialComplex, Complex128), which is difficult...

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

I think there is a limited and acceptable amount of fuzzyness arising from promote_type:

  promote_type(type1, type2)

  Determine a type big enough to hold values of each argument type without
  loss, whenever possible. In some cases, where no type exists to which both
  types can be promoted losslessly, some loss is tolerated; for example,
  promote_type(Int64, Float64) returns Float64 even though strictly, not all
  Int64 values can be represented exactly as Float64 values.

  julia> promote_type(Int64, Float64)
  Float64
  
  julia> promote_type(Int32, Int64)
  Int64
  
  julia> promote_type(Float32, BigInt)
  BigFloat

I think it is OK to follow the promote_type fuzzyness rule of almost no fuzzyness.

from domainsets.jl.

daanhb avatar daanhb commented on September 25, 2024

Okay, I think we agree on the notion that an interval is best defined mathematically, not in terms of possible concrete values of types. Good. Also, in general, it is a safe bet to follow Julia's standard practices in Base. I'm reverting the iterators :-)

We will still need more discussion about strictness for anything but intervals, but perhaps that is a separate issue.

from domainsets.jl.

dlfivefifty avatar dlfivefifty commented on September 25, 2024

Aren't there examples of functions which have finite arclength as defined via Riemann integration but infinite Lebesgue measure?

from domainsets.jl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.