Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inexact error when constructing SymmetricTensor #224

Closed
henrij22 opened this issue Jan 23, 2025 · 5 comments
Closed

Inexact error when constructing SymmetricTensor #224

henrij22 opened this issue Jan 23, 2025 · 5 comments

Comments

@henrij22
Copy link

Dear all,

I now came across the following behavior multiple times.
When costructing a SymmetricTensor, either from an expression or a Matrix i sometimes get an InexactError.

    SymmetricTensor{2, 𝔇}(N * diagm(S) * N')

produces

ERROR: InexactError: convert(SymmetricTensor{2, 3, Float64}, 
[1808.135883822873 549.1225426055513 0.0; 549.1225426055512 1016.2664852460059 0.0; 0.0 0.0 678.3238495344586])
Stacktrace:
 [1] convert
   @ C:\Users\xxx\.julia\packages\Tensors\DZnYM\src\promotion_conversion.jl:86 [inlined]

as you can see the off diagonal entry only differs at the last digit. Is there somehow a way to set a tolerance for the symmetry check?
As far as i can tell the check happens here:

@inline LinearAlgebra.issymmetric(t::Tensor{2, 1}) = true

Of course you can circumvent the check by doing the construction via a function

    S_ = N * diagm(S) * N'
    SymmetricTensor{2, 𝔇}((i,j) -> S_[i,j])

But this adds another line and sometimes a symmetry check (with a tolerance) might be beneficial.

Thank you so much

@fredrikekre
Copy link
Member

Is there a reason why N and S in your case arent' Tensors? If they were I would do this:

symmetric(N  D  N')

If you need to keep them as matrices, perhaps casting to Tensor first:

symmetric(Tensor{2, 𝔇}(N * diagm(S) * N'))

@henrij22
Copy link
Author

Hi Thank you for your quick answer.

This actually helped me. I didn't know about the symmetric function.
From my side we can close this issue.

@fredrikekre
Copy link
Member

Note that symmetric will compute the symmetric part, i.e. (A + A') / 2, but of course if you know A is already symmetric it is the same.

@fredrikekre
Copy link
Member

Could be usefule to export

# Unsafe versions that just truncates
@inline unsafe_symmetric(S::SymmetricTensors) = S
@inline function unsafe_symmetric(S::Tensor{2, dim}) where {dim}
SymmetricTensor{2, dim}(@inline function(i, j) @inbounds S[i,j] end)
end
@inline function unsafe_symmetric(S::Tensor{4, dim}) where {dim}
SymmetricTensor{4, dim}(@inline function(i, j, k, l) @inbounds return S[i,j,k,l] end)
end
to do "truncated symmetric" to avoid the extra computation.

@henrij22
Copy link
Author

Thank you fir your help, this is indeed very useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants