## Re: interpolating in a list (was: Re: "ocaml_beginners"::[] Too many words ruin the function)

Expand Messages
• Hi, Thanks a million. That s a very interesting idea of having a variable declared with keyword as inside a rec function. There is however a very very small
Message 1 of 4 , Jan 10, 2012
• 0 Attachment
Hi,

Thanks a million. That's a very interesting idea of having a variable declared with keyword "as"

inside a rec function.

There is however a very very small problem. The data with which I am working, and I am not so sure how,

contains some mystery element called a "residual", so that a function with symmetrical values, such as

a half and a quarter (and so on) introduce an error. With these algorithmic values I am ready for the gentlemen in white coats. The distance between x and y is 5415, 5550, 5640, it all varies. So I could not map "one of a kind" value to the entire list. My apologies for the muddle-headed language here. I am coerced for lack of a better word to subtract and divide each in turn.

Jean

----- Original Message -----
From: Toby Kelsey <toby.kelsey@...>
To: ocaml_beginners@yahoogroups.com
Cc: Jean Saint-Remy <jeansaintremy@...>
Sent: Monday, January 9, 2012 1:14 PM
Subject: interpolating in a list (was: Re: "ocaml_beginners"::[] Too many words ruin the function)

On 09/01/12 17:02, Jean Saint-Remy wrote:
> let fa = [| 1325221860.; 1325243520.; 1325265720.; 1325288280.; |]  ;;
>
> for i=0 to ( Array.length fa ) - 1
>  do
>    try
>        Printf.printf "%.f\n" fa.(i);
>        Printf.printf "%.f\n" (((fa.(i+1) -. fa.(i)) /. 4.0 ) +. fa.(i));
>        Printf.printf "%.f\n" ((((fa.(i+1) -. fa.(i)) /. 4.0 ) *. 2.0 ) +. fa.(i));
>        Printf.printf "%.f\n" ((((fa.(i+1) -. fa.(i)) /. 4.0 ) *. 3.0 ) +. fa.(i));
>    with Invalid_argument i -> ();
> done ;;

So basically you want to interpolate some values in a list. You could add
mid-points with something like this:

let rec add_mid lst = match lst with
| h1 :: (h2 :: t as rest) -> h1 :: 0.5*.(h1+.h2) :: add_mid rest
| [x] -> lst
| [] -> lst;;

which produces:

- : float list = [1.; 1.5; 2.; 2.5; 3.]

and run it twice to get quarters:

or just directly add multiple values in one go:

let rec add_quarters lst = match lst with
| h1 :: (h2 :: t as rest) ->
let q = 0.25*.(h2-.h1) in
h1 :: h1+.q :: h1+.2.0*.q :: h1+.3.0*.q :: add_quarters rest
| [x] -> lst
| [] -> lst;;

If you're not sure what the "as rest" line means, it is almost the same as writing:

| h1 :: h2 :: t -> h1 :: 0.5*.(h1+.h2) :: add_mid (h2::t)

except you reuse part of the list instead of reconstructing it (potentially
faster).

Hope this helps,
Toby
• ... If you are thinking about mimicking the where keyword of Haskell, I don t think that s very nice for readability: when you read the code, if where is
Message 2 of 4 , Jan 10, 2012
• 0 Attachment
On 01/11/2012 09:05 AM, Jean Saint-Remy wrote:
> Hi,
>
> Thanks a million. That's a very interesting idea of having a variable
> declared with keyword "as"

I don't think that's very nice for readability:
when you read the code, if "where" is used too much, you are
reading some text/code with a lot of forward references.

As functions in Haskell code usually have too much short names
and variable names, it is painful to read. You read a lot
of code calling functions that you don't know yet what they
are doing.

Regards,
F.

> inside a rec function.
>
> There is however a very very small problem. The data with which I am
> working, and I am not so sure how,
>
> contains some mystery element called a "residual", so that a function
> with symmetrical values, such as
>
> a half and a quarter (and so on) introduce an error. With these
> algorithmic values I am ready for the gentlemen in white coats. The
> distance between x and y is 5415, 5550, 5640, it all varies. So I could
> not map "one of a kind" value to the entire list. My apologies for the
> muddle-headed language here. I am coerced for lack of a better word to
> subtract and divide each in turn.
>
> Jean
>
> ----- Original Message -----
> From: Toby Kelsey <toby.kelsey@... <mailto:toby.kelsey%40gmail.com>>
> To: ocaml_beginners@yahoogroups.com
> <mailto:ocaml_beginners%40yahoogroups.com>
> Cc: Jean Saint-Remy <jeansaintremy@...
> <mailto:jeansaintremy%40yahoo.com>>
> Sent: Monday, January 9, 2012 1:14 PM
> Subject: interpolating in a list (was: Re: "ocaml_beginners"::[] Too
> many words ruin the function)
>
> On 09/01/12 17:02, Jean Saint-Remy wrote:
> > let fa = [| 1325221860.; 1325243520.; 1325265720.; 1325288280.; |] ;;
> >
> > for i=0 to ( Array.length fa ) - 1
> > do
> > try
> > Printf.printf "%.f\n" fa.(i);
> > Printf.printf "%.f\n" (((fa.(i+1) -. fa.(i)) /. 4.0 ) +. fa.(i));
> > Printf.printf "%.f\n" ((((fa.(i+1) -. fa.(i)) /. 4.0 ) *. 2.0
> ) +. fa.(i));
> > Printf.printf "%.f\n" ((((fa.(i+1) -. fa.(i)) /. 4.0 ) *. 3.0
> ) +. fa.(i));
> > with Invalid_argument i -> ();
> > done ;;
>
> So basically you want to interpolate some values in a list. You could add
> mid-points with something like this:
>
> let rec add_mid lst = match lst with
> | h1 :: (h2 :: t as rest) -> h1 :: 0.5*.(h1+.h2) :: add_mid rest
> | [x] -> lst
> | [] -> lst;;
>
> which produces:
>
> # add_mid [1.0; 2.0; 3.0];;
> - : float list = [1.; 1.5; 2.; 2.5; 3.]
>
> and run it twice to get quarters:
>
>
> or just directly add multiple values in one go:
>
> let rec add_quarters lst = match lst with
> | h1 :: (h2 :: t as rest) ->
> let q = 0.25*.(h2-.h1) in
> h1 :: h1+.q :: h1+.2.0*.q :: h1+.3.0*.q :: add_quarters rest
> | [x] -> lst
> | [] -> lst;;
>
>
> If you're not sure what the "as rest" line means, it is almost the same
> as writing:
>
> | h1 :: h2 :: t -> h1 :: 0.5*.(h1+.h2) :: add_mid (h2::t)
>
> except you reuse part of the list instead of reconstructing it (potentially
> faster).
>
> Hope this helps,
> Toby
>
>
Your message has been successfully submitted and would be delivered to recipients shortly.