This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Scala Double Iteration

16 replies
Samuel Robert Reid
Joined: 2008-12-17,
User offline. Last seen 1 year 22 weeks ago.

What is the best way to write this kind of double iteration in Scala?

for (double x=-10;x<=10;x+=0.025){...}

Thanks,
Sam Reid

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Scala Double Iteration

On Thu, Feb 12, 2009 at 08:56:44PM -0700, Samuel Robert Reid wrote:
> What is the best way to write this kind of double iteration in Scala?
>
> for (double x=-10;x<=10;x+=0.025){...}

The BEST? The best is definitely this:

(-10000 to 10000 by 25).map(_ / 1000d) foreach _

I will brook no debate, that is the best no matter what else you hear.

Tony Morris
Joined: 2008-12-19,
User offline. Last seen 30 weeks 4 days ago.
Re: Scala Double Iteration

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

- -40 to 40 map (_ / 4D) foreach k

Note that map/foreach can be composed into a single foreach.

Samuel Robert Reid wrote:
> What is the best way to write this kind of double iteration in
> Scala?
>
> for (double x=-10;x<=10;x+=0.025){...}
>
> Thanks, Sam Reid
>
>
>

- --
Tony Morris
http://tmorris.net/

*********************************************************
* Anteromedial Heterotopic Osseous Impingement Syndrome *
*********************************************************

http://www.ajronline.org/cgi/content/full/178/3/601
"can result in chronic ankle pain, especially in athletes and the
younger population (15-40 years old)"

http://radiographics.rsnajnls.org/cgi/content/figsonly/22/6/1457
"Soft-tissue and osseous impingement syndromes of the ankle can be an
important cause of chronic pain, particularly in the professional
athlete."

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFJlPDDmnpgrYe6r60RAoDSAJ9EsFi3SsNdaj7xmhM63K1LrSFHvACePeRI
yNuMq5OUZX8Sq1ie5LAz+ow=
=HQLy
-----END PGP SIGNATURE-----

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: Scala Double Iteration
It'd be nice to have a Range class for Longs, Doubles, Floats....

Then we could have

  for (x <- -10 to 10 by 0.025) { ... }

among other things.

Anyone want to volunteer a patch?

--j

On Thu, Feb 12, 2009 at 8:03 PM, Paul Phillips <paulp@improving.org> wrote:
On Thu, Feb 12, 2009 at 08:56:44PM -0700, Samuel Robert Reid wrote:
> What is the best way to write this kind of double iteration in Scala?
>
> for (double x=-10;x<=10;x+=0.025){...}

The BEST? The best is definitely this:

 (-10000 to 10000 by 25).map(_ / 1000d) foreach _

I will brook no debate, that is the best no matter what else you hear.

--
Paul Phillips      | A national political campaign is better than the
Caged Spirit       | best circus ever heard of, with a mass baptism and
Empiricist         | a couple of hangings thrown in.
i'll ship a pulp   |     -- H. L. Mencken

Samuel Robert Reid
Joined: 2008-12-17,
User offline. Last seen 1 year 22 weeks ago.
Re: Scala Double Iteration
I agree with Jorge Ortiz that Range (or equivalent) support would be nice for things other than Int.

  for (x <- -10 to 10 by 0.025) { ... }

is much more readable than:

for (x <- (-10000 to 10000 by 25).map(_ / 1000d)) ) { ... }

We should take care that the endpoint is correctly included or discarded (maybe include a tolerance to account for tiny errors in the floating point arithmetic).

Sam Reid

Jorge Ortiz wrote:
22a410d00902122023l388f4a40h14058cbe9164c3e4 [at] mail [dot] gmail [dot] com" type="cite">It'd be nice to have a Range class for Longs, Doubles, Floats....

Then we could have

  for (x <- -10 to 10 by 0.025) { ... }

among other things.

Anyone want to volunteer a patch?

--j

On Thu, Feb 12, 2009 at 8:03 PM, Paul Phillips <paulp [at] improving [dot] org" rel="nofollow">paulp@improving.org> wrote:
On Thu, Feb 12, 2009 at 08:56:44PM -0700, Samuel Robert Reid wrote:
> What is the best way to write this kind of double iteration in Scala?
>
> for (double x=-10;x<=10;x+=0.025){...}

The BEST? The best is definitely this:

 (-10000 to 10000 by 25).map(_ / 1000d) foreach _

I will brook no debate, that is the best no matter what else you hear.

--
Paul Phillips      | A national political campaign is better than the
Caged Spirit       | best circus ever heard of, with a mass baptism and
Empiricist         | a couple of hangings thrown in.
i'll ship a pulp   |     -- H. L. Mencken

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: Scala Double Iteration

for (x <- -10000 to 10000; y = x / 1000.0) { ... }

Looping over floats and doubles is inherently a bit silly. For
example, 16777216F + 1 == 16777216F.

2009/2/13 Samuel Robert Reid :
> I agree with Jorge Ortiz that Range (or equivalent) support would be nice
> for things other than Int.
>
> for (x <- -10 to 10 by 0.025) { ... }
>
> is much more readable than:
>
> for (x <- (-10000 to 10000 by 25).map(_ / 1000d)) ) { ... }
>
> We should take care that the endpoint is correctly included or discarded
> (maybe include a tolerance to account for tiny errors in the floating point
> arithmetic).
>
> Sam Reid
>
> Jorge Ortiz wrote:
>
> It'd be nice to have a Range class for Longs, Doubles, Floats....
>
> Then we could have
>
> for (x <- -10 to 10 by 0.025) { ... }
>
> among other things.
>
> Anyone want to volunteer a patch?
>
> --j
>
> On Thu, Feb 12, 2009 at 8:03 PM, Paul Phillips wrote:
>>
>> On Thu, Feb 12, 2009 at 08:56:44PM -0700, Samuel Robert Reid wrote:
>> > What is the best way to write this kind of double iteration in Scala?
>> >
>> > for (double x=-10;x<=10;x+=0.025){...}
>>
>> The BEST? The best is definitely this:
>>
>> (-10000 to 10000 by 25).map(_ / 1000d) foreach _
>>
>> I will brook no debate, that is the best no matter what else you hear.
>>
>> --
>> Paul Phillips | A national political campaign is better than the
>> Caged Spirit | best circus ever heard of, with a mass baptism and
>> Empiricist | a couple of hangings thrown in.
>> i'll ship a pulp | -- H. L. Mencken
>
>

tolsen77
Joined: 2008-10-08,
User offline. Last seen 1 year 38 weeks ago.
Re: Scala Double Iteration
I think they will lead to surprises for programmers (as me), like incrementing by a small number, the accumulated number (and sometimes total increments) will not be what was expected.

On Fri, Feb 13, 2009 at 9:50 AM, Ricky Clarkson <ricky.clarkson@gmail.com> wrote:
for (x <- -10000 to 10000; y = x / 1000.0) { ... }

Looping over floats and doubles is inherently a bit silly.  For
example, 16777216F + 1 == 16777216F.

2009/2/13 Samuel Robert Reid <Reids@colorado.edu>:
> I agree with Jorge Ortiz that Range (or equivalent) support would be nice
> for things other than Int.
>
>   for (x <- -10 to 10 by 0.025) { ... }
>
> is much more readable than:
>
> for (x <- (-10000 to 10000 by 25).map(_ / 1000d)) ) { ... }
>
> We should take care that the endpoint is correctly included or discarded
> (maybe include a tolerance to account for tiny errors in the floating point
> arithmetic).
>
> Sam Reid
>
> Jorge Ortiz wrote:
>
> It'd be nice to have a Range class for Longs, Doubles, Floats....
>
> Then we could have
>
>   for (x <- -10 to 10 by 0.025) { ... }
>
> among other things.
>
> Anyone want to volunteer a patch?
>
> --j
>
> On Thu, Feb 12, 2009 at 8:03 PM, Paul Phillips <paulp@improving.org> wrote:
>>
>> On Thu, Feb 12, 2009 at 08:56:44PM -0700, Samuel Robert Reid wrote:
>> > What is the best way to write this kind of double iteration in Scala?
>> >
>> > for (double x=-10;x<=10;x+=0.025){...}
>>
>> The BEST? The best is definitely this:
>>
>>  (-10000 to 10000 by 25).map(_ / 1000d) foreach _
>>
>> I will brook no debate, that is the best no matter what else you hear.
>>
>> --
>> Paul Phillips      | A national political campaign is better than the
>> Caged Spirit       | best circus ever heard of, with a mass baptism and
>> Empiricist         | a couple of hangings thrown in.
>> i'll ship a pulp   |     -- H. L. Mencken
>
>

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: Scala Double Iteration
How about using BigDecimal?

--j

On Fri, Feb 13, 2009 at 1:26 AM, Trond Olsen <tolsen77@gmail.com> wrote:
I think they will lead to surprises for programmers (as me), like incrementing by a small number, the accumulated number (and sometimes total increments) will not be what was expected.

On Fri, Feb 13, 2009 at 9:50 AM, Ricky Clarkson <ricky.clarkson@gmail.com> wrote:
for (x <- -10000 to 10000; y = x / 1000.0) { ... }

Looping over floats and doubles is inherently a bit silly.  For
example, 16777216F + 1 == 16777216F.

2009/2/13 Samuel Robert Reid <Reids@colorado.edu>:
> I agree with Jorge Ortiz that Range (or equivalent) support would be nice
> for things other than Int.
>
>   for (x <- -10 to 10 by 0.025) { ... }
>
> is much more readable than:
>
> for (x <- (-10000 to 10000 by 25).map(_ / 1000d)) ) { ... }
>
> We should take care that the endpoint is correctly included or discarded
> (maybe include a tolerance to account for tiny errors in the floating point
> arithmetic).
>
> Sam Reid
>
> Jorge Ortiz wrote:
>
> It'd be nice to have a Range class for Longs, Doubles, Floats....
>
> Then we could have
>
>   for (x <- -10 to 10 by 0.025) { ... }
>
> among other things.
>
> Anyone want to volunteer a patch?
>
> --j
>
> On Thu, Feb 12, 2009 at 8:03 PM, Paul Phillips <paulp@improving.org> wrote:
>>
>> On Thu, Feb 12, 2009 at 08:56:44PM -0700, Samuel Robert Reid wrote:
>> > What is the best way to write this kind of double iteration in Scala?
>> >
>> > for (double x=-10;x<=10;x+=0.025){...}
>>
>> The BEST? The best is definitely this:
>>
>>  (-10000 to 10000 by 25).map(_ / 1000d) foreach _
>>
>> I will brook no debate, that is the best no matter what else you hear.
>>
>> --
>> Paul Phillips      | A national political campaign is better than the
>> Caged Spirit       | best circus ever heard of, with a mass baptism and
>> Empiricist         | a couple of hangings thrown in.
>> i'll ship a pulp   |     -- H. L. Mencken
>
>


Alex Boisvert
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala Double Iteration
On Thu, Feb 12, 2009 at 7:56 PM, Samuel Robert Reid <Reids@colorado.edu> wrote:
What is the best way to write this kind of double iteration in Scala?

for (double x=-10;x<=10;x+=0.025){...}

def loop(start: Double, stop: Double, increment: Double)(f: Double => Unit): Unit = {
  if (start <= stop) {
    f(start)
    loop(start+increment, stop, increment)(f)
  }
}

loop(-10, 10, 0.025) { x => Console println x }
Colin Bullock
Joined: 2009-01-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala Double Iteration
Except:

scala> loop(1.0, 2.0, 0.1) { println _ }
1.0
1.1
1.2000000000000002
1.3000000000000003
1.4000000000000004
1.5000000000000004
1.6000000000000005
1.7000000000000006
1.8000000000000007
1.9000000000000008

scala>

Kinda missed an iteration there...

- Colin
Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Scala Double Iteration
Sometimes floating point numbers are more like sinking point numbers...

On Fri, Feb 13, 2009 at 4:39 PM, Colin Bullock <cmbullock@gmail.com> wrote:
Except:

scala> loop(1.0, 2.0, 0.1) { println _ }
1.0
1.1
1.2000000000000002
1.3000000000000003
1.4000000000000004
1.5000000000000004
1.6000000000000005
1.7000000000000006
1.8000000000000007
1.9000000000000008

scala>

Kinda missed an iteration there...

- Colin



--
Viktor Klang
Senior Systems Analyst
Szymon Jachim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala Double Iteration
IMHO, your solutio0ns it's doing N times FP division - not optimal.
It's also not very readable.  (comparing to the original)

Szymon

On Fri, Feb 13, 2009 at 5:03 AM, Paul Phillips <paulp@improving.org> wrote:
On Thu, Feb 12, 2009 at 08:56:44PM -0700, Samuel Robert Reid wrote:
> What is the best way to write this kind of double iteration in Scala?
>
> for (double x=-10;x<=10;x+=0.025){...}

The BEST? The best is definitely this:

 (-10000 to 10000 by 25).map(_ / 1000d) foreach _

I will brook no debate, that is the best no matter what else you hear.

--
Paul Phillips      | A national political campaign is better than the
Caged Spirit       | best circus ever heard of, with a mass baptism and
Empiricist         | a couple of hangings thrown in.
i'll ship a pulp   |     -- H. L. Mencken

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: Scala Double Iteration
0.1 can't be represented in binary, as it's an infinitely repeating decimal.  You probably want to use Tony or Paul's solution as you retain the greatest accuracy before converting to doubles.  Either that our add some kind of "acceptable error" in your check.


def loop(start: Double, stop: Double, increment: Double)(f: Double => Unit): Unit = {
  val err = 0.0000001
  if (start <= stop + err) {
    f(start)
    loop(start+increment, stop, increment)(f)
  }
}


On Fri, Feb 13, 2009 at 10:43 AM, Viktor Klang <viktor.klang@gmail.com> wrote:
Sometimes floating point numbers are more like sinking point numbers...

On Fri, Feb 13, 2009 at 4:39 PM, Colin Bullock <cmbullock@gmail.com> wrote:
Except:

scala> loop(1.0, 2.0, 0.1) { println _ }
1.0
1.1
1.2000000000000002
1.3000000000000003
1.4000000000000004
1.5000000000000004
1.6000000000000005
1.7000000000000006
1.8000000000000007
1.9000000000000008

scala>

Kinda missed an iteration there...

- Colin



--
Viktor Klang
Senior Systems Analyst

Colin Bullock
Joined: 2009-01-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala Double Iteration


On Fri, Feb 13, 2009 at 9:56 AM, Josh Suereth <joshua.suereth@gmail.com> wrote:
0.1 can't be represented in binary, as it's an infinitely repeating decimal.

Of course, that was my point really. If you're iterating over doubles, it's all too easy to pick values that don't always give you what you expect. Even accounting for some epsilon value in the stop criteria, the error compounds on each iteration for certain values and eventually (with a large enough range) you run up against the same problem.

If you iterate over integers, and calculate doubles, you avoid the problem (or at least the compounding error).

- Colin

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Scala Double Iteration

On Fri, Feb 13, 2009 at 04:54:29PM +0100, Szymon Jachim wrote:
> IMHO, your solutio0ns it's doing N times FP division - not optimal.
> It's also not very readable. (comparing to the original)

Hey, didn't I say it's the best no matter what anyone says? But you can have the original speedy one and I'll
take the one which is slow, unreadable, and works. I think anyone sweating a few expensive FP ops here is
insufficiently scared of floating point. Let's look at the original again:

> > > for (double x=-10;x<=10;x+=0.025){...}

How many iterations is that? Let's see, adding 0.025 40 times gives me 1.0000000000000004... looking forward
to the == 10 case. I wonder how many iterations it takes to accumulate enough rounding to gives us a bonus
one. I can feel the rocket swerving into a mountainside as we speak.

Robert Fischer
Joined: 2009-01-31,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala Double Iteration

This is one place where a BigDecimal works better -- the for loop will work as the user expected
given BigDecimal math.

~~ Robert Fischer.
Grails Training http://GroovyMag.com/training
Smokejumper Consulting http://SmokejumperIT.com
Enfranchised Mind Blog http://EnfranchisedMind.com/blog

Check out my book, "Grails Persistence with GORM and GSQL"!
http://www.smokejumperit.com/redirect.html

Colin Bullock wrote:
>
>
> On Fri, Feb 13, 2009 at 9:56 AM, Josh Suereth > wrote:
>
> 0.1 can't be represented in binary, as it's an infinitely repeating
> decimal.
>
> Of course, that was my point really. If you're iterating over doubles, it's all too easy to pick
values that don't always give you what you expect. Even accounting for some epsilon value in the
stop criteria, the error compounds on each iteration for certain values and eventually (with a large
enough range) you run up against the same problem.
>
> If you iterate over integers, and calculate doubles, you avoid the problem (or at least the
compounding error).
>
> - Colin
>

Paavo Nevalainen
Joined: 2009-02-13,
User offline. Last seen 42 years 45 weeks ago.
Re: Scala Double Iteration

Colin Bullock gmail.com> writes:

>
> Except:scala> loop(1.0, 2.0, 0.1) { println _ }
1.01.11.20000000000000021.30000000000000031.40000000000000041.50000000000000041
.60000000000000051.70000000000000061.80000000000000071.9000000000000008scala>Ki
nda missed an iteration there...- Colin

Probably this thread contains some humor, since nobody uses floats that way,
yet they ARE used widely around. Of course there are occasional round-offs
here and there, so better not let them cumulate:

def loop(start: Double, stop: Double, step: Double)(f: Double => Unit): Unit
= {

val upwards= stop > start
val downwards= stop < start

def loop0(counter: Int): Unit = {

Console print " "

val current= start + counter * step
f(current)
if((upwards && current < stop) || (downwards && current > stop))
loop0(counter + 1)
}

if(upwards && step > 0.0 || (downwards && step < 0.0))
loop0(0)
else
throw new IllegalArgumentException
}
...
loop(-10,10, 0.025){x => Console println x}
...

===>

9.725000000000001
9.75
9.775000000000002
9.8
9.835000000000003
9.850000000000001
9.875
9.900000000000002
9.925
9.950000000000003
9.975000000000001
10.0

There is no worry about the inexact values, that is how numerical world is!
And there is no worry about matching exactly with the end value! Consider the
following:

// the last value is about 3.100000000000000z,
// insert your guess for z, the right answer
// wins you a free Scala compiler!
for(x <- 0.0 to Math.PI by 0.1) println(x)

Also, we cannot do much more than what primitives .>. and .<. do when
trying to decide whether it is a valid raneg definition or not. (I guess
to and by can be implemented the same way as in the standard package range.
I am a complete Scala noob so cannot be sure though.)

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland