diff --git a/base/inference.jl b/base/inference.jl index 432f1ac25ab74..dedbf6f70bd5d 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -267,6 +267,8 @@ const tupleref_tfunc = function (A, t, i) end elseif i == n && vararg return last.parameters[1] + elseif i <= 0 + return None else return tupleref(t,i) end diff --git a/base/linalg/factorization.jl b/base/linalg/factorization.jl index 40a48a6fec1b4..a05df7a19509a 100644 --- a/base/linalg/factorization.jl +++ b/base/linalg/factorization.jl @@ -10,8 +10,14 @@ macro assertnonsingular(A, info) :(($info)==0 ? $A : throw(SingularException($info))) end -\(F::Factorization, b::Union(AbstractVector, AbstractMatrix)) = A_ldiv_B!(F, copy(b)) -A_ldiv_B!(C::Factorization, B::StridedVecOrMat) = A_ldiv_B!(C, float(B)) +typealias AbstractVecOrMat Union(AbstractVector, AbstractMatrix) + +\(F::Factorization, B::AbstractVecOrMat) = A_ldiv_B!(F, copy(B)) +Ac_ldiv_B(F::Factorization, B::AbstractVecOrMat) = Ac_ldiv_B!(F, copy(B)) +At_ldiv_B(F::Factorization, B::AbstractVecOrMat) = At_ldiv_B!(F, copy(B)) +A_ldiv_B!(F::Factorization, B::StridedVecOrMat) = A_ldiv_B!(F, float(B)) +Ac_ldiv_B!(F::Factorization, B::StridedVecOrMat) = Ac_ldiv_B!(F, float(B)) +At_ldiv_B!(F::Factorization, B::StridedVecOrMat) = At_ldiv_B!(F, float(B)) type Cholesky{T<:BlasFloat} <: Factorization{T} UL::Matrix{T} diff --git a/base/linalg/sparse.jl b/base/linalg/sparse.jl index 0cc22f9f15769..4946b20e121ca 100644 --- a/base/linalg/sparse.jl +++ b/base/linalg/sparse.jl @@ -126,6 +126,62 @@ function *{Tv,Ti}(A::SparseMatrixCSC{Tv,Ti}, B::SparseMatrixCSC{Tv,Ti}) Ctt = Base.SparseMatrix.transpose!(Ct, SparseMatrixCSC(mA, nB, colptrC, rowvalC, nzvalC)) end +## solvers +function A_ldiv_B!(A::SparseMatrixCSC, b::AbstractVector) + if istril(A) + if istriu(A) return A_ldiv_B!(Diagonal(A.nzval), b) end + return fwdTriSolve!(A, b) + end + if istriu(A) return bwdTriSolve!(A, b) end + return A_ldiv_B!(lufact(A),b) +end + +function fwdTriSolve!(A::SparseMatrixCSC, b::AbstractVector) +# forward substitution for CSC matrices + n = length(b) + ncol = chksquare(A) + if n != ncol throw(DimensionMismatch("A is $(ncol)X$(ncol) and b has length $(n)")) end + + aa = A.nzval + ja = A.rowval + ia = A.colptr + + for j = 1:n - 1 + i1 = ia[j] + i2 = ia[j+1]-1 + b[j] /= aa[i1] + bj = b[j] + for i = i1+1:i2 + b[ja[i]] -= bj*aa[i] + end + end + b[end] /= aa[end] + return b +end + +function bwdTriSolve!(A::SparseMatrixCSC, b::AbstractVector) +# backward substitution for CSC matrices + n = length(b) + ncol = chksquare(A) + if n != ncol throw(DimensionMismatch("A is $(ncol)X$(ncol) and b has length $(n)")) end + + aa = A.nzval + ja = A.rowval + ia = A.colptr + + for j = n:-1:2 + i1 = ia[j] + i2 = ia[j+1]-1 + b[j] /= aa[i2] + bj = b[j] + for i = i2-1:-1:i1 + b[ja[i]] -= bj*aa[i] + end + end + b[1] /= aa[1] + return b +end + ## triu, tril function triu{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}, k::Integer) diff --git a/base/linalg/umfpack.jl b/base/linalg/umfpack.jl index ae5d26775a798..9f6289a1a43ea 100644 --- a/base/linalg/umfpack.jl +++ b/base/linalg/umfpack.jl @@ -8,7 +8,7 @@ export UmfpackLU, import Base: (\), Ac_ldiv_B, At_ldiv_B, findnz, getindex, nnz, show, size -import ..LinAlg: Factorization, det, lufact, lufact!, solve +import ..LinAlg: A_ldiv_B!, Ac_ldiv_B!, At_ldiv_B!, Factorization, det, lufact, lufact!, solve include("umfpack_h.jl") type MatrixIllConditionedException <: Exception @@ -278,42 +278,29 @@ for (sym_r,sym_c,num_r,num_c,sol_r,sol_c,det_r,det_z,lunz,get_num_r,get_num_z,it end ### Solve with Factorization - -(\){T<:UMFVTypes}(fact::UmfpackLU{T}, b::Vector{T}) = solve(fact, b) -(\){Ts<:UMFVTypes,Tb<:Number}(fact::UmfpackLU{Ts}, b::Vector{Tb}) = fact\convert(Vector{Ts},b) -function (\){Tb<:Complex}(fact::UmfpackLU{Float64}, b::Vector{Tb}) - r = fact\[convert(Float64,real(be)) for be in b] - i = fact\[convert(Float64,imag(be)) for be in b] - Complex128[r[k]+im*i[k] for k = 1:length(r)] -end -At_ldiv_B{T<:UMFVTypes}(fact::UmfpackLU{T}, b::Vector{T}) = solve(fact, b, UMFPACK_Aat) -At_ldiv_B{Ts<:UMFVTypes,Tb<:Number}(fact::UmfpackLU{Ts}, b::Vector{Tb}) = fact.'\convert(Vector{Ts},b) -At_ldiv_B{Tb<:Complex}(fact::UmfpackLU{Float64}, b::Vector{Tb}) = fact.'\b -Ac_ldiv_B{T<:UMFVTypes}(fact::UmfpackLU{T}, b::Vector{T}) = solve(fact, b, UMFPACK_At) -Ac_ldiv_B{Ts<:UMFVTypes,Tb<:Number}(fact::UmfpackLU{Ts}, b::Vector{Tb}) = fact'\convert(Vector{Ts},b) -Ac_ldiv_B{Tb<:Complex}(fact::UmfpackLU{Float64}, b::Vector{Tb}) = fact'\b - -### Solve directly with matrix - -(\)(S::SparseMatrixCSC, b::Vector) = lufact(S) \ b -At_ldiv_B{T<:UMFVTypes}(S::SparseMatrixCSC{T}, b::Vector{T}) = solve(lufact(S), b, UMFPACK_Aat) -At_ldiv_B{Ts<:UMFVTypes,Tb<:Number}(S::SparseMatrixCSC{Ts}, b::Vector{Tb}) = At_ldiv_B(S, convert(Vector{Ts}, b)) -function At_ldiv_B{Tb<:Complex}(S::SparseMatrixCSC{Float64}, b::Vector{Tb}) - F = lufact(S) - r = solve(F, [convert(Float64,real(be)) for be in b], UMFPACK_Aat) - i = solve(F, [convert(Float64,imag(be)) for be in b], UMFPACK_Aat) - Complex128[r[k]+im*i[k] for k = 1:length(r)] +A_ldiv_B!{T<:UMFVTypes}(lu::UmfpackLU{T}, b::Vector{T}) = solve(lu, b, UMFPACK_A) +function A_ldiv_B!{Tlu<:Real,Tb<:Complex}(lu::UmfpackLU{Tlu}, b::Vector{Tb}) + r = solve(lu, [convert(Tlu,real(be)) for be in b], UMFPACK_A) + i = solve(lu, [convert(Tlu,imag(be)) for be in b], UMFPACK_A) + Tb[r[k]+im*i[k] for k = 1:length(r)] end -Ac_ldiv_B{T<:UMFVTypes}(S::SparseMatrixCSC{T}, b::Vector{T}) = solve(lufact(S), b, UMFPACK_At) -Ac_ldiv_B{Ts<:UMFVTypes,Tb<:Number}(S::SparseMatrixCSC{Ts}, b::Vector{Tb}) = Ac_ldiv_B(S, convert(Vector{Ts}, b)) -function Ac_ldiv_B{Tb<:Complex}(S::SparseMatrixCSC{Float64}, b::Vector{Tb}) - F = lufact(S) - r = solve(F, [convert(Float64,real(be)) for be in b], UMFPACK_At) - i = solve(F, [convert(Float64,imag(be)) for be in b], UMFPACK_At) - Complex128[r[k]+im*i[k] for k = 1:length(r)] +A_ldiv_B!{Tlu<:UMFVTypes,Tb<:Number}(lu::UmfpackLU{Tlu}, b::Vector{Tb}) = A_ldiv_B!(lu, convert(Vector{Tlu}, b)) + +Ac_ldiv_B!{T<:UMFVTypes}(lu::UmfpackLU{T}, b::Vector{T}) = solve(lu, b, UMFPACK_At) +function Ac_ldiv_B!{Tlu<:Real,Tb<:Complex}(lu::UmfpackLU{Tlu}, b::Vector{Tb}) + r = solve(lu, [convert(Float64,real(be)) for be in b], UMFPACK_At) + i = solve(lu, [convert(Float64,imag(be)) for be in b], UMFPACK_At) + Tb[r[k]+im*i[k] for k = 1:length(r)] end +Ac_ldiv_B!{Tlu<:UMFVTypes,Tb<:Number}(lu::UmfpackLU{Tlu}, b::Vector{Tb}) = Ac_ldiv_B!(lu, convert(Vector{Tlu}, b)) -solve(lu::UmfpackLU, b::Vector) = solve(lu, b, UMFPACK_A) +At_ldiv_B!{T<:UMFVTypes}(lu::UmfpackLU{T}, b::Vector{T}) = solve(lu, b, UMFPACK_Aat) +function At_ldiv_B!{Tlu<:Real,Tb<:Complex}(lu::UmfpackLU{Tlu}, b::Vector{Tb}) + r = solve(lu, [convert(Float64,real(be)) for be in b], UMFPACK_Aat) + i = solve(lu, [convert(Float64,imag(be)) for be in b], UMFPACK_Aat) + Tb[r[k]+im*i[k] for k = 1:length(r)] +end +At_ldiv_B!{Tlu<:UMFVTypes,Tb<:Number}(lu::UmfpackLU{Tlu}, b::Vector{Tb}) = At_ldiv_B!(lu, convert(Vector{Tlu}, b)) function getindex(lu::UmfpackLU, d::Symbol) L,U,p,q,Rs = umf_extract(lu) diff --git a/base/profile.jl b/base/profile.jl index 5aa4d08c3c48c..31f769deae4f2 100644 --- a/base/profile.jl +++ b/base/profile.jl @@ -22,13 +22,13 @@ end #### User-level functions #### function init(n::Integer, delay::Float64) - status = ccall(:profile_init, Cint, (Csize_t, Uint64), n, iround(10^9*delay)) + status = ccall(:jl_profile_init, Cint, (Csize_t, Uint64), n, iround(10^9*delay)) if status == -1 error("could not allocate space for ", n, " instruction pointers") end end -clear() = ccall(:profile_clear_data, Void, ()) +clear() = ccall(:jl_profile_clear_data, Void, ()) function print{T<:Unsigned}(io::IO = STDOUT, data::Vector{T} = fetch(); format = :tree, C = false, combine = true, cols = Base.tty_cols()) if format == :tree @@ -75,17 +75,17 @@ isequal(a::LineInfo, b::LineInfo) = a.line == b.line && a.func == b.func && a.fi hash(li::LineInfo) = bitmix(hash(li.func), bitmix(hash(li.file), hash(li.line))) # C wrappers -start_timer() = ccall(:profile_start_timer, Cint, ()) +start_timer() = ccall(:jl_profile_start_timer, Cint, ()) -stop_timer() = ccall(:profile_stop_timer, Void, ()) +stop_timer() = ccall(:jl_profile_stop_timer, Void, ()) -is_running() = bool(ccall(:profile_is_running, Cint, ())) +is_running() = bool(ccall(:jl_profile_is_running, Cint, ())) -get_data_pointer() = convert(Ptr{Uint}, ccall(:profile_get_data, Ptr{Uint8}, ())) +get_data_pointer() = convert(Ptr{Uint}, ccall(:jl_profile_get_data, Ptr{Uint8}, ())) -len_data() = convert(Int, ccall(:profile_len_data, Csize_t, ())) +len_data() = convert(Int, ccall(:jl_profile_len_data, Csize_t, ())) -maxlen_data() = convert(Int, ccall(:profile_maxlen_data, Csize_t, ())) +maxlen_data() = convert(Int, ccall(:jl_profile_maxlen_data, Csize_t, ())) function lookup(ip::Uint, doCframes::Bool) info = ccall(:jl_lookup_code_address, Any, (Ptr{Void}, Bool), ip, doCframes) diff --git a/src/julia.expmap b/src/julia.expmap index e1352c991ff17..6337dcebe6f51 100644 --- a/src/julia.expmap +++ b/src/julia.expmap @@ -257,14 +257,14 @@ jl_lookup_code_address; jl_read_sonames; rec_backtrace; - profile_init; - profile_get_data; - profile_len_data; - profile_maxlen_data; - profile_clear_data; - profile_start_timer; - profile_stop_timer; - profile_is_running; + jl_profile_init; + jl_profile_get_data; + jl_profile_len_data; + jl_profile_maxlen_data; + jl_profile_clear_data; + jl_profile_start_timer; + jl_profile_stop_timer; + jl_profile_is_running; jl_reshape_array; jl_restore_system_image; jl_run_event_loop; diff --git a/src/profile.c b/src/profile.c index 2fd8c0b8432be..a7e1f1e838c88 100644 --- a/src/profile.c +++ b/src/profile.c @@ -57,7 +57,7 @@ static DWORD WINAPI profile_bt( LPVOID lparam ) hBtThread = 0; return 0; } -DLLEXPORT int profile_start_timer(void) +DLLEXPORT int jl_profile_start_timer(void) { running = 1; if (hBtThread == 0) { @@ -78,7 +78,7 @@ DLLEXPORT int profile_start_timer(void) } return (hBtThread != NULL ? 0 : -1); } -DLLEXPORT void profile_stop_timer(void) +DLLEXPORT void jl_profile_stop_timer(void) { running = 0; } @@ -229,7 +229,7 @@ void *mach_profile_listener(void *arg) } } -DLLEXPORT int profile_start_timer(void) +DLLEXPORT int jl_profile_start_timer(void) { kern_return_t ret; if (!profile_started) { @@ -268,7 +268,7 @@ DLLEXPORT int profile_start_timer(void) return 0; } -DLLEXPORT void profile_stop_timer(void) +DLLEXPORT void jl_profile_stop_timer(void) { running = 0; } @@ -296,7 +296,7 @@ static void profile_bt(int dummy) } } -DLLEXPORT int profile_start_timer(void) +DLLEXPORT int jl_profile_start_timer(void) { timerprof.it_interval.tv_sec = 0; timerprof.it_interval.tv_usec = 0; @@ -311,7 +311,7 @@ DLLEXPORT int profile_start_timer(void) return 0; } -DLLEXPORT void profile_stop_timer(void) +DLLEXPORT void jl_profile_stop_timer(void) { running = 0; } @@ -343,7 +343,7 @@ static void profile_bt(int signal, siginfo_t *si, void *uc) } } -DLLEXPORT int profile_start_timer(void) +DLLEXPORT int jl_profile_start_timer(void) { struct sigevent sigprof; struct sigaction sa; @@ -376,7 +376,7 @@ DLLEXPORT int profile_start_timer(void) return 0; } -DLLEXPORT void profile_stop_timer(void) +DLLEXPORT void jl_profile_stop_timer(void) { if (running) timer_delete(timerprof); @@ -389,7 +389,7 @@ DLLEXPORT void profile_stop_timer(void) /////////////////////// // Utility functions // /////////////////////// -DLLEXPORT int profile_init(size_t maxsize, u_int64_t delay_nsec) +DLLEXPORT int jl_profile_init(size_t maxsize, u_int64_t delay_nsec) { bt_size_max = maxsize; nsecprof = delay_nsec; @@ -402,27 +402,27 @@ DLLEXPORT int profile_init(size_t maxsize, u_int64_t delay_nsec) return 0; } -DLLEXPORT u_int8_t* profile_get_data(void) +DLLEXPORT u_int8_t* jl_profile_get_data(void) { return (u_int8_t*) bt_data_prof; } -DLLEXPORT size_t profile_len_data(void) +DLLEXPORT size_t jl_profile_len_data(void) { return bt_size_cur; } -DLLEXPORT size_t profile_maxlen_data(void) +DLLEXPORT size_t jl_profile_maxlen_data(void) { return bt_size_max; } -DLLEXPORT void profile_clear_data(void) +DLLEXPORT void jl_profile_clear_data(void) { bt_size_cur = 0; } -DLLEXPORT int profile_is_running(void) +DLLEXPORT int jl_profile_is_running(void) { return running; } diff --git a/test/core.jl b/test/core.jl index 9d8664f044790..60987d84a3a22 100644 --- a/test/core.jl +++ b/test/core.jl @@ -1165,3 +1165,14 @@ macro myassert4873(ex) end x4873 = 1 @myassert4873 (x -> x)(x4873) == 1 + +# issue from IRC +function invalid_tupleref() + A = (1, "2", 3.0) + try + return A[0] + catch + return true + end +end +@test invalid_tupleref()==true diff --git a/test/sparse.jl b/test/sparse.jl index f7344e9cb3bea..73aac32eba551 100644 --- a/test/sparse.jl +++ b/test/sparse.jl @@ -75,12 +75,57 @@ for i = 1:5 @test (maximum(abs(a*b - full(a)*b)) < 100*eps()) @test (maximum(abs(a\b - full(a)\b)) < 1000*eps()) @test (maximum(abs(a'\b - full(a')\b)) < 1000*eps()) + @test (maximum(abs(a.'\b - full(a.')\b)) < 1000*eps()) + a = speye(5) + 0.1*sprandn(5, 5, 0.2) + 0.1*im*sprandn(5, 5, 0.2) b = randn(5) @test (maximum(abs(a*b - full(a)*b)) < 100*eps()) @test (maximum(abs(a\b - full(a)\b)) < 1000*eps()) @test (maximum(abs(a'\b - full(a')\b)) < 1000*eps()) @test (maximum(abs(a.'\b - full(a.')\b)) < 1000*eps()) + + a = speye(5) + tril(0.1*sprandn(5, 5, 0.2)) + b = randn(5) + im*randn(5) + @test (maximum(abs(a*b - full(a)*b)) < 100*eps()) + @test (maximum(abs(a\b - full(a)\b)) < 1000*eps()) + @test (maximum(abs(a'\b - full(a')\b)) < 1000*eps()) + @test (maximum(abs(a.'\b - full(a.')\b)) < 1000*eps()) + + a = speye(5) + tril(0.1*sprandn(5, 5, 0.2) + 0.1*im*sprandn(5, 5, 0.2)) + b = randn(5) + @test (maximum(abs(a*b - full(a)*b)) < 100*eps()) + @test (maximum(abs(a\b - full(a)\b)) < 1000*eps()) + @test (maximum(abs(a'\b - full(a')\b)) < 1000*eps()) + @test (maximum(abs(a.'\b - full(a.')\b)) < 1000*eps()) + + a = speye(5) + triu(0.1*sprandn(5, 5, 0.2)) + b = randn(5) + im*randn(5) + @test (maximum(abs(a*b - full(a)*b)) < 100*eps()) + @test (maximum(abs(a\b - full(a)\b)) < 1000*eps()) + @test (maximum(abs(a'\b - full(a')\b)) < 1000*eps()) + @test (maximum(abs(a.'\b - full(a.')\b)) < 1000*eps()) + + a = speye(5) + triu(0.1*sprandn(5, 5, 0.2) + 0.1*im*sprandn(5, 5, 0.2)) + b = randn(5) + @test (maximum(abs(a*b - full(a)*b)) < 100*eps()) + @test (maximum(abs(a\b - full(a)\b)) < 1000*eps()) + @test (maximum(abs(a'\b - full(a')\b)) < 1000*eps()) + @test (maximum(abs(a.'\b - full(a.')\b)) < 1000*eps()) + + a = speye(5) + triu(0.1*sprandn(5, 5, 0.2)) + b = randn(5) + im*randn(5) + @test (maximum(abs(a*b - full(a)*b)) < 100*eps()) + @test (maximum(abs(a\b - full(a)\b)) < 1000*eps()) + @test (maximum(abs(a'\b - full(a')\b)) < 1000*eps()) + @test (maximum(abs(a.'\b - full(a.')\b)) < 1000*eps()) + + a = spdiagm(randn(5)) + im*spdiagm(randn(5)) + b = randn(5) + @test (maximum(abs(a*b - full(a)*b)) < 100*eps()) + @test (maximum(abs(a\b - full(a)\b)) < 1000*eps()) + @test (maximum(abs(a'\b - full(a')\b)) < 1000*eps()) + @test (maximum(abs(a.'\b - full(a.')\b)) < 1000*eps()) + b = randn(5) + im*randn(5) @test (maximum(abs(a*b - full(a)*b)) < 100*eps()) @test (maximum(abs(a\b - full(a)\b)) < 1000*eps())