¿Es esta una implementación razonable de la función de Bézier cuadrática en OCaml?

StackOverflow https://stackoverflow.com/questions/145056

  •  02-07-2019
  •  | 
  •  

Pregunta

Un amigo se encontró con una función de curva de B y # 233; cuadrática en su base de código que usaba un nido de ratas gigantescas de una tabla de interruptores para realizar el cálculo. Me desafió a encontrar una expresión corta y única que le permitiera reemplazar el bloque de código gigantesco.

Al intentar satisfacer dos curiosidades diferentes, pensé que intentaría implementar la función en OCaml. Soy un programador OCaml muy novato y tampoco estoy familiarizado con la función y esta implementación específica es difícil de conseguir a través de Google.

Las críticas sobre el rendimiento / corrección de la función, así como su implementación, son muy apreciadas.

Implementación de Quadratic B & # 233; zier Curve :

let rec b2 n =
let p1 = -10. in
let p2 = 10. in
let q = n*.n in
let rec b2i n i hd =
  if i > n then
    List.rev hd
  else
    let t = i /. n in
  b2i n (i+.1.) ((((1.-.t)**2.)*.p1+.(2.*.t*.(1.-.t)*.q)+.(t**2.)*.p2) :: hd)
in b2i n 0. []
;;
let floatprint lst = List.iter (fun f -> Printf.printf "%f; " f) lst ;;
floatprint (b2 8.);;
¿Fue útil?

Solución

b2 no es recursivo, por lo que no es necesario [vamos a rec b2 n =]. Dado que n nunca cambia, no es necesario tenerlo como argumento para b2i, solo use n del ámbito que lo incluye. Su función interna debe depender de p0, p1 y p2, pero la veo dependiendo de -10., N ** 2 y 10. La función también tiene la forma de un mapa de [0.0; 1.0; 2.0; ...; n.0] a los valores finales. Podrías escribirlo:

let b i = 
  let t = i /. n in
  let tminus = (1.-.t) in
  (tminus *. tminus *. p0) +. (2. *. t *. tminus *. p1) +. (t *. t * p2)
in
List.map b ([generate list 1.0; 2.0; ... n.0])

Una función para generar la lista 1.0 ... n.0 podría ser: (para n pequeña)

let rec count m n = if m > n then [] else m :: (count (m+.1.) n)

Otros consejos

Tengo dos sugerencias:

Debería llamar a List.rev después de que b2i regrese para que ocaml pueda explotar sus optimizaciones de recursión de cola. No estoy seguro de qué tan bien tratará Ocaml con la implementación actual, aunque List.rev es recursivo. Notarás que en esta publicación se hace como que.

Además, puede hacer que la resolución de la iteración sea un argumento opcional como ? (epsilon = 0.1) .

Como programador de Ocaml, no veo mucho mal aquí aparte de eso, siempre y cuando P1 y P2 sean en realidad constantes. Compílelo y vea cuál es la diferencia en el ensamblaje al mover List.rev dentro o fuera de la recursión de la cola.

Esto puede ser picayune, pero hd no es un buen nombre para un parámetro de lista. List.hd es una función estándar que devuelve el primer elemento de una lista. El uso de hd como nombre para una lista dará lugar a confusión.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top