Finding the point closest to a parameteric curve produced by a numerical method
Clash Royale CLAN TAG#URR8PPP
$begingroup$
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_0to p$ where $x_0in mathbbR^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.
- Finding closest point to implicitly defined curve
- Finding the point of minimum distance between two parametric functions
differential-equations functions syntax regions parametric-functions
$endgroup$
add a comment |
$begingroup$
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_0to p$ where $x_0in mathbbR^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.
- Finding closest point to implicitly defined curve
- Finding the point of minimum distance between two parametric functions
differential-equations functions syntax regions parametric-functions
$endgroup$
3
$begingroup$
Nicely written question.randNum
andsimplexSol
are not defined as far as I can tell though.
$endgroup$
– C. E.
Feb 7 at 18:30
$begingroup$
Apologies I copied the code from a match larger document. Forgot to clear memory to test it. The new edited code should work as intended.
$endgroup$
– AzJ
Feb 7 at 18:37
add a comment |
$begingroup$
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_0to p$ where $x_0in mathbbR^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.
- Finding closest point to implicitly defined curve
- Finding the point of minimum distance between two parametric functions
differential-equations functions syntax regions parametric-functions
$endgroup$
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_0to p$ where $x_0in mathbbR^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.
- Finding closest point to implicitly defined curve
- Finding the point of minimum distance between two parametric functions
differential-equations functions syntax regions parametric-functions
differential-equations functions syntax regions parametric-functions
edited Feb 7 at 18:37
AzJ
asked Feb 7 at 18:24
AzJAzJ
41428
41428
3
$begingroup$
Nicely written question.randNum
andsimplexSol
are not defined as far as I can tell though.
$endgroup$
– C. E.
Feb 7 at 18:30
$begingroup$
Apologies I copied the code from a match larger document. Forgot to clear memory to test it. The new edited code should work as intended.
$endgroup$
– AzJ
Feb 7 at 18:37
add a comment |
3
$begingroup$
Nicely written question.randNum
andsimplexSol
are not defined as far as I can tell though.
$endgroup$
– C. E.
Feb 7 at 18:30
$begingroup$
Apologies I copied the code from a match larger document. Forgot to clear memory to test it. The new edited code should work as intended.
$endgroup$
– AzJ
Feb 7 at 18:37
3
3
$begingroup$
Nicely written question.
randNum
and simplexSol
are not defined as far as I can tell though.$endgroup$
– C. E.
Feb 7 at 18:30
$begingroup$
Nicely written question.
randNum
and simplexSol
are not defined as far as I can tell though.$endgroup$
– C. E.
Feb 7 at 18:30
$begingroup$
Apologies I copied the code from a match larger document. Forgot to clear memory to test it. The new edited code should work as intended.
$endgroup$
– AzJ
Feb 7 at 18:37
$begingroup$
Apologies I copied the code from a match larger document. Forgot to clear memory to test it. The new edited code should work as intended.
$endgroup$
– AzJ
Feb 7 at 18:37
add a comment |
2 Answers
2
active
oldest
votes
$begingroup$
It seems like the most straightforward way to handle this is to just use NMinimize
directly on the norm. I do this here by defining a function to by find the t
value which minimizes the distance between the function and the point:
nearestT[f_, pt_, tmin_, tmax_] :=
Module[t,
t /. NMinimize[Norm[f[t] - pt], tmin <= t, t <= tmax, t][[2]]
];
And then subsequently a function which inserts that t
value back into the original function to find the nearest point on the curve:
nearestPt[f_, pt_, tmin_, tmax_] := f[nearestT[f, pt, tmin, tmax]];
For gCurve
, this is used as:
nearestT[gCurve, 2, 2, 2, 0, tmax], nearestPt[gCurve, 2, 2, 2, 0, tmax]
12.9809, 4.25274, 6.24997, 10.07
If it's too slow and you suspect that gCurve
will be relatively well behaved with regards to the point you're minimizing at, you may wish to use FindMinimum
instead. However, FindMinimum
does not make nearly as many attempts to find global minima, so it may not always provide the best answer.
$endgroup$
$begingroup$
I tested your code a little bit for robustness and it seems to work. I did not know thatFindMinimum
would work given that the functiongcurve
is not a standard function. I really like your approach. I am keeping the question open for a while to see if people have any alternative answers. If no one answers this question in 24 hours I will accept your answer.
$endgroup$
– AzJ
Feb 7 at 19:23
1
$begingroup$
@AzJ It is true that there can be some odd issues here and there when using non-standard function forms, but the numerical functions tend to be pretty uncaring about the underlying nature of the function so long as the objective function you're working with is numerical by the time it's fully evaluated. With some functions, that might involve redefining things to usex_?NumericQ
and such, but once that's done they're usually quite reliable.
$endgroup$
– eyorble
Feb 7 at 19:30
add a comment |
$begingroup$
nF = RegionNearest[Cases[simplexPlot, _Line, All][[1]]];
pnt = 2, 2, 2;
npnt = nF @ pnt
4.56162,6.16536,10.9321
EuclideanDistance[pnt, nF@pnt]
10.1831
Show[simplexPlot,
Graphics3D[Red, Sphere[pnt, .2], Green, Sphere[npnt, .2],
Gray, Dashed, Arrow[pnt, npnt]]]
$endgroup$
$begingroup$
I like how elegant your method is. Could you explain a little bit howCases[simplexPlot, _Line, All]
works?
$endgroup$
– AzJ
Feb 7 at 23:24
1
$begingroup$
@AzJ,Cases[expr, _h, All]
extracts objects with Headh
that appear at any Level inexpr
. If you look atInputForm[simplexPlot]
it is a collection of directives and a single primitiveLine[...]
andCases[simplexPlot, _Line, All]
gets that line expression.
$endgroup$
– kglr
Feb 7 at 23:38
$begingroup$
Okay that makes sense. Does this mean that the accuracy ofRegionNearest[Cases[simplexPlot, _Line, All][[1]]]
depend on how accurate the graphing method is? i..e. ChangingMaxRecursion
,PerformaceGoal
,WorkingPrecision
changes the accuracy of the method.
$endgroup$
– AzJ
Feb 7 at 23:50
1
$begingroup$
@AzJ, good point re accuracy. In addition to the options you mentionedPlotPoints
also affects theLine
produced by the plot function.
$endgroup$
– kglr
Feb 7 at 23:55
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
);
);
, "mathjax-editing");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "387"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f191082%2ffinding-the-point-closest-to-a-parameteric-curve-produced-by-a-numerical-method%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
It seems like the most straightforward way to handle this is to just use NMinimize
directly on the norm. I do this here by defining a function to by find the t
value which minimizes the distance between the function and the point:
nearestT[f_, pt_, tmin_, tmax_] :=
Module[t,
t /. NMinimize[Norm[f[t] - pt], tmin <= t, t <= tmax, t][[2]]
];
And then subsequently a function which inserts that t
value back into the original function to find the nearest point on the curve:
nearestPt[f_, pt_, tmin_, tmax_] := f[nearestT[f, pt, tmin, tmax]];
For gCurve
, this is used as:
nearestT[gCurve, 2, 2, 2, 0, tmax], nearestPt[gCurve, 2, 2, 2, 0, tmax]
12.9809, 4.25274, 6.24997, 10.07
If it's too slow and you suspect that gCurve
will be relatively well behaved with regards to the point you're minimizing at, you may wish to use FindMinimum
instead. However, FindMinimum
does not make nearly as many attempts to find global minima, so it may not always provide the best answer.
$endgroup$
$begingroup$
I tested your code a little bit for robustness and it seems to work. I did not know thatFindMinimum
would work given that the functiongcurve
is not a standard function. I really like your approach. I am keeping the question open for a while to see if people have any alternative answers. If no one answers this question in 24 hours I will accept your answer.
$endgroup$
– AzJ
Feb 7 at 19:23
1
$begingroup$
@AzJ It is true that there can be some odd issues here and there when using non-standard function forms, but the numerical functions tend to be pretty uncaring about the underlying nature of the function so long as the objective function you're working with is numerical by the time it's fully evaluated. With some functions, that might involve redefining things to usex_?NumericQ
and such, but once that's done they're usually quite reliable.
$endgroup$
– eyorble
Feb 7 at 19:30
add a comment |
$begingroup$
It seems like the most straightforward way to handle this is to just use NMinimize
directly on the norm. I do this here by defining a function to by find the t
value which minimizes the distance between the function and the point:
nearestT[f_, pt_, tmin_, tmax_] :=
Module[t,
t /. NMinimize[Norm[f[t] - pt], tmin <= t, t <= tmax, t][[2]]
];
And then subsequently a function which inserts that t
value back into the original function to find the nearest point on the curve:
nearestPt[f_, pt_, tmin_, tmax_] := f[nearestT[f, pt, tmin, tmax]];
For gCurve
, this is used as:
nearestT[gCurve, 2, 2, 2, 0, tmax], nearestPt[gCurve, 2, 2, 2, 0, tmax]
12.9809, 4.25274, 6.24997, 10.07
If it's too slow and you suspect that gCurve
will be relatively well behaved with regards to the point you're minimizing at, you may wish to use FindMinimum
instead. However, FindMinimum
does not make nearly as many attempts to find global minima, so it may not always provide the best answer.
$endgroup$
$begingroup$
I tested your code a little bit for robustness and it seems to work. I did not know thatFindMinimum
would work given that the functiongcurve
is not a standard function. I really like your approach. I am keeping the question open for a while to see if people have any alternative answers. If no one answers this question in 24 hours I will accept your answer.
$endgroup$
– AzJ
Feb 7 at 19:23
1
$begingroup$
@AzJ It is true that there can be some odd issues here and there when using non-standard function forms, but the numerical functions tend to be pretty uncaring about the underlying nature of the function so long as the objective function you're working with is numerical by the time it's fully evaluated. With some functions, that might involve redefining things to usex_?NumericQ
and such, but once that's done they're usually quite reliable.
$endgroup$
– eyorble
Feb 7 at 19:30
add a comment |
$begingroup$
It seems like the most straightforward way to handle this is to just use NMinimize
directly on the norm. I do this here by defining a function to by find the t
value which minimizes the distance between the function and the point:
nearestT[f_, pt_, tmin_, tmax_] :=
Module[t,
t /. NMinimize[Norm[f[t] - pt], tmin <= t, t <= tmax, t][[2]]
];
And then subsequently a function which inserts that t
value back into the original function to find the nearest point on the curve:
nearestPt[f_, pt_, tmin_, tmax_] := f[nearestT[f, pt, tmin, tmax]];
For gCurve
, this is used as:
nearestT[gCurve, 2, 2, 2, 0, tmax], nearestPt[gCurve, 2, 2, 2, 0, tmax]
12.9809, 4.25274, 6.24997, 10.07
If it's too slow and you suspect that gCurve
will be relatively well behaved with regards to the point you're minimizing at, you may wish to use FindMinimum
instead. However, FindMinimum
does not make nearly as many attempts to find global minima, so it may not always provide the best answer.
$endgroup$
It seems like the most straightforward way to handle this is to just use NMinimize
directly on the norm. I do this here by defining a function to by find the t
value which minimizes the distance between the function and the point:
nearestT[f_, pt_, tmin_, tmax_] :=
Module[t,
t /. NMinimize[Norm[f[t] - pt], tmin <= t, t <= tmax, t][[2]]
];
And then subsequently a function which inserts that t
value back into the original function to find the nearest point on the curve:
nearestPt[f_, pt_, tmin_, tmax_] := f[nearestT[f, pt, tmin, tmax]];
For gCurve
, this is used as:
nearestT[gCurve, 2, 2, 2, 0, tmax], nearestPt[gCurve, 2, 2, 2, 0, tmax]
12.9809, 4.25274, 6.24997, 10.07
If it's too slow and you suspect that gCurve
will be relatively well behaved with regards to the point you're minimizing at, you may wish to use FindMinimum
instead. However, FindMinimum
does not make nearly as many attempts to find global minima, so it may not always provide the best answer.
answered Feb 7 at 18:44
eyorbleeyorble
5,64311028
5,64311028
$begingroup$
I tested your code a little bit for robustness and it seems to work. I did not know thatFindMinimum
would work given that the functiongcurve
is not a standard function. I really like your approach. I am keeping the question open for a while to see if people have any alternative answers. If no one answers this question in 24 hours I will accept your answer.
$endgroup$
– AzJ
Feb 7 at 19:23
1
$begingroup$
@AzJ It is true that there can be some odd issues here and there when using non-standard function forms, but the numerical functions tend to be pretty uncaring about the underlying nature of the function so long as the objective function you're working with is numerical by the time it's fully evaluated. With some functions, that might involve redefining things to usex_?NumericQ
and such, but once that's done they're usually quite reliable.
$endgroup$
– eyorble
Feb 7 at 19:30
add a comment |
$begingroup$
I tested your code a little bit for robustness and it seems to work. I did not know thatFindMinimum
would work given that the functiongcurve
is not a standard function. I really like your approach. I am keeping the question open for a while to see if people have any alternative answers. If no one answers this question in 24 hours I will accept your answer.
$endgroup$
– AzJ
Feb 7 at 19:23
1
$begingroup$
@AzJ It is true that there can be some odd issues here and there when using non-standard function forms, but the numerical functions tend to be pretty uncaring about the underlying nature of the function so long as the objective function you're working with is numerical by the time it's fully evaluated. With some functions, that might involve redefining things to usex_?NumericQ
and such, but once that's done they're usually quite reliable.
$endgroup$
– eyorble
Feb 7 at 19:30
$begingroup$
I tested your code a little bit for robustness and it seems to work. I did not know that
FindMinimum
would work given that the function gcurve
is not a standard function. I really like your approach. I am keeping the question open for a while to see if people have any alternative answers. If no one answers this question in 24 hours I will accept your answer.$endgroup$
– AzJ
Feb 7 at 19:23
$begingroup$
I tested your code a little bit for robustness and it seems to work. I did not know that
FindMinimum
would work given that the function gcurve
is not a standard function. I really like your approach. I am keeping the question open for a while to see if people have any alternative answers. If no one answers this question in 24 hours I will accept your answer.$endgroup$
– AzJ
Feb 7 at 19:23
1
1
$begingroup$
@AzJ It is true that there can be some odd issues here and there when using non-standard function forms, but the numerical functions tend to be pretty uncaring about the underlying nature of the function so long as the objective function you're working with is numerical by the time it's fully evaluated. With some functions, that might involve redefining things to use
x_?NumericQ
and such, but once that's done they're usually quite reliable.$endgroup$
– eyorble
Feb 7 at 19:30
$begingroup$
@AzJ It is true that there can be some odd issues here and there when using non-standard function forms, but the numerical functions tend to be pretty uncaring about the underlying nature of the function so long as the objective function you're working with is numerical by the time it's fully evaluated. With some functions, that might involve redefining things to use
x_?NumericQ
and such, but once that's done they're usually quite reliable.$endgroup$
– eyorble
Feb 7 at 19:30
add a comment |
$begingroup$
nF = RegionNearest[Cases[simplexPlot, _Line, All][[1]]];
pnt = 2, 2, 2;
npnt = nF @ pnt
4.56162,6.16536,10.9321
EuclideanDistance[pnt, nF@pnt]
10.1831
Show[simplexPlot,
Graphics3D[Red, Sphere[pnt, .2], Green, Sphere[npnt, .2],
Gray, Dashed, Arrow[pnt, npnt]]]
$endgroup$
$begingroup$
I like how elegant your method is. Could you explain a little bit howCases[simplexPlot, _Line, All]
works?
$endgroup$
– AzJ
Feb 7 at 23:24
1
$begingroup$
@AzJ,Cases[expr, _h, All]
extracts objects with Headh
that appear at any Level inexpr
. If you look atInputForm[simplexPlot]
it is a collection of directives and a single primitiveLine[...]
andCases[simplexPlot, _Line, All]
gets that line expression.
$endgroup$
– kglr
Feb 7 at 23:38
$begingroup$
Okay that makes sense. Does this mean that the accuracy ofRegionNearest[Cases[simplexPlot, _Line, All][[1]]]
depend on how accurate the graphing method is? i..e. ChangingMaxRecursion
,PerformaceGoal
,WorkingPrecision
changes the accuracy of the method.
$endgroup$
– AzJ
Feb 7 at 23:50
1
$begingroup$
@AzJ, good point re accuracy. In addition to the options you mentionedPlotPoints
also affects theLine
produced by the plot function.
$endgroup$
– kglr
Feb 7 at 23:55
add a comment |
$begingroup$
nF = RegionNearest[Cases[simplexPlot, _Line, All][[1]]];
pnt = 2, 2, 2;
npnt = nF @ pnt
4.56162,6.16536,10.9321
EuclideanDistance[pnt, nF@pnt]
10.1831
Show[simplexPlot,
Graphics3D[Red, Sphere[pnt, .2], Green, Sphere[npnt, .2],
Gray, Dashed, Arrow[pnt, npnt]]]
$endgroup$
$begingroup$
I like how elegant your method is. Could you explain a little bit howCases[simplexPlot, _Line, All]
works?
$endgroup$
– AzJ
Feb 7 at 23:24
1
$begingroup$
@AzJ,Cases[expr, _h, All]
extracts objects with Headh
that appear at any Level inexpr
. If you look atInputForm[simplexPlot]
it is a collection of directives and a single primitiveLine[...]
andCases[simplexPlot, _Line, All]
gets that line expression.
$endgroup$
– kglr
Feb 7 at 23:38
$begingroup$
Okay that makes sense. Does this mean that the accuracy ofRegionNearest[Cases[simplexPlot, _Line, All][[1]]]
depend on how accurate the graphing method is? i..e. ChangingMaxRecursion
,PerformaceGoal
,WorkingPrecision
changes the accuracy of the method.
$endgroup$
– AzJ
Feb 7 at 23:50
1
$begingroup$
@AzJ, good point re accuracy. In addition to the options you mentionedPlotPoints
also affects theLine
produced by the plot function.
$endgroup$
– kglr
Feb 7 at 23:55
add a comment |
$begingroup$
nF = RegionNearest[Cases[simplexPlot, _Line, All][[1]]];
pnt = 2, 2, 2;
npnt = nF @ pnt
4.56162,6.16536,10.9321
EuclideanDistance[pnt, nF@pnt]
10.1831
Show[simplexPlot,
Graphics3D[Red, Sphere[pnt, .2], Green, Sphere[npnt, .2],
Gray, Dashed, Arrow[pnt, npnt]]]
$endgroup$
nF = RegionNearest[Cases[simplexPlot, _Line, All][[1]]];
pnt = 2, 2, 2;
npnt = nF @ pnt
4.56162,6.16536,10.9321
EuclideanDistance[pnt, nF@pnt]
10.1831
Show[simplexPlot,
Graphics3D[Red, Sphere[pnt, .2], Green, Sphere[npnt, .2],
Gray, Dashed, Arrow[pnt, npnt]]]
answered Feb 7 at 20:39
kglrkglr
186k10203422
186k10203422
$begingroup$
I like how elegant your method is. Could you explain a little bit howCases[simplexPlot, _Line, All]
works?
$endgroup$
– AzJ
Feb 7 at 23:24
1
$begingroup$
@AzJ,Cases[expr, _h, All]
extracts objects with Headh
that appear at any Level inexpr
. If you look atInputForm[simplexPlot]
it is a collection of directives and a single primitiveLine[...]
andCases[simplexPlot, _Line, All]
gets that line expression.
$endgroup$
– kglr
Feb 7 at 23:38
$begingroup$
Okay that makes sense. Does this mean that the accuracy ofRegionNearest[Cases[simplexPlot, _Line, All][[1]]]
depend on how accurate the graphing method is? i..e. ChangingMaxRecursion
,PerformaceGoal
,WorkingPrecision
changes the accuracy of the method.
$endgroup$
– AzJ
Feb 7 at 23:50
1
$begingroup$
@AzJ, good point re accuracy. In addition to the options you mentionedPlotPoints
also affects theLine
produced by the plot function.
$endgroup$
– kglr
Feb 7 at 23:55
add a comment |
$begingroup$
I like how elegant your method is. Could you explain a little bit howCases[simplexPlot, _Line, All]
works?
$endgroup$
– AzJ
Feb 7 at 23:24
1
$begingroup$
@AzJ,Cases[expr, _h, All]
extracts objects with Headh
that appear at any Level inexpr
. If you look atInputForm[simplexPlot]
it is a collection of directives and a single primitiveLine[...]
andCases[simplexPlot, _Line, All]
gets that line expression.
$endgroup$
– kglr
Feb 7 at 23:38
$begingroup$
Okay that makes sense. Does this mean that the accuracy ofRegionNearest[Cases[simplexPlot, _Line, All][[1]]]
depend on how accurate the graphing method is? i..e. ChangingMaxRecursion
,PerformaceGoal
,WorkingPrecision
changes the accuracy of the method.
$endgroup$
– AzJ
Feb 7 at 23:50
1
$begingroup$
@AzJ, good point re accuracy. In addition to the options you mentionedPlotPoints
also affects theLine
produced by the plot function.
$endgroup$
– kglr
Feb 7 at 23:55
$begingroup$
I like how elegant your method is. Could you explain a little bit how
Cases[simplexPlot, _Line, All]
works?$endgroup$
– AzJ
Feb 7 at 23:24
$begingroup$
I like how elegant your method is. Could you explain a little bit how
Cases[simplexPlot, _Line, All]
works?$endgroup$
– AzJ
Feb 7 at 23:24
1
1
$begingroup$
@AzJ,
Cases[expr, _h, All]
extracts objects with Head h
that appear at any Level in expr
. If you look at InputForm[simplexPlot]
it is a collection of directives and a single primitive Line[...]
and Cases[simplexPlot, _Line, All]
gets that line expression.$endgroup$
– kglr
Feb 7 at 23:38
$begingroup$
@AzJ,
Cases[expr, _h, All]
extracts objects with Head h
that appear at any Level in expr
. If you look at InputForm[simplexPlot]
it is a collection of directives and a single primitive Line[...]
and Cases[simplexPlot, _Line, All]
gets that line expression.$endgroup$
– kglr
Feb 7 at 23:38
$begingroup$
Okay that makes sense. Does this mean that the accuracy of
RegionNearest[Cases[simplexPlot, _Line, All][[1]]]
depend on how accurate the graphing method is? i..e. Changing MaxRecursion
, PerformaceGoal
,WorkingPrecision
changes the accuracy of the method.$endgroup$
– AzJ
Feb 7 at 23:50
$begingroup$
Okay that makes sense. Does this mean that the accuracy of
RegionNearest[Cases[simplexPlot, _Line, All][[1]]]
depend on how accurate the graphing method is? i..e. Changing MaxRecursion
, PerformaceGoal
,WorkingPrecision
changes the accuracy of the method.$endgroup$
– AzJ
Feb 7 at 23:50
1
1
$begingroup$
@AzJ, good point re accuracy. In addition to the options you mentioned
PlotPoints
also affects the Line
produced by the plot function.$endgroup$
– kglr
Feb 7 at 23:55
$begingroup$
@AzJ, good point re accuracy. In addition to the options you mentioned
PlotPoints
also affects the Line
produced by the plot function.$endgroup$
– kglr
Feb 7 at 23:55
add a comment |
Thanks for contributing an answer to Mathematica Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f191082%2ffinding-the-point-closest-to-a-parameteric-curve-produced-by-a-numerical-method%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
$begingroup$
Nicely written question.
randNum
andsimplexSol
are not defined as far as I can tell though.$endgroup$
– C. E.
Feb 7 at 18:30
$begingroup$
Apologies I copied the code from a match larger document. Forgot to clear memory to test it. The new edited code should work as intended.
$endgroup$
– AzJ
Feb 7 at 18:37