J'ai une fonction bidimensionnelle dont je voudrais échantillonner les valeurs. La fonction est très coûteuse à calculer et elle a une forme complexe, j'ai donc besoin de trouver un moyen d'obtenir le plus d'informations sur sa forme en utilisant le moins de points d'échantillonnage.
Quelles sont les bonnes méthodes pour y parvenir?
Ce que j'ai jusqu'ici
Je pars d'un ensemble de points existant où j'ai déjà calculé la valeur de la fonction (cela pourrait être un réseau carré de points ou autre chose).
Ensuite, je calcule une triangulation de Delaunay de ces points.
Si deux points voisins dans la triangulation de Delaunay sont suffisamment éloignés ( ) et que la valeur de la fonction diffère suffisamment en eux ( > Δ f ), alors j'insère un nouveau point à mi-chemin entre eux. Je fais cela pour chaque paire de points voisins.
Quel est le problème avec cette méthode?
Eh bien, cela fonctionne relativement bien, mais sur des fonctions similaires à celle-ci, ce n'est pas idéal car les points d'échantillonnage ont tendance à "sauter" la crête et ne remarquent même pas qu'elle est là.
Il produit des résultats comme celui-ci (si la résolution de la grille de points initiale est suffisamment approximative):
Ce graphique ci-dessus montre les points où la valeur de la fonction est calculée (en fait des cellules de Voronoi autour d'eux).
Ce graphique ci-dessus montre l'interpolation linéaire générée à partir des mêmes points et la compare à la méthode d'échantillonnage intégrée de Mathematica (pour environ la même résolution de départ).
Comment l'améliorer?
Je pense que le principal problème ici est que ma méthode décide d'ajouter ou non un point de raffinement en fonction du gradient.
Il serait préférable de prendre en compte la courbure ou au moins la dérivée seconde lors de l'ajout de points de raffinement.
Question
Quelle est une manière très simple à mettre en œuvre pour prendre en compte la dérivée seconde ou la courbure lorsque les emplacements de mes points ne sont pas du tout contraints? (Je n'ai pas nécessairement un réseau carré de points de départ, cela devrait idéalement être général.)
Ou quels autres moyens simples existe-t-il pour calculer la position des points de raffinement de manière optimale?
Je vais implémenter cela dans Mathematica, mais cette question concerne principalement la méthode. Pour le bit "facile à implémenter", cela compte cependant que j'utilise Mathematica (c'est-à-dire que c'était facile à faire jusqu'à présent car il a un paquet pour faire la triangulation de Delaunay)
À quel problème pratique j'applique ceci
Je calcule un diagramme de phases. Il a une forme complexe. Dans une région, sa valeur est 0, dans une autre région, elle est comprise entre 0 et 1. Il y a un net saut entre les deux régions (c'est discontinu). Dans la région où la fonction est supérieure à zéro, il y a à la fois une certaine variation en douceur et quelques discontinuités.
La valeur de la fonction est calculée sur la base d'une simulation de Monte Carlo, donc parfois une valeur de fonction ou un bruit incorrect est à prévoir (cela est très rare, mais pour un grand nombre de points, cela se produit, par exemple lorsque l'état stationnaire n'est pas atteint en raison un facteur aléatoire)
J'ai déjà posé cette question sur Mathematica.SE mais je ne peux pas le lier car il est toujours en version bêta privée. Cette question concerne la méthode, pas la mise en œuvre.
Répondre à @suki
Est-ce le type de division que vous proposez, c'est-à-dire mettre un nouveau point au milieu des triangles?
Ma préoccupation ici est qu'elle semble nécessiter une manipulation spéciale aux bords de la région, sinon elle donnera des triangles très longs et très fins, comme indiqué ci-dessus. Avez-vous corrigé cela?
MISE À JOUR
Un problème qui apparaît à la fois avec la méthode que je décris et avec la suggestion de @ suki de mettre la subdivision basée sur des triangles et de placer les points de subdivision à l'intérieur du triangle est que lorsqu'il y a des discontinuités (comme dans mon problème), recalculer la triangulation de Delaunay après une étape peut faire changer les triangles et peut-être apparaître de gros triangles qui ont des valeurs de fonction différentes dans les trois sommets.
Voici deux exemples:
Le premier montre le résultat final lors de l'échantillonnage autour d'une discontinuité droite. La seconde montre la distribution des points d'échantillonnage pour un cas similaire.
Quels sont les moyens simples d'éviter cela? Actuellement, je subdivise simplement les egdes qui disparaissent après une retriangulation, mais cela ressemble à un hack et doit être fait avec soin car dans le cas des maillages symétriques (comme une grille carrée), il existe plusieurs triangulations Delaunay valides, donc les bords peuvent changer au hasard après retriangulation.