Hello everybody I try to find ALL the maxima of a function and plot the points where the maxima are.
The Function is:
U[x_,y_,a_]:=-((1-a)/Sqrt[(x-a)^2+y^2])-a/Sqrt[(x+1-a)^2+y^2]- 0.5*(x^2+y^2);
Of course this is a 3D function but i satisfied also if someone give me a code to find all
maxima with the 2D version of the function. I put a graph of the function.
points1=Table[{x, 2*U[x, 0, a]}, {x, -1.5, 1.5,0.005}];
ListPlot[points1, Joined->True,PlotRange->{{-1.5,1.5},{-5.5,-3.0}},
AxesLabel->{"x","cost. di Jacobi"}]
I saw a similar post but with a more complex function so i can't understand how modify the code: https://mathematica.stackexchange.com/questions/5575/how-to-find-all-the-local-minima-maxima-in-a-range .
Some one can help me? Thanks.
i finally solve the 2d problem with maximize. Take a look of how i solve the problem !
a=0.23;
J=-3.5;
U[x_,y_,a_]:=-((1-a)/Sqrt[(x-a)^2+y^2])-a/Sqrt[(x+1-a)^2+y^2]- 0.5*(x^2+y^2);
f[x_] := U[x, 0, a];
g[x_] := J;
{max1,val1} = Maximize[{U[x,0,a], x < a-1}, x];
{max2,val2} = Maximize[{U[x,0,a], a-1 < x < a}, x];
{max3,val3} = Maximize[{U[x,0,a], x > a}, x];
sol = x /. NSolve[g[x] == f[x] && -1.5 < x < 1.5, x];
Show[
Plot[{f[x], g[x]}, {x, -1.5, 1.5},AxesLabel->{"x","cost. di Jacobi J(x,a)"},
Epilog -> {
{Red, PointSize[0.025],
Point[{x /. val1, max1}],
Point[{x /. val2, max2}],
Point[{x /. val3, max3}],
Text["\!\(\*SubscriptBox[\(L\), \(1\)]\)",{x /. val1, max1-0.4}],
Text["\!\(\*SubscriptBox[\(L\), \(2\)]\)",{x /. val2, max2-0.4}],
Text["\!\(\*SubscriptBox[\(L\), \(3\)]\)",{x /. val3, max3-0.4}]},
{Black, PointSize[0.025],
Point[{a, -6.0}],
Point[{a-1, -6.0}],
Text["Cost. di Jacobi \!\(\*SubscriptBox[\(J\), \(0\)]\)",{1.0, J-0.2}]}
}
],
ListPlot[{#, g[#]} & /# sol, PlotStyle -> PointSize[Large]]
]
Related
In gnuplot, is there a way to pass a user defined function as an argument to another user defined function? For example, I can write a function loop which will sum shifts of a given function:
f(x) = (x <= 0) ? 0 : 1/(1+x)**2
loop(x, i, s) = (i == 0) ? f(x) : loop(x-s, i-1, s) + f(x)
Then I can do things like:
plot loop(x, 10, 1)
But, how do I define a function loop2 that does this for any function, as in something like:
loop2(g, x, i, s) = (i == 0) ? g(x) : loop2(g, x-s, i-1, s) + g(x)
so that I can then do things like:
f3(x) = (x <= 0) ? 0 : 1/(1+x)**3
plot loop2(f, x, 10, 1)
replot loop2(f3, x, 10, 1)
I think this is not possible in gnuplot 5.4.
The development version (gnuplot 5.5) has recently gained the ability to label a block of text commands as a named executable function, known as a "function block". This gives you access to commands in a function block that are not possible in a one-line user defined function. Here is your example run in a recent build of the development version. At the top level the name of the function ("f" or "f3") is passed as a parameter that can be used to construct a call of the function itself.
function $loop2(name, x, i, s) << EOF
local temp = 0
eval sprintf("temp = %s(x)", name)
return (i == 0) ? temp : temp + $loop2(name, x-s, i-1, s)
EOF
f(x) = (x <= 0) ? 0 : 1/(1+x)**2
f3(x) = (x <= 0) ? 0 : 1/(1+x)**3
set key left Left reverse
set tics nomirror
set border 3
set xrange [0:10]
set yrange [0:1.5]
plot $loop2("f", x, 10, 1), $loop2("f3", x, 10, 1)
And here is a link to an example in the demo collection that illustrates calling one function block from another, wrapping both in a top-level user defined function.
function_block demo
I have a problen in scilab
How can I plot functions containing if and < like
function y = alpha(t)
if (t < 227.8) then
y = 0.75;
elseif (t < 300) then
y = 2.8 - 0.009 .* t;
else
y = 0.1;
end
endfunction
and
function [r]=minus_alpha(t)
r = 1 - alpha(t)
endfunction
When I use
x = linspace(0,300)
plot(x, alpha(x))
I got the error message
WARNING: Transposing row vector X to get compatible dimensions
plot2d: falsche Größe für Eingangsargument: inkompatible Größen.
Error 999 : in plot2d called by plot
Sorry for german mix. Thank you.
You can avoid explicit loop and be more efficient using the followin code
function y = alpha(t)
y=0.1*ones(t);
y(t<227.8)=0.75;
i=t>=227.8&t<300;
y(i)=2.8 - 0.009 .* t(i);
endfunction
It is really sad to see a great majority of Scilab community is not aware of vectorized operations. You can change your function to:
function y = alpha(t)
y = 0.1;
if t < 227.8 then
y = 0.75;
elseif t < 300 then
y = 2.8 - 0.009 * t;
end
y = 1 - y;
endfunction
and then use feval to broadcast the function over the sequence:
x = linspace(0, 300);
plot2d(x, feval(x, alpha));
which results:
rule of thumb if you are using for loop you need to revise your code and if someone is offering you a code where there is unnecessary for loop you shouldn't probably use it.
All the proposed answers are overcomplicated considering that the function alpha in the original demand is piecewise-affine. In Scilab in can be coded that way:
x = linspace(0,400,1000);
plot(x,linear_interpn(x,[227.8 300],[0.75 0.1]))
i.e. you just have to know the nodes coordinates (here abscissae) and value of the function at nodes. The function linear_interpn does also multilinear interpolation, it is worth knowing it guys...
If you check the output of your alpha(x), you will see that it is just a scalar (not a vector). I guess you wanted something like this, so it's necessary to iterate through t to compute each value of y based on the value of t:
clc;
clear;
function y = alpha(t)
for i=1:size(t,"*")
if t(i) < 227.8 then
y(i) = 0.75;
elseif t(i) < 300 then
y(i) = 2.8 - 0.009 * t(i);
else
y(i) = 0.1;
end
end
endfunction
x = linspace(0,300);
plot2d(x,alpha(x));
If you find the answer useful, please do not forget to accept it, so others will see that your problem is solved.
Before your answers (thank you) my workaround was a combination of indicator functions composed with floor and exp( -t^2):
function y = alpha(t)
y = floor(exp(-(t .* (t-T1)) / (T1*T1))) * 0.75
+ floor(exp(-((t-T2) .* (t- T1) / (2000)))) .* (2.8-0.009 .* t)
+ floor(exp(-((t-T2) .* (t-1000) / (200000))))*0.1
endfunction
I would like to define a list using a for loop and I need to do it using a function of the n-iterate.
I have:
Initialization
In[176]: Subscript[y, 0] = {1, 2, 3}
Out[180]: {1,2,3}
The function:
In[181]: F[n_] := For[l = 1, l++, l <= 3, Subscript[y, n + 1][[l]] :=Subscript[y, n][[l]]+ n]
I call the function
F[0]
and I get:
In[183]: Subscript[y, 1]
Out[183]: Subscript[0, 1]
I should have {1,2,3}.
Anyone know why it isn't working as it should?
I have troubles recreating your error, problem.
I understand you want to add n to your vector, where n is the number of the subscript.
Here's another way to have a go at your question, avoiding the loop and the subscripts:
Clear#y;
y[0] = {1, 2, 3};
y[n_Integer] : =y[n - 1] + n
(as Plus is Listable, you can just add n to the vector, avoiding the For)
and then call it using, e.g.
y[0]
{1,2,3}
or
y[5]
{16,17,18}
Alternatively, using memoization, you could define y as follows:
y[n_Integer] := y[n] = y[n - 1] + n
This will then store already calculated values (check ?y after executing e.g. y[5]). Don't forget to Clear y, if y changes.
Obviously, for a function as this one, you might want to consider:
y[n_Integer] := y[0] + Total[Range[n]]
Hi does anyone know how to visualize the tetrahedrons in the output of the delaunay3() function in Octave?
http://www.obihiro.ac.jp/~suzukim/masuda/octave/html3/octave_151.html
In MATLAB this visualization is done with the tetramesh() function but Octave does not have this function built in!
The link does mention the triplot and trimesh functions but they only create triangles, not tetrahedra.
Unfortunately, I don't know enough about this to give any thoughts on it. But, I would like to mention the following, in case you hadn't seen it before. There have been discussions on tetramesh before. A quick solution was written up by martin_helm:
function tetramesh( T, X, C)
if nargin < 3
C = mod((1:size(T, 1))'-1, size(colormap(), 1) + 1);
endif
triang = [T(:, 1) T(:, 2) T(:, 3); ...
T(:, 2) T(:, 3) T(:, 4); ...
T(:, 3) T(:, 4) T(:, 1); ...
T(:, 4) T(:, 1) T(:, 2)];
patch("Faces", triang, "Vertices", X, "FaceVertexCData", [C; C; C; C])
endfunction
Along with some example usage:
backend("fltk") % backend("gnuplot") could also be used
d = [-1 1];
[x,y,z] = meshgrid(d,d,d);
x = [x(:);0];
y = [y(:);0];
z = [z(:);0];
tetra = delaunay3(x,y,z);
X = [x(:) y(:) z(:)];
tetramesh(tetra, X)
view(30,30)
Given a 2D circle with 2 angles in the range -PI -> PI around a coordinate, what is the value of the smallest angle between them?
Taking into account that the difference between PI and -PI is not 2 PI but zero.
An Example:
Imagine a circle, with 2 lines coming out from the center, there are 2 angles between those lines, the angle they make on the inside aka the smaller angle, and the angle they make on the outside, aka the bigger angle.
Both angles when added up make a full circle. Given that each angle can fit within a certain range, what is the smaller angles value, taking into account the rollover
This gives a signed angle for any angles:
a = targetA - sourceA
a = (a + 180) % 360 - 180
Beware in many languages the modulo operation returns a value with the same sign as the dividend (like C, C++, C#, JavaScript, full list here). This requires a custom mod function like so:
mod = (a, n) -> a - floor(a/n) * n
Or so:
mod = (a, n) -> (a % n + n) % n
If angles are within [-180, 180] this also works:
a = targetA - sourceA
a += (a>180) ? -360 : (a<-180) ? 360 : 0
In a more verbose way:
a = targetA - sourceA
a -= 360 if a > 180
a += 360 if a < -180
x is the target angle. y is the source or starting angle:
atan2(sin(x-y), cos(x-y))
It returns the signed delta angle. Note that depending on your API the order of the parameters for the atan2() function might be different.
If your two angles are x and y, then one of the angles between them is abs(x - y). The other angle is (2 * PI) - abs(x - y). So the value of the smallest of the 2 angles is:
min((2 * PI) - abs(x - y), abs(x - y))
This gives you the absolute value of the angle, and it assumes the inputs are normalized (ie: within the range [0, 2π)).
If you want to preserve the sign (ie: direction) of the angle and also accept angles outside the range [0, 2π) you can generalize the above. Here's Python code for the generalized version:
PI = math.pi
TAU = 2*PI
def smallestSignedAngleBetween(x, y):
a = (x - y) % TAU
b = (y - x) % TAU
return -a if a < b else b
Note that the % operator does not behave the same in all languages, particularly when negative values are involved, so if porting some sign adjustments may be necessary.
An efficient code in C++ that works for any angle and in both: radians and degrees is:
inline double getAbsoluteDiff2Angles(const double x, const double y, const double c)
{
// c can be PI (for radians) or 180.0 (for degrees);
return c - fabs(fmod(fabs(x - y), 2*c) - c);
}
See it working here:
https://www.desmos.com/calculator/sbgxyfchjr
For signed angle:
return fmod(fabs(x - y) + c, 2*c) - c;
In some other programming languages where mod of negative numbers are positive, the inner abs can be eliminated.
I rise to the challenge of providing the signed answer:
def f(x,y):
import math
return min(y-x, y-x+2*math.pi, y-x-2*math.pi, key=abs)
For UnityEngine users, the easy way is just to use Mathf.DeltaAngle.
Arithmetical (as opposed to algorithmic) solution:
angle = Pi - abs(abs(a1 - a2) - Pi);
I absolutely love Peter B's answer above, but if you need a dead simple approach that produces the same results, here it is:
function absAngle(a) {
// this yields correct counter-clock-wise numbers, like 350deg for -370
return (360 + (a % 360)) % 360;
}
function angleDelta(a, b) {
// https://gamedev.stackexchange.com/a/4472
let delta = Math.abs(absAngle(a) - absAngle(b));
let sign = absAngle(a) > absAngle(b) || delta >= 180 ? -1 : 1;
return (180 - Math.abs(delta - 180)) * sign;
}
// sample output
for (let angle = -370; angle <= 370; angle+=20) {
let testAngle = 10;
console.log(testAngle, "->", angle, "=", angleDelta(testAngle, angle));
}
One thing to note is that I deliberately flipped the sign: counter-clockwise deltas are negative, and clockwise ones are positive
There is no need to compute trigonometric functions. The simple code in C language is:
#include <math.h>
#define PIV2 M_PI+M_PI
#define C360 360.0000000000000000000
double difangrad(double x, double y)
{
double arg;
arg = fmod(y-x, PIV2);
if (arg < 0 ) arg = arg + PIV2;
if (arg > M_PI) arg = arg - PIV2;
return (-arg);
}
double difangdeg(double x, double y)
{
double arg;
arg = fmod(y-x, C360);
if (arg < 0 ) arg = arg + C360;
if (arg > 180) arg = arg - C360;
return (-arg);
}
let dif = a - b , in radians
dif = difangrad(a,b);
let dif = a - b , in degrees
dif = difangdeg(a,b);
difangdeg(180.000000 , -180.000000) = 0.000000
difangdeg(-180.000000 , 180.000000) = -0.000000
difangdeg(359.000000 , 1.000000) = -2.000000
difangdeg(1.000000 , 359.000000) = 2.000000
No sin, no cos, no tan,.... only geometry!!!!
A simple method, which I use in C++ is:
double deltaOrientation = angle1 - angle2;
double delta = remainder(deltaOrientation, 2*M_PI);