diff --git a/NEWS.md b/NEWS.md index 7ef91ecf65efe..c6462b408de58 100644 --- a/NEWS.md +++ b/NEWS.md @@ -34,6 +34,10 @@ New language features Library improvements -------------------- + * `convert(Ptr{T1}, x::Array{T2})` is now deprecated unless `T1 == T2` + or `T1 == None` ([#6073]). (You can still explicitly `convert` + one pointer type into another if needed.) + * Well-behaved floating-point ranges ([#2333], [#5636]). Introduced the `FloatRange` type for floating-point ranges with a step, which will give intuitive/correct results for classically problematic diff --git a/base/array.jl b/base/array.jl index 3e7057f5b89b6..74725fbf2b86a 100644 --- a/base/array.jl +++ b/base/array.jl @@ -802,15 +802,26 @@ end # functions that should give an Int result for Bool arrays for f in (:+, :-) @eval begin - function ($f)(x::Bool, y::StridedArray{Bool}) - reshape([ ($f)(x, y[i]) for i=1:length(y) ], size(y)) + function ($f)(A::Bool, B::StridedArray{Bool}) + F = Array(Int, size(B)) + for i=1:length(B) + @inbounds F[i] = ($f)(A, B[i]) + end + return F end - function ($f)(x::StridedArray{Bool}, y::Bool) - reshape([ ($f)(x[i], y) for i=1:length(x) ], size(x)) + function ($f)(A::StridedArray{Bool}, B::Bool) + F = Array(Int, size(A)) + for i=1:length(A) + @inbounds F[i] = ($f)(A[i], B) + end + return F end - function ($f)(x::StridedArray{Bool}, y::StridedArray{Bool}) - shp = promote_shape(size(x),size(y)) - reshape([ ($f)(x[i], y[i]) for i=1:length(x) ], shp) + function ($f)(A::StridedArray{Bool}, B::StridedArray{Bool}) + F = Array(Int, promote_shape(size(A), size(B))) + for i=1:length(A) + @inbounds F[i] = ($f)(A[i], B[i]) + end + return F end end end diff --git a/base/bitarray.jl b/base/bitarray.jl index 5744b154ef5f2..1cc388d8c8005 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -350,7 +350,7 @@ end ## Indexing: getindex ## function getindex_unchecked(Bc::Vector{Uint64}, i::Int) - return (Bc[@_div64(int(i)-1)+1] & (uint64(1)<<@_mod64(int(i)-1))) != 0 + return (Bc[@_div64(i-1)+1] & (uint64(1)<<@_mod64(i-1))) != 0 end function getindex(B::BitArray, i::Int) @@ -885,25 +885,35 @@ end ## Binary arithmetic operators ## for f in (:+, :-) - @eval begin - function ($f)(A::BitArray, B::BitArray) - shp = promote_shape(size(A),size(B)) - reshape(Int[ ($f)(A[i], B[i]) for i=1:length(A) ], shp) - end - function ($f)(B::BitArray, x::Bool) - reshape([ ($f)(B[i], x) for i = 1:length(B) ], size(B)) - end - function ($f)(B::BitArray, x::Number) - pt = promote_array_type(typeof(x), Bool) - reshape((pt)[ ($f)(B[i], x) for i = 1:length(B) ], size(B)) - end - function ($f)(x::Bool, B::BitArray) - reshape([ ($f)(x, B[i]) for i = 1:length(B) ], size(B)) - end - function ($f)(x::Number, B::BitArray) - pt = promote_array_type(typeof(x), Bool) - reshape((pt)[ ($f)(x, B[i]) for i = 1:length(B) ], size(B)) - end + @eval function ($f)(A::BitArray, B::BitArray) + r = Array(Int, promote_shape(size(A), size(B))) + ai = start(A) + bi = start(B) + ri = 1 + while !done(A, ai) + a, ai = next(A, ai) + b, bi = next(B, bi) + @inbounds r[ri] = ($f)(a, b) + ri += 1 + end + return r + end +end +for f in (:+, :-), + (arg1, arg2, T, fargs) in ((:(B::BitArray), :(x::Bool) , Int , :(b, x)), + (:(B::BitArray), :(x::Number) , :(promote_array_type(typeof(x), Bool)), :(b, x)), + (:(x::Bool) , :(B::BitArray), Int , :(x, b)), + (:(x::Number) , :(B::BitArray), :(promote_array_type(typeof(x), Bool)), :(x, b))) + @eval function ($f)($arg1, $arg2) + r = Array($T, size(B)) + bi = start(B) + ri = 1 + while !done(B, bi) + b, bi = next(B, bi) + @inbounds r[ri] = ($f)($fargs...) + ri += 1 + end + return r end end diff --git a/base/complex.jl b/base/complex.jl index 3c2ec63b39a7b..097e48ea8122d 100644 --- a/base/complex.jl +++ b/base/complex.jl @@ -35,8 +35,10 @@ reim(z) = (real(z), imag(z)) isreal(x::Real) = true isreal(z::Complex) = imag(z) == 0 isimag(z::Number) = real(z) == 0 -isinteger(z::Complex) = isreal(z) && isinteger(real(z)) -isfinite(z::Complex) = isfinite(real(z)) && isfinite(imag(z)) +isinteger(z::Complex) = isreal(z) & isinteger(real(z)) +isfinite(z::Complex) = isfinite(real(z)) & isfinite(imag(z)) +isnan(z::Complex) = isnan(real(z)) | isnan(imag(z)) +isinf(z::Complex) = isinf(real(z)) | isinf(imag(z)) complex(x::Real, y::Real) = Complex(x, y) complex(x::Real) = Complex(x) diff --git a/base/deprecated.jl b/base/deprecated.jl index ed39c6229bd11..a2165ab4dc88c 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -12,9 +12,16 @@ macro deprecate(old,new) elseif isa(old,Expr) && old.head == :call oldcall = sprint(io->show_unquoted(io,old)) newcall = sprint(io->show_unquoted(io,new)) - oldname = Expr(:quote, old.args[1]) + oldsym = if isa(old.args[1],Symbol) + old.args[1] + elseif isa(old.args[1],Expr) && old.args[1].head == :curly + old.args[1].args[1] + else + error("invalid usage of @deprecate") + end + oldname = Expr(:quote, oldsym) Expr(:toplevel, - Expr(:export,esc(old.args[1])), + Expr(:export,esc(oldsym)), :($(esc(old)) = begin depwarn(string($oldcall," is deprecated, use ",$newcall," instead."), $oldname) @@ -402,6 +409,8 @@ Set{T<:Number}(xs::T...) = Set{T}(xs) @deprecate normfro(A) vecnorm(A) +@deprecate convert{T}(p::Type{Ptr{T}}, a::Array) convert(p, pointer(a)) + # 0.3 discontinued functions function nnz(X) diff --git a/base/gmp.jl b/base/gmp.jl index efc4684a57b95..11eb0dd9653aa 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -363,25 +363,19 @@ function sum(arr::AbstractArray{BigInt}) return n end -function factorial(bn::BigInt) - if bn<0 - return BigInt(0) - else - n = uint(bn) - end +function factorial(x::BigInt) + x.size < 0 && return BigInt(0) z = BigInt() - ccall((:__gmpz_fac_ui, :libgmp), Void, - (Ptr{BigInt}, Culong), &z, n) + ccall((:__gmpz_fac_ui, :libgmp), Void, (Ptr{BigInt}, Culong), &z, x) return z end function binomial(n::BigInt, k::Uint) z = BigInt() - ccall((:__gmpz_bin_ui, :libgmp), Void, - (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &n, k) + ccall((:__gmpz_bin_ui, :libgmp), Void, (Ptr{BigInt}, Ptr{BigInt}, Culong), &z, &n, k) return z end -binomial(n::BigInt, k::Integer) = k<0 ? throw(DomainError()) : binomial(n, uint(k)) +binomial(n::BigInt, k::Integer) = k < 0 ? throw(DomainError()) : binomial(n, uint(k)) ==(x::BigInt, y::BigInt) = cmp(x,y) == 0 isequal(x::BigInt, y::BigInt) = cmp(x,y) == 0 @@ -390,16 +384,8 @@ isequal(x::BigInt, y::BigInt) = cmp(x,y) == 0 <(x::BigInt, y::BigInt) = cmp(x,y) < 0 >(x::BigInt, y::BigInt) = cmp(x,y) > 0 -function string(x::BigInt) - lng = ndigits(x) + 2 - z = Array(Uint8, lng) - lng = ccall((:__gmp_snprintf,:libgmp), Int32, (Ptr{Uint8}, Culong, Ptr{Uint8}, Ptr{BigInt}...), z, lng, "%Zd", &x) - return bytestring(z[1:lng]) -end - -function show(io::IO, x::BigInt) - print(io, string(x)) -end +string(x::BigInt) = dec(x) +show(io::IO, x::BigInt) = print(io, string(x)) bin(n::BigInt) = base( 2, n) oct(n::BigInt) = base( 8, n) @@ -407,22 +393,18 @@ dec(n::BigInt) = base(10, n) hex(n::BigInt) = base(16, n) function base(b::Integer, n::BigInt) - if !(2 <= b <= 62) - error("invalid base: $b") - end - p = ccall((:__gmpz_get_str,:libgmp), Ptr{Uint8}, (Ptr{Uint8}, Cint, Ptr{BigInt}), - C_NULL, b, &n) + 2 <= b <= 62 || error("invalid base: $b") + p = ccall((:__gmpz_get_str,:libgmp), Ptr{Uint8}, (Ptr{Uint8}, Cint, Ptr{BigInt}), C_NULL, b, &n) len = int(ccall(:strlen, Csize_t, (Ptr{Uint8},), p)) ASCIIString(pointer_to_array(p,len,true)) end -function ndigits(x::BigInt, base::Integer=10) +function ndigits0z(x::BigInt, b::Integer=10) # mpz_sizeinbase might return an answer 1 too big - n = int(ccall((:__gmpz_sizeinbase,:libgmp), Culong, (Ptr{BigInt}, Int32), &x, base)) - abs(x) < big(base)^(n-1) ? n-1 : n + n = int(ccall((:__gmpz_sizeinbase,:libgmp), Culong, (Ptr{BigInt}, Int32), &x, b)) + abs(x) < big(b)^(n-1) ? n-1 : n end - -ndigits0z(x::BigInt, base::Integer=10) = x == 0 ? 0 : ndigits(x) +ndigits(x::BigInt, b::Integer=10) = x.size == 0 ? 1 : ndigits0z(x,b) isprime(x::BigInt, reps=25) = ccall((:__gmpz_probab_prime_p,:libgmp), Cint, (Ptr{BigInt}, Cint), &x, reps) > 0 @@ -431,7 +413,7 @@ widemul(x::Int128, y::Uint128) = BigInt(x)*BigInt(y) widemul(x::Uint128, y::Int128) = BigInt(x)*BigInt(y) widemul{T<:Integer}(x::T, y::T) = BigInt(x)*BigInt(y) -prevpow2(x::BigInt) = x < 0 ? -prevpow2(-x) : (x <= 2 ? x : one(BigInt) << (ndigits(x, 2)-1)) -nextpow2(x::BigInt) = x < 0 ? -nextpow2(-x) : (x <= 2 ? x : one(BigInt) << ndigits(x-1, 2)) +prevpow2(x::BigInt) = x.size < 0 ? -prevpow2(-x) : (x <= 2 ? x : one(BigInt) << (ndigits(x, 2)-1)) +nextpow2(x::BigInt) = x.size < 0 ? -nextpow2(-x) : (x <= 2 ? x : one(BigInt) << ndigits(x-1, 2)) end # module diff --git a/base/grisu.jl b/base/grisu.jl index 32d002a04119c..04cbdd104aea7 100644 --- a/base/grisu.jl +++ b/base/grisu.jl @@ -4,11 +4,11 @@ export @grisu_ccall, NEG, DIGITS, BUFLEN, LEN, POINT import Base.show, Base.print, Base.showcompact -const NEG = Array(Bool,1) +const NEG = Array(Bool) const DIGITS = Array(Uint8,309+17) const BUFLEN = int32(length(DIGITS)+1) -const LEN = Array(Int32,1) -const POINT = Array(Int32,1) +const LEN = Array(Int32) +const POINT = Array(Int32) macro grisu_ccall(value, mode, ndigits) quote diff --git a/base/inference.jl b/base/inference.jl index 5989f7a61fdba..d4ea6764ac0da 100644 --- a/base/inference.jl +++ b/base/inference.jl @@ -300,31 +300,45 @@ function limit_type_depth(t::ANY, d::Int, cov::Bool, vars) if isa(t,TypeVar) || isa(t,TypeConstructor) return t end + inexact = !cov && d > MAX_TYPE_DEPTH if isa(t,Tuple) + t === () && return t if d > MAX_TYPE_DEPTH - R = Tuple + if isvatuple(t) + R = Tuple + else + R = NTuple{length(t),Any} + end else - R = map(x->limit_type_depth(x, d+1, cov, vars), t) + l0 = length(vars) + R = map(x->limit_type_depth(x, d+1, true, vars), t) + if !cov && (length(vars) > l0 || d == MAX_TYPE_DEPTH) + inexact = true + end end elseif isa(t,UnionType) + t === None && return t if d > MAX_TYPE_DEPTH R = Any else - R = Union(limit_type_depth(t.types, d, cov, vars)...) + R = limit_type_depth(t.types, d, cov, vars) + if isa(R,TypeVar) + R = Union(R.ub...) + inexact = true + else + R = Union(R...) + end end elseif isa(t,DataType) P = t.parameters - if P === () - return t - end + P === () && return t if d > MAX_TYPE_DEPTH R = t.name.primary else Q = map(x->limit_type_depth(x, d+1, false, vars), P) if !cov && any(p->contains_is(vars,p), Q) - R = TypeVar(:_,t.name.primary) - push!(vars, R) - return R + R = t.name.primary + inexact = true else R = t.name.primary{Q...} end @@ -332,7 +346,7 @@ function limit_type_depth(t::ANY, d::Int, cov::Bool, vars) else return t end - if !cov && d > MAX_TYPE_DEPTH + if inexact R = TypeVar(:_,R) push!(vars, R) end @@ -377,8 +391,13 @@ const getfield_tfunc = function (A, s0, name) end for i=1:length(s.names) if is(s.names[i],fld) - return limit_type_depth(s.types[i], 0, true, - filter!(x->isa(x,TypeVar), {s.parameters...})) + R = s.types[i] + if s.parameters === () + return R + else + return limit_type_depth(R, 0, true, + filter!(x->isa(x,TypeVar), {s.parameters...})) + end end end return None diff --git a/base/linalg/cholmod.jl b/base/linalg/cholmod.jl index ce797bd5989b0..5dcc61dfeae1e 100644 --- a/base/linalg/cholmod.jl +++ b/base/linalg/cholmod.jl @@ -86,7 +86,7 @@ end ### These offsets should be reconfigured to be less error-prone in matches const chm_com_offsets = Array(Int, length(ChmCommon.types)) ccall((:jl_cholmod_common_offsets, :libsuitesparse_wrapper), - Void, (Ptr{Uint8},), chm_com_offsets) + Void, (Ptr{Int},), chm_com_offsets) const chm_final_ll_inds = (1:4) + chm_com_offsets[7] const chm_prt_inds = (1:4) + chm_com_offsets[13] const chm_ityp_inds = (1:4) + chm_com_offsets[18] diff --git a/base/linalg/factorization.jl b/base/linalg/factorization.jl index 9213c9e20c3d6..479b1470042af 100644 --- a/base/linalg/factorization.jl +++ b/base/linalg/factorization.jl @@ -137,7 +137,7 @@ function lufact!{T}(A::AbstractMatrix{T}) ipiv = Array(BlasInt, minmn) for k = 1:minmn # find index max - kp = 1 + kp = k amax = real(zero(T)) for i = k:m absi = abs(A[i,k]) @@ -148,11 +148,13 @@ function lufact!{T}(A::AbstractMatrix{T}) end ipiv[k] = kp if A[kp,k] != 0 - # Interchange - for i = 1:n - tmp = A[k,i] - A[k,i] = A[kp,i] - A[kp,i] = tmp + if k != kp + # Interchange + for i = 1:n + tmp = A[k,i] + A[k,i] = A[kp,i] + A[kp,i] = tmp + end end # Scale first column Akkinv = inv(A[k,k]) @@ -167,9 +169,8 @@ function lufact!{T}(A::AbstractMatrix{T}) for i = k+1:m A[i,j] -= A[i,k]*A[k,j] end - end + end end - if minmn > 0 && A[minmn,minmn] == 0; info = minmn; end LU(A, ipiv, convert(BlasInt, info)) end lufact{T<:BlasFloat}(A::StridedMatrix{T}) = lufact!(copy(A)) @@ -281,14 +282,14 @@ function qrfact!{T}(A::AbstractMatrix{T}; pivot=false) τk = elementaryLeft!(A, k, k) τ[k] = τk for j = k+1:n - νAj = A[k,j] + vAj = A[k,j] for i = k+1:m - νAj += conj(A[i,k])*A[i,j] + vAj += conj(A[i,k])*A[i,j] end - νAj *= conj(τk) - A[k,j] -= νAj + vAj = conj(τk)*vAj + A[k,j] -= vAj for i = k+1:m - A[i,j] -= A[i,k]*νAj + A[i,j] -= A[i,k]*vAj end end end @@ -351,9 +352,7 @@ size(A::Union(QR,QRCompactWY,QRPivoted)) = size(A.factors) size(A::Union(QRPackedQ,QRCompactWYQ), dim::Integer) = 0 < dim ? (dim <= 2 ? size(A.factors, 1) : 1) : throw(BoundsError()) size(A::Union(QRPackedQ,QRCompactWYQ)) = size(A, 1), size(A, 2) -full{T}(A::Union(QRPackedQ{T},QRCompactWYQ{T}); thin::Bool=true) = A_mul_B!(A, thin ? eye(T, size(A.factors)...) : eye(T, size(A.factors,1))) - -print_matrix(io::IO, A::Union(QRPackedQ,QRCompactWYQ), rows::Integer, cols::Integer) = print_matrix(io, full(A, thin=false), rows, cols) +full{T}(A::Union(QRPackedQ{T},QRCompactWYQ{T}); thin::Bool=true) = A_mul_B!(A, thin ? eye(T, size(A.factors,1), minimum(size(A.factors))) : eye(T, size(A.factors,1))) ## Multiplication by Q ### QB @@ -367,14 +366,14 @@ function A_mul_B!{T}(A::QRPackedQ{T}, B::AbstractVecOrMat{T}) @inbounds begin for k = min(mA,nA):-1:1 for j = 1:nB - νBj = B[k,j] + vBj = B[k,j] for i = k+1:mB - νBj += conj(Afactors[i,k])*B[i,j] + vBj += conj(Afactors[i,k])*B[i,j] end - νBj *= conj(A.τ[k]) - B[k,j] -= νBj + vBj = A.τ[k]*vBj + B[k,j] -= vBj for i = k+1:mB - B[i,j] -= Afactors[i,k]*νBj + B[i,j] -= Afactors[i,k]*vBj end end end @@ -406,14 +405,14 @@ function Ac_mul_B!{T}(A::QRPackedQ{T}, B::AbstractVecOrMat{T}) @inbounds begin for k = 1:min(mA,nA) for j = 1:nB - νBj = B[k,j] + vBj = B[k,j] for i = k+1:mB - νBj += conj(Afactors[i,k])*B[i,j] + vBj += conj(Afactors[i,k])*B[i,j] end - νBj *= A.τ[k] - B[k,j] -= νBj + vBj = conj(A.τ[k])*vBj + B[k,j] -= vBj for i = k+1:mB - B[i,j] -= Afactors[i,k]*νBj + B[i,j] -= Afactors[i,k]*vBj end end end @@ -435,14 +434,14 @@ function A_mul_B!{T}(A::StridedMatrix{T},Q::QRPackedQ{T}) @inbounds begin for k = 1:min(mQ,nQ) for i = 1:mA - νAi = A[i,k] + vAi = A[i,k] for j = k+1:mQ - νAi += Qfactors[j,k]*A[i,j] + vAi += A[i,j]*Qfactors[j,k] end - νAi *= conj(Q.τ[k]) - A[i,k] -= νAi + vAi = vAi*Q.τ[k] + A[i,k] -= vAi for j = k+1:nA - A[i,j] -= Qfactors[j,k]*νAi + A[i,j] -= vAi*conj(Qfactors[j,k]) end end end @@ -451,7 +450,7 @@ function A_mul_B!{T}(A::StridedMatrix{T},Q::QRPackedQ{T}) end function *{TA,TQ}(A::StridedVecOrMat{TA}, Q::Union(QRPackedQ{TQ},QRCompactWYQ{TQ})) TAQ = promote_type(TA, TQ) - A_mul_B!(TA==TAQ ? copy(A) : convert(typeof(A).name.primary{TAQ}, A), convert(typeof(Q).name.primary{TAQ}, Q)) + A_mul_B!(TA==TAQ ? copy(A) : convert(Matrix{TAQ}, A), convert(typeof(Q).name.primary{TAQ}, Q)) end ### AQc A_mul_Bc!{T<:BlasReal}(A::StridedVecOrMat{T}, B::QRCompactWYQ{T}) = LAPACK.gemqrt!('R','T',B.factors,B.T,A) @@ -466,14 +465,14 @@ function A_mul_Bc!{T}(A::AbstractMatrix{T},Q::QRPackedQ{T}) @inbounds begin for k = min(mQ,nQ):-1:1 for i = 1:mA - νAi = A[i,k] + vAi = A[i,k] for j = k+1:mQ - νAi += Qfactors[j,k]*A[i,j] + vAi += A[i,j]*Qfactors[j,k] end - νAi *= Q.τ[k] - A[i,k] -= νAi + vAi = vAi*conj(Q.τ[k]) + A[i,k] -= vAi for j = k+1:nA - A[i,j] -= Qfactors[j,k]*νAi + A[i,j] -= vAi*conj(Qfactors[j,k]) end end end @@ -482,7 +481,7 @@ function A_mul_Bc!{T}(A::AbstractMatrix{T},Q::QRPackedQ{T}) end function A_mul_Bc{TA,TB}(A::AbstractVecOrMat{TA}, B::Union(QRCompactWYQ{TB},QRPackedQ{TB})) TAB = promote_type(TA,TB) - A_mul_Bc!(size(A,2)==size(B.factors,1) ? copy(A) : (size(A,2)==size(B.factors,2) ? [A zeros(T, size(A, 1), size(B.factors, 1) - size(B.factors, 2))] : throw(DimensionMismatch("")))) + A_mul_Bc!(size(A,2)==size(B.factors,1) ? (TA == TAB ? copy(A) : convert(Matrix{TAB}, A)) : (size(A,2)==size(B.factors,2) ? [A zeros(T, size(A, 1), size(B.factors, 1) - size(B.factors, 2))] : throw(DimensionMismatch(""))),B) end # Julia implementation similarly to xgelsy @@ -526,14 +525,14 @@ function A_ldiv_B!{T}(A::QR{T},B::StridedMatrix{T}) for k = m:-1:1 # Trapezoid to triangular by elementary operation τ[k] = elementaryRightTrapezoid!(R,k) for i = 1:k-1 - νRi = R[i,k] + vRi = R[i,k] for j = m+1:n - νRi += R[i,j]*R[k,j] + vRi += R[i,j]*R[k,j] end - νRi *= τ[k] - R[i,k] -= νRi + vRi *= τ[k] + R[i,k] -= vRi for j = m+1:n - R[i,j] -= νRi*R[k,j] + R[i,j] -= vRi*R[k,j] end end end @@ -550,14 +549,14 @@ function A_ldiv_B!{T}(A::QR{T},B::StridedMatrix{T}) B[m+1:mB,1:nB] = zero(T) for j = 1:nB for k = 1:m - νBj = B[k,j] + vBj = B[k,j] for i = m+1:n - νBj += B[i,j]*conj(R[k,i]) + vBj += B[i,j]*conj(R[k,i]) end - νBj *= τ[k] - B[k,j] -= νBj + vBj *= τ[k] + B[k,j] -= vBj for i = m+1:n - B[i,j] -= R[k,i]*νBj + B[i,j] -= R[k,i]*vBj end end end @@ -602,9 +601,6 @@ immutable HessenbergQ{T} <: AbstractMatrix{T} end HessenbergQ(A::Hessenberg) = HessenbergQ(A.factors, A.τ) size(A::HessenbergQ, args...) = size(A.factors, args...) -getindex(A::HessenbergQ, i::Real) = getindex(full(A), i) -getindex(A::HessenbergQ, i::AbstractArray) = getindex(full(A), i) -getindex(A::HessenbergQ, args...) = getindex(full(A), args...) function getindex(A::Hessenberg, d::Symbol) d == :Q && return HessenbergQ(A) @@ -614,6 +610,10 @@ end full(A::HessenbergQ) = LAPACK.orghr!(1, size(A.factors, 1), copy(A.factors), A.τ) +# Also printing of QRQs +print_matrix(io::IO, A::Union(QRPackedQ,QRCompactWYQ,HessenbergQ), rows::Integer, cols::Integer, punct...) = print_matrix(io, full(A), rows, cols, punct...) + + ####################### # Eigendecompositions # ####################### diff --git a/base/linalg/lapack.jl b/base/linalg/lapack.jl index 1a542f17b5111..5f5d4653b53ed 100644 --- a/base/linalg/lapack.jl +++ b/base/linalg/lapack.jl @@ -1027,7 +1027,7 @@ for (geev, gesvd, gesdd, ggsvd, elty, relty) in if cmplx ccall(($(string(gesdd)),liblapack), Void, (Ptr{BlasChar}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{$elty}, - Ptr{BlasInt}, Ptr{$elty}, Ptr{$elty}, Ptr{BlasInt}, + Ptr{BlasInt}, Ptr{$relty}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$relty}, Ptr{BlasInt}, Ptr{BlasInt}), &job, &m, &n, A, &max(1,stride(A,2)), S, U, &max(1,stride(U,2)), VT, &max(1,stride(VT,2)), @@ -2070,7 +2070,7 @@ for (trcon, trevc, trrfs, elty, relty) in @chkuplo rcond = Array($relty, 1) work = Array($elty, 2n) - rwork = Array($elty, n) + rwork = Array($relty, n) info = Array(BlasInt, 1) ccall(($(string(trcon)),liblapack), Void, (Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasInt}, @@ -2150,7 +2150,7 @@ for (trcon, trevc, trrfs, elty, relty) in nrhs=size(B,2) nrhs==size(X,2) || throw(DimensionMismatch("")) work=Array($elty, 2n) - rwork=Array($elty, n) + rwork=Array($relty, n) info=Array(BlasInt, 1) ccall(($(string(trrfs)),liblapack), Void, (Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasInt}, @@ -2987,7 +2987,7 @@ for (syev, syevr, sygvd, elty, relty) in (Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasChar}, Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$elty}, Ptr{$elty}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt}, - Ptr{$elty}, Ptr{$elty}, Ptr{BlasInt}, Ptr{BlasInt}, + Ptr{$relty}, Ptr{$elty}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{$elty}, Ptr{BlasInt}, Ptr{$relty}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{BlasInt}, Ptr{BlasInt}), &jobz, &range, &uplo, &n, diff --git a/base/linalg/symmetric.jl b/base/linalg/symmetric.jl index f34f9841bd01b..d1ba5ab940242 100644 --- a/base/linalg/symmetric.jl +++ b/base/linalg/symmetric.jl @@ -38,13 +38,13 @@ factorize(A::HermOrSym) = bkfact(A.S, symbol(A.uplo), issym(A)) eigfact!{T<:BlasReal}(A::Symmetric{T}) = Eigen(LAPACK.syevr!('V', 'A', A.uplo, A.S, 0.0, 0.0, 0, 0, -1.0)...) eigfact!{T<:BlasComplex}(A::Hermitian{T}) = Eigen(LAPACK.syevr!('V', 'A', A.uplo, A.S, 0.0, 0.0, 0, 0, -1.0)...) eigfact{T<:BlasFloat}(A::HermOrSym{T}) = eigfact!(copy(A)) -eigfact{T}(A::HermOrSym{T}) = (S = promote_type(Float32,typeof(sqrt(one(T)))); S != T ? eigfact!(convert(typeof(A).name.primary{S}, A)) : eigfact!(copy(A))) +eigfact{T}(A::HermOrSym{T}) = (S = promote_type(Float32,typeof(one(T)/norm(one(T)))); S != T ? eigfact!(convert(typeof(A).name.primary{S}, A)) : eigfact!(copy(A))) eigvals!{T<:BlasReal}(A::Symmetric{T}, il::Int=1, ih::Int=size(A,1)) = LAPACK.syevr!('N', 'I', A.uplo, A.S, 0.0, 0.0, il, ih, -1.0)[1] eigvals!{T<:BlasReal}(A::Symmetric{T}, vl::Real, vh::Real) = LAPACK.syevr!('N', 'V', A.uplo, A.S, vl, vh, 0, 0, -1.0)[1] eigvals!{T<:BlasComplex}(A::Hermitian{T}, il::Int=1, ih::Int=size(A,1)) = LAPACK.syevr!('N', 'I', A.uplo, A.S, 0.0, 0.0, il, ih, -1.0)[1] eigvals!{T<:BlasComplex}(A::Hermitian{T}, vl::Real, vh::Real) = LAPACK.syevr!('N', 'V', A.uplo, A.S, vl, vh, 0, 0, -1.0)[1] eigvals{T<:BlasFloat}(A::HermOrSym{T},l::Real=1,h::Real=size(A,1)) = eigvals!(copy(A),l,h) -eigvals{T}(A::HermOrSym{T},l::Real=1,h::Real=size(A,1)) = (S = promote_type(Float32,typeof(sqrt(one(T)))); S != T ? eigvals!(convert(typeof(A).name.primary{S}, A, l, h)) : eigvals!(copy(A), l, h)) +eigvals{T}(A::HermOrSym{T},l::Real=1,h::Real=size(A,1)) = (S = promote_type(Float32,typeof(one(T)/norm(one(T)))); S != T ? eigvals!(convert(typeof(A).name.primary{S}, A, l, h)) : eigvals!(copy(A), l, h)) eigmax(A::HermOrSym) = eigvals(A, size(A, 1), size(A, 1))[1] eigmin(A::HermOrSym) = eigvals(A, 1, 1)[1] diff --git a/base/linalg/umfpack.jl b/base/linalg/umfpack.jl index 0a618ea55042c..ed4e5b45e9283 100644 --- a/base/linalg/umfpack.jl +++ b/base/linalg/umfpack.jl @@ -131,9 +131,8 @@ function lufact!{Tv<:UMFVTypes,Ti<:UMFITypes}(S::SparseMatrixCSC{Tv,Ti}) end function show(io::IO, f::UmfpackLU) - @printf(io, "UMFPACK LU Factorization of a %d-by-%d sparse matrix\n", - f.m, f.n) - if f.numeric != C_NULL println(f.numeric) end + println(io, "UMFPACK LU Factorization of a $(f.m)-by-$(f.n) sparse matrix") + f.numeric != C_NULL && println(f.numeric) end ## Wrappers for UMFPACK functions diff --git a/base/math.jl b/base/math.jl index 7fb6a30ad3ea1..8570ec8b3553e 100644 --- a/base/math.jl +++ b/base/math.jl @@ -306,6 +306,11 @@ function hypot{T<:FloatingPoint}(x::T, y::T) r = y/one(x) else r = y/x + if isnan(r) + isinf(x) && return x + isinf(y) && return y + return r + end end x * sqrt(one(r)+r*r) end diff --git a/base/pointer.jl b/base/pointer.jl index 3e2debbaca24c..1c52dec7bb173 100644 --- a/base/pointer.jl +++ b/base/pointer.jl @@ -16,10 +16,12 @@ convert{T}(::Type{Ptr{T}}, p::Ptr) = box(Ptr{T}, unbox(Ptr,p)) # object to pointer convert(::Type{Ptr{Uint8}}, x::Symbol) = ccall(:jl_symbol_name, Ptr{Uint8}, (Any,), x) convert(::Type{Ptr{Int8}}, x::Symbol) = ccall(:jl_symbol_name, Ptr{Int8}, (Any,), x) -convert{T}(::Type{Ptr{T}}, a::Array) = ccall(:jl_array_ptr, Ptr{T}, (Any,), a) convert(::Type{Ptr{Uint8}}, s::ByteString) = convert(Ptr{Uint8}, s.data) convert(::Type{Ptr{Int8}}, s::ByteString) = convert(Ptr{Int8}, s.data) +convert{T}(::Type{Ptr{T}}, a::Array{T}) = ccall(:jl_array_ptr, Ptr{T}, (Any,), a) +convert(::Type{Ptr{None}}, a::Array) = ccall(:jl_array_ptr, Ptr{None}, (Any,), a) + pointer{T}(::Type{T}, x::Uint) = convert(Ptr{T}, x) pointer{T}(::Type{T}, x::Ptr) = convert(Ptr{T}, x) # note: these definitions don't mean any AbstractArray is convertible to diff --git a/base/printf.jl b/base/printf.jl index 5c90708a5da76..cfe1f4bd13925 100644 --- a/base/printf.jl +++ b/base/printf.jl @@ -4,21 +4,21 @@ export @printf, @sprintf ### printf formatter generation ### -function _gen(s::String) +function gen(s::String) args = {:(out::IO)} blk = Expr(:block, :(local neg, pt, len, exp)) - for x in _parse(s) + for x in parse(s) if isa(x,String) push!(blk.args, :(write(out, $(length(x)==1 ? x[1] : x)))) else c = lowercase(x[end]) - f = c=='f' ? _gen_f : - c=='e' ? _gen_e : - c=='g' ? _gen_g : - c=='c' ? _gen_c : - c=='s' ? _gen_s : - c=='p' ? _gen_p : - _gen_d + f = c=='f' ? gen_f : + c=='e' ? gen_e : + c=='g' ? gen_g : + c=='c' ? gen_c : + c=='s' ? gen_s : + c=='p' ? gen_p : + gen_d arg, ex = f(x...) push!(args, arg) push!(blk.args, ex) @@ -30,7 +30,7 @@ end ### printf format string parsing ### -function _parse(s::String) +function parse(s::String) # parse format string in to stings and format tuples list = {} i = j = start(s) @@ -38,8 +38,8 @@ function _parse(s::String) c, k = next(s,j) if c == '%' isempty(s[i:j-1]) || push!(list, s[i:j-1]) - flags, width, precision, conversion, k = _parse1(s,k) - in('\'',flags) && error("printf format flag ' not yet supported") + flags, width, precision, conversion, k = parse1(s,k) + '\'' in flags && error("printf format flag ' not yet supported") conversion == 'a' && error("printf feature %a not yet supported") conversion == 'n' && error("printf feature %n not supported") push!(list, conversion == '%' ? "%" : (flags,width,precision,conversion)) @@ -78,51 +78,51 @@ end # (h|hh|l|ll|L|j|t|z|q)? # modifier (ignored) # [diouxXeEfFgGaAcCsSp%] # conversion -_next_or_die(s::String, k) = !done(s,k) ? next(s,k) : +next_or_die(s::String, k) = !done(s,k) ? next(s,k) : error("invalid printf format string: ", repr(s)) -function _parse1(s::String, k::Integer) +function parse1(s::String, k::Integer) j = k width = 0 precision = -1 - c, k = _next_or_die(s,k) + c, k = next_or_die(s,k) # handle %% if c == '%' return "", width, precision, c, k end # parse flags - while in(c, "#0- + '") - c, k = _next_or_die(s,k) + while c in "#0- + '" + c, k = next_or_die(s,k) end flags = ascii(s[j:k-2]) # parse width while '0' <= c <= '9' width = 10*width + c-'0' - c, k = _next_or_die(s,k) + c, k = next_or_die(s,k) end # parse precision if c == '.' - c, k = _next_or_die(s,k) + c, k = next_or_die(s,k) if '0' <= c <= '9' precision = 0 while '0' <= c <= '9' precision = 10*precision + c-'0' - c, k = _next_or_die(s,k) + c, k = next_or_die(s,k) end end end # parse length modifer (ignored) if c == 'h' || c == 'l' prev = c - c, k = _next_or_die(s,k) + c, k = next_or_die(s,k) if c == prev - c, k = _next_or_die(s,k) + c, k = next_or_die(s,k) end - elseif in(c,"Ljqtz") - c, k = _next_or_die(s,k) + elseif c in "Ljqtz" + c, k = next_or_die(s,k) end # validate conversion - if !in(c,"diouxXDOUeEfFgGaAcCsSpn") + if !(c in "diouxXDOUeEfFgGaAcCsSpn") error("invalid printf format string: ", repr(s)) end # TODO: warn about silly flag/conversion combinations @@ -131,12 +131,12 @@ end ### printf formatter generation ### -function _special_handler(flags::ASCIIString, width::Int) +function special_handler(flags::ASCIIString, width::Int) @gensym x blk = Expr(:block) - pad = in('-',flags) ? rpad : lpad - pos = in('+',flags) ? "+" : - in(' ',flags) ? " " : "" + pad = '-' in flags ? rpad : lpad + pos = '+' in flags ? "+" : + ' ' in flags ? " " : "" abn = quote isnan($x) ? $(pad("NaN", width)) : $x < 0 ? $(pad("-Inf", width)) : @@ -146,7 +146,7 @@ function _special_handler(flags::ASCIIString, width::Int) x, ex, blk end -function _pad(m::Int, n, c::Char) +function pad(m::Int, n, c::Char) if m <= 1 :($n > 0 && write(out,$c)) else @@ -161,7 +161,7 @@ function _pad(m::Int, n, c::Char) end end -function _print_fixed(out, precision) +function print_fixed(out, precision) pdigits = pointer(DIGITS) ndigits = LEN[1] pt = POINT[1] @@ -198,7 +198,7 @@ function _print_fixed(out, precision) end end -function _print_exp(out, exp) +function print_exp(out, exp) write(out, exp < 0 ? '-' : '+') exp = abs(exp) d = div(exp,100) @@ -208,7 +208,7 @@ function _print_exp(out, exp) write(out, char('0'+rem(exp,10))) end -function _gen_d(flags::ASCIIString, width::Int, precision::Int, c::Char) +function gen_d(flags::ASCIIString, width::Int, precision::Int, c::Char) # print integer: # [dDiu]: print decimal digits # [o]: print octal digits @@ -222,32 +222,32 @@ function _gen_d(flags::ASCIIString, width::Int, precision::Int, c::Char) # ( ): precede non-negative values with " " # (+): precede non-negative values with "+" # - x, ex, blk = _special_handler(flags,width) + x, ex, blk = special_handler(flags,width) # interpret the number prefix = "" if lowercase(c)=='o' - f = in('#',flags) ? :_int_0ct : :_int_oct + f = '#' in flags ? :int_0ct : :int_oct push!(blk.args, :(($f)($x))) elseif c=='x' - if in('#',flags); prefix = "0x"; end - push!(blk.args, :(_int_hex($x))) + '#' in flags && (prefix = "0x") + push!(blk.args, :(int_hex($x))) elseif c=='X' - if in('#',flags); prefix = "0X"; end - push!(blk.args, :(_int_HEX($x))) + '#' in flags && (prefix = "0X") + push!(blk.args, :(int_HEX($x))) else - push!(blk.args, :(_int_dec($x))) + push!(blk.args, :(int_dec($x))) end push!(blk.args, :(neg = NEG[1])) push!(blk.args, :(pt = POINT[1])) # calculate padding width -= length(prefix) - space_pad = width > max(1,precision) && in('-',flags) || - precision < 0 && width > 1 && !in('0',flags) || + space_pad = width > max(1,precision) && '-' in flags || + precision < 0 && width > 1 && !('0' in flags) || precision >= 0 && width > precision padding = nothing if precision < 1; precision = 1; end if space_pad - if in('+',flags) || in(' ',flags) + if '+' in flags || ' ' in flags width -= 1 if width > precision padding = :($width-(pt > $precision ? pt : $precision)) @@ -259,36 +259,35 @@ function _gen_d(flags::ASCIIString, width::Int, precision::Int, c::Char) end end # print space padding - if padding != nothing && !in('-',flags) - push!(blk.args, _pad(width-precision, padding, ' ')) + if padding != nothing && !('-' in flags) + push!(blk.args, pad(width-precision, padding, ' ')) end # print sign - in('+',flags) ? push!(blk.args, :(write(out, neg?'-':'+'))) : - in(' ',flags) ? push!(blk.args, :(write(out, neg?'-':' '))) : - push!(blk.args, :(neg && write(out, '-'))) + '+' in flags ? push!(blk.args, :(write(out, neg?'-':'+'))) : + ' ' in flags ? push!(blk.args, :(write(out, neg?'-':' '))) : + push!(blk.args, :(neg && write(out, '-'))) # print prefix for ch in prefix push!(blk.args, :(write(out, $ch))) end # print zero padding & leading zeros if space_pad && precision > 1 - push!(blk.args, _pad(precision-1, :($precision-pt), '0')) + push!(blk.args, pad(precision-1, :($precision-pt), '0')) elseif !space_pad && width > 1 - zeros = in('+',flags) || in(' ',flags) ? - :($(width-1)-pt) : :($width-neg-pt) - push!(blk.args, _pad(width-1, zeros, '0')) + zeros = '+' in flags || ' ' in flags ? :($(width-1)-pt) : :($width-neg-pt) + push!(blk.args, pad(width-1, zeros, '0')) end # print integer push!(blk.args, :(write(out, pointer(DIGITS), pt))) # print padding - if padding != nothing && in('-',flags) - push!(blk.args, _pad(width-precision, padding, ' ')) + if padding != nothing && '-' in flags + push!(blk.args, pad(width-precision, padding, ' ')) end # return arg, expr :(($x)::Real), ex end -function _gen_f(flags::ASCIIString, width::Int, precision::Int, c::Char) +function gen_f(flags::ASCIIString, width::Int, precision::Int, c::Char) # print to fixed trailing precision # [fF]: the only choice # @@ -299,19 +298,19 @@ function _gen_f(flags::ASCIIString, width::Int, precision::Int, c::Char) # ( ): precede non-negative values with " " # (+): precede non-negative values with "+" # - x, ex, blk = _special_handler(flags,width) + x, ex, blk = special_handler(flags,width) # interpret the number if precision < 0; precision = 6; end - push!(blk.args, :(_fix_dec($x,$precision))) + push!(blk.args, :(fix_dec($x,$precision))) push!(blk.args, :(neg = NEG[1])) push!(blk.args, :(pt = POINT[1])) push!(blk.args, :(len = LEN[1])) # calculate padding padding = nothing - if precision > 0 || in('#',flags) + if precision > 0 || '#' in flags width -= precision+1 end - if in('+',flags) || in(' ',flags) + if '+' in flags || ' ' in flags width -= 1 if width > 1 padding = :($width-(pt > 0 ? pt : 1)) @@ -322,34 +321,34 @@ function _gen_f(flags::ASCIIString, width::Int, precision::Int, c::Char) end end # print space padding - if padding != nothing && !in('-',flags) && !in('0',flags) - push!(blk.args, _pad(width-1, padding, ' ')) + if padding != nothing && !('-' in flags) && !('0' in flags) + push!(blk.args, pad(width-1, padding, ' ')) end # print sign - in('+',flags) ? push!(blk.args, :(write(out, neg?'-':'+'))) : - in(' ',flags) ? push!(blk.args, :(write(out, neg?'-':' '))) : - push!(blk.args, :(neg && write(out, '-'))) + '+' in flags ? push!(blk.args, :(write(out, neg?'-':'+'))) : + ' ' in flags ? push!(blk.args, :(write(out, neg?'-':' '))) : + push!(blk.args, :(neg && write(out, '-'))) # print zero padding - if padding != nothing && !in('-',flags) && in('0',flags) - push!(blk.args, _pad(width-1, padding, '0')) + if padding != nothing && !('-' in flags) && '0' in flags + push!(blk.args, pad(width-1, padding, '0')) end # print digits if precision > 0 - push!(blk.args, :(_print_fixed(out,$precision))) + push!(blk.args, :(print_fixed(out,$precision))) else push!(blk.args, :(write(out, pointer(DIGITS), len))) push!(blk.args, :(while pt >= (len+=1) write(out,'0') end)) - in('#',flags) && push!(blk.args, :(write(out, '.'))) + '#' in flags && push!(blk.args, :(write(out, '.'))) end # print space padding - if padding != nothing && in('-',flags) - push!(blk.args, _pad(width-1, padding, ' ')) + if padding != nothing && '-' in flags + push!(blk.args, pad(width-1, padding, ' ')) end # return arg, expr :(($x)::Real), ex end -function _gen_e(flags::ASCIIString, width::Int, precision::Int, c::Char) +function gen_e(flags::ASCIIString, width::Int, precision::Int, c::Char) # print float in scientific form: # [e]: use 'e' to introduce exponent # [E]: use 'E' to introduce exponent @@ -361,22 +360,22 @@ function _gen_e(flags::ASCIIString, width::Int, precision::Int, c::Char) # ( ): precede non-negative values with " " # (+): precede non-negative values with "+" # - x, ex, blk = _special_handler(flags,width) + x, ex, blk = special_handler(flags,width) # interpret the number if precision < 0; precision = 6; end ndigits = min(precision+1,BUFLEN-1) - push!(blk.args, :(_ini_dec($x,$ndigits))) + push!(blk.args, :(ini_dec($x,$ndigits))) push!(blk.args, :(neg = NEG[1])) push!(blk.args, :(exp = POINT[1]-1)) expmark = c=='E' ? "E" : "e" - if precision==0 && in('#',flags) + if precision==0 && '#' in flags expmark = string(".",expmark) end # calculate padding padding = nothing width -= precision+length(expmark)+(precision>0)+4 # 4 = leading + expsign + 2 exp digits - if in('+',flags) || in(' ',flags) + if '+' in flags || ' ' in flags width -= 1 # for the sign indicator if width > 0 padding = :($width-((exp<=-100)|(100<=exp))) @@ -387,16 +386,16 @@ function _gen_e(flags::ASCIIString, width::Int, precision::Int, c::Char) end end # print space padding - if padding != nothing && !in('-',flags) && !in('0',flags) - push!(blk.args, _pad(width, padding, ' ')) + if padding != nothing && !('-' in flags) && !('0' in flags) + push!(blk.args, pad(width, padding, ' ')) end # print sign - in('+',flags) ? push!(blk.args, :(write(out, neg?'-':'+'))) : - in(' ',flags) ? push!(blk.args, :(write(out, neg?'-':' '))) : + '+' in flags ? push!(blk.args, :(write(out, neg?'-':'+'))) : + ' ' in flags ? push!(blk.args, :(write(out, neg?'-':' '))) : push!(blk.args, :(neg && write(out, '-'))) # print zero padding - if padding != nothing && !in('-',flags) && in('0',flags) - push!(blk.args, _pad(width, padding, '0')) + if padding != nothing && !('-' in flags) && '0' in flags + push!(blk.args, pad(width, padding, '0')) end # print digits push!(blk.args, :(write(out, DIGITS[1]))) @@ -405,22 +404,22 @@ function _gen_e(flags::ASCIIString, width::Int, precision::Int, c::Char) push!(blk.args, :(write(out, pointer(DIGITS)+1, $(ndigits-1)))) if ndigits < precision+1 n = precision+1-ndigits - push!(blk.args, _pad(n, n, '0')) + push!(blk.args, pad(n, n, '0')) end end for ch in expmark push!(blk.args, :(write(out, $ch))) end - push!(blk.args, :(_print_exp(out, exp))) + push!(blk.args, :(print_exp(out, exp))) # print space padding - if padding != nothing && in('-',flags) - push!(blk.args, _pad(width, padding, ' ')) + if padding != nothing && '-' in flags + push!(blk.args, pad(width, padding, ' ')) end # return arg, expr :(($x)::Real), ex end -function _gen_c(flags::ASCIIString, width::Int, precision::Int, c::Char) +function gen_c(flags::ASCIIString, width::Int, precision::Int, c::Char) # print a character: # [cC]: both the same for us (Unicode) # @@ -430,18 +429,18 @@ function _gen_c(flags::ASCIIString, width::Int, precision::Int, c::Char) # @gensym x blk = Expr(:block, :($x = char($x))) - if width > 1 && !in('-',flags) - p = in('0',flags) ? '0' : ' ' - push!(blk.args, _pad(width-1, :($width-charwidth($x)), p)) + if width > 1 && !('-' in flags) + p = '0' in flags ? '0' : ' ' + push!(blk.args, pad(width-1, :($width-charwidth($x)), p)) end push!(blk.args, :(write(out, $x))) - if width > 1 && in('-',flags) - push!(blk.args, _pad(width-1, :($width-charwidth($x)), ' ')) + if width > 1 && '-' in flags + push!(blk.args, pad(width-1, :($width-charwidth($x)), ' ')) end :(($x)::Integer), blk end -function _gen_s(flags::ASCIIString, width::Int, precision::Int, c::Char) +function gen_s(flags::ASCIIString, width::Int, precision::Int, c::Char) # print a string: # [sS]: both the same for us (Unicode) # @@ -452,20 +451,20 @@ function _gen_s(flags::ASCIIString, width::Int, precision::Int, c::Char) @gensym x blk = Expr(:block) if width > 0 - if !in('#',flags) + if !('#' in flags) push!(blk.args, :($x = string($x))) else push!(blk.args, :($x = repr($x))) end - if !in('-',flags) - push!(blk.args, _pad(width, :($width-strwidth($x)), ' ')) + if !('-' in flags) + push!(blk.args, pad(width, :($width-strwidth($x)), ' ')) end push!(blk.args, :(write(out, $x))) - if in('-',flags) - push!(blk.args, _pad(width, :($width-strwidth($x)), ' ')) + if '-' in flags + push!(blk.args, pad(width, :($width-strwidth($x)), ' ')) end else - if !in('#',flags) + if !('#' in flags) push!(blk.args, :(print(out, $x))) else push!(blk.args, :(show(out, $x))) @@ -476,7 +475,7 @@ end # TODO: faster pointer printing. -function _gen_p(flags::ASCIIString, width::Int, precision::Int, c::Char) +function gen_p(flags::ASCIIString, width::Int, precision::Int, c::Char) # print pointer: # [p]: the only option # @@ -484,27 +483,27 @@ function _gen_p(flags::ASCIIString, width::Int, precision::Int, c::Char) blk = Expr(:block) ptrwidth = WORD_SIZE>>2 width -= ptrwidth+2 - if width > 0 && !in('-',flags) - push!(blk.args, _pad(width, width, ' ')) + if width > 0 && !('-' in flags) + push!(blk.args, pad(width, width, ' ')) end push!(blk.args, :(write(out, '0'))) push!(blk.args, :(write(out, 'x'))) push!(blk.args, :(write(out, bytestring(hex(unsigned($x), $ptrwidth))))) - if width > 0 && in('-',flags) - push!(blk.args, _pad(width, width, ' ')) + if width > 0 && '-' in flags + push!(blk.args, pad(width, width, ' ')) end :(($x)::Ptr), blk end -function _gen_g(flags::ASCIIString, width::Int, precision::Int, c::Char) +function gen_g(flags::ASCIIString, width::Int, precision::Int, c::Char) error("printf \"%g\" format specifier not implemented") end ### core unsigned integer decoding functions ### -macro _handle_zero() +macro handle_zero(ex) quote - if $(esc(:x)) == 0 + if $(esc(ex)) == 0 POINT[1] = 1 DIGITS[1] = '0' return @@ -512,8 +511,8 @@ macro _handle_zero() end end -function _decode_oct(x::Unsigned) - @_handle_zero +function decode_oct(x::Unsigned) + @handle_zero x POINT[1] = i = div((sizeof(x)<<3)-leading_zeros(x)+2,3) while i > 0 DIGITS[i] = '0'+(x&0x7) @@ -522,7 +521,8 @@ function _decode_oct(x::Unsigned) end end -function _decode_0ct(x::Unsigned) +function decode_0ct(x::Unsigned) + # doesn't need special handling for zero POINT[1] = i = div((sizeof(x)<<3)-leading_zeros(x)+5,3) while i > 0 DIGITS[i] = '0'+(x&0x7) @@ -531,8 +531,8 @@ function _decode_0ct(x::Unsigned) end end -function _decode_dec(x::Unsigned) - @_handle_zero +function decode_dec(x::Unsigned) + @handle_zero x POINT[1] = i = Base.ndigits0z(x) while i > 0 DIGITS[i] = '0'+rem(x,10) @@ -541,8 +541,8 @@ function _decode_dec(x::Unsigned) end end -function _decode_hex(x::Unsigned, symbols::Array{Uint8,1}) - @_handle_zero +function decode_hex(x::Unsigned, symbols::Array{Uint8,1}) + @handle_zero x POINT[1] = i = (sizeof(x)<<1)-(leading_zeros(x)>>2) while i > 0 DIGITS[i] = symbols[(x&0xf)+1] @@ -551,18 +551,43 @@ function _decode_hex(x::Unsigned, symbols::Array{Uint8,1}) end end -const _hex_symbols = "0123456789abcdef".data -const _HEX_symbols = "0123456789ABCDEF".data +const hex_symbols = "0123456789abcdef".data +const HEX_symbols = "0123456789ABCDEF".data + +decode_hex(x::Unsigned) = decode_hex(x,hex_symbols) +decode_HEX(x::Unsigned) = decode_hex(x,HEX_symbols) -_decode_hex(x::Unsigned) = _decode_hex(x,_hex_symbols) -_decode_HEX(x::Unsigned) = _decode_hex(x,_HEX_symbols) +function decode(b::Int, x::BigInt) + neg = NEG[1] = x.size < 0 + pt = POINT[1] = Base.ndigits(x, abs(b)) + length(DIGITS) < pt+1 && resize!(DIGITS, pt+1) + neg && (x.size = -x.size) + ccall((:__gmpz_get_str, :libgmp), Ptr{Uint8}, + (Ptr{Uint8}, Cint, Ptr{BigInt}), DIGITS, b, &x) + neg && (x.size = -x.size) +end + +function decode_0ct(x::BigInt) + neg = NEG[1] = x.size < 0 + DIGITS[1] = '0' + if x.size == 0 + POINT[1] = 1 + return + end + pt = POINT[1] = Base.ndigits0z(x, 8) + 1 + length(DIGITS) < pt+1 && resize!(DIGITS, pt+1) + neg && (x.size = -x.size) + p = convert(Ptr{Uint8}, DIGITS) + 1 + ccall((:__gmpz_get_str, :libgmp), Ptr{Uint8}, + (Ptr{Uint8}, Cint, Ptr{BigInt}), p, 8, &x) + neg && (x.size = -x.size) +end ### decoding functions directly used by printf generated code ### # int_*(x) => fixed precision, to 0th place, filled out # fix_*(x,n) => fixed precision, to nth place, not filled out # ini_*(x,n) => n initial digits, filled out -# sig_*(x,n) => n initial digits, zero-stripped # alternate versions: # *_0ct(x,n) => ensure that the first octal digits is zero @@ -575,36 +600,38 @@ _decode_HEX(x::Unsigned) = _decode_hex(x,_HEX_symbols) # - implies len[1] = point[1] # -_int_oct(x::Unsigned) = (NEG[1]=false; _decode_oct(x)) -_int_0ct(x::Unsigned) = (NEG[1]=false; _decode_0ct(x)) -_int_dec(x::Unsigned) = (NEG[1]=false; _decode_dec(x)) -_int_hex(x::Unsigned) = (NEG[1]=false; _decode_hex(x)) -_int_HEX(x::Unsigned) = (NEG[1]=false; _decode_HEX(x)) +int_oct(x::Unsigned) = (NEG[1]=false; decode_oct(x)) +int_0ct(x::Unsigned) = (NEG[1]=false; decode_0ct(x)) +int_dec(x::Unsigned) = (NEG[1]=false; decode_dec(x)) +int_hex(x::Unsigned) = (NEG[1]=false; decode_hex(x)) +int_HEX(x::Unsigned) = (NEG[1]=false; decode_HEX(x)) -macro _handle_negative() +macro handle_negative() quote if $(esc(:x)) < 0 NEG[1] = true - $(esc(:x)) = -$(esc(:x)) + $(esc(:x)) = oftype($(esc(:x)),-$(esc(:x))) else NEG[1] = false end end end -_int_oct(x::Integer) = (@_handle_negative; _decode_oct(unsigned(x))) -_int_0ct(x::Integer) = (@_handle_negative; _decode_0ct(unsigned(x))) -_int_dec(x::Integer) = (@_handle_negative; _decode_dec(unsigned(x))) -_int_hex(x::Integer) = (@_handle_negative; _decode_hex(unsigned(x))) -_int_HEX(x::Integer) = (@_handle_negative; _decode_HEX(unsigned(x))) +int_oct(x::Integer) = (@handle_negative; decode_oct(unsigned(x))) +int_0ct(x::Integer) = (@handle_negative; decode_0ct(unsigned(x))) +int_dec(x::Integer) = (@handle_negative; decode_dec(unsigned(x))) +int_hex(x::Integer) = (@handle_negative; decode_hex(unsigned(x))) +int_HEX(x::Integer) = (@handle_negative; decode_HEX(unsigned(x))) -_int_oct(x::Real) = _int_oct(integer(x)) # TODO: real float decoding. -_int_0ct(x::Real) = _int_0ct(integer(x)) # TODO: real float decoding. -_int_dec(x::Real) = _int_dec(float(x)) -_int_hex(x::Real) = _int_hex(integer(x)) # TODO: real float decoding. -_int_HEX(x::Real) = _int_HEX(integer(x)) # TODO: real float decoding. +int_oct(x::BigInt) = decode(8, x) +int_0ct(x::BigInt) = decode_0ct(x) +int_dec(x::BigInt) = decode(10, x) +int_hex(x::BigInt) = decode(16, x) +int_HEX(x::BigInt) = decode(-16, x) -function _int_dec(x::FloatingPoint) +const SmallFloatingPoint = Union(Float64,Float32,Float16) + +function int_dec(x::SmallFloatingPoint) if x == 0.0 NEG[1] = false POINT[1] = 1 @@ -623,6 +650,12 @@ function _int_dec(x::FloatingPoint) end end +int_oct(x::Real) = int_oct(integer(x)) # TODO: real float decoding. +int_0ct(x::Real) = int_0ct(integer(x)) # TODO: real float decoding. +int_dec(x::Real) = int_dec(float(x)) +int_hex(x::Real) = int_hex(integer(x)) # TODO: real float decoding. +int_HEX(x::Real) = int_HEX(integer(x)) # TODO: real float decoding. + ## fix decoding functions ## # # - sets neg[1] @@ -630,10 +663,10 @@ end # - sets len[1]; if less than point[1], trailing zeros implied # -_fix_dec(x::Integer, n::Int) = (_int_dec(x); LEN[1]=POINT[1]) -_fix_dec(x::Real, n::Int) = _fix_dec(float(x),n) +fix_dec(x::Integer, n::Int) = (int_dec(x); LEN[1]=POINT[1]) +fix_dec(x::Real, n::Int) = fix_dec(float(x),n) -function _fix_dec(x::FloatingPoint, n::Int) +function fix_dec(x::SmallFloatingPoint, n::Int) if n > BUFLEN-1; n = BUFLEN-1; end @grisu_ccall x Grisu.FIXED n if LEN[1] == 0 @@ -650,7 +683,7 @@ end # - implies len[1] = n (requested digits) # -function _ini_dec(x::Unsigned, n::Int) +function ini_dec(x::Unsigned, n::Int) k = ndigits(x) if k <= n POINT[1] = k @@ -680,83 +713,41 @@ function _ini_dec(x::Unsigned, n::Int) end end -_ini_dec(x::Integer, n::Int) = (@_handle_negative; _ini_dec(unsigned(x),n)) -_ini_dec(x::Real, n::Int) = _ini_dec(float(x),n) +ini_dec(x::Integer, n::Int) = (@handle_negative; ini_dec(unsigned(x),n)) +ini_dec(x::Real, n::Int) = ini_dec(float(x),n) -function _ini_dec(x::FloatingPoint, n::Int) +function ini_dec(x::SmallFloatingPoint, n::Int) if x == 0.0 POINT[1] = 1 NEG[1] = signbit(x) - ccall(:memset, Ptr{Void}, (Ptr{Void}, Int32, Csize_t), DIGITS, '0', n) + ccall(:memset, Ptr{Void}, (Ptr{Void}, Cint, Csize_t), DIGITS, '0', n) else @grisu_ccall x Grisu.PRECISION n end end -## sig decoding functions ## -# -# - sets neg[1] -# - sets point[1] -# - sets len[1] -# - -function _sig_dec(x::Unsigned, n::Int) - if x == 0 - NEG[1] = false +function ini_dec(x::BigInt, n::Int) + if x.size == 0 POINT[1] = 1 - LEN[1] = 1 - DIGITS[1] = '0' - return - end - k = Base.ndigits0z(x) - if k <= n - POINT[1] = k - for i = k:-1:1 - DIGITS[i] = '0'+rem(x,10) - x = div(x,10) - end - while DIGITS[k] == '0' - k -= 1 - end - LEN[1] = k + NEG[1] = false + ccall(:memset, Ptr{Void}, (Ptr{Void}, Cint, Csize_t), DIGITS, '0', n) else - p = Base.powers_of_ten[k-n+1] - r = rem(x,p) - if r >= (p>>1) - x += p - if x >= Base.powers_of_ten[k+1] - p *= 10 - k += 1 - end - end - POINT[1] = k - x = div(x,p) - for i = n:-1:1 - DIGITS[i] = '0'+rem(x,10) - x = div(x,10) - end - while DIGITS[n] == '0' - n -= 1 + d = Base.ndigits0z(x) + if d <= n + int_dec(x) + d == n && return + p = convert(Ptr{Void}, DIGITS) + POINT[1] + ccall(:memset, Ptr{Void}, (Ptr{Void}, Cint, Csize_t), p, '0', n - POINT[1]) + else + int_dec(iround(x/big(10)^(d-n))) + POINT[1] = d end - LEN[1] = n - end -end - -_sig_dec(x::Integer, n::Int) = (@_handle_negative; _sig_dec(unsigned(x),n)) -_sig_dec(x::Real, n::Int) = _sig_dec(float(x),n) - -function _sig_dec(x::FloatingPoint, n::Int) - @grisu_ccall x Grisu.PRECISION n - if x == 0.0; return; end - while DIGITS[n] == '0' - n -= 1 end - LEN[1] = n end ### external printf interface ### -_is_str_expr(ex) = +is_str_expr(ex) = isa(ex,Expr) && ex.head==:macrocall && isa(ex.args[1],Symbol) && (ex.args[1] == :str || endswith(string(ex.args[1]),"_str")) @@ -765,7 +756,7 @@ macro printf(args...) error("@printf: called with zero arguments") end if !isa(args[1],String) && !(length(args) > 1 && isa(args[2],String)) - if _is_str_expr(args[1]) || length(args) > 1 && _is_str_expr(args[2]) + if is_str_expr(args[1]) || length(args) > 1 && is_str_expr(args[2]) error("format must be a plain static string (no interpolation or prefix)") end error("first or second argument must be a format string") @@ -781,7 +772,7 @@ macro printf(args...) args = args[3:end] end args = {io,args...} - sym_args, blk = _gen(fmt) + sym_args, blk = gen(fmt) if length(sym_args) != length(args) error("@printf: wrong number of arguments") end diff --git a/base/random.jl b/base/random.jl index 9d58096ff816a..199c178e2bf9b 100644 --- a/base/random.jl +++ b/base/random.jl @@ -14,26 +14,13 @@ type MersenneTwister <: AbstractRNG state::DSFMT_state seed::Union(Uint32,Vector{Uint32}) - function MersenneTwister() - seed = uint32(0) - state = DSFMT_state() - dsfmt_init_gen_rand(state, seed) - return new(state, seed) - end - - function MersenneTwister(seed::Uint32) - state = DSFMT_state() - dsfmt_init_gen_rand(state, seed) - return new(state, seed) - end - function MersenneTwister(seed::Vector{Uint32}) state = DSFMT_state() dsfmt_init_by_array(state, seed) return new(state, seed) end - MersenneTwister(seed) = MersenneTwister(reinterpret(Uint32, [seed])) + MersenneTwister(seed=0) = MersenneTwister(make_seed(seed)) end function srand(r::MersenneTwister, seed) diff --git a/base/show.jl b/base/show.jl index 4c8d7b1d8f917..e6c05a28a6259 100644 --- a/base/show.jl +++ b/base/show.jl @@ -412,18 +412,27 @@ function show_unquoted(io::IO, ex::Expr, indent::Int, prec::Int) # binary operator (i.e. "x + y") elseif func in bin_ops - sep = func_prec >= bin_op_precs[:(^)] ? "$func" : " $func " - if func_prec <= prec - show_enclosed_list(io, '(', func_args, sep, ')', indent, func_prec) + if length(func_args) > 1 + sep = func_prec >= bin_op_precs[:(^)] ? "$func" : " $func " + if func_prec <= prec + show_enclosed_list(io, '(', func_args, sep, ')', indent, func_prec) + else + show_list(io, func_args, sep, indent, func_prec) + end else - show_list(io, func_args, sep, indent, func_prec) + # 1-argument call to normally-binary operator + op, cl = expr_calls[head] + print(io, "(") + show_unquoted(io, func, indent) + print(io, ")") + show_enclosed_list(io, op, func_args, ",", cl, indent) end # normal function (i.e. "f(x,y)") else op, cl = expr_calls[head] - show_unquoted(io, args[1], indent) - show_enclosed_list(io, op, args[2:end], ",", cl, indent) + show_unquoted(io, func, indent) + show_enclosed_list(io, op, func_args, ",", cl, indent) end elseif is(head, :ccall) show_unquoted(io, :ccall, indent) diff --git a/base/sparse/sparsematrix.jl b/base/sparse/sparsematrix.jl index 6694d7fff5084..c2d81286d29b2 100644 --- a/base/sparse/sparsematrix.jl +++ b/base/sparse/sparsematrix.jl @@ -353,9 +353,12 @@ function findnz{Tv,Ti}(S::SparseMatrixCSC{Tv,Ti}) return (I, J, V) end -function sprand(m::Integer, n::Integer, density::FloatingPoint, rng::Function, v) +truebools(n::Integer) = ones(Bool, n) +function sprand{T}(m::Integer, n::Integer, density::FloatingPoint, rng::Function,::Type{T}=eltype(rng(1))) 0 <= density <= 1 || throw(ArgumentError("density must be between 0 and 1")) N = n*m + N == 0 && return spzeros(T,m,n) + N == 1 && return rand() <= density ? sparse(rng(1)) : spzeros(T,1,1) # if density < 0.5, we'll randomly generate the indices to set # otherwise, we'll randomly generate the indices to skip K = (density > 0.5) ? N*(1-density) : N*density @@ -370,7 +373,7 @@ function sprand(m::Integer, n::Integer, density::FloatingPoint, rng::Function, v sizehint(uind, int(N*density)) if density < 0.5 if ik == 0 - return sparse(Int[],Int[],Array(eltype(v),0),m,n) + return sparse(Int[],Int[],Array(T,0),m,n) end j = ind[1] push!(uind, j) @@ -396,17 +399,11 @@ function sprand(m::Integer, n::Integer, density::FloatingPoint, rng::Function, v end end I, J = ind2sub((m,n), uind) - if !iseltype(v,Bool) - return sparse_IJ_sorted!(I, J, rng(length(uind)), m, n, +) # it will never need to combine - else - return sparse_IJ_sorted!(I, J, ones(Bool, length(uind)), m, n, +) - end + return sparse_IJ_sorted!(I, J, rng(length(uind)), m, n, +) # it will never need to combine end - -sprand(m::Integer, n::Integer, density::FloatingPoint, rng::Function) = sprand(m,n,density,rng, 1.0) -sprand(m::Integer, n::Integer, density::FloatingPoint) = sprand(m,n,density,rand, 1.0) -sprandn(m::Integer, n::Integer, density::FloatingPoint) = sprand(m,n,density,randn, 1.0) -sprandbool(m::Integer, n::Integer, density::FloatingPoint) = sprand(m,n,density,randbool, true) +sprand(m::Integer, n::Integer, density::FloatingPoint) = sprand(m,n,density,rand,Float64) +sprandn(m::Integer, n::Integer, density::FloatingPoint) = sprand(m,n,density,randn,Float64) +sprandbool(m::Integer, n::Integer, density::FloatingPoint) = sprand(m,n,density,truebools,Bool) spones{T}(S::SparseMatrixCSC{T}) = SparseMatrixCSC(S.m, S.n, copy(S.colptr), copy(S.rowval), ones(T, S.colptr[end]-1)) diff --git a/base/stream.jl b/base/stream.jl index ece519f915a08..397f2b78b0f4d 100644 --- a/base/stream.jl +++ b/base/stream.jl @@ -415,23 +415,6 @@ type SingleAsyncWork <: AsyncWork end end -type IdleAsyncWork <: AsyncWork - handle::Ptr{Void} - cb::Function - function IdleAsyncWork(cb::Function) - this = new(c_malloc(_sizeof_uv_idle), cb) - disassociate_julia_struct(this) - err = ccall(:uv_idle_init,Cint,(Ptr{Void},Ptr{Void}),eventloop(),this) - if err != 0 - c_free(this.handle) - this.handle = C_NULL - error(UVError("uv_make_timer",err)) - end - finalizer(this,uvfinalize) - this - end -end - type Timer <: AsyncWork handle::Ptr{Void} cb::Function @@ -442,7 +425,7 @@ type Timer <: AsyncWork # ->data field disassociate_julia_struct(this.handle) err = ccall(:uv_timer_init,Cint,(Ptr{Void},Ptr{Void}),eventloop(),this.handle) - if err != 0 + if err != 0 c_free(this.handle) this.handle = C_NULL error(UVError("uv_make_timer",err)) @@ -476,28 +459,27 @@ function _uv_hook_asynccb(async::AsyncWork, status::Int32) end try async.cb(async, status) - catch err - #bt = catch_backtrace() - if isa(err, MethodError) - warn_once("async callbacks should take an AsyncWork object as the first argument") - async.cb(status) - return - end - rethrow(err) + catch end nothing end function start_timer(timer::Timer, timeout::Real, repeat::Real) associate_julia_struct(timer.handle, timer) + preserve_handle(timer) ccall(:uv_update_time,Void,(Ptr{Void},),eventloop()) ccall(:uv_timer_start,Cint,(Ptr{Void},Ptr{Void},Uint64,Uint64), - timer.handle, uv_jl_asynccb::Ptr{Void}, uint64(round(timeout*1000))+1, uint64(round(repeat*1000))) + timer.handle, uv_jl_asynccb::Ptr{Void}, uint64(round(timeout*1000))+1, uint64(round(repeat*1000))) end function stop_timer(timer::Timer) + # ignore multiple calls to stop_timer + !haskey(uvhandles, timer) && return + timer.handle == C_NULL && return + ccall(:uv_timer_stop,Cint,(Ptr{Void},),timer.handle) disassociate_julia_struct(timer.handle) + unpreserve_handle(timer) end function sleep(sec::Real) @@ -518,17 +500,6 @@ function sleep(sec::Real) nothing end -function add_idle_cb(cb::Function) - work = IdleAsyncWork(cb) - associate_julia_struct(work.handle, work) - ccall(:uv_idle_start,Cint,(Ptr{Void},Ptr{Void}),work.handle,uv_jl_asynccb::Ptr{Void}) - work -end - -function queueAsync(work::SingleAsyncWork) - ccall(:uv_async_send,Cint,(Ptr{Void},),work.handle) -end - ## event loop ## eventloop() = global uv_eventloop::Ptr{Void} #mkNewEventLoop() = ccall(:jl_new_event_loop,Ptr{Void},()) # this would probably be fine, but is nowhere supported @@ -620,7 +591,7 @@ function start_reading(stream::AsyncStream) error("tried to read a stream that is not readable") end ret = ccall(:uv_read_start,Cint,(Ptr{Void},Ptr{Void},Ptr{Void}), - handle(stream),uv_jl_alloc_buf::Ptr{Void},uv_jl_readcb::Ptr{Void}) + handle(stream),uv_jl_alloc_buf::Ptr{Void},uv_jl_readcb::Ptr{Void}) stream.status = StatusActive ret elseif stream.status == StatusActive @@ -862,7 +833,7 @@ const BACKLOG_DEFAULT = 511 function _listen(sock::UVServer; backlog::Integer=BACKLOG_DEFAULT) err = ccall(:uv_listen, Cint, (Ptr{Void}, Cint, Ptr{Void}), - sock.handle, backlog, uv_jl_connectioncb::Ptr{Void}) + sock.handle, backlog, uv_jl_connectioncb::Ptr{Void}) sock.status = StatusActive err end @@ -870,8 +841,8 @@ end function bind(server::PipeServer, name::ASCIIString) @assert server.status == StatusInit err = ccall(:uv_pipe_bind, Int32, (Ptr{Void}, Ptr{Uint8}), - server.handle, name) - if err != 0 + server.handle, name) + if err != 0 if err != UV_EADDRINUSE && err != UV_EACCES error(UVError("bind",err)) else diff --git a/base/sysimg.jl b/base/sysimg.jl index af56b2379e4bf..265b3ef0c3134 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -109,8 +109,6 @@ importall .Multimedia ccall(:jl_get_uv_hooks, Void, (Cint,), 0) include("grisu.jl") import .Grisu.print_shortest -include("printf.jl") -importall .Printf include("file.jl") include("methodshow.jl") @@ -181,8 +179,6 @@ include("mmap.jl") include("sharedarray.jl") # utilities - version, timing, help, edit, metaprogramming -include("sysinfo.jl") -import .Sys.CPU_CORES include("version.jl") include("datafmt.jl") include("deepcopy.jl") @@ -223,6 +219,14 @@ big(q::Rational) = big(num(q))//big(den(q)) big(z::Complex) = complex(big(real(z)),big(imag(z))) @vectorize_1arg Number big +# (s)printf macros +include("printf.jl") +importall .Printf + +# system information +include("sysinfo.jl") +import .Sys.CPU_CORES + # mathematical constants include("constants.jl") diff --git a/base/test.jl b/base/test.jl index 5c531522a844e..a4e6581e33fcb 100644 --- a/base/test.jl +++ b/base/test.jl @@ -61,9 +61,25 @@ macro test_fails(ex) :(@test_throws $ex) end +approx_full(x::StoredArray) = x +approx_full(x::Number) = x +approx_full(x) = full(x) + function test_approx_eq(va, vb, Eps, astr, bstr) - diff = maximum(abs(va - vb)) - if diff > Eps + va = approx_full(va) + vb = approx_full(vb) + diff = real(zero(eltype(va))) + ok = true + for i = 1:length(va) + xa = va[i]; xb = vb[i] + if isfinite(xa) && isfinite(xb) + diff = max(diff, abs(xa-xb)) + elseif !isequal(xa,xb) + ok = false; break + end + end + + if !ok || (!isnan(Eps) && !(diff <= Eps)) sdiff = string("|", astr, " - ", bstr, "| <= ", Eps) error("assertion failed: ", sdiff, "\n ", astr, " = ", va, @@ -72,8 +88,10 @@ function test_approx_eq(va, vb, Eps, astr, bstr) end end +array_eps(a) = eps(float(maximum(x->(isfinite(x) ? abs(x) : nan(x)), a))) + test_approx_eq(va, vb, astr, bstr) = - test_approx_eq(va, vb, 1E4*length(va)*max(eps(float(maximum(abs(va)))), eps(float(maximum(abs(vb))))), astr, bstr) + test_approx_eq(va, vb, 1E4*length(va)*max(array_eps(va), array_eps(vb)), astr, bstr) macro test_approx_eq_eps(a, b, c) :(test_approx_eq($(esc(a)), $(esc(b)), $(esc(c)), $(string(a)), $(string(b)))) diff --git a/deps/Makefile b/deps/Makefile index e6f277e518fe9..9898d385b5b1d 100644 --- a/deps/Makefile +++ b/deps/Makefile @@ -826,6 +826,8 @@ else ifeq ($(ARCH),i387) OPENBLAS_BUILD_OPTS += BINARY=32 else ifeq ($(ARCH),i486) OPENBLAS_BUILD_OPTS += BINARY=32 +else ifeq ($(ARCH),i586) +OPENBLAS_BUILD_OPTS += BINARY=32 else ifeq ($(ARCH),i686) OPENBLAS_BUILD_OPTS += BINARY=32 else ifeq ($(ARCH),x86_64) diff --git a/doc/manual/calling-c-and-fortran-code.rst b/doc/manual/calling-c-and-fortran-code.rst index ff5cb1b494f1f..77664853f96f6 100644 --- a/doc/manual/calling-c-and-fortran-code.rst +++ b/doc/manual/calling-c-and-fortran-code.rst @@ -192,16 +192,20 @@ When a scalar value is passed with ``&`` as an argument of type Array conversions ~~~~~~~~~~~~~~~~~ -When an ``Array`` is passed to C as a ``Ptr`` argument, it is -"converted" simply by taking the address of the first element. This is -done in order to avoid copying arrays unnecessarily, and to tolerate the -slight mismatches in pointer types that are often encountered in C APIs -(for example, passing a ``Float64`` array to a function that operates on -uninterpreted bytes). +When an ``Array{T}`` is passed to C as a ``Ptr{T}`` or ``Ptr{Void}`` +argument, it is "converted" simply by taking the address of the first +element. This is done in order to avoid copying arrays unnecessarily. Therefore, if an ``Array`` contains data in the wrong format, it will have to be explicitly converted using a call such as ``int32(a)``. +To pass an array ``A`` as a pointer of a different type *without* +converting the data (for example, to pass a ``Float64`` array to a +function that operates on uninterpreted bytes), you can either declare +the argument as ``Ptr{Void}`` or you can explicitly call +``convert(Ptr{T}, pointer(A))``. + + Type correspondences ~~~~~~~~~~~~~~~~~~~~ diff --git a/src/codegen.cpp b/src/codegen.cpp index 7282268bc9612..ebed2ab9110f4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2350,11 +2350,24 @@ static Value *emit_expr(jl_value_t *expr, jl_codectx_t *ctx, bool isboxed, if (head == goto_ifnot_sym) { jl_value_t *cond = args[0]; int labelname = jl_unbox_long(args[1]); - Value *isfalse = emit_condition(cond, "if", ctx); BasicBlock *ifso = BasicBlock::Create(getGlobalContext(), "if", ctx->f); BasicBlock *ifnot = (*ctx->labels)[labelname]; assert(ifnot); - builder.CreateCondBr(isfalse, ifnot, ifso); + // NOTE: if type inference sees a constant condition it behaves as if + // the branch weren't there. But LLVM will not see constant conditions + // this way until a later optimization pass, so it might see one of our + // SSA vars as not dominating all uses. see issue #6068 + // Work around this by generating unconditional branches. + if (cond == jl_true) { + builder.CreateBr(ifso); + } + else if (cond == jl_false) { + builder.CreateBr(ifnot); + } + else { + Value *isfalse = emit_condition(cond, "if", ctx); + builder.CreateCondBr(isfalse, ifnot, ifso); + } builder.SetInsertPoint(ifso); } diff --git a/src/interpreter.c b/src/interpreter.c index c47e7137ae0bb..b7ef108e8f656 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -501,13 +501,13 @@ static jl_value_t *eval_body(jl_array_t *stmts, jl_value_t **locals, size_t nl, else if (head == enter_sym) { jl_enter_handler(&__eh); if (!jl_setjmp(__eh.eh_ctx,1)) { + return eval_body(stmts, locals, nl, i+1, toplevel); + } + else { #ifdef _OS_WINDOWS_ if (jl_exception_in_transit == jl_stackovf_exception) _resetstkoflw(); #endif - return eval_body(stmts, locals, nl, i+1, toplevel); - } - else { i = label_idx(jl_exprarg(stmt,0), stmts); continue; } diff --git a/src/jl_uv.c b/src/jl_uv.c index cd394dae5b0f9..2b7bd58d585d2 100644 --- a/src/jl_uv.c +++ b/src/jl_uv.c @@ -181,12 +181,15 @@ DLLEXPORT void jl_uv_readcb(uv_stream_t *handle, ssize_t nread, const uv_buf_t* DLLEXPORT void jl_uv_alloc_buf(uv_handle_t *handle, size_t suggested_size, uv_buf_t* buf) { - JULIA_CB(alloc_buf,handle->data,1,CB_INT32,suggested_size); - if (!jl_is_tuple(ret) || !jl_is_pointer(jl_t0(ret)) || !jl_is_int32(jl_t1(ret))) { - jl_error("jl_alloc_buf: Julia function returned invalid value for buffer allocation callback"); + if (handle->data) { + JULIA_CB(alloc_buf,handle->data,1,CB_INT32,suggested_size); + assert(jl_is_tuple(ret) && jl_is_pointer(jl_t0(ret)) && jl_is_int32(jl_t1(ret))); + buf->base = (char*)jl_unbox_voidpointer(jl_t0(ret)); + buf->len = jl_unbox_int32(jl_t1(ret)); + } + else { + buf->len = 0; } - buf->base = (char*)jl_unbox_voidpointer(jl_t0(ret)); - buf->len = jl_unbox_int32(jl_t1(ret)); } DLLEXPORT void jl_uv_connectcb(uv_connect_t *connect, int status) @@ -506,7 +509,7 @@ DLLEXPORT int jl_puts(char *str, uv_stream_t *stream) DLLEXPORT void jl_uv_writecb(uv_write_t* req, int status) { - if(req->data) { + if (req->data) { JULIA_CB(writecb, req->data, 2, CB_PTR, req, CB_INT32, status) (void)ret; } diff --git a/src/julia-syntax.scm b/src/julia-syntax.scm index a38db9a2a22ee..4691dc6811a50 100644 --- a/src/julia-syntax.scm +++ b/src/julia-syntax.scm @@ -3090,17 +3090,24 @@ So far only the second case can actually occur. (if (symbol? e) e (cadr e))) +(define (new-expansion-env-for x env) + (append! + (filter (lambda (v) + (not (assq (car v) env))) + (append! + (pair-with-gensyms (vars-introduced-by x)) + (map (lambda (v) (cons v v)) + (keywords-introduced-by x)))) + env)) + (define (resolve-expansion-vars-with-new-env x env m inarg) (resolve-expansion-vars- x - (append! - (filter (lambda (x) - (not (assq (car x) env))) - (append! - (pair-with-gensyms (vars-introduced-by x)) - (map (lambda (s) (cons s s)) - (keywords-introduced-by x)))) - env) + (if (and (pair? x) (eq? (car x) 'let)) + ;; let is strange in that it needs both old and new envs within + ;; the same expression + env + (new-expansion-env-for x env)) m inarg)) (define (resolve-expansion-vars- e env m inarg) @@ -3167,6 +3174,21 @@ So far only the second case can actually occur. (cadr e)) ,(resolve-expansion-vars- (caddr e) env m inarg)))) + ((let) + (let* ((newenv (new-expansion-env-for e env)) + (body (resolve-expansion-vars- (cadr e) newenv m inarg)) + ;; expand initial values in old env + (rhss (map (lambda (a) + (resolve-expansion-vars- (caddr a) env m inarg)) + (cddr e))) + ;; expand binds in old env with dummy RHS + (lhss (map (lambda (a) + (cadr + (resolve-expansion-vars- (make-assignment (cadr a) 0) + newenv m inarg))) + (cddr e)))) + `(let ,body ,@(map make-assignment lhss rhss)))) + ;; todo: trycatch (else (cons (car e) @@ -3197,7 +3219,7 @@ So far only the second case can actually occur. (if (or (not (pair? e)) (quoted? e)) '() (case (car e) - ((escape) '()) + ((escape let) '()) ((= function) (append! (filter symbol? diff --git a/test/core.jl b/test/core.jl index 78d799121dcae..516a74e83cca1 100644 --- a/test/core.jl +++ b/test/core.jl @@ -1423,3 +1423,27 @@ macro m6031(x); x; end @test Base.getfield_tfunc({nothing,QuoteNode(:vals)}, Dict{Int64,(Range1{Int64},Range1{Int64})}, :vals) == Array{(Range1{Int64},Range1{Int64}),1} + +# issue #6068 +x6068 = 1 +function test6068() + local a + while true + a = x6068 + break + end + a + 1 +end +@test test6068() == 2 + +# issue #6074 +macro X6074() + quote + global x6074 + let x6074 = x6074 + x6074 + end + end +end +x6074 = 6074 +@test @X6074() == 6074 diff --git a/test/linalg2.jl b/test/linalg2.jl index 3869b584a9a13..9ddb296788171 100644 --- a/test/linalg2.jl +++ b/test/linalg2.jl @@ -196,7 +196,9 @@ function test_approx_eq_vecs{S<:Real,T<:Real}(a::StridedVecOrMat{S}, b::StridedV for i=1:n ev1, ev2 = a[:,i], b[:,i] deviation = min(abs(norm(ev1-ev2)),abs(norm(ev1+ev2))) - @test_approx_eq_eps deviation 0.0 error + if !isnan(deviation) + @test_approx_eq_eps deviation 0.0 error + end end end @@ -473,7 +475,7 @@ for elty in (Float32, Float64, Complex{Float32}, Complex{Float64}) A = convert(Matrix{elty}, randn(10,nn)) else A = convert(Matrix{elty}, complex(randn(10,nn),randn(10,nn))) - end ## LU (only equal for real because LAPACK uses difference absolute value when choosing permutations) + end ## LU (only equal for real because LAPACK uses different absolute value when choosing permutations) if elty <: Real FJulia = invoke(lufact!, (AbstractMatrix,), copy(A)) FLAPACK = Base.LinAlg.LAPACK.getrf!(copy(A)) diff --git a/test/random.jl b/test/random.jl index 6da5374879d15..4d6295d2aedb0 100644 --- a/test/random.jl +++ b/test/random.jl @@ -9,6 +9,12 @@ @test length(randn(4, 5)) == 20 @test length(randbool(4, 5)) == 20 +@test rand(MersenneTwister()) == 0.8236475079774124 +@test rand(MersenneTwister(0)) == 0.8236475079774124 +@test rand(MersenneTwister(42)) == 0.5331830160438613 +# Try a seed larger than 2^32 +@test rand(MersenneTwister(5294967296)) == 0.3498809918210497 + for T in (Int8, Uint8, Int16, Uint16, Int32, Uint32, Int64, Uint64, Int128, Uint128, Char, BigInt, Float16, Float32, Float64, Rational{Int}) r = rand(convert(T, 97):convert(T, 122))