1
$\begingroup$

I have a function $f$ defined on $[-1,1]$. For a minimal example, it suffices to define

f[z_]:=z^2 - 1

I need to find a list of points such that $f(z_0)= f(z_1)$, points whose image "lies at the same height". I proceeded by finding the minimum via

  min = First@Minimize[f[z], {z}]

which occurs for $z$ equal to

argmin = Values@Last@Minimize[f[z], {z}]

I further created a list with

  rang = Subdivide[a, 0,10]

spanning the range from the minimum to the a predefined value.

Now I would like to find, for each element of this list, points such that $f(z_0)=f(z_1) = rang_j$, for each element of the list.

I could not find any better plan than to define a list of functions $fun_j = (f(z)+rang_j)^2$. By shifting the original function and squaring I am certain that the functions $fun_j$, one for each element in the list $rang$ are positive everywhere except the roots.

I wanted then to iterate over the list of functions a constrained minimization via the commands (the argument $f_j$ being just used to clarify my question, I understand the sintax will be different actually that is exactly what the question is about):

   Minimize[{f_j, z > argmin}, {z}]
   Minimize[{f_j, z > argmin}, {z}]

that is, running two minimisations one to the left and one to the right of the ${arg\,min}$. I know on mathematical grounds two unique solutions exists.

I create my list of functions as

 f1[z_,c_]:=f[z]+c

and then using

 f1[z,rang]

but I struggle with iterating Minimize, any suggestion would be helpful.

Trying

  Minimize[{f1[ z, rang], z > b}, z]

yields an error message, as the function argument of Minimize is expected to be a scalar function. I would also love to hear about better methods altoghether, in general and in reference to Mathematica. Cheers

$\endgroup$

2 Answers 2

3
$\begingroup$
Clear["Global`*"]

Manipulate[
 Module[{f0},
  f0 = func /. z -> z0;
  pts = {z, func} /.
     NSolve[{func == f0, -1 <= z <= 1}, z, Reals] // Normal;
  Column[{
    Row[{TraditionalForm[f[Subscript[z, 0]]], " = ", f0}],
    Row[{"z values = ", NumberForm[Or @@ (First /@ pts), {5, 3}]}],
    Plot[func, {z, -1, 1},
     Frame -> True, Axes -> False,
     FrameLabel -> {z, func},
     Epilog -> {Green, Dashed, Line[pts], Red,
       AbsolutePointSize[4], (Tooltip[Point[#], #] & /@ pts)},
     ImageSize -> Medium]}]],
 {{func, z^2 - 1, "function"}, {z^2 - 1 -> TraditionalForm[z^2 - 1],
   z (z^2 - 9/16) -> TraditionalForm[z (z^2 - 9/16)],
   Sin[2 Pi z] -> TraditionalForm[Sin[2 Pi z]]},
  ControlType -> RadioButtonBar},
 {{z0, 0, TraditionalForm[Subscript[z, 0]]}, -1, 1, 0.005, 
  Appearance -> "Labeled"}]

enter image description here

EDIT: pts was removed from the list of local variables in the Module which moved it into the Global name space.

Dynamic[First /@ pts]

enter image description here

Dynamic[Integrate[z^2 - 1, {z, pts[[1, 1]], pts[[2, 1]]}]]

enter image description here

Or with static values

Integrate[z^2 - 1, {z, pts[[1, 1]], pts[[2, 1]]}]

(* -0.953531 *)
$\endgroup$
1
  • $\begingroup$ thanks a lot for this. extremely instructive. It will take me some time to decipher it, but I appreciate your help. I need to use the pairs of values as upper and lower integration limits of a list of integrals, so I need to understand how to get them out of your code in a form suitable to be used in Integrate. The Manipulate feature is stunning though. $\endgroup$
    – Smerdjakov
    Commented Apr 6, 2020 at 6:44
1
$\begingroup$

Create a function over the range {-1,1}

f[z_] := Sin[2π z]
Plot[f[z], {z, -1, 1}]

enter image description here

A function to find possible z1 given a z0, uses Reduce to find all solutions.

findZ1[z0_] := Reduce[{f[x] == f[z0], x != z0, -1 <= x <= 1}, {x}]

Note the x!=z0 term in there. It doesn't seem to work, I left it in there to show I tried it.

Pick a z0

res= findZ1[.2]

(* x == -0.8 || x == -0.7 || x == 0.2 || x == 0.3 *)

Convert to rules

{ToRules[res]} // Flatten
(* {x -> -0.8, x -> -0.7, x -> 0.2, x -> 0.3} *)

you'll need to remove the z1 that matches the orginal z0.

EDIT

For a simple function that is everywhere convex and the minimum lies in the interval {-1,1}...

f[z_] := (z^2) - 1 

Subdivide the interval. It's not clear to me what you are doing in your question, so just subdivide it from 0 to 1. Drop the first point, which is at the minimum.

pts = Subdivide[0, 1, 5]//Rest
(* {1/5, 2/5, 3/5, 4/5, 1} *)

findZ1[z0_] := First@Values@ToRules@Reduce[{f[x] == f[z0], x != z0, -1 <= x <= 1}, {x}]

Map[findZ1, pts]
(* {-(1/5), -(2/5), -(3/5), -(4/5), -1} *)
$\endgroup$
3
  • $\begingroup$ thanks a lot for this. I need to iterate your function findZ1: the function I am considering is such that your findZ1 it will return 2 values, and I want to use them as upper and lower integration limits in the next stage of the code. How can I iterate findZ1, over different values? If I define a list ran = {0.8,0.6,0.4.0.2}, I was hoping to be able to get pairs of values like with Apply[findZ1, ran], but it is not the case. $\endgroup$
    – Smerdjakov
    Commented Apr 6, 2020 at 6:54
  • $\begingroup$ OK, if we can guarantee the shape is convex upward in the interval...see my edit. We use Map instead of Apply. $\endgroup$
    – MikeY
    Commented Apr 6, 2020 at 13:16
  • 1
    $\begingroup$ Thanks a lot, it works and I have learnt a few things. $\endgroup$
    – Smerdjakov
    Commented Apr 8, 2020 at 21:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.