Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add exponential ranges #43

Closed
wants to merge 1 commit into from

Conversation

chris-martin
Copy link
Contributor

Closes #37

clamp 0 99 sz0

diff =
(((abs (n - z) + 1) ** (realToFrac sz / 99)) - 1) * signum (n - z)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The outcome seems right, but my math could probably use a double-check here. I seem to be struggling to recall my high school algebra today.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could change this to:

scaleExponentialFrac :: RealFrac a => Size -> a -> a -> a
scaleExponentialFrac sz0 z n =
  let
    sz =
      clamp 0 99 sz0

    p :: Double
    p =
      realToFrac (abs (n - z) + 1) ** (realToFrac sz / 99)

    diff =
      (realToFrac p - 1) * signum (n - z)
  in
    if sz == 99 then
      z + n
    else
      z + diff

That way it's using floating point for less of the calculation, and it will work for Rational too, even if it's not ideal.

Copy link
Contributor Author

@chris-martin chris-martin Apr 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still doubting whether it's desirable to have Rational exponential ranges, because "shrinking" sort of loses its human relevance if the numerators and denominators are always huge numbers regardless of the size parameter.

> scaleExponentialFrac 80 (0 :: Rational) (100 :: Rational)
5721500312938077 % 140737488355328

> scaleExponentialFrac 2 (0 :: Rational) (100 :: Rational)
440089068475887 % 4503599627370496

If I were to really need this, I think rather have to write realToFrac <$> Range.exponentialFloat 0 (2^64) to acknowledge that I'm generating messy arbitrarily-precise ratios.

But... hmmm, maybe we could do better. Given that there's a fixed number of outputs from sizes 0 to 99, Maybe there's a clever way to reduce the ratios to a precision that is contextually appropriate?

@jacobstanley
Copy link
Member

I should get a chance to look at this tonight

@chris-martin
Copy link
Contributor Author

chris-martin commented Apr 11, 2017

Some notes on the design:

  • The way I'm doing the calculation involves a non-integral exponent, so I had to use floating-point arithmetic.
  • The Integral functions are just based on the Floating functions, with a rounding step at the end.
  • I didn't include Fractional exponential ranges; I'm not sure whether there is a reasonable way to do that.

-- (-39,112)
--
-- >>> bounds 99 $ exponentialFrom 0 (-128) 512
-- (-128,512)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These examples should probably have x instead of 0 because those things are true for all x

@jacobstanley
Copy link
Member

:shipit: I think this is better than what we have, so I'm going to rebase and merge it, we can always improve the algorithm in the future. No sense bikeshedding over Rational imo.

@jacobstanley
Copy link
Member

Rebase and merged fca1700

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants