Loading ...
Sorry, an error occurred while loading the content.

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

Expand Messages
  • Jean Saint-Remy
    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:

      # 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
    • Francois Berenger
      ... 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"

        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 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
        >
        >
      Your message has been successfully submitted and would be delivered to recipients shortly.