Tengo una función bidimensional cuyos valores me gustaría muestrear. La función es muy costosa de calcular y tiene una forma compleja, por lo que necesito encontrar una manera de obtener la mayor información sobre su forma utilizando el menor número de puntos de muestra.
¿Qué buenos métodos hay para hacer esto?
Lo que tengo hasta ahora
Comienzo desde un conjunto de puntos existente donde ya he calculado el valor de la función (esto podría ser una red cuadrada de puntos u otra cosa).
Luego calculo una triangulación de Delaunay de estos puntos.
Si dos puntos vecinos en la triangulación de Delaunay están lo suficientemente lejos ( ) y el valor de la función difiere lo suficiente en ellos ( > Δ f ), entonces inserto un nuevo punto a medio camino entre ellos. Hago esto para cada par de puntos vecinos.
¿Qué tiene de malo este método?
Bueno, funciona relativamente bien, pero en funciones similares a esta no es ideal porque los puntos de muestra tienden a "saltar" sobre la cresta y ni siquiera se dan cuenta de que está allí.
Produce resultados como este (si la resolución de la cuadrícula de puntos inicial es suficientemente aproximada):
Este gráfico anterior muestra los puntos donde se calcula el valor de la función (en realidad, las celdas de Voronoi a su alrededor).
Este gráfico anterior muestra la interpolación lineal generada a partir de los mismos puntos y la compara con el método de muestreo incorporado de Mathematica (para aproximadamente la misma resolución inicial).
¿Cómo mejorarlo?
Creo que el problema principal aquí es que mi método decide si agregar un punto de refinamiento o no en función del gradiente.
Sería mejor tener en cuenta la curvatura o al menos la segunda derivada al agregar puntos de refinamiento.
Pregunta
¿Cuál es una forma muy sencilla de implementar para tener en cuenta la segunda derivada o curvatura cuando las ubicaciones de mis puntos no están limitadas en absoluto? (No necesariamente tengo una red cuadrada de puntos de partida, esto idealmente debería ser general).
¿O qué otras formas simples existen para calcular la posición de los puntos de refinamiento de manera óptima?
Voy a implementar esto en Mathematica, pero esta pregunta es principalmente sobre el método. Para el bit "fácil de implementar", sí cuenta que estoy usando Mathematica (es decir, esto fue fácil de hacer hasta ahora porque tiene un paquete para hacer la triangulación de Delaunay)
¿A qué problema práctico estoy aplicando esto?
Estoy calculando un diagrama de fase. Tiene una forma compleja. En una región su valor es 0, en otra región está entre 0 y 1. Hay un salto brusco entre las dos regiones (es discontinuo). En la región donde la función es mayor que cero, existe una variación suave y un par de discontinuidades.
El valor de la función se calcula en base a una simulación de Monte Carlo, por lo que ocasionalmente se espera un valor de función incorrecto o ruido (esto es muy raro, pero ocurre en un gran número de puntos, por ejemplo, cuando no se alcanza el estado estable debido algún factor aleatorio)
Ya he preguntado esto en Mathematica.SE, pero no puedo vincularlo porque todavía está en beta privada. Esta pregunta aquí es sobre el método, no la implementación.
Responder a @suki
¿Es este el tipo de división que sugiere, es decir, poner un nuevo punto en el medio de los triángulos?
Mi preocupación aquí es que parece requerir un manejo especial en los bordes de la región, de lo contrario dará triángulos muy largos y muy delgados, como se muestra arriba. ¿Corrigiste esto?
ACTUALIZAR
Un problema que aparece tanto con el método que describo como con la sugerencia de @ suki de subdividir en base a triángulos y colocar los puntos de subdivisión dentro del triángulo es que cuando hay discontinuidades (como en mi problema), volver a calcular la triangulación de Delaunay después de un paso puede hacen que los triángulos cambien y tal vez aparezcan algunos triángulos grandes que tienen diferentes valores de función en los tres vértices.
Aquí hay dos ejemplos:
El primero muestra el resultado final al muestrear alrededor de una discontinuidad directa. El segundo muestra la distribución del punto de muestreo para un caso similar.
¿Qué formas simples hay para evitar esto? Actualmente, simplemente estoy subdividiendo esos egdes que desaparecen después de una retriangulación, pero esto se siente como un truco y debe hacerse con cuidado ya que en el caso de mallas simétricas (como una cuadrícula cuadrada) hay varias triangulaciones válidas de Delaunay, por lo tanto, los bordes pueden cambiar aleatoriamente después de la retriangulación.