Skip to content

tensor_inner_product_to_scalar hash/equality ignore the index sequences — dot(A,{1,2},B,{1,2}) == dot(A,{1,2},B,{2,1}) #343

Description

@petlenz

Summary

tensor_inner_product_to_scalar (include/numsim_cas/tensor_to_scalar/tensor_inner_product_to_scalar.h) stores contraction index sequences but has no update_hash_value/operator== override — it inherits binary_op's hash (id+lhs+rhs only) and binary_op::operator== (core/binary_op.h:162-166, children only). Distinct contractions compare equal (reproduced at 0f6c0b9, non-symmetric A, B):

dot_product(A, {1,2}, B, {1,2}) == dot_product(A, {1,2}, B, {2,1})  // true — A:B vs A:Bᵀ
// their sum  → 2*dot(A,{1,2},B,{2,1})   — WRONG
// their diff → 0                        — WRONG

This is the same bug class as #266 (fixed there for inner_product_wrapper; tensor_to_scalar_eigenvalue.h:42-48 explicitly mirrors that fix — this node was missed) and the permute_indices_wrapper issue (#342).

Severity: critical (silent wrong algebra for any permuted contraction). The evaluator half of this node's problems is tracked separately (evaluator ignores the sequences).

Fix

Add an update_hash_value() override that hash_combines m_lhs_indices/m_rhs_indices (copy inner_product_wrapper.h:59-67), and a member operator== comparing both sequences in addition to the children.

Tests (lock-in)

TEST(T2sInnerProductIdentity, IndexSequencesDistinguish) {
  auto [A] = make_tensor_variable(std::tuple{"A", 3, 2});
  auto [B] = make_tensor_variable(std::tuple{"B", 3, 2});
  auto ab  = dot_product(A, sequence{1,2}, B, sequence{1,2});
  auto abt = dot_product(A, sequence{1,2}, B, sequence{2,1});
  EXPECT_FALSE(*ab == *abt);
  EXPECT_NE(ab.get().hash_value(), abt.get().hash_value());
  EXPECT_NE(to_string(ab - abt), "0");
  // identical sequences still fold
  auto ab2 = dot_product(A, sequence{1,2}, B, sequence{1,2});
  EXPECT_EQ(to_string(ab - ab2), "0");
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions