Skip to content

Derive orthogonal (and chirality) for products of orthogonal tensors #393

Description

@petlenz

Summary

The product of orthogonal tensors is orthogonal: Q₁·Q₂ is orthogonal when both Q₁, Q₂ are. The CAS drops the annotation. Chirality composes too (relevant to #269): proper·proper → proper, proper·improper → improper, improper·improper → proper.

Math

(Q₁Q₂)ᵀ(Q₁Q₂) = Q₂ᵀ Q₁ᵀ Q₁ Q₂ = Q₂ᵀ Q₂ = I → orthogonal. det(Q₁Q₂) = det(Q₁)det(Q₂), so the ±1 determinant (proper/improper) multiplies.

Current behavior (probed)

Q*Q2   (both orthogonal)   -> (none)   expected: orth

How to fix

Two parts:

  1. Binary hook in tag_invoke(mul_fn, tensor, tensor) (include/numsim_cas/tensor/tensor_operators.h): after building the product, if (is_orthogonal(lhs) && is_orthogonal(rhs)) result.data()->tensor_algebra_assumptions().insert(orthogonal{});. Beware the existing trans(Q)·Q → I fold fires first for the transpose pair — that path returns identity and is unaffected.

  2. Chirality composition (optional, ties into Add chirality sub-tag to refine det(orthogonal) fold (proper vs improper rotation) #269): if both are proper_rotation → insert proper_rotation; mixed → improper_rotation; both improper → proper_rotation. Only when both factors carry a chirality tag; otherwise fall back to plain orthogonal.

  3. N-ary generalization: an all-orthogonal tensor_mul factor list → orthogonal. Fold into the classify_tensor_mul_space classifier used by the sandwich issues so multi-factor Q₁Q₂Q₃… is covered.

How to test

auto Q1 = mk("Q1", 3); assume_orthogonal(Q1);
auto Q2 = mk("Q2", 3); assume_orthogonal(Q2);
EXPECT_TRUE(is_orthogonal(Q1 * Q2));
// chirality (if implemented, uses assume_proper_rotation / assume_improper_rotation from #269):
auto R1 = mk("R1", 3); assume_proper_rotation(R1);
auto R2 = mk("R2", 3); assume_improper_rotation(R2);
EXPECT_TRUE(is_improper_rotation(R1 * R2));   // det = (+1)(-1) = -1
// safety: mixing orthogonal with a general tensor drops it
EXPECT_FALSE(is_orthogonal(Q1 * mk("G",3)));

Part of the annotation-completeness umbrella below. Chirality piece relates to #269.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions