What is it about my julia function that is incomplete? - julia

I am writing a function, actually translating it from a pseudocode form to julia. I keep getting the following complaint:
julia> include("coefficients.jl")
ERROR: syntax: incomplete: "function" at /Users/comerduncan/MarkFiniteDiffDerivativs/coefficients.jl:1 requires end
in include at boot.jl:244
while loading /Users/comerduncan/MarkFiniteDiffDerivativs/coefficients.jl, in expression starting on line 1
Here is my current version of the function:
function coefficients(order, x_list, x0)
M = order
N = length(x_list) - 1
delta = [0 for i=0:N,j=0:N,k=0:M]
delta[0,0,0]= 1
c1 = 1
for n =1:N+1
c2 = 1
for nu =0:n
c3 = x_list[n]-x_list[nu]
c2 = c2 * c3
if n <= M
delta[n,n-1,nu]=0
for k=0:min(n,M)+1
delta[k,n,nu] = (x_list[n]-x0)*delta[k,n-1,nu] -\
k*delta[k-1,n-1,nu]
delta[k,n,nu] /= c3
end # k
end # nu
for m=0:min(n,M)+1
delta[m,n,n] = c1/c2*(m*delta[m-1,n-1,n-1] \
- (x_list[n-1]-x0)*delta[m,n-1,n-1] )
end # m
c1 = c2
end # n
return delta
end

Unless I'm missing something, you have four ends, and four loops: but you also write if n <= M, and that isn't ended.
So your end # nu isn't actually closing the nu loop, it's closing the if, and you have one too few.

Related

Why two styles of executing Juilia programs are giving different results?

If a run a program written in julia as
sachin#localhost:$ julia mettis.jl then it runs sucessfully, without printing anything, though one print statement is in it.
And Secondly If run it as by going in julia:
sachin#localhost:$ julia
julia> include("mettis.jl")
main (generic function with 1 method)`
julia> main()
Then It gives some error.
I am puzzled why two style of executing is giving different result ?
Here is my code:
using ITensors
using Printf
function ITensors.op(::OpName"expτSS", ::SiteType"S=1/2", s1::Index, s2::Index; τ)
h =
1 / 2 * op("S+", s1) * op("S-", s2) +
1 / 2 * op("S-", s1) * op("S+", s2) +
op("Sz", s1) * op("Sz", s2)
return exp(τ * h)
end
function main(; N=10, cutoff=1E-8, δτ=0.1, beta_max=2.0)
# Make an array of 'site' indices
s = siteinds("S=1/2", N; conserve_qns=true)
# #show s
# Make gates (1,2),(2,3),(3,4),...
gates = ops([("expτSS", (n, n + 1), (τ=-δτ / 2,)) for n in 1:(N - 1)], s)
# Include gates in reverse order to complete Trotter formula
append!(gates, reverse(gates))
# Initial state is infinite-temperature mixed state
rho = MPO(s, "Id") ./ √2
#show inner(rho, H)
# Make H for measuring the energy
terms = OpSum()
for j in 1:(N - 1)
terms += 1 / 2, "S+", j, "S-", j + 1
terms += 1 / 2, "S-", j, "S+", j + 1
terms += "Sz", j, "Sz", j + 1
end
H = MPO(terms, s)
# Do the time evolution by applying the gates
# for Nsteps steps
for β in 0:δτ:beta_max
energy = inner(rho, H)
#printf("β = %.2f energy = %.8f\n", β, energy)
rho = apply(gates, rho; cutoff)main
rho = rho / tr(rho)
end
# #show energy
return nothing
end
There is nothing special about a function called main in Julia and defining a function is different from calling it. Consequently a file mettis.jl with the following code:
function main()
println("Hello, World!")
end
will not "do" anything when run (julia mettis.jl). However if you actually call the function at the end:
function main()
println("Hello, World!")
end
main()
you get the expected result
$ julia mettis.jl
Hello, World!

JuMP constraints involving matrix inverse

I'm attempting to solve for an n*n matrix U, which satisfies a variety of constraints, including some involving inverses of its sub-matrices. However, it seems that JuMP can't handle inverses, at least without some additional specification of invertibility. Here's an example of the problem with n=2.
using JuMP, Ipopt
m = Model(with_optimizer(Ipopt.Optimizer))
A = [5 7; 7 10]
B = [9 13; 13 19]
C = [3 4; 4 6]
nnodes = 2
#variable(m, U[1:nnodes, 1:nnodes])
A1 = U * A * U'
B1 = U * B * U'
C1 = U * C * U'
c1 = A1[1, 1] - 1
c2 = A1[2, 2] - 1
c3 = C1[1, 1] - 1
c4 = unmixed_iv2[1, 2]
a = A1[2, 2] - A1[2, 1] * inv(A1[1, 1]) * A1[2,1] # Schur complement
b = B1[2, 2] - B1[2, 1] * inv(B1[1, 1]) * B1[2,1] # Schur complement
c5 = a - b
#NLconstraint(m, c1 == 0)
#NLconstraint(m, c2 == 0)
#NLconstraint(m, c3 == 0)
#NLconstraint(m, c4 == 0)
#NLconstraint(m, c5 == 0)
solve(m)
This raises the following error:
ERROR: inv is not defined for type GenericQuadExpr. Are you trying to build a nonlinear problem? Make sure you use #NLconstraint/#NLobjective.
Any suggestions on how to solve this problem?
You cannot use inv outside the macros (or more generally, build up any nonlinear expression). Just put it inside like so:
using JuMP
model = Model()
#variable(model, x >= 0.5)
#NLconstraint(model, inv(x) <= 0.5)
p.s., I can't run your example because I don't know what unmixed_iv2 is.

Dijkstra's algorithm with adjacency matrix

I'm trying to implement the following code from here but it won't work correctly.
What I want is the shortest path distances from a source to all nodes and also the predecessors. Also, I want the input of the graph to be an adjacency matrix which contains all of the edge weights.
I'm trying to make it work in just one function so I have to rewrite it. If I'm right the original code calls other functions (from graph.jl for example).
I don't quite understand how to rewrite the for loop which calls the adj() function.
Also, I'm not sure if the input is correct in the way the code is for now.
function dijkstra(graph, source)
node_size = size(graph, 1)
dist = ones(Float64, node_size) * Inf
dist[source] = 0.0
Q = Set{Int64}() # visited nodes
T = Set{Int64}(1:node_size) # unvisited nodes
pred = ones(Int64, node_size) * -1
while condition(T)
# node selection
untraversed_nodes = [(d, k) for (k, d) in enumerate(dist) if k in T]
if minimum(untraversed_nodes)[1] == Inf
break # Break if remaining nodes are disconnected
end
node_ind = untraversed_nodes[argmin(untraversed_nodes)][2]
push!(Q, node_ind)
delete!(T, node_ind)
# distance update
curr_node = graph.nodes[node_ind]
for (neigh, edge) in adj(graph, curr_node)
t_ind = neigh.index
weight = edge.cost
if dist[t_ind] > dist[node_ind] + weight
dist[t_ind] = dist[node_ind] + weight
pred[t_ind] = node_ind
end
end
end
return dist, pred
end
So if I'm trying it with the following matrix
A = [0 2 1 4 5 1; 1 0 4 2 3 4; 2 1 0 1 2 4; 3 5 2 0 3 3; 2 4 3 4 0 1; 3 4 7 3 1 0]
and source 2 i would like to get the distances in a vector dist and the predeccessors in anothe vectore pred.
Right now I'm getting
ERROR: type Array has no field nodes
Stacktrace: [1] getproperty(::Any, ::Symbol) at .\sysimg.jl:18
I guess I have to rewrite it a bit more.
I m thankful for any help.
Assuming that graph[i,j] is a length of path from i to j (your graph is directed looking at your data), and it is a Matrix with non-negative entries, where 0 indicates no edge from i to j, a minimal rewrite of your code should be something like:
function dijkstra(graph, source)
#assert size(graph, 1) == size(graph, 2)
node_size = size(graph, 1)
dist = fill(Inf, node_size)
dist[source] = 0.0
T = Set{Int}(1:node_size) # unvisited nodes
pred = fill(-1, node_size)
while !isempty(T)
min_val, min_idx = minimum((dist[v], v) for v in T)
if isinf(min_val)
break # Break if remaining nodes are disconnected
end
delete!(T, min_idx)
# distance update
for nei in 1:node_size
if graph[min_idx, nei] > 0 && nei in T
possible_dist = dist[min_idx] + graph[min_idx, nei]
if possible_dist < dist[nei]
dist[nei] = possible_dist
pred[nei] = min_idx
end
end
end
end
return dist, pred
end
(I have not tested it extensively, so please report if you find any bugs)

How to fix "dt <= dtmin. Aborting" error in solveODE

I'm trying to emulate a system of ODEs (Fig3 B in Tilman, 1994.Ecology, Vol.75,No1,pp-2-16) but Julia Integration method failed to give a solution.
The error is dt <= dtmin. Aborting.
using DifferentialEquations
TFour = #ode_def TilmanFour begin
dp1 = c1*p1*(1-p1) - m*p1
dp2 = c2*p2*(1-p1-p2) -m*p2 -c1*p1*p2
dp3 = c3*p3*(1-p1-p2-p3) -m*p3 -c1*p1*p2 -c2*p2*p3
dp4 = c4*p4*(1-p1-p2-p3-p4) -m*p4 -c1*p1*p2 -c2*p2*p3 -c3*p3*p4
end c1 c2 c3 c4 m
u0 = [0.05,0.05,0.05,0.05]
p = (0.333,3.700,41.150,457.200,0.100)
tspan = (0.0,300.0)
prob = ODEProblem(TFour,u0,tspan,p)
sol = solve(prob,alg_hints=[:stiff])
I think that you read the equations wrong. The last term in the paper is
sum(c[j]*p[j]*p[i] for j<i)
Note that every term in the equation for dp[i] has a factor p[i].
Thus your equations should read
dp1 = p1 * (c1*(1-p1) - m)
dp2 = p2 * (c2*(1-p1-p2) - m - c1*p1)
dp3 = p3 * (c3*(1-p1-p2-p3) - m - c1*p1 -c2*p2)
dp4 = p4 * (c4*(1-p1-p2-p3-p4) - m - c1*p1 - c2*p2 - c3*p3)
where I also made explicit that dpk is a multiple of pk. This is necessary as it ensures that the dynamic stays in the octand of positive variables.
Using python the plot looks like in the paper
def p_ode(p,c,m):
return [ p[i]*(c[i]*(1-sum(p[j] for j in range(i+1))) - m[i] - sum(c[j]*p[j] for j in range(i))) for i in range(len(p)) ]
c = [0.333,3.700,41.150,457.200]; m=4*[0.100]
u0 = [0.05,0.05,0.05,0.05]
t = np.linspace(0,60,601)
p = odeint(lambda u,t: p_ode(u,c,m), u0, t)
for k in range(4): plt.plot(t,p[:,k], label='$p_%d$'%(k+1));
plt.grid(); plt.legend(); plt.show()

convert an R script to IDL: Array manipulation

I am an R and IDL beginner. Im trying to convert an R script to IDL.
R can do array manipulation with t1 (array[100000]) but IDL cannot.
ERROR: Array subscript for CZ must have same size as source expression
s1= 100000.
c1 = array[200000]
n1 = s1*2+2
t1 = array[100000]
————————————————————————————————
(function)
f03, c1, s1, n1
cz = fltarr(n1,3)
cz[0:((2*s1)-1),0] = c1
cz[1:(2*s1),1] = c1
cz[2:((2*1)+1),2] = c1
cr = cz[0:(n1-1),1] - cz[0:(n1-1),2]
cl = cz[0:(n1-1),1] - cz[0:(n1-1),0]
p1 = where(cr GE 0.0 AND cl GE 0.0 AND (cz[0:(n1-1),1]) GE 1.4)
n2 = n_elements(p1)
ct = fltarr(n2+1,2)
ct[0:n2-1,0] = p1
ct[1:n2,1] = p1
c2 = ct[*,0] - ct[*,1]
ip = where(c2 GT 2.)
ch = p1[ip]
return, ch
————————————————————————————————
p1 = f03(c1,s1,n1) ;;;;; function works here
f1 = f03(t1,s1,n1) ;;;;; error on array size
I used MATRIX and AS.MATRIX in R (for f03). Does FLTARR cause this error?
Your lines:
cz = fltarr(n1, 3)
cz[0:((2 * s1) - 1), 0] = c1
make sense when cz has a first dimension of size 2000002 and c1 is 200000 elements — the sizes on the left and right of the = sign match, i.e., 0:199999 is 2000000 elements just like the size of c1.
But in the second call, c1 only has 100000 elements, but the left side is still asking for 2000000 elements.
Also, define a function like:
function f03, c1, s1, n1
; a bunch of code goes here
return, ch
end

Resources