How to define a piecewise map in sage - function

I want to define in Sage the following
map. I've attempted to use the following code in Sage:
gamma=function('gamma')
gamma(t)=piecewise([(t>0,(t,0,e^(-1/t^2))),(t==0,(0,0,0)),(t<0,(t,e^(-1/t^2),0))])
This, however, gives me the error TypeError: unable to convert (t, 0, e^(-1/t^2)) to a symbolic expression. How could I change it to create such a type of map?

It seems piecewise does not support vector-valued functions.
Possible workaround: define each coordinate as a piecewise function.
sage: gamma(t) = (t,
....: piecewise([(t <= 0, 0), (t > 0, exp(-t^-2))]),
....: piecewise([(t < 0, exp(-t^-2)), (t > 0, 0)]))
....:
sage: gamma
t |--> (t,
piecewise(t|-->0 on (-oo, 0], t|-->e^(-1/t^2) on (0, +oo); t),
piecewise(t|-->e^(-1/t^2) on (-oo, 0), t|-->0 on (0, +oo); t))
sage: parametric_plot(gamma, (t, -1, 1))
Launched html viewer for Graphics3d Object

Related

How to make the sum of output to 1

My (PyTorch) sum of model’s output isn’t 1. And this is the structure of model.
LSTM(4433, 64)
LSTM(64, 64)
Linear(64, 4433)
Sigmoid()
And this is the predicted output of the model.
Input
[1, 0, 0, …, 0, 0]
Output
[.7842, .5, .5, …, .5, .5]
Do you know any function that can make its sum 1?
Sigmoid activation function maps every input to a value between [0, 1], without taking into account other elements in the input vector. However, Softmax does a similar transformation but the output vector sums 1.
TL;DR: use softmax instead of sigmoid.

Scipy Optimization: Pass a function as a constraint with additional arguments (args)

I have an optimization problem (optimze by changing x[0] and x[1]), where one of the constraints is a function, that uses the same constant variables (a and b) as the optimization function.
min f(x, a, b)
x[0] <= 100
x[1] <= 500
g(x, a, b) >= 0.9
But I am not sure how to realize the connection between function f and g:
x0 = np.array([10, 100])
bnds = ((0, 500), (0, 5000))
arguments = (100, 4) # This are varibles a and b
cons = ({'type': 'ineq', 'fun': lambda x: x[0]},
{'type': 'ineq', 'fun': lambda x: x[1]},
{'type': 'ineq', 'fun': lambda x: g(x, 100, 4)-0.9})
res = minimize(f, x0, args=arguments, method='SLSQP', bounds=bnds, constraints=cons)
print(res.x)
>> x: array([10, 5000])
But using this results function g results in
g(x,a,b)=0.85434
There is an optimal solution with x=[452, 4188], where
g(x,a,b)=0.901839
How do I need to adapt the constraints, that g(x,a,b) is valid.
Edit: Obviously the optimization is not sucessful:
print(res)
>> fun: 1778.86301369863
>> jac: array([1.00019786e+09, 9.31503296e-01])
>> message: 'Inequality constraints incompatible'
>> nfev: 4
>> nit: 1
>> njev: 1
>> status: 4
>> success: False
>> x: array([ 10., 5000.])
Thanks a lot.
UvW
f() and g() are not convex, not smooth and derivates are not available. Nevertheless my questioned aimed for the right syntax (using a function as a constraint). So I tried it with two "simpler" functions (see executeable code below) and it worked. So I assume, that my syntax is right and the problem lies with optimization method "SLSQP".
Is there an optimization method within the SCIPY package (some kind of Evolutionary algorithm) that I can use to solve my problem with g() and f()
not convex,
not smooth and
derivates are not available?
import numpy as np
from scipy.optimize import minimize
def g(x, a, b):
return (x[0]+x[1]+a+b)/100
def f(x, a, b):
return (x[0]*a+x[1]*b)*g(x, a, b)
x0 = np.array([0, 0]) bnds = ((0, 30), (0, 20)) arguments = (2, 3) # This are varibles a and b
cons = ({'type': 'ineq', 'fun': lambda x: x[0]},
{'type': 'ineq', 'fun': lambda x: x[1]},
{'type': 'ineq', 'fun': lambda x: g(x, 2, 3)-0.5}) #<--My question was about the correct syntax of that constraint
res = minimize(f, x0, args=arguments, method='SLSQP', bounds=bnds, constraints=cons)
print(res)
>> fun: 52.50000000000027
>> jac: array([2.05000019, 2.55000019])
>> message: 'Optimization terminated successfully.'
>> nfev: 20
>> nit: 5
>> njev: 5
>> status: 0
>> success: True
>> x: array([30., 15.])

Fourier series of a box function using sympy

I tried this code but i m getting an error. And If possible pls tell me how to lambdify the defined funct
CODE
from sympy.abc import x
from sympy import *
init_printing()
def func(y):
if y>0:
return 1
elif y<0:
return -1
else:
return 0
s = fourier_series(func(x), (x, -1, 1))
s = s.truncate(n=4)
s
"TypeError: cannot determine truth value of Relational"
this is the error im getting
Please help,
Thank you.
Note that sympy can only work with functions that are fully defined as a sympy expression. To emulate if - elif - else, Piecewise can be used. There is also a special function, Heaviside, that directly corresponds to your given function. Default, Heaviside(0) is undefined. However, the value for 0 can be provided as a second argument.
Using the Heaviside function doesn't seem to work in this case:
from sympy import Heaviside, fourier_series
from sympy.abc import x
s = fourier_series(Heaviside(x, 0), (x, -1, 1))
print(s)
This results in an unevaluated integral with which sympy can't do further operations:
FourierSeries(Heaviside(x, 0), (x, -1, 1), (Integral(Heaviside(x, 0), (x, -1, 1))/2, SeqFormula(cos(_n*pi*x)*Integral(cos(_n*pi*x)*Heaviside(x, 0), (x, -1, 1)), (_n, 1, oo)), SeqFormula(sin(_n*pi*x)*Integral(sin(_n*pi*x)*Heaviside(x, 0), (x, -1, 1)), (_n, 1, oo))))
Fortunately, with Piecewise, everything works as desired:
from sympy import lambdify, Piecewise, fourier_series
from sympy.abc import x
s = fourier_series(Piecewise((1, x > 0), (-1, x < 0), (0, True)), (x, -1, 1))
The function can be lambdified calling lambdify(x, s.truncate(n=4)), and then be used for example to draw curves via matplotlib:
import numpy as np
import matplotlib.pyplot as plt
for k in range(1, 7):
s_np = lambdify(x, s.truncate(n=k))
xs = np.linspace(-1, 1, 500)
plt.plot(xs, s_np(xs), label=f'$n={k}$')
plt.autoscale(enable=True, axis='x', tight=True)
plt.legend()
plt.show()

Octave: expecting scalar N, or 2-/4-element vector DOM-ezsurf Error

I need some kind of help about ezsurf
as I understand from my research matlab fplot is equal to ezplot in octave. And I write a script
fx = #(x,y) x.*sin(y);
fy = #(x,y) -x.*cos(y);
fz = #(x,y) y;
ezsurf(fx, fy, fz,[-5 5 -5 -2],'--','EdgeColor','g')
hold on
ezsurf(fx, fy, fz,[-5 5 -5 -2],'EdgeColor','none')
hold off
if I able to run the script I expect to see this image
However when I run the script I get this error
error: ezsurf: expecting scalar N, or 2-/4-element vector DOM
error: called from
__ezplot__ at line 260 column 7
ezsurf at line 78 column 19
file at line 4 column 1
What is the "expecting scalar N" what should I understand I how can I fix this.
Thank you so much in advance
fx = # (x,y) x .*sin(y);
fy = # (x,y) -x .*cos(y);
fz = # (x,y) y;
h1 = ezsurf (fx, fy, fz, [-5, 5, -5, -2]);
set (h1, 'edgecolor', 'g', 'linestyle', '--', 'linewidth', 0.1);
hold on
h2 = ezsurf (fx, fy, fz, [5, -5, 5, -2]);
set (h2, 'edgecolor', 'none');
hold off
colormap (parula (256)); % assuming you have the parula colormap installed

plotting on the y-axis in Mathematica

I have another question about Wolfram Mathematica. Is there someone that knows how I can plot a graphic on the y axis?
I hope that the figure helps.
ParametricPlot[{5 Sin[y], y}, {y, -2 \[Pi], 2 \[Pi]},
Frame -> True, AxesLabel -> {"x", "y"}]
EDIT
None of the answers given thus far can work with Plot's Filling option. Plot's output contains a GraphicsComplex in that case (which, incidentally, breaks Mr.Wizard's replacements). To get the filling capability (it doesn't work for a standard plot without filling) you could use the following:
Plot[Sin[x], {x, 0, 2 \[Pi]}, Filling -> Axis] /. List[x_, y_] -> List[y, x]
Plot[{Sin[x], .5 Sin[2 x]}, {x, 0, 2 \[Pi]}, Filling -> {1 -> {2}}]
/. List[x_, y_] -> List[y, x]
You can flip the axes after plotting with Reverse:
g = Plot[Sin[x], {x, 0, 9}];
Show[g /. x_Line :> Reverse[x, 3], PlotRange -> Automatic]
With a minor change this works for plots using Filling as well:
g1 = Plot[{Sin[x], .5 Sin[2 x]}, {x, 0, 2 \[Pi]}];
g2 = Plot[{Sin[x], .5 Sin[2 x]}, {x, 0, 2 \[Pi]}, Filling -> {1 -> {2}}];
Show[# /. x_Line | x_GraphicsComplex :> x~Reverse~3,
PlotRange -> Automatic] & /# {g1, g2}
(It may be more robust to replace the RHS of :> with MapAt[#~Reverse~2 &, x, 1])
As a Function
Here is the form I recommend one use. It includes flipping of the original PlotRange rather than forcing PlotRange -> All:
axisFlip = # /. {
x_Line | x_GraphicsComplex :>
MapAt[#~Reverse~2 &, x, 1],
x : (PlotRange -> _) :>
x~Reverse~2 } &;
To be used like: axisFlip # g1 or axisFlip # {g1, g2}
A different effect can be had with Rotate:
Show[g /. x_Line :> Rotate[x, Pi/2, {0,0}], PlotRange -> Automatic]
One possibility is to use a ParametricPlot like this:
ParametricPlot[
{-y*Exp[-y^2], y}, {y, -0.3, 4},
PlotRange -> {{-2, 2}, All},
AxesLabel -> {"x", "y"},
AspectRatio -> 1/4
]
Just for fun:
ContourPlot is another alternative.
Using Thies function:
ContourPlot[-y*Exp[-y^2/2] - x == 0,
{x, -2, 2}, {y, 0, 4},
Axes -> True, Frame -> None]
RegionPlot is another
RegionPlot[-y*Exp[-y^2/2] > x,
{x, -2.1, 2.1}, {y, -.1, 4.1},
Axes -> True, Frame -> None, PlotStyle -> White,
PlotRange -> {{-2, 2}, {0, 4}}]
And finally, a REALLY convoluted way using ListCurvePathPlot and Solve:
Off[Solve::ifun, FindMaxValue::fmgz];
ListCurvePathPlot[
Join ##
Table[
{x, y} /. Solve[-y*Exp[-y^2/2] == x, y],
{x, FindMaxValue[-y*Exp[-y^2/2], y], 0, .01}],
PlotRange -> {{-2, 2}, {0, 4}}]
On[Solve::ifun, FindMaxValue::fmgz];
Off Topic
Answer to Sjoerd's None of the answers given thus far can work with Plot's Filling option.
Reply: Not necessary
f={.5 Sin[2 y],Sin[y]};
RegionPlot[Min#f<=x<=Max#f,{x,-1,1},{y,-0.1,2.1 Pi},
Axes->True,Frame->None,
PlotRange->{{-2,2},{0,2 Pi}},
PlotPoints->500]
Depending on how you wanted the axis labels to show, you could just wrap the code for the original Plot in the Rotate function.