In [3]:
using Plots
using Optim
In [6]:
# example of Rosenbrock function
function f(x)
return (1.0 - x[1])^2 + 100.0 * (x[2] - x[1]^2)^2
end
function g!(x::Vector, storage::Vector)
storage[1] = -2.0 * (1.0 - x[1]) - 400.0 * (x[2] - x[1]^2) * x[1]
storage[2] = 200.0 * (x[2] - x[1]^2)
end
soln = optimize(f, g!, [0.0, 0.0], GradientDescent())
Out[6]:
In [5]:
reshape(randn(5,3),15,1)
Out[5]:
In [7]:
# now, we do the matrix factorization example
# originally from Poblano example2
function matrix_approx_function(x::Vector, A::Matrix, r::Int)
# unpack U and V from x
m,n = size(A)
U = reshape(x[1:m*r],m,r)
V = reshape(x[(m*r+1):end],n,r)
return 0.5*vecnorm(A - U*V')^2
end
function matrix_approx_gradient!(x::Vector, storage::Vector, A::Matrix, r::Int)
m,n = size(A)
U = reshape(x[1:m*r],m,r)
V = reshape(x[(m*r+1):end],n,r)
D = A - U*V'
storage[1:(m*r)] = -vec(D*V)
storage[(m*r+1):end] = -vec(D'*U)
end
Out[7]:
In [9]:
m = 5
n = 4
A = randn(m,n)
r = 2
myf = x -> matrix_approx_function(x, A, r)
myg! = (x, storage) -> matrix_approx_gradient!(x, storage, A, r)
#soln = optimize(myf, myg!, randn(m*r+n*r), LBFGS(), Optim.Options(f_tol = 1e-8))
soln = optimize(myf, myg!, randn(m*r+n*r), LBFGS(), OptimizationOptions(ftol = 1e-8))
x = Optim.minimizer(soln)
@show soln
Uopt = reshape(x[(1:m*r)],m,r)
Vopt = reshape(x[(m*r+1):end],n,r)
objval = 2*myf(x)
opterr = vecnorm(A-Uopt*Vopt')^2
Usvd,Ssvd,Vsvd = svd(A)
svderr = vecnorm(A-Usvd[:,1:r]*diagm(Ssvd[1:r])*Vsvd[:,1:r]')^2
@show objval
@show opterr
@show svderr
; # hide final output in JuliaBox
In [ ]: