Frames Exactly
To compute frames exxactly we utilize CalciumField (documentation: here) from Oscar.jl to compute real and complex numbers exactly. Oscar loads a wrapper, for the c library Calcium, from Nemo.jl. Exact number can be loaded as follows
julia> using Oscar;
julia> C = CalciumField();
julia> C(2)
2
julia> sqrt(C(2))
1.41421 {a where a = 1.41421 [a^2-2=0]}
julia exp(C(2)*C(pi)*C(1im)/C(3))
-0.500000 + 0.866025*I {a where a = -0.500000 + 0.866025*I [a^2+a+1=0]}Basic Functionality
FrameTheory.is_frame — Method
is_frame(gram) -> Tuple{Bool,Int}Arguments
gram::MatElem{CalciumFieldElem}: A square matrix defined over Oscar's Calcium Field
Returns
frame_bool::Boold::Int
Determines if the matrix gram is the Gram matrix for some frame. Returns a boolean frame_bool if the provided matrix is the Gram matrix of a frame for some d-dimensional space. If frame_bool' is 'false then d would be nothing.
Examples
julia> C = CalciumField();
julia> ζ = exp(C(2)*C(pi)*C(1im)/C(7));
julia> Phi = matrix(C, [1 ζ ζ^2 ζ^3 ζ^4 ζ^5 ζ^6;
1 ζ^2 ζ^4 ζ^6 ζ ζ^3 ζ^5
1 ζ^4 ζ ζ^5 ζ^2 ζ^6 ζ^3]);
julia> gram = conjugate_transpose(Phi)*Phi;
julia> is_frame(gram)
(true, 3)FrameTheory.is_equiangular — Method
is_equiangular(gram) -> Tuple{Bool,CalciumFieldElem,CalciumFieldElem}Arguments
gram::MatElem{CalciumFieldElem}: A square matrix defined over CalciumField.
Returns
equiangular_bool::Boola::CalciumFieldElemb::CalciumFieldElem
Determines if the matrix gram is the Gram matrix for some collection of equiangular vectors. Returns a boolean equiangular_bool if the provided matrix is the Gram matrix of a collection of equiangular lines. With a being the vectors common 'magnatudes' and b the 'angle'. If equiangular_bool is False, then a and b will be nothing.
Examples
julia> C = CalciumField();
julia> ζ = exp(C(2)*C(pi)*C(1im)/C(7));
julia> Phi = matrix(C, [1 ζ ζ^2 ζ^3 ζ^4 ζ^5 ζ^6;
1 ζ^2 ζ^4 ζ^6 ζ ζ^3 ζ^5
1 ζ^4 ζ ζ^5 ζ^2 ζ^6 ζ^3]);
julia> gram = conjugate_transpose(Phi)*Phi;
julia> (equi_bool, a, b) = is_equiangular(gram)
(true, 3, 2.00000 {a^2+b^2 where a = 1.32288 [Im(-0.500000 + 1.32288*I {c^4+c^2-c})], b = -0.500000 [Re(-0.500000 + 1.32288*I {c^4+c^2-c})], c = 0.900969 + 0.433884*I [c^6-c^5+c^4-c^3+c^2-c+1=0]})
julia> QQ(b)
2FrameTheory.is_frame_tight — Method
is_frame_tight(gram) -> Tuple{Bool,CalciumFieldElem}Arguments
gram::MatElem{CalciumFieldElem}: A square matrix which is the Gram matrix for a frame.
Returns
tight_bool::Boolc::CalciumFieldElem
Determines if the matrix gram is the Gram matrix for frame which is tight. If so returns c being the constant such that gram^2=c*gram. If tight_bool is False, then c will be nothing.
Examples
julia> C = CalciumField();
julia> ζ = exp(C(2)*C(pi)*C(1im)/C(7));
julia> Phi = matrix(C, [1 ζ ζ^2 ζ^3 ζ^4 ζ^5 ζ^6;
1 ζ^2 ζ^4 ζ^6 ζ ζ^3 ζ^5
1 ζ^4 ζ ζ^5 ζ^2 ζ^6 ζ^3]);
julia> gram = conjugate_transpose(Phi)*Phi;
julia> is_frame_tight(gram)
(true, 7)FrameTheory.is_ETF — Method
is_ETF(gram) -> Tuple{Bool,CalciumFieldElem,CalciumFieldElem,CalciumFieldElem}Arguments
gram::MatElem{CalciumFieldElem}: A square matrix defined over the Reals or Complexes through CalciumField.
Returns
etf_bool::Boola::CalciumFieldElemb::CalciumFieldElemc::CalciumFieldElemd::Int
Determines if the matrix gram is the Gram matrix for some collection of vectors which form an equiangular tight frame (ETF). Calls and returns the same parameters from is_frame, is_equiangular, and is_frame_tight.
Examples
A 3x7 Paley (3,2,7)-ETF.
julia> C = CalciumField();
julia> ζ = exp(C(2)*C(pi)*C(1im)/C(7));
julia> Phi = matrix(C, [1 ζ ζ^2 ζ^3 ζ^4 ζ^5 ζ^6;
1 ζ^2 ζ^4 ζ^6 ζ ζ^3 ζ^5
1 ζ^4 ζ ζ^5 ζ^2 ζ^6 ζ^3]);
julia> gram = conjugate_transpose(Phi)*Phi;
julia> is_ETF(gram)
(true, 3, 2.00000 {a^2+b^2 where a = 1.32288 [Im(-0.500000 + 1.32288*I {c^4+c^2-c})], b = -0.500000 [Re(-0.500000 + 1.32288*I {c^4+c^2-c})], c = 0.900969 + 0.433884*I [c^6-c^5+c^4-c^3+c^2-c+1=0]}, 7, 3)Constructions
FrameTheory.ExactCons.dx2d_etf_from_prime_power — Method
ExactCons.dx2d_etf_from_prime_power(prime_power) -> MatElem{CalciumFieldElem}Arguments
prime_power::Int: an odd prime power
Returns
gram::MatElem{CalciumFieldElem}the Gram matrix of a(prime_power^2+1)/2byprime_power^2+1ETF.
Examples
A real Example
julia> gram = ExactCons.dx2d_etf_from_prime_power(5^2);
julia> is_ETF(gram)
(true, 5,1,10,13)
julia> n = size(gram)[1]
26
julia> all(isreal.(gram))
true
A complex example
julia> gram = ExactCons.dx2d_etf_from_prime_power(3);
julia> is_ETF(gram)
(true, 1.73205 {a where a = 1.73205 [a^2-3=0]}, 1, 3.46410 {2*a where a = 1.73205 [a^2-3=0]}, 2)
julia> n = size(gram)[1]
4
julia> all(isreal.(gram))
false
Binder Finder
FrameTheory.binder_finder — Method
binder_finder(gram) -> Matrix{Int}Arguments
gram::MatElem{CalciumFieldElem}: The Gram matrix of an ETF.
Returns
binder::Matrix{Int}: The Binder of the provided frame, where each row denotes a simplex.
Examples
julia> C = CalciumField();
julia> ζ = exp(C(2)*C(pi)*C(1im)/C(3));
julia> hessa_sic = matrix(C, [
1 1 1 -1 -1 -1 0 0 0;
0 0 0 1 ζ ζ^2 -1 -1*ζ -1*ζ^2;
-1 -1*ζ^2 -1*ζ 0 0 0 1 ζ^2 ζ
]);
julia> hessa_gram = conjugate_transpose(hessa_sic)*hessa_sic;
julia> is_ETF(hessa_gram)
(true, 2, 1.00000 {a^2+b^2 where a = -0.866025 [Im(0.500000 - 0.866025*I {-c})], b = 0.500000 [Re(0.500000 - 0.866025*I {-c})], c = -0.500000 + 0.866025*I [c^2+c+1=0]}, 6, 3)
julia> binder_finder(hessa_gram)
12×9 Matrix{Int64}:
1 1 1 0 0 0 0 0 0
1 0 0 1 0 0 1 0 0
1 0 0 0 1 0 0 0 1
1 0 0 0 0 1 0 1 0
0 1 0 1 0 0 0 0 1
0 1 0 0 1 0 0 1 0
0 1 0 0 0 1 1 0 0
0 0 1 1 0 0 0 1 0
0 0 1 0 1 0 1 0 0
0 0 1 0 0 1 0 0 1
0 0 0 1 1 1 0 0 0
0 0 0 0 0 0 1 1 1julia> C = CalciumField();
julia> ζ = exp(C(2)*C(pi)*C(1im)/C(3));
julia> hessa_sic = matrix(C, [
1 1 1 1 1 1 0 0 0;
0 0 0 1 ζ ζ^2 1 1*ζ 1*ζ^2;
1 1*ζ^2 1*ζ 0 0 0 1 ζ^2 ζ
]);
julia> hessa_gram = conjugate_transpose(hessa_sic)*hessa_sic;
julia> is_ETF(hessa_gram)
(true, 2, 1.00000 {a^2+b^2 where a = -0.866025 [Im(0.500000 - 0.866025*I {-c})], b = 0.500000 [Re(0.500000 - 0.866025*I {-c})], c = -0.500000 + 0.866025*I [c^2+c+1=0]}, 6, 3)
julia> binder_finder(hessa_gram)
3×9 Matrix{Int64}:
1 1 1 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0
0 0 0 0 0 0 1 1 1The Projective Symmetry Group of an ETF
FrameTheory.projective_symmetry_group — Method
projective_symmetry_group(gram) -> PermGroupArguments
gram::MatElem{CalciumFieldElem}: A square matrix which is the Gram matrix of some ETF.verbose::Bool: (Defaultfalse).
Returns
G::PermGroup: The group of permutations of the vector of the frame, that correspond to switching equivalences.
BFS backen Adapted from the following Gap code by Joey Iverson: https://github.com/jwiverson/frame-symmetries/blob/main/symp.gap both backends implement the algorithm from section 4 of [7]. Over R or C this algorithm utilizes Proposition 3.3 from the same paper.
Examples
The following is an example of a 2x4 ETF with S4 its symmetry group.
julia> gram = ExactCons.dx2d_etf_from_prime_power(3);
julia> G = projective_symmetry_group(gram)
Permutation group of degree 4
julia> transitivity(G, 1:4)
2
julia> describe(G)
"A4"