Question How can I find the closest point to a parametric curve produced by a numerical method.
General Context I have a parametric curve (which I will call $g$) produced from a averaging many solutions of an ODE system. As part of further analysis I would like to construct a function that given a point outside the curve, it gives the closest point on the parametric curve $g$.
i.e. I am looking for a function $f:x_0\to p$ where $x_0\in \mathbb{R}^3_+$, and $p$ is a point on the parametric curve $g:t \to (x,y,z)$ such that $||x_0-p||$ is minimized (Where the norm is the standard euclidean norm).
Why do I want such a function? I want to compare the distance of another parametric curve (which I will call $h$) to $g$ at a given $t$. Or put another way for a time $t$ what is $||h(t)-p||$. (Note that I am not trying to do what it done in this post which is trying to find $||h(t)-g(t)||$. I am looking for the point on $g$ which is closest to $h(t)$, anywhere on $g$.)
My biggest problem is using Mathematica to construct an appropriate $f$.
Problems Using Mathematica
There are quite a few Mathematica functions that I have looked at, and I believe that the the appropriate answer is just a question of calling the right functions with proper syntax. Possible Mathematica functions include
RegionNearest
NMinimize
ParametricRegion
ImplicitRegion
the idea being that we can use either ImplicitRegion
or ParametricRegion
to define a region which is all of $g$, then use either RegionNearest
or NMinimize
. As an example
RegionNearest[ParametricRegion[{Cos[theta], Sin[theta]}, {{theta, 0, 2 \[Pi]}}], {2,2}]
I haven't been apply to figure the right combination functions and syntax though.
Minimum Working Example Note there are two separate sections. One where $g$ is generated and another where I test different options. I have included the way in which $g$ is generated is as there may be a syntax problems, in the way $g$ is generated. Otherwise you may consider $g$ a blackbox.
(*Simulation Parameters and definitions*)
Clear[f]
Clear[i, P, B]
f[P_, B_] := 1/2 P + 10 B/(1 + B);
tmax = 20;
randNum = 50;
A = {{1/20, 1/4, 1/50}, {1/4, 1/26, 1/40}};
point = {16.666666666666735`, 0.`, 8.333333333333345`};
(*ODE System*)
ODEsys = {i'[t] == f[P[t], B[t]] - i[t],
P'[t] ==
P[t] (1 - A[[1, 1]] P[t] - A[[1, 2]] B[t] - A[[1, 3]] i[t]),
B'[t] == B[t] (1 - A[[2, 2]] B[t] - A[[2, 3]] i[t])};
(*Generating parametric g curve.*)
(*--------------------------*)
eps = 0.001;
set = List[];
While[Length[set] < randNum,
holdSet =
Join[set, Map[point + # &, RandomReal[{-eps, eps}, {randNum, 3}]]];
set = Select[holdSet, #[[2]] >= 0 &];
]
set = Drop[set, -(randNum - Length[set])];
(* Simulation *)
sol = ParametricNDSolveValue[{ODEsys, {P[0] == init1, B[0] == init2,
i[0] == init0}}, {P, B, i}, {t, 0, tmax}, {init1, init2, init0}];
(* Averging solution over multiple inital conditions. *)
gCurve[t_] :=
Evaluate[Mean[
Through /@ (sol[#[[1]], #[[2]], #[[3]]][t] & /@ set)]] ;
(* Below is a test that gCorve works as intended. If gcurve works as \
intended we should get a single curve in 3D *)
simplexPlot =
ParametricPlot3D[gCurve[t], {t, 0, tmax}, PlotRange -> All,
ImageSize -> Large, PlotStyle -> Black]
(*-------------------------*)
(*Attempt to solve the problem*)
(*-------------------------*)
(* Attempt *)
(* Problem: gives out a function and not a number *)
nearestPoint[{x_, y_, z_}] :=
Evaluate[RegionNearest[
ParametricRegion[gCurve[t], {{t, 0, tmax}}], {x, y, z}]];
nearestPoint[{2, 2, 2}]
Notes
If you need any clarification don't be afraid to ask.
Some previous posts that I've seen but have answered my question.
randNum
andsimplexSol
are not defined as far as I can tell though. $\endgroup$