Julia- Make Array{Float64,3} in a short time - arrays

I want to get Array{Float64,3} from a matrix-valued function H(Lx,Ly,Lz) ,where Lx,Ly,Lz are parameters and H is a (Lx×Ly×Lz)×(Lx×Ly×Lz) matrix.
The sample code is
using LinearAlgebra
eye(T::Type,n) = Diagonal{T}(I, n)
eye(n) = eye(Float64,n)
function H(Lx,Ly,Lz) #def of H
N = Lx*Ly*Lz 
 mat_Htb = zeros(Complex{Float64},N,N)
 for iz = 1:Lz
 for ix = 1:Lx
 for iy=1:Ly
 for dz in -1:1
 jz = iz + dz
 for dx in -1:1
 jx = ix + dx
 for dy in -1:1
 jy = iy + dy
 ii = (iz-1)*Lx*Ly + (ix-1)*Ly + (iy-1) + 1
 jj = (jz-1)*Lx*Ly + (jx-1)*Ly + (jy-1) + 1
 if 1 <= jx <= Lx && 1 <= jy <= Ly && 1 <= jz <= Lz
 if dx == +1 && dy == 0 && dz == 0
 mat_Htb[ii,jj] += im  
 end
 if dx == -1 && dy == 0 && dz == 0
 mat_Htb[ii,jj] += im/4  
 end
 if dx == 0 && dy == +1 && dz == 0
 mat_Htb[ii,jj] += im/2
 end
 if dx == 0 && dy == -1 && dz == 0
 mat_Htb[ii,jj] += im
 end
 if dx == 0 && dy == 0 && dz == +1
 mat_Htb[ii,jj] += -im
 end
 if dx == 0 && dy == 0 && dz == -1
 mat_Htb[ii,jj] += im*(3/7)
 end
 if dx == 0 && dy == 0 && dz == 0
 mat_Htb[ii,jj] += im
 end
 end
 end
 end
 end
 end
 end
 end
 return mat_Htb
end
Lx = 10 #systemsize-parameters
Ly = 10
Lz = 10
ψ0 = Complex{Float64}[] #def of \psi0 ,(Lx×Ly×Lz)×1 vector
for iz = 1:Lz
for ix = 1:Lx
for iy=1:Ly
gauss = exp(-((ix-5)^2 + (iy-5)^2 + (iz-5)^2))
push!(ψ0,gauss)
end
end
end
ψ(t) = exp((-im*t).*H(Lx,Ly,Lz))*ψ0 #time-evolution
abs2ψ(t) = abs2.(ψ(t)./norm(ψ(t))) #normalized density
Then, I tried to make an Array{Float64,3} like this.
x = 1:Lx # our value range
y = 1:Ly
z = 1:Lz
t = 15 #time
ρ(ix,iy,iz) = abs2ψ(t)[(iz-1)*Lx*Ly + (ix-1)*Ly + (iy-1) + 1]
density = Float64[ρ(ix,iy,iz) for ix in x, iy in y,iz in z]
H(Lx,Ly,Lz),ψ(t),abs2ψ(t),ρ(ix,iy,iz) are calculated smoothly.
But the density takes about 30 minutes.
Ultimately, I will do loop-calculations for t.
So I want to reduce the calculation time.
Could you tell me how to solve this problem?

There are still numerous things that would probably need to be improved, but the following version should already be much faster than yours.
The key thing to remember is to try and not recompute the same thing several times (especially if it takes some time to compute it, and you're going to re-use the result a large number of times).
In your example, this applies to :
H, which only depends on Lx, Ly and Lz, and as such can be computed once and for all
ψ and abs2ψ, which depend on H and t, and should therefore get updated at each time step -- but can be re-used for all (ix, iy, iz) triplets.
using LinearAlgebra
function H(Lx,Ly,Lz)
N = Lx*Ly*Lz 
mat_Htb = zeros(Complex{Float64},N,N)
for iz = 1:Lz
for ix = 1:Lx
for iy=1:Ly
for dz in -1:1
jz = iz + dz
for dx in -1:1
jx = ix + dx
for dy in -1:1
jy = iy + dy
ii = (iz-1)*Lx*Ly + (ix-1)*Ly + (iy-1) + 1
jj = (jz-1)*Lx*Ly + (jx-1)*Ly + (jy-1) + 1
if 1 <= jx <= Lx && 1 <= jy <= Ly && 1 <= jz <= Lz
if dx == +1 && dy == 0 && dz == 0
mat_Htb[ii,jj] += im
end
if dx == -1 && dy == 0 && dz == 0
mat_Htb[ii,jj] += im/4
end
if dx == 0 && dy == +1 && dz == 0
mat_Htb[ii,jj] += im/2
end
if dx == 0 && dy == -1 && dz == 0
mat_Htb[ii,jj] += im
end
if dx == 0 && dy == 0 && dz == +1
mat_Htb[ii,jj] += -im
end
if dx == 0 && dy == 0 && dz == -1
mat_Htb[ii,jj] += im*(3/7)
end
if dx == 0 && dy == 0 && dz == 0
mat_Htb[ii,jj] += im
end
end
end
end
end
end
end
end
return mat_Htb
end
function run(Lx, Ly, Lz)
ψ0 = Complex{Float64}[] #def of \psi0 ,(Lx×Ly×Lz)×1 vector
for iz = 1:Lz
for ix = 1:Lx
for iy=1:Ly
gauss = exp(-((ix-5)^2 + (iy-5)^2 + (iz-5)^2))
push!(ψ0,gauss)
end
end
end
x = 1:Lx # our value range
y = 1:Ly
z = 1:Lz
t = 15 #time
H_ = H(Lx,Ly,Lz)
ψ = exp((-im*t).*H_)*ψ0 #time-evolution
abs2ψ = abs2.(ψ./norm(ψ)) #normalized density
ρ(ix,iy,iz) = abs2ψ[(iz-1)*Lx*Ly + (ix-1)*Ly + (iy-1) + 1]
density = Float64[ρ(ix,iy,iz) for ix in x, iy in y,iz in z]
end
Lx = 10 #systemsize-parameters
Ly = 10
Lz = 10
run(Lx, Ly, Lz)
For questions like this, which are very specific to a code that you want to optimize, I tend to think that posting on Julia's discourse forum would be more appropriate.

Related

I tried to record 24 green bar in br but I failed

n = input(24,title = "n")
gap = high - low
ret = close - open
greenbar = ret > 0
redbar = ret < 0
sr = array.new_float(0)
br = array.new_float(0)
for i = 0 to n-1 by 1
if greenbar[i]
array.push( br, high[i] - low[i])
plot(array.get(br ,1) )
Im new in pinescript and I tried to record 24 green bar in br but I failed...
There are some cases where the br array will have less than 2 elements, and therefore there will be no element in position 1. You can check this before plotting:
n = input.int(24, title = "n")
gap = high - low
ret = close - open
greenbar = ret > 0
redbar = ret < 0
sr = array.new_float(0)
br = array.new_float(0)
for i = 0 to n-1 by 1
if greenbar[i]
array.push(br, high[i] - low[i])
plot(array.size(br) > 2 ? array.get(br, 1) : na )

Defining variables explicitly vs accessing arrays

I am implementing the Runge-Kutta-Fehlberg method with adaptive step-size (RK45). I define and call my Butcher tableau in a notebook with
module FehlbergTableau
using StaticArrays
export A, B, CH, CT
A = #SVector [ 0 , 2/9 , 1/3 , 3/4 , 1 , 5/6 ]
B = #SMatrix [ 0 0 0 0 0
2/9 0 0 0 0
1/12 1/4 0 0 0
69/128 -243/128 135/64 0 0
-17/12 27/4 -27/5 16/15 0
65/432 -5/16 13/16 4/27 5/144 ]
CH = #SVector [ 47/450 , 0 , 12/25 , 32/225 , 1/30 , 6/25 ]
CT = #SVector [ -1/150 , 0 , 3/100 , -16/75 , -1/20 , 6/25 ]
end
using .FehlbergTableau
If I code the algorithm for RK45 straightforwardly as
function infinitesimal_flow(A::SVector{6,Float64}, B::SMatrix{6,5,Float64}, CH::SVector{6,Float64}, CT::SVector{6,Float64}, t0::Float64, Δt::Float64, J∇H::Function, x0::SVector{N,Float64}) where N
k1 = Δt * J∇H( t0 + Δt*A[1], x0 )
k2 = Δt * J∇H( t0 + Δt*A[2], x0 + B[2,1]*k1 )
k3 = Δt * J∇H( t0 + Δt*A[3], x0 + B[3,1]*k1 + B[3,2]*k2 )
k4 = Δt * J∇H( t0 + Δt*A[4], x0 + B[4,1]*k1 + B[4,2]*k2 + B[4,3]*k3 )
k5 = Δt * J∇H( t0 + Δt*A[5], x0 + B[5,1]*k1 + B[5,2]*k2 + B[5,3]*k3 + B[5,4]*k4 )
k6 = Δt * J∇H( t0 + Δt*A[6], x0 + B[6,1]*k1 + B[6,2]*k2 + B[6,3]*k3 + B[6,4]*k4 + B[6,5]*k5 )
TE = CT[1]*k1 + CT[2]*k2 + CT[3]*k3 + CT[4]*k4 + CT[5]*k5 + CT[6]*k6
xt = x0 + CH[1]*k1 + CH[2]*k2 + CH[3]*k3 + CH[4]*k4 + CH[5]*k5 + CH[6]*k6
norm(TE), xt
end
and compare it with the more compact implementation
function infinitesimal_flow_2(A::SVector{6,Float64}, B::SMatrix{6,5,Float64}, CH::SVector{6,Float64}, CT::SVector{6,Float64}, t0::Float64,Δt::Float64,J∇H::Function, x0::SVector{N,Float64}) where N
k = MMatrix{N,6}(0.0I)
TE = zero(x0); xt = x0
for i=1:6
# EDIT: this is wrong! there should be a new variable here, as pointed
# out by Lutz Lehmann: xs = x0
for j=1:i-1
# xs += B[i,j] * k[:,j]
x0 += B[i,j] * k[:,j] #wrong
end
k[:,i] = Δt * J∇H(t0 + Δt*A[i], x0)
TE += CT[i]*k[:,i]
xt += CH[i]*k[:,i]B[i,j] * k[:,j]
end
norm(TE), xt
end
Then the first function, which defines variables explicitly, is much faster:
J∇H(t::Float64, X::SVector{N,Float64}) where N = #SVector [ -X[2]^2, X[1] ]
x0 = SVector{2}([0.0, 1.0])
infinitesimal_flow(A, B, CH, CT, 0.0, 1e-2, J∇H, x0)
infinitesimal_flow_2(A, B, CH, CT, 0.0, 1e-2, J∇H, x0)
#btime infinitesimal_flow($A, $B, $CH, $CT, 0.0, 1e-2, $J∇H, $x0)
>> 19.387 ns (0 allocations: 0 bytes)
#btime infinitesimal_flow_2($A, $B, $CH, $CT, 0.0, 1e-2, $J∇H, $x0)
>> 50.985 ns (0 allocations: 0 bytes)
I cannot find a type instability or anything to justify the lag, and for more complex tableaus it is mandatory that I use the algorithm in loop form. What am I doing wrong?
P.S.: The bottleneck in infinitesimal_flow_2 is the line k[:,i] = Δt * J∇H(t0 + Δt*A[i], x0).
Each stage of the RK method computes its evaluation point directly from the base point of the RK step. This is explicit in the first method. In the second method you would have to reset the point computation in each stage, such as in
for i=1:6
xs = x0
for j=1:i-1
xs += B[i,j] * k[:,j]
end
k[:,i] = Δt * J∇H(t0 + Δt*A[i], xs)
...
The slightest error in the step computation can catastrophically throw off the step-size controller, forcing the step size to fall towards zero and thus the effort to increase drastically. An example is the 4101 error in RKF45

Julia: faster matrix calculation

In my work, I have to deal with large size matrices.
For example, I use the following matrices.
using LinearAlgebra
#Pauli matrices
σ₁ = [0 1; 1 0]
σ₂ = [0 -im; im 0]
τ₁ = [0 1; 1 0]
τ₃ = [1 0; 0 -1]
#Trigonometric functions in real space
function EYE(Lx,Ly,Lz)
   
N = Lx*Ly*Lz
mat = Matrix{Complex{Float64}}(I, N, N)
return mat
end
function SINk₁(Lx,Ly,Lz)
   
N = Lx*Ly*Lz
mat = zeros(Complex{Float64},N,N)
for ix = 1:Lx
for iy = 1:Ly
for iz = 1:Lz
for dx in -1:1
jx = ix + dx
jx += ifelse(jx > Lx,-Lx,0)
jx += ifelse(jx < 1,Lx,0)
for dy in -1:1
jy = iy + dy
jy += ifelse(jy > Ly,-Ly,0)
jy += ifelse(jy < 1,Ly,0)
for dz in -1:1
jz = iz + dz
ii = (iz-1)*Lx*Ly + (ix-1)*Ly + iy
jj = (jz-1)*Lx*Ly + (jx-1)*Ly + jy
if 1 <= jz <= Lz
if dx == +1 && dy == 0 && dz == 0
mat[ii,jj] += -(im/2) 
end
if dx == -1 && dy == 0 && dz == 0
mat[ii,jj] += im/2
end
end
end
end
end
end
end
end
return mat
end
function COSk₃(Lx,Ly,Lz)
   
N = Lx*Ly*Lz
mat = zeros(Complex{Float64},N,N)
for ix = 1:Lx
for iy = 1:Ly
for iz = 1:Lz
for dx in -1:1
jx = ix + dx
jx += ifelse(jx > Lx,-Lx,0)
jx += ifelse(jx < 1,Lx,0)
for dy in -1:1
jy = iy + dy
jy += ifelse(jy > Ly,-Ly,0)
jy += ifelse(jy < 1,Ly,0)
for dz in -1:1
jz = iz + dz
ii = (iz-1)*Lx*Ly + (ix-1)*Ly + iy
jj = (jz-1)*Lx*Ly + (jx-1)*Ly + jy
if 1 <= jz <= Lz
if dx == 0 && dy == 0 && dz == +1
mat[ii,jj] += 1/2 
end
if dx == 0 && dy == 0 && dz == -1
mat[ii,jj] += 1/2
end
end
end
end
end
end
end
end
return mat
end
Then, I calculate
kron(SINk₁(Lx,Ly,Lz),kron(σ₁,τ₁)) + kron(EYE(Lx,Ly,Lz) + COSk₃(Lx,Ly,Lz),kron(σ₂,τ₃))
This calculation, however, takes much times for large Lx,Ly,Lz;
Lx = Ly = Lz = 15
#time kron(SINk₁(Lx,Ly,Lz),kron(σ₁,τ₁)) + kron(EYE(Lx,Ly,Lz) + COSk₃(Lx,Ly,Lz),kron(σ₂,τ₃))
4.692591 seconds (20 allocations: 8.826 GiB, 6.53% gc time)
Lx = Ly = Lz = 20
#time kron(SINk₁(Lx,Ly,Lz),kron(σ₁,τ₁)) + kron(EYE(Lx,Ly,Lz) + COSk₃(Lx,Ly,Lz),kron(σ₂,τ₃))
52.687861 seconds (20 allocations: 49.591 GiB, 2.69% gc time)
Are there faster ways to calculate Kronecker product, Addition or more proper definitions of EYE(Lx,Ly,Lz), SINk₁(Lx,Ly,Lz), COSk₃(Lx,Ly,Lz)?
The problem you're having is really simple. You are using at least O(n^12) memory. Since almost all of these values are 0, this is a huge waste. You should almost certainly be using Sparse arrays. This should bring your runtime to reasonable levels

How to get SQL case or C style if-else-if code from rpart in R

I am nearly certain that someone has done this before me.
The final code will not be in R but rather SQL.
require(rpart)
model=rpart.m=rpart(clazz~.,data=df)
printcp(rpart.m)
summary(rpart.m)
rpart.m
Produces something like so
n= 2500
node), split, n, deviance, yval
* denotes terminal node
1) root 2500 505.753600 0.2816000
2) x>=3.44898 250 0.000000 0.0000000 *
3) x< 3.44898 2250 483.726200 0.3128889
6) x< -1.44898 250 0.000000 0.0000000 *
7) x>=-1.44898 2000 456.192000 0.3520000
14) y< -1.44898 200 0.000000 0.0000000 *
etc...
I really don't want to write a parser for the text in order to generate SQL case statements.
I noticed https://www.r-bloggers.com/create-sql-rules-from-rpart-model/ but this only goes halfway. It is a case statement that gives the nodes but not the final predictions.
Any suggestions?
Update
I posted code as requested and I may have successfully adapted/fixed tomasgreif's code to include the predicted values.
#' Toy Data for a case that is very non-linear
#'create a circle data.frame
n=2500
df=expand.grid(x=seq(-2,4,length.out = floor(sqrt(n))),y=seq(-2,4,length.out = floor(sqrt(n))))
cx=mean(df$x)
cy=mean(df$y)
r=(max(df$x)-min(df$x))*0.35
thinness=0.6
df$clazz=(with(df,1/(1+abs(((x-cx)^2+(y-cy)^2)-r^2)*thinness)))
df$clazz[sample(nrow(df),nrow(df)*0.05)]=runif(nrow(df)*0.05) ##introduce noise
df$clazz=round(df$clazz)
#' a simple function to plot
plotxyfit=function(df,what='fit',numcolors=5) {
df$fit=df[[what]]
plot(df$x,df$y,col=heat.colors(5+numcolors)[round(2+numcolors*as.numeric(df$fit))],pch=1+round(as.numeric(df$fit)))
title(what)
}
plotxyfit(df,'clazz')
#' build a *tree* decision tree model
require(tree)
tree.m=tree(clazz~.,df)
summary(tree.m)
plot(tree.m)
text(tree.m,pretty=0)
tree.m
#' build a rpart decision tree model
require(rpart)
rpart.m=rpart(clazz~.,data=df)
printcp(rpart.m)
summary(rpart.m)
rpart.m
require(rpart.plot)
plot(rpart.m) # Will make a mess of the plot
text(rpart.m)
rpart.plot(rpart.m,tweak=1.5) # nicer plot
prp(rpart.m) #really nice plot
df$fit.t=predict(tree.m,df)
df$fit.rp=predict(rpart.m,df)
plotxyfit(df,'fit.t') #looks rather poor
plotxyfit(df,'fit.rp') #does an ok job
summary(df)
#' get output as pmml xml
require(pmml)
pmml(rpart.m)
#Adapted from https://gist.github.com/tomasgreif/6038822
#'
#' Rpart rules are changed to sql CASE statement.
#'
#' #param df data frame used for rpart model
#' #param model rpart model
#' #export
#' #examples
#' parse_tree(df=kyphosis,model=rpart(data=kyphosis,formula=Kyphosis~.))
#' parse_tree(df=mtcars,model=rpart(data=mtcars,formula=am~.))
#' parse_tree(df=iris,model=rpart(data=iris,formula=Species~.))
#' x <- german_data
#' x$gbbin <- NULL
#' model <- rpart(data=x,formula=gb~.)
#' parse_tree(x,model)
parse.tree.to.sql <- function (df=NULL, model=NULL) { #https://gist.github.com/tomasgreif/6038822
log <- capture.output({
rpart.rules <- path.rpart(model,rownames(model$frame)[model$frame$var=="<leaf>"])
})
args <- c("<=",">=","<",">","=")
rules_out <- "case "
i <- 1
for (rule in rpart.rules) {
rule_out <- character(0)
for (component in rule) {
sep <- lapply(args, function(x) length(unlist(strsplit(component,x)))) > 1
elements <- unlist(strsplit(component,(args[sep])[1]))
if(!(elements[1]=="root")) {
if (is.numeric(df[,elements[[1]]])) {
rule_out <- c(rule_out,paste(elements[1],(args[sep])[1],elements[2]))
} else {
rule_out <- c(rule_out,paste0(elements[1]," in (",paste0("'",unlist(strsplit(elements[2],",")),"'",collapse=","),")"))
}
}
}
rules_out <- c(rules_out, paste0("when ", paste(rule_out,collapse=" AND ")," then ",
sprintf("%f /*node %s */",rpart.m$frame$yval[row.names(rpart.m$frame)==names(rpart.rules)[i] ],names(rpart.rules)[i]) ))
if(i==length(rpart.rules)) rules_out <- c(rules_out," end ")
i <- i +1
}
sql_out <- paste(rules_out, collapse=" ")
sql_out
}
results=parse.tree.to.sql(df=df,model=rpart.m)
cat(results) ##if you see truncated on output, you must configure lines output in rstudio
Among other things, this produces:
case when y < -1.449 then 0.012000 /*node 2 */ when y >= -1.449 AND y >= 3.327 then 0.050000 /*node 6 */ when y >= -1.449 AND y < 3.327 AND x >= 3.449 then 0.025641 /*node 14 */ when y >= -1.449 AND y < 3.327 AND x < 3.449 AND x < -1.449 then 0.030769 /*node 30 */ when y >= -1.449 AND y < 3.327 AND x < 3.449 AND x >= -1.449 AND y < 2.469 AND x < 2.469 AND y >= -0.3469 AND x >= -0.3469 then 0.079395 /*node 496 */ when y >= -1.449 AND y < 3.327 AND x < 3.449 AND x >= -1.449 AND y < 2.469 AND x < 2.469 AND y >= -0.3469 AND x < -0.3469 then 0.753623 /*node 497 */ when y >= -1.449 AND y < 3.327 AND x < 3.449 AND x >= -1.449 AND y < 2.469 AND x < 2.469 AND y < -0.3469 AND x < -0.5918 then 0.174603 /*node 498 */ when y >= -1.449 AND y < 3.327 AND x < 3.449 AND x >= -1.449 AND y < 2.469 AND x < 2.469 AND y < -0.3469 AND x >= -0.5918 then 0.746667 /*node 499 */ when y >= -1.449 AND y < 3.327 AND x < 3.449 AND x >= -1.449 AND y < 2.469 AND x >= 2.469 AND y < -0.5918 then 0.142857 /*node 250 */ when y >= -1.449 AND y < 3.327 AND x < 3.449 AND x >= -1.449 AND y < 2.469 AND x >= 2.469 AND y >= -0.5918 then 0.775000 /*node 251 */ when y >= -1.449 AND y < 3.327 AND x < 3.449 AND x >= -1.449 AND y >= 2.469 AND x >= 2.714 then 0.095238 /*node 126 */ when y >= -1.449 AND y < 3.327 AND x < 3.449 AND x >= -1.449 AND y >= 2.469 AND x < 2.714 AND x < -0.5918 then 0.163265 /*node 254 */ when y >= -1.449 AND y < 3.327 AND x < 3.449 AND x >= -1.449 AND y >= 2.469 AND x < 2.714 AND x >= -0.5918 then 0.814815 /*node 255 */ end

All values changes in array using vhdl

I'm trying to make brick break in VHDL.
Everything went well but I have a weird problem.
In a piece of my code you see below I change the value to '0' at index (y,x) in my array when the ball reaches the edges of a brick. The problem is that all the values in my array change to 0, even when the ball is not moving (When the program start up, the ball is not moving).
process(Ball_x1,Ball_x2,Ball_y1,Ball_y2) begin
x1 <= 280 + (x * 55); --edges of my brick
x2 <= 280 + ((x + 1) * 55);
y1 <= 108 + (y * 13);
y2 <= 108 + ((y + 1) * 13);
waardeArray := level1(y,x);
if (vcnt >= y1) and (vcnt <= y2) then
if (Ball_x1 >= x1) and (Ball_x1 <= x2) then -- edges of my ball
if waardeArray = '1' then
level1(y,x) := '0';
end if;
end if;
end if;
end process;
The declaration of my array is
type levels is array ( 0 to 3, 0 to 5 ) of bit;
shared variable level1 : levels := (
('1','0','0','0','0','1'),
('0','1','0','0','1','0'),
('0','0','1','1','0','0'),
('0','0','1','1','0','0')
);
Next variable is used to store the value of the array at place (y,x)
shared variable waardeArray: bit;
It's the intention to use Ball_x2 etc too but I just tried with 1 edge of my ball to test the code.
Update
process(Ball_x1,Ball_x2,Ball_y1,Ball_y2) begin
x1 <= 280 + (x * 55); -- edges of my brick
x2 <= 280 + ((x + 1) * 55);
y1 <= 108 + (y * 13);
y2 <= 108 + ((y + 1) * 13);
if (vcnt >= y1) and (vcnt <= y2) then --vcnt is from another component where I send my data to my screen
if (Ball_x1 >= x1) and (Ball_x1 <= x2) then -- left edge of my ball
if level1(y)(x) = '1' then
level1(y)(x) <= '1'; --I do this to test if the elements with value 1 stay 1 and the 0 stay 0 ata initialization, but every element in my array change to 1.
else
level1(y)(x) <= level1(y)(x);
end if;
end if;
end if;
end process;
Declarations
signal x: integer range 0 to 6 := 0; --Six is used for something else.
signal y: integer range 0 to 3 := 0;
signal x1: integer range 279 to 616;
signal x2: integer range 279 to 616;
signal y1: integer range 107 to 228;
signal y2: integer range 107 to 228;
signal color: std_logic_vector (7 downto 0) := "00000111";
type levels is array ( 0 to 3) of std_logic_vector (5 downto 0);
signal level1 : levels := ("101101",
"010010",
"001100",
"001100");
This is my intention
Don't use shared variables. If you need to communicate a value between processes, use a signal. You can't be sure of the order at which updates compared to reads occur using shared variables. Well, you can, but you have to use protected types.
Also, in your process, you are looking at the values of x, y and vcnt. But those signals (I hope they are signals not shared variables :) are not in the sensitivity list of the process, so when they change, your process will not be triggered.

Resources