I want to make a contour plot of the loss space for a rather simple regression. Whenever I go to plot the space my session dies. Is there something that I'm doing wrong or do I need to trouble shoot installation? (just installed a couple days ago but haven't used Julia before)
using Plots, DataFrames, StatsPlots, Statistics, LinearAlgebra
f(t) = t.^2
c(θ₁, θ₂) = sum(f(t)-θ₁*t-θ₂*t.^2)
t = LinRange(0,1,20) |> collect
θ₁ = LinRange(-3,2,100) |> collect
θ₂ = LinRange(-1,3.5,100)|> collect
X = [t t.^2]
θ = [θ₁ θ₂]
yhats = X * transpose(θ)
ytrue = t.^2
e = yhats .- ytrue
tse = sum(e.^2, dims=1)
contour(θ[:,1],θ[:,2], tse)
It looks like you are trying to do
using Plots
f(t) = t^2
y(θ₁, θ₂, t) = θ₁ * t + θ₂ * t^2
ts = LinRange(0, 1, 20)
e(θ₁, θ₂) = sum(abs2, f(t) - y(θ₁, θ₂, t) for t in ts)
θ₁ = LinRange(-3, 2, 100)
θ₂ = LinRange(-1, 3.5, 100)
contourf(θ₁, θ₂, e)
which gives
Related
I am trying to test a linear approximation function and I am getting the error "no method matching current_axis(::Nothing)".
Here is my linear approximation function:
function linear_approx(A,b,c,p0)
p0 = [i for i in p0]
y(p) = p'*A*p .+ b'*p .+ c .-1
e = y(p0)
d = 2*A*p0 + b
(; d, e)
end
Here is the function that attempts to plot and throws an exception. I also included that value of the parameter when I tried to call it:
pts = [(1,1), (3,2), (4,4)]
function visualize_approx(pts)
# Use this function to inspect your solution, and
# ensure that the three points lie on one of
# the level-sets of your quadratic approximation.
(; A, b, c) = constant_curvature_approx(pts)
min_val = Inf
max_val = -Inf
for pt in pts
(; d, e) = linear_approx(A,b,c,pt)
P = LinRange(pt[1] - 0.2, pt[1]+0.2, 100)
Q = linear_segment(pt, d, e, P)
# the error arises here
plot!(P, Q)
plot!([pt[1]], [pt[2]])
end
delta = max_val - min_val
min_val -= 0.25*delta
max_val += 0.25*delta
X = Y = LinRange(min_val,max_val, 100)
Z = zeros(100,100)
for i = 1:100
for j = 1:100
pt = [X[i]; Y[j]]
Z[i,j] = pt'*A*pt + pt'*b + c
end
end
contour(X,Y,Z,levels=[-1,0,1,2,3])
for pt in pts
plot!([pt[1]], [pt[2]])
end
current_figure()
end
Does anyone know why this error arises?
plot! modifies a previously created plot object. It seems like you did not create a plot before calling it. This is why you get the error. Use plot when creating the plot and plot! when modifying it.
I want to plot a time-evolution of 3D Gaussian with Makie.jl.
Here is a surface-version code of sin(r)/r.
So I wrote a code in reference to it.
using Makie
using FileIO
using LinearAlgebra
using AbstractPlotting
scene = Scene(backgroundcolor = :black);
f(x,y,z) = exp(-((x)^2 + (y)^2 + (z)^2))
r = LinRange(-5, 5, 50)
vol_func(t) = [Float64(f(x - cos(t),y - sin(t),z - t)) for x = r, y = r,z = r]
vol = volume!(scene,r,r,r,vol_func(20),algorithm = :mip)[end]
scene[Axis].names.textcolor = :gray
N = 20
scene
record(scene, "voloutput.mp4", range(0, stop = 5, length = N)) do t
vol[3] = vol_func(t)
end
But this code does not work.
MethodError: Cannot `convert` an object of type Array{Float64,3} to an object of type LinRange{Float64}
How should I fix the code?
P.S.
The snapshot at initial time is like this.(reference)
using Makie
using FileIO
using LinearAlgebra
using AbstractPlotting
r = LinRange(-20, 20, 500); # our value range
ρ(x, y, z) = exp(-((x-1)^2 + (y)^2 + (z)^2)) # function (charge density)
# create a Scene with the attribute `backgroundcolor = :black`,
# can be any compatible color. Useful for better contrast and not killing your eyes with a white background.
scene = Scene(backgroundcolor = :black)
volume!(
scene,
r, r, r, # coordinates to plot on
ρ, # charge density (functions as colorant)
algorithm = :mip # maximum-intensity-projection
)
scene[Axis].names.textcolor = :gray # let axis labels be seen on dark
background
save("sp.png",scene)
I want to see the yellow region moving as spiral. (2020/08/28)
I just realized not vol[3] but vol[4]. Then, it worked.
But I have a next question. (2020/08/31)
I tried to do the same thing for the matrix-form time-dependent Schrodinger equation with its initial condition being Gaussian.
using LinearAlgebra
using OrdinaryDiffEq
using DifferentialEquations
#Define the underlying equation
function time_evolution(ψdot,ψ,p,t)
ψdot.=-im.*H(Lx,Ly,Lz)*ψ
end
Lx = Ly = Lz = 10
ψ0 = [] # Initial conditions
for iz = 1:Lz
for ix = 1:Lx
for iy = 1:Ly
gauss = exp(-((ix)^2 + (iy)^2 + (iz)^2))
push!(ψ0,gauss)
end
end
end
tspan = (0.,1.0) # Simulation time span
#Pass to Solvers
prob = ODEProblem(time_evolution,ψ0,tspan)
sol = solve(prob)
Here,H(Lx,Ly,Lz) is a N×N matrix parameterized by systemsize Lx,Ly,Lz and N = Lx×Ly×Lz. The sample code of H(Lx,Ly,Lz) is here.
Then,
using Makie
using FileIO
using LinearAlgebra
using AbstractPlotting
using ColorSchemes
x = 1: Lx # our value range
y = 1: Ly
z = 1: Lz
ρ(ix,iy,iz,nt) = abs2.((sol[nt][(iz-1)*Lx*Ly + (ix-1)*Ly + (iy-1)])./norm(sol[nt][(iz-1)*Lx*Ly + (ix-1)*Ly + (iy-1)]))
ψ(nt) = Float64[ρ(ix,iy,iz,nt) for ix in x, iy in y,iz in z]
scene = Scene(backgroundcolor = :white)
c = ψ(length(sol.t))
vol = volume!(
scene,
x, y, z, # coordinates to plot on
c, # charge density (functions as colorant)
algorithm = :mip, # maximum-intensity-projection
colorrange = (0,0.01),
transparency = true,
)[end]
update_cam!(scene, Vec3f0(1,0.5,0.1), Vec3f0(0))
scene[Axis].names.textcolor = :gray # let axis labels be seen on darkbackground
record(scene, "output.mp4", range(0, stop = length(sol.t)-1, length = 1)) do nt
vol[4] = ψ(nt)
end
But this code has an error.
ArgumentError: range(0.0, stop=5.0, length=1): endpoints differ
Where is the mistake?
I found the mistake.(2020/09/02)
sol[nt]→sol(nt)
range(0, stop = length(sol.t)-1, length = 1)→range(0, stop = 1.0, length = 20)
Then, the code passed and a mp4 animation was obtained.
But the plot can't be seen in the mp4 file. Why...
I am struggling to plot evaluated function and Cbebyshev approximation.
I am using Julia 1.2.0.
EDIT: Sorry, added completed code.
using Plots
pyplot()
mutable struct Cheb_struct
c::Vector{Float64}
min::Float64
max::Float64
end
function cheb_coeff(min::Float64, max::Float64, n::Int, fn::Function)::Cheb_struct
struc = Cheb_struct(Vector{Float64}(undef,n), min, max)
f = Vector{Float64}(undef,n)
p = Vector{Float64}(undef,n)
max_plus_min = (max + min) / 2
max_minus_min = (max - min) / 2
for k in 0:n-1
p[k+1] = pi * ((k+1) - 0.5) / n
f[k+1] = fn(max_plus_min + cos(p[k+1])*max_minus_min)
end
n2 = 2 / n
for j in 0:n-1
s = 0
for i in 0:n-1
s += f[i+1]*cos(j*p[i+1])
struc.c[j+1] = s * n2
end
end
return struc
end
function approximate(struc::Cheb_struct, x::Float64)::Float64
x1 = (2*x - struc.max - struc.min) / (struc.max - struc.min)
x2 = 2*x1
t = s = 0
for j in length(struc.c):-1:2
pom = s
s = x2 * s - t + struc.c[j]
t = pom
end
return (x1 * s - t + struc.c[1] / 2)
end
fn = sin
struc = cheb_coeff(0.0, 1.0, 10, fn)
println("coeff:")
for x in struc.c
#printf("% .15f\n", x)
end
println("\n x eval approx eval-approx")
for x in struc.min:0.1:struc.max
eval = fn(x)
approx = approximate(struc, x)
#printf("%11.8f %12.8f %12.8f % .3e\n", x,eval, approx, eval - approx)
display(plot(x=eval,y=approx))
end
I am getting empty plot window.
I would be very grateful if someone coould how to plot these two functions.
You should provide a working code as an example.
However the code below can show you how to plot:
using Plots
pyplot()
fn = sin
approxf(x) = sin(x)+rand()/10
x = 0:0.1:1
evalv = fn.(x)
approxv = approxf.(x)
p = plot(evalv,approxv)
using PyPlot
PyPlot.display_figs() #needed when running in IDE such as Atom
https://en.wikipedia.org/wiki/Superellipse
I have read the SO questions on how to point-pick from a circle and an ellipse.
How would one uniformly select random points from the interior of a super-ellipse?
More generally, how would one uniformly select random points from the interior of the curve described by an arbitrary super-formula?
https://en.wikipedia.org/wiki/Superformula
The discarding method is not considered a solution, as it is mathematically unenlightening.
In order to sample the superellipse, let's assume without loss of generality that a = b = 1. The general case can be then obtained by rescaling the corresponding axis.
The points in the first quadrant (positive x-coordinate and positive y-coordinate) can be then parametrized as:
x = r * ( cos(t) )^(2/n)
y = r * ( sin(t) )^(2/n)
with 0 <= r <= 1 and 0 <= t <= pi/2:
Now, we need to sample in r, t so that the sampling transformed into x, y is uniform. To this end, let's calculate the Jacobian of this transform:
dx*dy = (2/n) * r * (sin(2*t)/2)^(2/n - 1) dr*dt
= (1/n) * d(r^2) * d(f(t))
Here, we see that as for the variable r, it is sufficient to sample uniformly the value of r^2 and then transform back with a square root. The dependency on t is a bit more complicated. However, with some effort, one gets
f(t) = -(n/2) * 2F1(1/n, (n-1)/n, 1 + 1/n, cos(t)^2) * cos(t)^(2/n)
where 2F1 is the hypergeometric function.
In order to obtain uniform sampling in x,y, we need now to sample uniformly the range of f(t) for t in [0, pi/2] and then find the t which corresponds to this sampled value, i.e., to solve for t the equation u = f(t) where u is a uniform random variable sampled from [f(0), f(pi/2)]. This is essentially the same method as for r, nevertheless in that case one can calculate the inverse directly.
One small issue with this approach is that the function f is not that well-behaved near zero - the infinite slope makes it quite challenging to find a root of u = f(t). To circumvent this, we can sample only the "upper part" of the first quadrant (i.e., area between lines x=y and x=0) and then obtain all the other points by symmetry (not only in the first quadrant but also for all the other ones).
An implementation of this method in Python could look like:
import numpy as np
from numpy.random import uniform, randint, seed
from scipy.optimize import brenth, ridder, bisect, newton
from scipy.special import gamma, hyp2f1
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
seed(100)
def superellipse_area(n):
#https://en.wikipedia.org/wiki/Superellipse#Mathematical_properties
inv_n = 1. / n
return 4 * ( gamma(1 + inv_n)**2 ) / gamma(1 + 2*inv_n)
def sample_superellipse(n, num_of_points = 2000):
def f(n, x):
inv_n = 1. / n
return -(n/2)*hyp2f1(inv_n, 1 - inv_n, 1 + inv_n, x)*(x**inv_n)
lb = f(n, 0.5)
ub = f(n, 0.0)
points = [None for idx in range(num_of_points)]
for idx in range(num_of_points):
r = np.sqrt(uniform())
v = uniform(lb, ub)
w = bisect(lambda w: f(n, w**n) - v, 0.0, 0.5**(1/n))
z = w**n
x = r * z**(1/n)
y = r * (1 - z)**(1/n)
if uniform(-1, 1) < 0:
y, x = x, y
x = (2*randint(0, 2) - 1)*x
y = (2*randint(0, 2) - 1)*y
points[idx] = [x, y]
return points
def plot_superellipse(ax, n, points):
coords_x = [p[0] for p in points]
coords_y = [p[1] for p in points]
ax.set_xlim(-1.25, 1.25)
ax.set_ylim(-1.25, 1.25)
ax.text(-1.1, 1, '{n:.1f}'.format(n = n), fontsize = 12)
ax.scatter(coords_x, coords_y, s = 0.6)
params = np.array([[0.5, 1], [2, 4]])
fig = plt.figure(figsize = (6, 6))
gs = gridspec.GridSpec(*params.shape, wspace = 1/32., hspace = 1/32.)
n_rows, n_cols = params.shape
for i in range(n_rows):
for j in range(n_cols):
n = params[i, j]
ax = plt.subplot(gs[i, j])
if i == n_rows-1:
ax.set_xticks([-1, 0, 1])
else:
ax.set_xticks([])
if j == 0:
ax.set_yticks([-1, 0, 1])
else:
ax.set_yticks([])
#ensure that the ellipses have similar point density
num_of_points = int(superellipse_area(n) / superellipse_area(2) * 4000)
points = sample_superellipse(n, num_of_points)
plot_superellipse(ax, n, points)
fig.savefig('fig.png')
This produces:
I have to simulate some data from a Linear fractional stable motion. I have found an article where they simulate such data using Matlab. The code is from the article "Simulation methods for linear fractional stable motion and
FARIMA using the Fast Fourier Transform" by Stilian Stoev and Murad S. Taqqu. The following is the matlab code:
% Written by Stilian Stoev 05.06.2002, sstoev#math.bu.edu
%
% Usage:
% y = fftlfsn(H,alpha,m,M,C,N,n)
%
mh = 1/m;
d = H-1/alpha;
t0 = [mh:mh:1];
t1 = [1+mh:mh:M];
A = mh^(1/alpha)*[t0.^d, t1.^d-(t1-1).^d];
C = C*(sum(abs(A).^alpha)^(-1/alpha));
A = C*A;
Na = m*(M+N);
A = fft(A,Na);
y = [];
for i=1:n,
if alpha<2,
Z = rstab(alpha,0,Na)’;
elseif alpha==2,
Z = randn(1,Na);
end;
Z = fft(Z,Na);
w = real(ifft(Z.*A,Na));
y = [y; w(1:m:N*m)];
end;
Example:
The commands
H = 0.2; alpha =1.5; m = 256; M = 6000; N = 2^14 - M;
y = fftlfsn(H,alpha,m,M,1,N,1);
x = cumsum(y);
generate a simulated path y of length N of linear
fractional stable noise and a path x of LFSM.
In the following I have tried to translate it,
but I have some questions. I have commented on it in the code.
fftlfsn <- function(H,alpha,m,M,C,N,n){
mh = 1/m;
d = H-1/alpha;
t0 = seq(mh,mh, by =1);
t1 = seq(1+mh,mh, by=M);
# Is the following the right way to translate the matlab code into R?
A = mh^(1/alpha)*matrix(c(t0^d, t1^d-(t1-1)^d), ncol = length(t0), nrow = length(t1));
C = C*(sum(abs(A)^alpha)^(-1/alpha));
A = C*A;
Na = m*(M+N);
# I don't konw if it is right to use the function "fft" here.
#Does this respond directly to the function "fft" in matlab?
A = fft(A,Na);
#how can I do somthing similar in R?
#I think they create an empty matrix? Could I just write y=0?
y = [];
for (i in 1:n)
{
if(alpha<2){
# The function "rstab" generates symmetric alpha-stable variables. Is there a similar function in R, or do you know how to write one?
Z = t(rstab(alpha,0,Na))
}
else if(alpha==2){
Z = matrix (rnorm(Na, mean = 0, sd = 1), nrow = 1, ncol = Na)
}
# Again, can I just use the R-function "fft" directly?
Z = fft(Z,Na);
w = Re(fft(Z*A,Na, inverse= TRUE));
#I have trouble understanding the following and therefore I can't translate it.
y = [y; w(1:m:N*m)];
}
}
Any help appreciated!