Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/itensor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,7 @@ dirs(A::ITensor, is) = dirs(inds(A), is)

# TODO: add isdiag(::Tensor) to NDTensors
isdiag(T::ITensor)::Bool = (storage(T) isa Diag || storage(T) isa DiagBlockSparse)
LinearAlgebra.isdiag(T::ITensor) = isdiag(T)

diaglength(T::ITensor) = diaglength(tensor(T))

Expand Down
26 changes: 26 additions & 0 deletions src/lib/SmallStrings/src/smallstring.jl
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,32 @@ end
Base.:(==)(s1::SmallString, s2::SmallString) = (s1.data == s2.data)
Base.isless(s1::SmallString, s2::SmallString) = isless(s1.data, s2.data)

maxlength(s::SmallString) = length(s.data)

function Base.length(s::SmallString)
n = 1
while n <= maxlength(s) && s[n] != zero(eltype(s))
n += 1
end
return n - 1
end

Base.lastindex(s::SmallString) = length(s)
Base.getindex(s::SmallString, r::UnitRange) = SmallString([s[n] for n in r])

# TODO: make this work directly on a Tag, without converting
# to String
function Base.parse(::Type{T}, s::SmallString) where {T<:Integer}
return parse(T, string(s))
end

function Base.startswith(s::SmallString, subtag::SmallString)
for n in 1:length(subtag)
s[n] ≠ subtag[n] && return false
end
return true
end

########################################################
# Here are alternative SmallString comparison implementations
#
Expand Down
1 change: 1 addition & 0 deletions src/lib/TagSets/src/TagSets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ data(T::TagSet) = T.data
Base.length(T::TagSet) = T.length
Base.@propagate_inbounds Base.getindex(T::TagSet, n::Integer) = SmallString(data(T)[n])
Base.copy(ts::TagSet) = TagSet(data(ts), length(ts))
Base.keys(ts::TagSet) = Base.OneTo(length(ts))

function Base.:(==)(ts1::TagSet, ts2::TagSet)
l1 = length(ts1)
Expand Down
13 changes: 13 additions & 0 deletions src/tensor_operations/matrix_decomposition.jl
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,19 @@ function sqrt_decomp(D::ITensor, u::Index, v::Index)
return sqrtDL, prime(δᵤᵥ), sqrtDR
end

# Take the square root of T assuming it is Hermitian
# TODO: add more general index structures
function Base.sqrt(T::ITensor; ishermitian=true, atol=1e-15)
@assert ishermitian
# TODO diagonal version
#if isdiag(T) && order(T) == 2
# return itensor(sqrt(tensor(T)))
#end
D, U = eigen(T; ishermitian=ishermitian)
sqrtD = map_diag(x -> x < 0 && abs(x) < atol ? 0 : sqrt(x), D)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
sqrtD = map_diag(x -> x < 0 && abs(x) < atol ? 0 : sqrt(x), D)
sqrtD = map_diag(x -> x < 0 && abs(x) < atol ? zero(real(eltype(T)) : sqrt(x), D)

Additionally, I agree with your comment above that for large negative values we should convert to complex.

return U' * sqrtD * dag(U)
end

function factorize_svd(
A::ITensor,
Linds...;
Expand Down
Loading