|
1 | 1 | # core/unpack_points.jl — Point unpacking and legacy/vector interop |
2 | 2 | export pack_point_rank1, |
3 | | - unpack_point_rank1, pack_point_rankr, unpack_point_rankr, unpack_point_rankr_components |
| 3 | + unpack_point_rank1, |
| 4 | + pack_point_rankr, |
| 5 | + unpack_point_rankr, |
| 6 | + unpack_point_rankr_components, |
| 7 | + canonical_to_joinpoint, |
| 8 | + joinpoint_to_canonical |
4 | 9 |
|
5 | 10 | function unpack_rankr_native(p, dims::NTuple{N,Int}, r::Int) where {N} |
6 | 11 | parts = normalize_rankr_native_point(p, dims, r) |
@@ -72,6 +77,43 @@ function unpack_rankr_join(p, dims::NTuple{N,Int}, r::Int) where {N} |
72 | 77 | return λ, U |
73 | 78 | end |
74 | 79 |
|
| 80 | +""" |
| 81 | + canonical_to_joinpoint(λ, U) |
| 82 | + canonical_to_joinpoint(p_canonical, dims, r) |
| 83 | +
|
| 84 | +Convert a CPD point from canonical factor-matrix storage to the native |
| 85 | +rank-`r` Segre join point layout used by generic `JoinModel((Segre, ...), A)`. |
| 86 | +
|
| 87 | +The conversion preserves the represented tensor but may renormalize component |
| 88 | +gauges the same way `pack_rankr_native` does. |
| 89 | +""" |
| 90 | +function canonical_to_joinpoint( |
| 91 | + λ::AbstractVector{T}, |
| 92 | + U::Vector{<:AbstractMatrix{T}}, |
| 93 | +) where {T<:AbstractFloat} |
| 94 | + r = length(λ) |
| 95 | + return pack_rankr_native(λ, U, r) |
| 96 | +end |
| 97 | + |
| 98 | +function canonical_to_joinpoint(p, dims::NTuple{N,Int}, r::Int) where {N} |
| 99 | + λ, U = unpack_rankr_canonical(p, dims, r) |
| 100 | + return canonical_to_joinpoint(λ, U) |
| 101 | +end |
| 102 | + |
| 103 | +""" |
| 104 | + joinpoint_to_canonical(p_join, dims, r) |
| 105 | +
|
| 106 | +Convert a native Segre join point layout back to the canonical CPD point |
| 107 | +layout `(λ, (u₁¹, …, uᵣ¹), …, (u₁ᴺ, …, uᵣᴺ))`. |
| 108 | +
|
| 109 | +The conversion preserves the represented tensor but may renormalize component |
| 110 | +gauges the same way `pack_rankr_canonical` does. |
| 111 | +""" |
| 112 | +function joinpoint_to_canonical(p, dims::NTuple{N,Int}, r::Int) where {N} |
| 113 | + λ, U = unpack_rankr_native(p, dims, r) |
| 114 | + return pack_rankr_canonical(λ, U, r) |
| 115 | +end |
| 116 | + |
75 | 117 | function pack_point_rank1(λ::T, U::Vector{Vector{T}}) where {T<:AbstractFloat} |
76 | 118 | parts = Vector{Vector{T}}(undef, length(U) + 1) |
77 | 119 | parts[1] = T[λ] |
|
0 commit comments