Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Programming > Functional > Re: in F#, how ...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 2 of 3 Topic 2692 of 3037
Post > Topic >>

Re: in F#, how do I...

by Jon Harrop <usenet@[EMAIL PROTECTED] > Dec 14, 2007 at 01:09 PM

mensanator@[EMAIL PROTECTED]
 wrote:
> ...access individual members of a tuple?
> 
> This works, but is it right?
> let remainder a b =
> let rem (x,y) = y

There is already a built-in function call "snd" that extracts the second
element of a pair.

> rem (BigInt.divmod a b)

So this could be:

  snd (BigInt.divmod a b)

> ...access individual members of a list?
> 
> This also works, but appears horribly inefficient...
> > a;;
> val it : int list = [1; 2; 3; 4]
> > List.nth a 1;;
> val it : int = 2

As long as you're using a list, you can do no better.

> ...when used to iterate through the list
> let hailstone_function_parameters sv =
> let mutable list_sum = 0I
> let mutable list_cnt = 0I
> let mutable Z = 0I
> let mutable e = 0I
> let svl = (List.length sv) - 1
> for i = (svl) downto 0 do
> // slow (due to List.nth)
> list_sum <- list_sum + (List.nth sv i)
> // fast
> list_cnt <- list_cnt + 1I
> // REAL slow
> Z <- Z+((BigInt.pow 3I (BigInt.of_int i))*(BigInt.pow 2I e))

Actually that bit is fast.

> // slow
> e <- e + (List.nth sv (svl - i))

But this bit is really slow.

> done
> let X = BigInt.pow 2I list_sum
> let Y = BigInt.pow 3I list_cnt
> (X,Y,Z)

If that is too slow then use an array. Try something like:

  let hailstone_function_parameters sv =
    let sv = Array.of_list sv
    let n = Array.length sv
    let mutable z = 0I
    let mutable e = 0I
    for i = 0 to n - 1 do
      z <- z + BigInt.pow 3I (BigInt.of_int i) * BigInt.pow 2I e
      e <- e + sv.[n - 1 - i]
    BigInt.pow 2I (Array.fold1_left ( + ) sv),
    BigInt.pow 3I (Array.length sv |> BigInt.of_int),
    z

Also, are you sure you need big ints here?

> I note List methods like .iter and .map but haven't quite
> figured out how to use them or if they are faster than
> List.nth.

Learn them: iter and map are O(n) wheras nth in a loop is O(n^2).

> And I'm not changing every item on the list or 
> creating a new list, I'm creating a running sum based on
> list contents.

Then you want a fold, e.g. to compute ((1+2)+3)+4 = 10:

  List.fold1_left ( + ) [1;2;3;4]
val it : int = 10

> Is a list even the right thing to use?

Not for your last function, no. You might consider using arrays
throughout.

Lists are great when you want to keep prepending elements.

> To creat the list, I was doing
> while (ccc>1I) do
> let fs = fell_swoop ccc
> ccc <- t_0 fs
> sv  <- List.append sv [t_1 fs] // slow

That can be written:

  sv @[EMAIL PROTECTED]
 [t_1 fs]

Note that this iterates over the whole of sv.

> done

Without fell_swoop, t_0 and t_1, I can't tell what this is trying to
achieve.

You probably want a simple recursive function instead:

  let rec create rsv ccc =
    if ccc <= 1I then List.rev rsv else
    let fs = fell_swoop ccc
    create (t_1 fs :: rsv) (t_0 fs)

> But that's real slow also. OTOH,
> while (loop_point_found=0) do
> let fs = test_fell_swoop ccc
> ccc <- t_0 fs
> L <- L + 1
> test_sv <- (t_1 fs)::test_sv // fast
> if ccc=19I then
> (loop_point_found  <- 1)
> printf "\n %d odd numbers found\n\n" L
> if L>124000 then (loop_point_found  <- 1)
> done
> 
> works fast (we're talking a couple seconds vs almost 9 minutes)
> although the list is constructed backwards. Luckily, List.rev
> seems quite fast.

Yes, List.rev is O(n). You've rediscovered that constructing lists in
reverse is very common in the ML family of languages, including F#. The
trade-off is that lists are very lightweight in these languages compared
to
the heavy doubly-linked mutable lists that you find in C++ and (probably)
C#.

> But is this the right way to build a list dynamically?

Lists in F# are fast for prepend only. So always prepend.

> Should I be using something else, like an array?

Possibly. See the article about data structures in the F#.NET Journal.

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?u
 




 3 Posts in Topic:
in F#, how do I...
"mensanator@[EMAIL P  2007-12-13 13:44:22 
Re: in F#, how do I...
Jon Harrop <usenet@[EM  2007-12-14 13:09:31 
Re: in F#, how do I...
"mensanator@[EMAIL P  2007-12-14 17:24:27 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Sat Oct 11 6:30:06 CDT 2008.