- 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:

# add_mid [1.0; 2.0; 3.0];;

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

and run it twice to get quarters:

let add_quarters l = add_mid (add_mid l)

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;;

which is more adaptable (eg if you want thirds instead).

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 - On 01/11/2012 09:05 AM, Jean Saint-Remy wrote:
> Hi,

If you are thinking about mimicking the "where" keyword of Haskell,

>

> 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:

>

> let add_quarters l = add_mid (add_mid l)

>

> 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;;

>

> which is more adaptable (eg if you want thirds instead).

>

> 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

>

>