I'm trying to vectorize an inequality constraint comparing two Convex types. On one side, I have Convex.MaxAtoms, and on the other side, I have Variables. I want to do something like the following:
using Convex
N = 10
t = Variable(1)
v = Variable(N)
x = Variable(1)
z = rand(100)
problem = minimize(x)
problem.constraints += [t >= 0]
ccc = Vector{Convex.MaxAtom}(N)
for i = 1:N
c = -(1. + minimum(x.*z))
cc = t + c
ccc[i] = max(cc,0.)
end
problem.constraints += [ccc <= v]
but I'm getting the following error on the final constraint:
ERROR: LoadError: MethodError: no method matching isless(::Complex{Int64}, ::Int64)
I'm not sure where the Int64 types are coming in. Is there a better way of adding this constraint besides looping through and adding individual comparisons like
for i = 1:N
problem.constraints += [ccc[i] <= v[i]]
end
I'm trying to avoid this because eventually my 10 will be much larger.
In this case (thanks to Dr. Udell), it works to vectorize as
c = -(1. + xisim + minimum(x.*z))
cc = t + c
ccc = max(cc,0.)
problem.constraints += [ccc <= v]
Related
I am new to Julia and have been trying to compute some polynomials using the Nemo library's multivariate polynomials. I have the following code:
R = GF(2); # create finite field
S, (z, x) = PolynomialRing(R, ["z", "x"]); # Multivariate polynomial
# polynomial initialisations
L = x^0;
E_L = x^0;
E = x*0;
a = z;
w = [1 1 a^3 a^2 a^1 0 0];
n = length(w); #input vector, in terms of a
j = 1;
for i = 1:n
if(w[i] != 0)
L = L*(1-(a^i)*x); # equation for the locator polynomial
if(i != j)
E_L = E_L*(1-(a^j)*x);
end
j = j + 1;
E = E + w[i]*(a^i)*E_L; # LINE WITH ERROR
end
end
I am not entirely sure why the line with the expression for E throws an error.
I have tried a similar thing with the declaration for L: L = L + L*(1-(a^i)*x) to see whether it was something to do with the addition of two polynomials, however, this works fine. Therefore, I am confused as to why E's expression throws an error.
Any help would greatly appreciated! Thanks in advance!
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 have a simple question. How do I use the command qpsolve from Scilab if I only want to use the lower bounds and upper bounds limit?
ci <= x <= cs
The command can be used as this:
[x [,iact [,iter [,f]]]] = qpsolve(Q,p,C,b,ci,cs,me)
But I want to use it like this:
x = qpsolve(Q,p,[],[],ci,cs,[])
Only ci and cs should explain the limits for vector x. Unfortunately, the command cannot take empty []. Should I take [] as a row vector of ones or zeros?
https://help.scilab.org/docs/6.0.1/en_US/qpsolve.html
In Scilab 5.5.1 , [] works for C and b but not for me. so C = [];b = [];me = 0; should work.
Why
qpsolve is an interface for qp_solve :
function [x, iact, iter, f]=qpsolve(Q,p,C,b,ci,cs,me)
rhs = argn(2);
if rhs <> 7
error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"), "qpsolve", 7));
end
C(me+1:$, :) = -C(me+1:$, :);
b(me+1:$) = -b(me+1:$);
// replace boundary contraints by linear constraints
Cb = []; bb = [];
if ci <> [] then
Cb = [Cb; speye(Q)]
bb = [bb; ci]
end
if cs <> [] then
Cb = [Cb; -speye(Q)]
bb = [bb; -cs]
end
C = [C; Cb]; b = [b; bb]
[x, iact, iter, f] = qp_solve(Q, -p, C', b, me)
endfunction
It transform every bound constraints into linear constraints. To begin, it swap the sign of the inequality constraints. To do that, it must know me, ie it must be an integer. Since C and b are empty matrices, is value doesn't matter.
Bonus:
if Q is inversible, you could skip the qpsolve macro and write
x = -Q\p
x(x<ci) = ci(x<ci)
x(x>cs) = cs(x>cs)
I am trying to use NLsolve.jl to solve a set of 6 equations with known Jacobian matrix.
The unknowns are in the array U, so following the repository example I created a function fun! as
function fun!(F, U, k)
W = anotherFunction(U, k)
F[1] = U[1] + 4*k[1]*U[4] - W[1]
F[2] = U[2] - 4*k[2]*U[5] - W[2]
F[3] = U[3] - 4*k[3]*U[6] - W[3]
F[4] = U[1]*(U[4]*U[4]*U[4]*U[4]) -
U[2]*(U[5]*U[5]*U[5]*U[5]) -
U[3]*(U[6]*U[6]*U[6]*U[6])
F[5] = k[7]*(U[4]*U[4]*k[4] - 1 ) -
(k[8]*(U[5]*U[5]*k[5] - 1))
F[6] = k[7]*(U[4]*U[4]*k[4] - 1 ) -
(k[9]*(U[6]*U[6]*k[6] - 1))
end
where the values of W are computed throuhg another function. Similarly, the Jacobian reads
function jac!(J, U, k)
J = eye(6)
J[1,4] = 4*k[1]
J[2,5] = -4*k[2]
J[3,6] = -4*k[3]
J[4,1] = (U[4]*U[4]*U[4]*U[4])
J[4,2] = -(U[5]*U[5]*U[5]*U[5])
J[4,3] = -(U[6]*U[6]*U[6]*U[6])
J[4,4] = 4*U[1]*(U[4]*U[4]*U[4])
J[4,5] = -4*U[2]*(U[5]*U[5]*U[5])
J[4,6] = -4*U[3]*(U[6]*U[6]*U[6])
J[5,1] = 0.
J[5,2] = 0.
J[5,4] = 2*k[7]*U[4]*k[4]
J[5,5] = -2*k[8]*U[5]*k[5]
J[6,1] = 0.
J[6,3] = 0.
J[6,4] = 2*k[7]*U[4]*k[4]
J[6,6] = -2*k[9]*U[6]*k[6]
end
The k array is constant and defined before calling nlsove, therefore I create two more functions to enclose fun! and jac! as described here, here, and here
f_closure!(U) = fun!(F, U, k)
j_closure!(U) = jac!(J, U, k)
However, calling res = nlsolve(f_closure!, j_closure!, U) results in this error
ERROR: LoadError: MethodError: no method matching
(::#f_closure!#5{Array{Float64,1}})(::Array{Float64,1},
::Array{Float64,1}) Closest candidates are: f_closure!(::Any)
Is there a different way to pass the k array? Thanks!
My first Fortran lesson is to plot the probability density function of the radial Sturmian functions. In case you are interested, the radial Sturmian functions are used to graph the momentum space eigenfunctions for the hydrogen atom.
In order to produce these radial functions, one needs to first produce some polynomials called the Gegenbauer polynomials, denoted
Cba(x),
where a and b should be stacked atop each other. One needs these polynomials because the Sturmians (let's call them R_n,l) are defined like so,
R_n,l(p) = N pl⁄(p2 + k2)l+2 Cn - l - 1l + 1(p2 - k2⁄p2 + k2),
where N is a normalisation constant, p is the momentum, n is the principle quantum number, l is the angular momentum and k is a constant. The normalisation constant is there so that when I come to square this function, it will produce a probability distribution for the momentum of the electron in a hydrogen atom.
Gegenbauer polynomials are generated using the following recurrence relation:
Cnl(x) = 1⁄n[2(l + n - 1) x Cn - 1l(x) - (2l + n - 2)Cn - 2l(x)],
with C0l(x) = 1 and C1l(x) = 2lx, as you may have noticed, l is fixed but n is not. At the start of my program, I will specify both l and n and work out the Gegenbauer polynomial I need for the radial function I wish to plot.
The problems I am having with my code at the moment are all in my subroutine for working out the value of the Gegenbauer polynomial Cn-l-1l+1(p2 - k2⁄p2 + k2) for incremental values of p between 0 and 3. I keep getting the error
Unclassified statement at (1)
but I cannot see what the issue is.
program Radial_Plot
implicit none
real, parameter :: pi = 4*atan(1.0)
integer, parameter :: top = 1000, l = 50, n = 100
real, dimension(1:top) :: x, y
real increment
real :: a=0.0, b = 2.5, k = 0.3
integer :: i
real, dimension(1:top) :: C
increment = (b-a)/(real(top)-1)
x(1) = 0.0
do i = 2, top
x(i) = x(i-1) + increment
end do
Call Gegenbauer(top, n, l, k, C)
y = x*C
! y is the function that I shall be plotting between values a and b.
end program Radial_Plot
Subroutine Gegenbauer(top1, n1, l1, k1, CSub)
! This subroutine is my attempt to calculate the Gegenbauer polynomials evaluated at a certain number of values between c and d.
implicit none
integer :: top1, i, j, n1, l1
real :: k1, increment1, c, d
real, dimension(1:top1) :: x1
real, dimension(1:n1 - l1, 1:top1) :: C1
real, dimension(1:n1 - l1) :: CSub
c = 0.0
d = 3.0
k1 = 0.3
n1 = 50
l1 = 25
top1 = 1000
increment1 = (d - c)/(real(top1) - 1)
x1(1) = 0.0
do i = 2, top1
x1(i) = x1(i-1) + increment1
end do
do j = 1, top1
C1(1,j) = 1
C1(2,j) = 2(l1 + 1)(x1(i)^2 - k1^2)/(x1(i)^2 + k1^2)
! All the errors occurring here are all due to, and I quote, 'Unclassifiable statement at (1)', I can't see what the heck I have done wrong.
do i = 3, n1 - l1
C1(i,j) = 2(((l1 + 1)/n1) + 1)(x1(i)^2 - k1^2)/(x1(i)^2 + k1^2)C1(i,j-1) - ((2(l1+1)/n1) + 1)C1(i,j-2)
end do
CSub(j) = Cn(n1 - l1,j)^2
end do
return
end Subroutine Gegenbauer
As francesalus correctly pointed out, the problem is because you use ^ instead of ** for exponentiation. Additionally, you do not put * between the terms you are multiplying.
C1(1,j) = 1
C1(2,j) = 2*(l1 + 1)*(x1(i)**2 - k1**2)/(x1(i)**2 + k1**2)
do i = 3, n1 - l1
C1(i,j) = 2 * (((l1 + 1)/n1) + 1) * (x1(i)**2 - k1**2) / &
(x1(i)**2 + k1**2)*C1(i,j-1) - ((2(l1+1)/n1) + 1) * &
C1(i,j-2)
end do
CSub(j) = Cn(n1 - l1,j)**2
Since you are beginning I have some advice. Learn to put all subroutines and functions to modules (unless they are internal). There is no reason for the return statement at the and of the subroutine, similarly as a stop statement isn't necessary at the and of the program.