Ich habe eine zweidimensionale Funktion deren Werte ich abtasten möchte. Die Berechnung der Funktion ist sehr aufwendig und weist eine komplexe Form auf. Ich muss daher einen Weg finden, um mit der geringsten Anzahl von Abtastpunkten die meisten Informationen über ihre Form zu erhalten.
Welche guten Methoden gibt es dafür?
Was ich bisher habe
Ich gehe von einer vorhandenen Menge von Punkten aus, bei denen ich den Funktionswert bereits berechnet habe (dies kann ein quadratisches Punktegitter oder etwas anderes sein).
Dann berechne ich eine Delaunay-Triangulation dieser Punkte.
Wenn zwei benachbarte Punkte in der Delaunay-Triangulation weit genug voneinander entfernt sind ( ) und sich der Funktionswert darin ausreichend unterscheidet ( ), füge ich einen neuen Punkt in der Mitte dazwischen ein. Ich mache das für jedes benachbarte Punktpaar.
Was ist los mit dieser Methode?
Nun, es funktioniert relativ gut, aber bei ähnlichen Funktionen ist es nicht ideal, da die Abtastpunkte dazu neigen, über den Grat zu springen und nicht einmal zu bemerken, dass sie dort sind.
Das Ergebnis ist wie folgt (wenn die Auflösung des Anfangspunktrasters ausreichend grob ist):
Dieses Diagramm oben zeigt die Punkte, an denen der Funktionswert berechnet wird (tatsächlich Voronoi-Zellen um sie herum).
Dieses Diagramm oben zeigt die lineare Interpolation, die aus denselben Punkten generiert wurde, und vergleicht sie mit der in Mathematica integrierten Abtastmethode (für ungefähr dieselbe Startauflösung).
Wie kann man es verbessern?
Ich denke, das Hauptproblem hierbei ist, dass meine Methode basierend auf dem Farbverlauf entscheidet, ob ein Verfeinerungspunkt hinzugefügt wird oder nicht.
Es ist besser, die Krümmung oder zumindest die zweite Ableitung beim Hinzufügen von Verfeinerungspunkten zu berücksichtigen.
Frage
Was ist eine sehr einfach zu implementierende Methode, um die zweite Ableitung oder Krümmung zu berücksichtigen, wenn die Positionen meiner Punkte überhaupt nicht eingeschränkt sind? (Ich habe nicht unbedingt ein quadratisches Gitter mit Startpunkten, dies sollte idealerweise allgemein sein.)
Oder welche anderen einfachen Möglichkeiten gibt es, um die Position von Verfeinerungspunkten optimal zu berechnen?
Ich werde dies in Mathematica implementieren, aber bei dieser Frage geht es hauptsächlich um die Methode. Für das "einfach zu implementierende" Bit zählt allerdings, dass ich Mathematica verwende (dh dies war bisher einfach, da es ein Paket für die Delaunay-Triangulation enthält).
Auf welches praktische Problem wende ich das an?
Ich berechne ein Phasendiagramm. Es hat eine komplexe Form. In einer Region ist der Wert 0, in einer anderen zwischen 0 und 1. Zwischen den beiden Regionen besteht ein starker Sprung (diskontinuierlich). In dem Bereich, in dem die Funktion größer als Null ist, gibt es sowohl eine sanfte Variation als auch ein paar Diskontinuitäten.
Der Funktionswert wird auf Basis einer Monte-Carlo-Simulation berechnet, so dass gelegentlich ein falscher Funktionswert oder Rauschen zu erwarten ist (dies ist sehr selten, aber bei einer großen Anzahl von Punkten tritt dies auf, z. B. wenn der eingeschwungene Zustand nicht erreicht wird) ein zufälliger Faktor)
Ich habe dies bereits auf Mathematica.SE gefragt , kann aber keinen Link dazu erstellen, da es sich noch in der privaten Beta befindet. Bei dieser Frage geht es um die Methode, nicht um die Implementierung.
Antworte auf @suki
Ist dies die Art der Unterteilung, die Sie vorschlagen, dh einen neuen Punkt in die Mitte der Dreiecke zu setzen?
Meine Sorge ist hier, dass es an den Rändern der Region anscheinend eine besondere Behandlung erfordert, da es sonst sehr lange und sehr dünne Dreiecke gibt, wie oben gezeigt. Hast du das korrigiert?
AKTUALISIEREN
Ein Problem, das sowohl bei der von mir beschriebenen Methode als auch bei dem Vorschlag von @ suki auftritt, eine Unterteilung basierend auf Dreiecken vorzunehmen und die Unterteilungspunkte innerhalb des Dreiecks zu setzen, besteht darin, dass bei Diskontinuitäten (wie in meinem Problem) die Delaunay-Triangulation nach einem Schritt möglicherweise neu berechnet wird bewirken, dass sich Dreiecke ändern und möglicherweise große Dreiecke mit unterschiedlichen Funktionswerten in den drei Scheitelpunkten angezeigt werden.
Hier sind zwei Beispiele:
Die erste zeigt das Endergebnis beim Abtasten um eine gerade Diskontinuität. Die zweite zeigt die Verteilung der Abtastpunkte für einen ähnlichen Fall.
Welche einfachen Möglichkeiten gibt es, dies zu vermeiden? Gegenwärtig unterteile ich einfach jene Egdes, die nach einer Retriangulation verschwinden, aber dies fühlt sich wie ein Hack an und muss mit Sorgfalt durchgeführt werden, da es bei symmetrischen Netzen (wie einem quadratischen Gitter) mehrere gültige Delaunay-Triangulationen gibt, daher können sich Kanten ändern zufällig nach retriangulation.