「新手入门」关于变量作用域的小问题

现在刚开始学习Julia语言并开始尝试谢了一些小程序,但是写的代码好像有点问题。报错截图如下:


代码段

        Threads.@threads for p in 1:r1
                local σ::Int64 = Threads.threadid()
				#println("the Thread id is $σ")
				i = I1[p]
				j = i + l
                α::Float64, β::Float64, γ::Float64 = 0.0,0.0,0.0
                for k in 1:N
					#i = global i
                    α = α + (U_t[i,k] * U_t[i,k])
                    β = β + (U_t[j,k] * U_t[j,k])
                    γ = γ + (U_t[i,k] * U_t[j,k])
                end
                C[σ] = max(C[σ], abs(γ)/sqrt(α * β))

                ζ = (β - α) / (2.0 * γ)
                t = sgn(ζ) / (abs(ζ) + sqrt(1.0 + (ζ * ζ)))
                c = 1.0 / (sqrt(1.0 + (t * t)))
                s = c * t

                for k in 1:N

					t = U_t[i,k]
					U_t[i,k] = c*t - s*U_t[j,k]
					U_t[j,k] = s*t + c*U_t[j,k]

					t = V_t[i,k]
					V_t[i,k] = c*t - s*V_t[j,k]
					V_t[j,k] = s*t + c*V_t[j,k]

                end
            end

希望各位能帮我看下到底是哪里出了问题,谢谢。

请提供能够复现这个错误的完整代码。

module Jacobi_SVD

export jacobi_SVD

using  Base.Threads

include("IO.jl")

const num = 8
const ϵ = 1.e-8

function sgn(num::Float64)
	if num == 0
		return 0.0
	else
		ans = num > 0.0 ? 1.0 : -1.0
	end

	ans

end

function jacobi_SVD(U_t,M::Int,N::Int) #Matrix for SVD - One side JAC

    #U_t = A
    V_t = [i == j ? 1.0 : 0.0 for i in 1:M, j in 1:N]
    I1 = zeros(Int64,N)
    I2 = zeros(Int64,N)
    C = zeros(100)
	S = zeros(min(M, N))

	acum::Int64 = 0
	converge::Float64 = 1.0


    while converge > ϵ

        println(converge) # Test
        converge = 0.0

        acum += 1 #counter for loops

        for l in 1:M
            r1::Int64, r2::Int64= 0,0
            for i in 1:M-l
                if i % (2*l) < l
                    r1 += 1
                    I1[r1] = i
                else
                    r2 += 1
                    I2[r2] = i
                end
            end

            for k in 1:num
                C[k] = converge
            end

            Threads.@threads for p in 1:r1
                local σ::Int64 = Threads.threadid()
				#println("the Thread id is $σ")
				i = I1[p]
				j = i + l
                α::Float64, β::Float64, γ::Float64 = 0.0,0.0,0.0
                for k in 1:N
					#i = global i
                    α = α + (U_t[i,k] * U_t[i,k])
                    β = β + (U_t[j,k] * U_t[j,k])
                    γ = γ + (U_t[i,k] * U_t[j,k])
                end
                C[σ] = max(C[σ], abs(γ)/sqrt(α * β))

                ζ = (β - α) / (2.0 * γ)
                t = sgn(ζ) / (abs(ζ) + sqrt(1.0 + (ζ * ζ)))
                c = 1.0 / (sqrt(1.0 + (t * t)))
                s = c * t

                for k in 1:N

					t = U_t[i,k]
					U_t[i,k] = c*t - s*U_t[j,k]
					U_t[j,k] = s*t + c*U_t[j,k]

					t = V_t[i,k]
					V_t[i,k] = c*t - s*V_t[j,k]
					V_t[j,k] = s*t + c*V_t[j,k]

                end
            end

            Threads.@threads for p in 1:r2
                local σ = Threads.threadid()
                i = I1[p],j = i + l
                α, β, γ = 0.0
                for k in 1:N
					#i = global i
                    α = α + (U_t[i,k] * U_t[i,k])
                    β = β + (U_t[j,k] * U_t[j,k])
                    γ = γ + (U_t[i,k] * U_t[j,k])
                end
                C[σ] = max(C[σ], abs(γ)/sqrt(α * β))

                ζ = (β - α) / (2.0 * γ)
                t::Float64 = sgn(ζ) / (abs(ζ) + sqrt(1.0 + (ζ * ζ)))
                c::Float64 = 1.0 / (sqrt(1.0 + (t * t)))
                s::Float64 = c * t

                for k in 1:N
					#i = global i

					t = U_t[i,k]
					U_t[i,k] = c*t - s*U_t[j,k]
					U_t[j,k] = s*t + c*U_t[j,k]

					t = V_t[i,k]
					V_t[i,k] = c*t - s*V_t[j,k]
					V_t[j,k] = s*t + c*V_t[j,k]


				end
            end

            for k in 1:num
                converge = max(converge,C[k])
            end


            #for k in 0:num
        end
	end

    #get Matrix S.Singular Value
    for i in 1:M
        t = 0
        for j in 1:N
            t = t + (U_t[i,j] * U_t[i,j])
        end
        t = sqrt(t)

        for j in 1:N
            U_t[i,j] = U_t[i,j] / t
            if i == j
                S[i] = t
            end
        end
    end

    U = zeros(M,N)
    V = zeros(M,N)
    for i in 1:M
        for j in 1:N
            U[i,j] = U_t[j,i]
            V[i,j] = V_t[j,i]
        end
    end

    U,S,V #Output the U S V -Three Matrices

end

A = rand(20,18)

IO.matrix_print(A)

U,S,V = jacobi_SVD(A,20,18)

#println(sgn(-187.0))

end

需要将include("IO.jl")以及后面的IO.matrix_print(A)注释掉,便可以进行复现。

新尝试写的程序出现了一点问题,还望大家能帮忙看下。

module Jacobi_SVD

export jacobi_SVD

using  Base.Threads

#include("IO.jl")

const num = 8
const ϵ = 1.e-8

function sgn(num::Float64)
	if num == 0
		return 0.0
	else
		ans = num > 0.0 ? 1.0 : -1.0
	end

	ans

end

function jacobi_SVD(U_t,M::Int,N::Int) #Matrix for SVD - One side JAC

    #U_t = A
    V_t = [i == j ? 1.0 : 0.0 for i in 1:M, j in 1:N]
    I1 = zeros(Int64,N)
    I2 = zeros(Int64,N)
    C = zeros(100)
	S = zeros(min(M, N))

	acum::Int64 = 0
	converge::Float64 = 1.0


    while converge > ϵ

        println(converge) # Test
        converge = 0.0

        acum += 1 #counter for loops

        for l in 1:M
            r1::Int64, r2::Int64= 0,0
            for i in 1:M-l
                if i % (2*l) < l
                    r1 += 1
                    I1[r1] = i
                else
                    r2 += 1
                    I2[r2] = i
                end
            end

            for k in 1:num
                C[k] = converge
            end

            Threads.@threads for p in 1:r1
                local σ::Int64 = Threads.threadid()
				#println("the Thread id is $σ")
				i = I1[p]
				j = i + l
                α::Float64, β::Float64, γ::Float64 = 0.0,0.0,0.0
                for k in 1:N
					#i = global i
                    α = α + (U_t[i,k] * U_t[i,k])
                    β = β + (U_t[j,k] * U_t[j,k])
                    γ = γ + (U_t[i,k] * U_t[j,k])
                end
                C[σ] = max(C[σ], abs(γ)/sqrt(α * β))

                ζ = (β - α) / (2.0 * γ)
                t = sgn(ζ) / (abs(ζ) + sqrt(1.0 + (ζ * ζ)))
                c = 1.0 / (sqrt(1.0 + (t * t)))
                s = c * t

                for k in 1:N

					t = U_t[i,k]
					U_t[i,k] = c*t - s*U_t[j,k]
					U_t[j,k] = s*t + c*U_t[j,k]

					t = V_t[i,k]
					V_t[i,k] = c*t - s*V_t[j,k]
					V_t[j,k] = s*t + c*V_t[j,k]

                end
            end

            Threads.@threads for p in 1:r2
                local σ = Threads.threadid()
                i = I1[p],j = i + l
                α, β, γ = 0.0
                for k in 1:N
					#i = global i
                    α = α + (U_t[i,k] * U_t[i,k])
                    β = β + (U_t[j,k] * U_t[j,k])
                    γ = γ + (U_t[i,k] * U_t[j,k])
                end
                C[σ] = max(C[σ], abs(γ)/sqrt(α * β))

                ζ = (β - α) / (2.0 * γ)
                t::Float64 = sgn(ζ) / (abs(ζ) + sqrt(1.0 + (ζ * ζ)))
                c::Float64 = 1.0 / (sqrt(1.0 + (t * t)))
                s::Float64 = c * t

                for k in 1:N
					#i = global i

					t = U_t[i,k]
					U_t[i,k] = c*t - s*U_t[j,k]
					U_t[j,k] = s*t + c*U_t[j,k]

					t = V_t[i,k]
					V_t[i,k] = c*t - s*V_t[j,k]
					V_t[j,k] = s*t + c*V_t[j,k]


				end
            end

            for k in 1:num
                converge = max(converge,C[k])
            end


            #for k in 0:num
        end
	end

    #get Matrix S.Singular Value
    for i in 1:M
        t = 0
        for j in 1:N
            t = t + (U_t[i,j] * U_t[i,j])
        end
        t = sqrt(t)

        for j in 1:N
            U_t[i,j] = U_t[i,j] / t
            if i == j
                S[i] = t
            end
        end
    end

    U = zeros(M,N)
    V = zeros(M,N)
    for i in 1:M
        for j in 1:N
            U[i,j] = U_t[j,i]
            V[i,j] = V_t[j,i]
        end
    end

    U,S,V #Output the U S V -Three Matrices

end

A = rand(20,18)

#IO.matrix_print(A)

U,S,V = jacobi_SVD(A,20,18)

#println(sgn(-187.0))

end

上面的程序跑的时候在并行段会出现UndefVarError的错误警告,错误为

Error thrown in threaded loop on thread 0: UndefVarError(var:=i)

希望大家能帮我看下到底是哪里出了问题:pray:

Hi @Kevvin 你好,

建议提问的时候,尽量提供简化后的例子,这样方便其他人快速复现和解决你的问题 。

针对你的这段代码,调试的时候尽量先在不使用 Threads.@threads的时候,保证代码能正常运行,然后分析一些潜在的竞态条件等问题。

这里出错信息写得很清楚了

代码里下面几行都会有问题的:(似乎是其它语言的写法?)

                i = I1[p],j = i + l
                α, β, γ = 0.0

好的,谢谢。

因为之前学过C、C++、Python等其他语言。由于是Julia初学者,所以写着写着语法就变成其他语言混用了。

之后提问关于代码的问题,我会注意简化问题以快速复现。谢谢您的提醒~