mrmatrices=Dict(
(l=0, m=0, mu=0, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.3333333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.3333333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.3333333333333333+0.0im),
(l=0, m=0, mu=0, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=0, m=0, mu=0, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=0, m=0, mu=0, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=0, m=0, mu=0, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.3333333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.3333333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.3333333333333333+0.0im),
(l=0, m=0, mu=0, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=0, m=0, mu=0, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=0, m=0, mu=0, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=0, m=0, mu=0, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.3333333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.3333333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.3333333333333333+0.0im),
(l=1, m=-1, mu=-1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=0, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=-1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=0, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=-1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=0, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=-1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=0, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.1178511301977579im, 0.0+0.0im, 0.0+0.0im, 0.1178511301977579+0.0im, 0.0+0.1178511301977579im, -0.1178511301977579+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=-1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=0, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, -0.1666666666666667+0.0im, 0.0+0.0im, 0.1666666666666667+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=-1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=0, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.1178511301977579im, 0.0+0.0im, 0.0+0.0im, -0.1178511301977579+0.0im, 0.0+0.1178511301977579im, 0.1178511301977579+0.0im, 0.0+0.0im),
(l=1, m=1, mu=1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=-1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.0833333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.0833333333333333im, 0.0833333333333333+0.0im, 0.0+0.0833333333333333im, 0.0+0.0im),
(l=1, m=-1, mu=0, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.0833333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.0833333333333333im, 0.0833333333333333+0.0im, 0.0+0.0833333333333333im, 0.0+0.0im),
(l=1, m=0, mu=-1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.1178511301977579im, 0.0+0.0im, 0.0+-0.1178511301977579im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=0, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.1178511301977579im, 0.0+0.0im, 0.0+-0.1178511301977579im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=-1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.0833333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0833333333333333im, 0.0833333333333333+0.0im, 0.0+-0.0833333333333333im, 0.0+0.0im),
(l=1, m=1, mu=0, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.0833333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0833333333333333im, 0.0833333333333333+0.0im, 0.0+-0.0833333333333333im, 0.0+0.0im),
(l=1, m=-1, mu=-1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=0, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.1178511301977579im, 0.0+0.0im, 0.0+0.0im, -0.1178511301977579+0.0im, 0.0+-0.1178511301977579im, 0.1178511301977579+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=-1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=0, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.1666666666666667+0.0im, 0.0+0.0im, -0.1666666666666667+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=-1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=0, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.1178511301977579im, 0.0+0.0im, 0.0+0.0im, 0.1178511301977579+0.0im, 0.0+-0.1178511301977579im, -0.1178511301977579+0.0im, 0.0+0.0im),
(l=1, m=1, mu=1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=-1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=0, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=-1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=0, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=-1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=0, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=-1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0833333333333333im, 0.0+0.0im, 0.0+0.0im, -0.0833333333333333+0.0im, 0.0+-0.0833333333333333im, 0.0833333333333333+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=0, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.0833333333333333im, 0.0+0.0im, 0.0+0.0im, 0.0833333333333333+0.0im, 0.0+0.0833333333333333im, -0.0833333333333333+0.0im, 0.0+0.0im),
(l=1, m=0, mu=-1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.1178511301977579+0.0im, 0.0+0.0im, -0.1178511301977579+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=0, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, -0.1178511301977579+0.0im, 0.0+0.0im, 0.1178511301977579+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=-1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0833333333333333im, 0.0+0.0im, 0.0+0.0im, 0.0833333333333333+0.0im, 0.0+-0.0833333333333333im, -0.0833333333333333+0.0im, 0.0+0.0im),
(l=1, m=1, mu=0, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.0833333333333333im, 0.0+0.0im, 0.0+0.0im, -0.0833333333333333+0.0im, 0.0+0.0833333333333333im, 0.0833333333333333+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=-1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0833333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0833333333333333im, -0.0833333333333333+0.0im, 0.0+-0.0833333333333333im, 0.0+0.0im),
(l=1, m=-1, mu=0, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0833333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0833333333333333im, -0.0833333333333333+0.0im, 0.0+-0.0833333333333333im, 0.0+0.0im),
(l=1, m=0, mu=-1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+-0.1178511301977579im, 0.0+0.0im, 0.0+0.1178511301977579im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=0, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+-0.1178511301977579im, 0.0+0.0im, 0.0+0.1178511301977579im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=-1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0833333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.0833333333333333im, -0.0833333333333333+0.0im, 0.0+0.0833333333333333im, 0.0+0.0im),
(l=1, m=1, mu=0, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0833333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.0833333333333333im, -0.0833333333333333+0.0im, 0.0+0.0833333333333333im, 0.0+0.0im),
(l=1, m=-1, mu=-1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.0833333333333333im, 0.0+0.0im, 0.0+0.0im, 0.0833333333333333+0.0im, 0.0+0.0833333333333333im, -0.0833333333333333+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=0, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0833333333333333im, 0.0+0.0im, 0.0+0.0im, -0.0833333333333333+0.0im, 0.0+-0.0833333333333333im, 0.0833333333333333+0.0im, 0.0+0.0im),
(l=1, m=0, mu=-1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, -0.1178511301977579+0.0im, 0.0+0.0im, 0.1178511301977579+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=0, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.1178511301977579+0.0im, 0.0+0.0im, -0.1178511301977579+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=-1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.0833333333333333im, 0.0+0.0im, 0.0+0.0im, -0.0833333333333333+0.0im, 0.0+0.0833333333333333im, 0.0833333333333333+0.0im, 0.0+0.0im),
(l=1, m=1, mu=0, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0833333333333333im, 0.0+0.0im, 0.0+0.0im, 0.0833333333333333+0.0im, 0.0+-0.0833333333333333im, -0.0833333333333333+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=-1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=0, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=-1, mu=1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=-1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=0, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=0, mu=1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=-1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=0, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=1, m=1, mu=1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-2, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.05im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=0, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(-0.04082482904638631+0.0im, 0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+-0.04082482904638631im, 0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=2, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.05im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-2, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, -0.05+0.0im, 0.0+-0.05im, 0.0+0.0im),
(l=2, m=-1, mu=-1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=0, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.04082482904638631im, 0.04082482904638631+0.0im, 0.0+0.04082482904638631im, 0.0+0.0im),
(l=2, m=-1, mu=1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=2, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, -0.05+0.0im, 0.0+-0.05im, 0.0+0.0im),
(l=2, m=0, mu=-2, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(-0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, -0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0816496580927726+0.0im),
(l=2, m=0, mu=-1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=0, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.03333333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.03333333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, -0.06666666666666666+0.0im),
(l=2, m=0, mu=1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=2, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(-0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, -0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0816496580927726+0.0im),
(l=2, m=1, mu=-2, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+-0.05im, 0.0+0.0im),
(l=2, m=1, mu=-1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=0, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.04082482904638631im, -0.04082482904638631+0.0im, 0.0+0.04082482904638631im, 0.0+0.0im),
(l=2, m=1, mu=1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=2, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+-0.05im, 0.0+0.0im),
(l=2, m=2, mu=-2, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+-0.05im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=0, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(-0.04082482904638631+0.0im, 0.0+0.04082482904638631im, 0.0+0.0im, 0.0+0.04082482904638631im, 0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=1, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=2, i=1, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+-0.05im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-2, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+-0.05im, 0.05+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=0, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=2, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, -0.05+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-2, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.05im, -0.05+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=0, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=2, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-2, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.0816496580927726im),
(l=2, m=0, mu=-1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=0, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=2, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0816496580927726im),
(l=2, m=1, mu=-2, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+-0.05im, -0.05+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=0, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=2, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-2, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+-0.05im, -0.05+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=0, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=1, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=2, i=1, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, 0.05+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-2, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(-0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=0, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.05im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=2, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-2, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.05im, 0.0+0.0im),
(l=2, m=-1, mu=0, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, -0.05+0.0im, 0.0+-0.05im, 0.0+0.0im),
(l=2, m=-1, mu=2, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-2, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, -0.0816496580927726+0.0im),
(l=2, m=0, mu=0, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(-0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, -0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0816496580927726+0.0im),
(l=2, m=0, mu=2, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-2, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.05im, -0.05+0.0im, 0.0+0.05im, 0.0+0.0im),
(l=2, m=1, mu=0, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+-0.05im, 0.0+0.0im),
(l=2, m=1, mu=2, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-2, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(-0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=0, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=1, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+-0.05im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=2, i=1, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-2, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+-0.05im, 0.05+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=0, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=2, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, -0.05+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-2, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.05im, -0.05+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=0, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=2, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-2, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.0816496580927726im),
(l=2, m=0, mu=-1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=0, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=2, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0816496580927726im),
(l=2, m=1, mu=-2, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+-0.05im, -0.05+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=0, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=2, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-2, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+-0.05im, -0.05+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=0, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=1, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=2, i=2, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, 0.05+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-2, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(-0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=0, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(-0.04082482904638631+0.0im, 0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+-0.04082482904638631im, 0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=2, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(-0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-2, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.05im, 0.0+0.0im),
(l=2, m=-1, mu=-1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=0, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.04082482904638631im, 0.04082482904638631+0.0im, 0.0+0.04082482904638631im, 0.0+0.0im),
(l=2, m=-1, mu=1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=2, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.05im, 0.0+0.0im),
(l=2, m=0, mu=-2, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, -0.0816496580927726+0.0im),
(l=2, m=0, mu=-1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=0, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.03333333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.03333333333333333+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, -0.06666666666666666+0.0im),
(l=2, m=0, mu=1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=2, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, -0.0816496580927726+0.0im),
(l=2, m=1, mu=-2, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.05im, -0.05+0.0im, 0.0+0.05im, 0.0+0.0im),
(l=2, m=1, mu=-1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=0, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.04082482904638631im, -0.04082482904638631+0.0im, 0.0+0.04082482904638631im, 0.0+0.0im),
(l=2, m=1, mu=1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=2, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.05im, -0.05+0.0im, 0.0+0.05im, 0.0+0.0im),
(l=2, m=2, mu=-2, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(-0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=0, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(-0.04082482904638631+0.0im, 0.0+0.04082482904638631im, 0.0+0.0im, 0.0+0.04082482904638631im, 0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=1, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=2, i=2, j=2) => SMatrix{3, 3, ComplexF64, 9}(-0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-2, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, -0.05+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=0, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, -0.05+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=2, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-2, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=0, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=2, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-2, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0816496580927726im),
(l=2, m=0, mu=0, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0816496580927726im),
(l=2, m=0, mu=2, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-2, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=1, mu=0, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=1, mu=2, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-2, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, 0.05+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=0, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=1, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, 0.05+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=2, i=2, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-2, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(-0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=0, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.05im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=2, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-2, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.05im, 0.0+0.0im),
(l=2, m=-1, mu=0, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, -0.05+0.0im, 0.0+-0.05im, 0.0+0.0im),
(l=2, m=-1, mu=2, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-2, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, -0.0816496580927726+0.0im),
(l=2, m=0, mu=0, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(-0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, -0.04082482904638631+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0816496580927726+0.0im),
(l=2, m=0, mu=2, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-2, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.05im, -0.05+0.0im, 0.0+0.05im, 0.0+0.0im),
(l=2, m=1, mu=0, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+-0.05im, 0.0+0.0im),
(l=2, m=1, mu=2, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-2, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(-0.05+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=0, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=1, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+-0.05im, -0.05+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=2, i=3, j=1) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-2, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, -0.05+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=0, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, -0.05+0.0im, 0.0+0.0im, -0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=2, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-2, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=0, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=2, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-2, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0816496580927726im),
(l=2, m=0, mu=0, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.04082482904638631im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0816496580927726im),
(l=2, m=0, mu=2, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-2, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=1, mu=0, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.05im, 0.0+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+0.05im, 0.05+0.0im, 0.0+0.0im),
(l=2, m=1, mu=2, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-2, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, 0.05+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=0, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=1, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.05im, 0.05+0.0im, 0.0+0.0im, 0.05+0.0im, 0.0+-0.05im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=2, i=3, j=2) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-2, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=-1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=0, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0816496580927726+0.0im, 0.0+0.0816496580927726im, 0.0+0.0im, 0.0+0.0816496580927726im, -0.0816496580927726+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-2, mu=2, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-2, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=-1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=0, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, -0.0816496580927726+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.0816496580927726im, -0.0816496580927726+0.0im, 0.0+-0.0816496580927726im, 0.0+0.0im),
(l=2, m=-1, mu=1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=-1, mu=2, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-2, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=-1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=0, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(-0.06666666666666666+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, -0.06666666666666666+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.1333333333333333+0.0im),
(l=2, m=0, mu=1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=0, mu=2, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-2, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=-1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=0, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0816496580927726+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+-0.0816496580927726im, 0.0816496580927726+0.0im, 0.0+-0.0816496580927726im, 0.0+0.0im),
(l=2, m=1, mu=1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=1, mu=2, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-2, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=-1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=0, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0816496580927726+0.0im, 0.0+-0.0816496580927726im, 0.0+0.0im, 0.0+-0.0816496580927726im, -0.0816496580927726+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=1, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im),
(l=2, m=2, mu=2, i=3, j=3) => SMatrix{3, 3, ComplexF64, 9}(0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im, 0.0+0.0im)
)


# name = "Couenne_jll"
# Couenne_jll = "f09e9e23-9010-5c9e-b679-9f1d8f79b85c"
# name = "AmplNLWriter"
# AmplNLWriter = "7c4d4715-977e-5154-bfe0-e096adeac482"

using AmplNLWriter, Couenne_jll

COUENNE_OPT = AmplNLWriter.Optimizer(Couenne_jll.amplexe)
# MOI.set(COUENNE_OPT, MOI.Silent(), true)
# MOI.set(COUENNE_OPT, MOI.TimeLimitSec(), 5)
# COUENNE_OPT = MOI.Bridges.Constraint.SOCtoNonConvexQuad{Float64}(COUENNE_OPT)

push!(solvers_nlp, (opt = COUENNE_OPT, mode = BilevelJuMP.ProductMode(1e-5)))


################################################################################
# Fuel requirements ############################################################
################################################################################

"""Fuel required to launch a given module is based on its mass.
Specifically, to find the fuel required for a module, take its mass,
divide by three, round down, and subtract 2.
"""
fuelForModule(mass) = max(0, (mass ÷ 3) - 2)

"""Fuel itself requires fuel just like a module.
However, that fuel also requires fuel, and that fuel requires fuel, and so on.
"""
function rocketEqFuel(mass)
    totalFuel = 0
    additionalFuel = fuelForModule(mass)
    while additionalFuel > 0
        totalFuel += additionalFuel
        additionalFuel = fuelForModule(additionalFuel)
    end
    totalFuel
end

################################################################################
# Elf Virtual Machine (Intcode computer) #######################################
################################################################################

"""When running many virtual machines in parallel, each machine has an execution
state. If the vm is waiting for input from another vm, it is set to WaitForInput."""
@enum VMState begin
    Initialized = 0
    Running = 1
    WaitForInput = 2
    Halted = 99
end

mutable struct ElfVM
    memory::Vector{Int}
    extraMemory::Dict{Int, Int}
    instructionPointer::Int
    relativePointer::Int
    stdin::Vector{Int}
    stdout::Vector{Int}
    state::VMState
end

function ElfVM(memory)
    ElfVM(memory, Dict(), 0, 0, [], [], Initialized)
end

function Base.copy(vm::ElfVM)::ElfVM
    ElfVM(copy(vm.memory), copy(vm.extraMemory), vm.instructionPointer, vm.relativePointer, copy(vm.stdin), copy(vm.stdout), vm.state)
end

@enum Opcode begin
    Addition = 1
    Multiplication = 2
    ReadStdin = 3
    WriteStdout = 4
    JumpIfTrue = 5
    JumpIfFalse = 6
    LessThan = 7
    Equals = 8
    ShiftRelativeBase = 9
    Halt = 99
end

function set!(vm::ElfVM, i, v)
    if length(vm.memory) >= i + 1
        vm.memory[i + 1] = v
    else
        vm.extraMemory[i + 1] = v
    end
end

function get(vm::ElfVM, i)
    if length(vm.memory) >= i + 1
        vm.memory[i + 1]
    else
        if i + 1 in keys(vm.extraMemory)
            vm.extraMemory[i + 1]
        else
            vm.extraMemory[i + 1] = 0
        end
    end
end

current_instruction(vm) = get(vm, vm.instructionPointer)

params3(vm) = (get(vm, vm.instructionPointer + 1),
    get(vm, vm.instructionPointer + 2),
    get(vm, vm.instructionPointer + 3))

"""Decodes an instruction into a tuple (opcode, parameter_modes)"""
parse_instruction(with_parameter_modes::Int) = (Opcode(with_parameter_modes % 100), digits(with_parameter_modes ÷ 100))

"""Reads a parameter of the instruction, given a relative offset.
Can differentiate between different read modes. (position/immediate/..)
Missing read modes are assumed to be position mode."""
function read_param(vm::ElfVM, i::Int, parameter_modes::Vector{Int})::Int
    mode = i <= length(parameter_modes) ? parameter_modes[i] : 0
    value = get(vm, vm.instructionPointer + i)
    if mode == 0
        # position mode
        return get(vm, value)
    elseif mode == 1
        # immediate mode
        return value
    elseif mode == 2
        # relative mode
        return get(vm, vm.relativePointer + value)
    end

end

"""Writes the value to the register given as the i-th parameter of
the current operation."""
function write_param!(vm::ElfVM, i::Int, value, parameter_modes::Vector{Int})
    mode = i <= length(parameter_modes) ? parameter_modes[i] : 0
    parameter = get(vm, vm.instructionPointer + i)
    if mode == 0
        target = parameter
    elseif mode == 2
        target = vm.relativePointer + parameter
    end
    set!(vm, target, value)
end

"""Executes one instruction on the ElfVM and returns whether it is still active.
"""
function tick!(vm::ElfVM)
    @assert vm.state == Running "The vm is $(vm.state), you must not call tick!()."
    (opcode, parameter_modes) = parse_instruction(current_instruction(vm))
    if opcode == Addition
        # Addition
        a = read_param(vm, 1, parameter_modes)
        b = read_param(vm, 2, parameter_modes)
        c = a + b
        write_param!(vm, 3, c, parameter_modes)
        step!(vm, 4)
    elseif opcode == Multiplication
        # Multiplication
        a = read_param(vm, 1, parameter_modes)
        b = read_param(vm, 2, parameter_modes)
        c = a * b
        write_param!(vm, 3, c, parameter_modes)
        step!(vm, 4)
    elseif opcode == ReadStdin
        # If there is no input on stdin, the vm suspends.
        if length(vm.stdin) > 0
            a = popfirst!(vm.stdin)
            write_param!(vm, 1, a, parameter_modes)
            step!(vm, 2)
        else
            vm.state = WaitForInput
        end
    elseif opcode == WriteStdout
        # Write to stdout
        a = read_param(vm, 1, parameter_modes)
        push!(vm.stdout, a)
        step!(vm, 2)
    elseif opcode == JumpIfTrue
        # jump-if-true
        a = read_param(vm, 1, parameter_modes)
        if a != 0
            b = read_param(vm, 2, parameter_modes)
            vm.instructionPointer = b
        else
            step!(vm, 3)
        end
    elseif opcode == JumpIfFalse
        # jump-if-false
        a = read_param(vm, 1, parameter_modes)
        if a == 0
            b = read_param(vm, 2, parameter_modes)
            vm.instructionPointer = b
        else
            step!(vm, 3)
        end
    elseif opcode == LessThan
        # less than
        a = read_param(vm, 1, parameter_modes)
        b = read_param(vm, 2, parameter_modes)
        c = a < b ? 1 : 0
        write_param!(vm, 3, c, parameter_modes)
        step!(vm, 4)
    elseif opcode == Equals
        # equals
        a = read_param(vm, 1, parameter_modes)
        b = read_param(vm, 2, parameter_modes)
        c = a == b ? 1 : 0
        write_param!(vm, 3, c, parameter_modes)
        step!(vm, 4)
    elseif opcode == ShiftRelativeBase
        # Opcode 9 adjusts the relative base by the value of its only parameter.
        a = read_param(vm, 1, parameter_modes)
        vm.relativePointer += a
        step!(vm, 2)
    elseif opcode == Halt
        vm.state = Halted
    else
        throw("Opcode $opcode not implemented!")
    end
end

function step!(vm, n)
    vm.instructionPointer += n
end

function runnable(vm::ElfVM)::Bool
    if vm.state == Initialized
        true
    elseif vm.state == Running
        true
    elseif vm.state == WaitForInput
        length(vm.stdin) > 0
    elseif vm.state == Halted
        false
    else
        throw("VM state $(vm.state) not recognized.")
    end
end

function run!(vm::ElfVM)::VMState
    vm.state = Running
    while vm.state == Running
        tick!(vm)
    end
    vm.state
end

function runWithArguments(vm, noun, verb)
    set!(vm, 1, noun)
    set!(vm, 2, verb)
    run!(vm)
    get(vm, 0)
end

function findArguments(vm, output)
    for i in 0:99, j in 0:99
        if runWithArguments(copy(vm2), i, j) == output
            return (i, j)
        end
    end
end

################################################################################
# Multithreaded Elf Virtual Machine ############################################
################################################################################

mutable struct MultiThreadElfVM
    threads::Dict{Int, ElfVM}
    forwards::Dict{Int, Int}
end

function MultiThreadElfVM(bytecode::Vector{Int}, pids::Vector{Int}, forwards::Dict{Int, Int})
    vm = MultiThreadElfVM(Dict(), Dict())
    for pid in pids
        vm.threads[pid] = ElfVM(copy(bytecode))
    end
    vm.forwards = copy(forwards)
    vm
end

# Convenicene functions to work with stdin

function push_stdin!(vm::MultiThreadElfVM, pid, value)
    push!(vm.threads[pid].stdin, value)
end

"""A scheduler that runs all the threads."""
function run!(multi_thread::MultiThreadElfVM)
    # Right now, I hope that "Round Robin" is going to be good enought.
    runnable_threads::Vector{Int} = []
    suspended_threads::Set{Int} = Set()
    for (pid, thread) in multi_thread.threads
        if runnable(thread)
            push!(runnable_threads, pid)
        else
            push!(suspended_threads, pid)
        end
    end

    while length(runnable_threads) > 0
        # Pick the next runnable thread in line and do one execution
        pid = popfirst!(runnable_threads)
        thread = multi_thread.threads[pid]
        thread.state = Running
        # As a possible performance improvement, I could do several ticks
        # at once. This reduces overhead from context switching.
        tick!(thread)

        # Decide where this thread goes next
        if runnable(thread)
            push!(runnable_threads, pid)
        else
            push!(suspended_threads, pid)
        end

        # Take care of signal forwarding
        if length(thread.stdout) > 0 && pid in keys(multi_thread.forwards)
            target_pid = multi_thread.forwards[pid]
            target_thread = multi_thread.threads[target_pid]

            while length(thread.stdout) > 0
                push!(target_thread.stdin, popfirst!(thread.stdout))
            end

            # Check, if this wakes the target thread
            if runnable(target_thread) && target_pid in suspended_threads
                delete!(suspended_threads, target_pid)
                push!(runnable_threads, target_pid)
            end
        end
    end
end

################################################################################
# Wire pannels #################################################################
################################################################################

struct HorizontalWire
    x1::Int
    x2::Int
    y::Int
    offset::Int
end

struct VerticalWire
    x::Int
    y1::Int
    y2::Int
    offset::Int
end

@enum Direction begin
    Up = 1
    Left = 2
    Down = 3
    Right = 4
end

direction_keys = Dict('U' => Up, 'L' => Left, 'D' => Down, 'R' => Right)

function Direction(str::SubString)
    dir = direction_keys[str[1]]
    len = parse(Int, str[2:end])
    (dir, len)
end

parseDirectionString(str::String) = Direction.(split(str, ","))

function createWires(directions)
    wires = Vector{Any}(undef, length(directions))
    x = 0
    y = 0
    offset = 0
    for i in 1:length(directions)
        (d, l) = directions[i]
        if d == Up
            y1 = y
            y += l
            wires[i] = VerticalWire(x, y1, y, offset)
        elseif d == Down
            y1 = y
            y -= l
            wires[i] = VerticalWire(x, y1, y, offset)
        elseif d == Right
            x1 = x
            x += l
            wires[i] = HorizontalWire(x1, x, y, offset)
        elseif d == Left
            x1 = x
            x -= l
            wires[i] = HorizontalWire(x1, x, y, offset)
        end
        offset += l
    end
    wires
    end

intersect(w1::HorizontalWire, w2::HorizontalWire) = Nothing()
intersect(w1::VerticalWire, w2::VerticalWire) = Nothing()
intersect(w1::VerticalWire, w2::HorizontalWire) = intersect(w2, w1)
function intersect(w1::HorizontalWire, w2::VerticalWire)
    if w1.x1 < w2.x < w1.x2 || w1.x1 > w2.x > w1.x2
        if w2.y1 < w1.y < w2.y2 || w2.y1 > w1.y > w2.y2
            signalTime = w1.offset + w2.offset
            signalTime += abs(w1.x1 - w2.x)
            signalTime += abs(w2.y1 - w1.y)
            return (w2.x, w1.y, signalTime)
        end
    end
    Nothing()
end

function intersections(wires1, wires2)
    result = []
    for w1 in wires1, w2 in wires2
        intersection = intersect(w1, w2)
        if intersection != Nothing()
            push!(result, intersection)
        end
    end
    result
end

intersection_offset((_, _, offset)) = offset

manhattan((x, y, _)) = abs(x) + abs(y)

################################################################################
# Password Check ###############################################################
################################################################################

"""However, they do remember a few key facts about the password:

* It is a six-digit number.
* The value is within the range given in your puzzle input.
* Two adjacent digits are the same (like 22 in 122345).
* Going from left to right, the digits never decrease; they only ever increase or stay the same (like 111123 or 135679).
"""
function check_password(number)
    dgts = digits(number)[end:-1:1]
    pairFound = false
    for i in 2:6
        pairFound = pairFound || dgts[i - 1] == dgts[i]
        if dgts[i] < dgts[i - 1]
            return false
        end
    end
    pairFound
end

"""An Elf just remembered one more important detail:
the two adjacent matching digits are not part of a larger group of matching digits.
"""
function check_password_stronger(number)
    dgts = digits(number)[end:-1:1]
    pairFound = false
    seqCount = 1
    for i in 2:6
        if dgts[i - 1] == dgts[i]
            seqCount += 1
        else
            if seqCount == 2
                pairFound = true
            end
            seqCount = 1
        end
        if dgts[i] < dgts[i - 1]
            return false
        end
        end

    if seqCount == 2
        pairFound = true
    end

    pairFound
end

################################################################################
# Orbit Maps ###################################################################
################################################################################

mutable struct OrbitMap
    centers::Dict{String,String}
    depth::Dict{String,Int}
end

"""Takes a string like "XQQ)W94" and outputs the tuple ("XQQ", "W94").
This indicates, that XQQ (e.g. Sun) is orbited by W94 (e.g. Planet).
"""
orbitRelationship(str::String) = (str[1:3], str[5:7])

function cacheOrbitDepth(om::OrbitMap, object::String)::Int
    if object in keys(om.depth)
        om.depth[object]
    else
        depth = 1 + cacheOrbitDepth(om, om.centers[object])
        om.depth[object] = depth
    end
end

    """Builds an OrbitMap from a readlines input."""
function OrbitMap(lines::Vector{String})::OrbitMap
    orbitMap = OrbitMap(Dict(), Dict("COM" => 0))
    for (inside, outside) in orbitRelationship.(lines)
        orbitMap.centers[outside] = inside
    end

    for (outside, _) in orbitMap.centers
        cacheOrbitDepth(orbitMap, outside)
    end
    orbitMap
end

"""Determine the distance, using the property that we are on a tree."""
function distance(om::OrbitMap, a::String, b::String)::Int
    if a == b
        0
    elseif om.depth[a] > om.depth[b]
        1 + distance(om, om.centers[a], b)
    elseif om.depth[a] < om.depth[b]
        1 + distance(om, a, om.centers[b])
    else
        2 + distance(om, om.centers[a], om.centers[b])
    end
end


using MANA
using JuliaDB, JWAS, DataFrames

function main()
	dir="~/MANA/example/"
        snpfilename=dir .* "plink.example"
        phenofilename=dir .* "phen.example2.txt"
        pedfilename=dir .* "ped.example2.csv"
        repeated_measures=false
        outputfilename=dir .* "out.example2.txt"
        Rvar=0.7 #total, not a proportion
        Gvar=0.3 #total, not a proportion
	Pvar=0
        y_tbl = loadtable(phenofilename; spacedelim = true)
        pedigree = get_pedigree(pedfilename)
        g_tbl, markerInfo = make_genotype_table(snpfilename)
        g_tbl = generate_genotypeclass_columns(g_tbl, markerInfo)
        tbl = join(y_tbl, g_tbl; lkey=:anml_key, rkey=:anml_key)
        tbl = MANA.center_phenotype(tbl)
        covariates = []
        if repeated_measures
                tbl = IndexedTables.transform(tbl, :anml_keyx => :anml_key)
                df = DataFrame(tbl)
                run_pedigree_model_multirecord(df, markerInfo, pedigree, Rvar, Gvar, Pvar; chainlength = 50000, outputfilename = outputfilename, covariates = covariates)
        else
                df = DataFrame(tbl)
                run_pedigree_model(df, markerInfo, pedigree, Rvar, Gvar; chainlength = 50000, outputfilename = outputfilename, covariates = covariates)
        end
end

main()


export encode_icm_cuda, train_lsq_cuda

"Encodes a database with ILS in cuda"
function encode_icm_cuda_single(
  RX::Matrix{Float32},         # in. The data to encode
  B::Matrix{Int16},            # in. Initial list of codes
  C::Vector{Matrix{Float32}},  # in. Codebooks
  ilsiters::Vector{Int64},     # in. ILS iterations to record Bs and obj function. Its max is the total number of iteration we will run.
  icmiter::Integer,            # in. Number of ICM iterations
  npert::Integer,              # in. Number of entries to perturb
  randord::Bool,               # in. Whether to randomize the order in which nodes are visited in ILS
  V::Bool=false)               # in. Whether to print progress

  d, n = size( RX )
  m    = length( C )
  _, h = size( C[1] )

  # Number of results to keep track of
  nr   = length( ilsiters )

  # Make space for the outputs
  Bs   = Vector{Matrix{Int16}}(undef, nr)
  objs = Vector{Float32}(undef, nr)

  # === Compute binary terms (products between all codebook pairs) ===
  binaries, cbi = get_binaries(C)
  _, ncbi       = size(cbi)

  # Create a transposed copy of the binaries for cache-friendliness
  binaries_t = similar(binaries)
  for j = 1:ncbi
    binaries_t[j] = collect(binaries[j]')
  end

  # Create an index from codebook pairs to indices
  cbpair2binaryidx = zeros(Int32, m, m)
  for j = 1:ncbi
    cbpair2binaryidx[ cbi[1,j], cbi[2,j] ] = j
  end

  dev = CuDevice(0)
  ctx = CuContext(dev)

  # Initialize the cuda module, and choose the GPU
  gpuid = 0
  CudaUtilsModule.init( gpuid, cudautilsptx )
  # CUDArt.device( devlist[gpuid] )

  # === Create a state for random number generation ===
  if V; @printf("Creating %d random states... ", n); start_time = time_ns(); end
  d_state = CUDAdrv.Mem.alloc(n*64)
  CudaUtilsModule.setup_kernel(cld(n, 1024), 1024, Cint(n), d_state)

  CUDAdrv.synchronize(ctx)
  if V; @printf("done in %.2f seconds\n", (time_ns() - start_time)/1e9); end

  # Measure time for encoding
  if V; start_time = time_ns(); end

  # Copy X and C to the GPU
  d_RX = CuArrays.CuArray(RX)
  d_C  = CuArrays.CuArray(cat(C..., dims=2))

  # === Get unaries in the gpu ===
  d_prevcost = CuArrays.CuArray{Cfloat}(n)
  d_newcost  = CuArrays.CuArray{Cfloat}(n)

  # CUBLAS.cublasCreate_v2( CUBLAS.cublashandle )
  d_unaries   = Vector{CuArrays.CuArray{Float32}}(undef, m)
  d_codebooks = Vector{CuArrays.CuArray{Float32}}(undef, m)
  for j = 1:m
    d_codebooks[j] = CuArrays.CuArray(C[j])
    # -2 * C' * X
    d_unaries[j] = CuArrays.BLAS.gemm('T', 'N', -2.0f0, d_codebooks[j], d_RX)
    # d_unaries[j] = -2.0f0 * d_codebooks[j]' * d_RX <-- thus runs out of memory real fast

    # Add self-codebook interactions || C_{i,i} ||^2
    CudaUtilsModule.vec_add(n, (1,h), d_unaries[j].buf, CuArrays.CuArray(diag( C[j]' * C[j] )).buf, Cint(n), Cint(h))
  end

  # === Get binaries to the GPU ===
  d_binaries  = Vector{CuArrays.CuArray{Float32}}(undef, ncbi)
  d_binariest = Vector{CuArrays.CuArray{Float32}}(undef, ncbi)
  for j = 1:ncbi
    d_binaries[j]  = CuArrays.CuArray(binaries[j])
    d_binariest[j] = CuArrays.CuArray(binaries_t[j])
  end

  # Allocate space for temporary results
  bbs = Vector{Matrix{Cfloat}}(undef, m-1)

  # Initialize the previous cost
  prevcost = Rayuela.veccost(RX, B, C)
  IDX = 1:n;

  # For codebook i, we have to condition on these codebooks
  to_look      = 1:m
  to_condition = zeros(Int32, m-1, m)
  for j = 1:m
    tmp = collect(1:m)
    splice!( tmp, j )
    to_condition[:,j] = tmp
  end

  # Loop for the number of requested ILS iterations
  for i = 1:maximum(ilsiters)

    # @show i, ilsiters
    # @time begin

    to_look_r      = to_look
    to_condition_r = to_condition

    # Compute the cost of the previous assignments
    # CudaUtilsModule.veccost(n, (1, d), d_RX, d_C, CuArray( convert(Matrix{Cuchar}, (B')-1) ), d_prevcost, Cint(m), Cint(n))
    CudaUtilsModule.veccost2(n, (1, d), d_RX.buf, d_C.buf, CuArrays.CuArray( convert(Matrix{Cuchar}, collect(B').-1) ).buf, d_prevcost.buf, Cint(d), Cint(m), Cint(n))
    CUDAdrv.synchronize(ctx)
    prevcost = Array(d_prevcost)

    newB = copy(B)

    # Randomize the visit order in ICM
    if randord
      to_look_r      = randperm( m )
      to_condition_r = to_condition[:, to_look_r]
    end

    d_newB = CuArrays.CuArray(convert(Matrix{Cuchar}, newB.-1 ))

    # Perturb `npert` entries in each code
    CudaUtilsModule.perturb(n, (1,m), d_state, d_newB.buf, Cint(n), Cint(m), Cint(npert))

    newB = Array( d_newB )
    Bt   = collect(newB')
    d_Bs = CuArrays.CuArray( Bt )

    CUDAdrv.synchronize(ctx)

    # Run the number of ICM iterations requested
    for j = 1:icmiter

      kidx = 1;
      # Loop through each MRF node
      for k = to_look_r

        lidx = 1;
        for l = to_condition_r[:, kidx]
          # Determine the pairwise tables that we'll use in this conditioning
          if k < l
            binariidx = cbpair2binaryidx[ k, l ]
            bbs[lidx] = binaries[ binariidx ]
          else
            binariidx = cbpair2binaryidx[ l, k ]
            bbs[lidx] = binaries_t[ binariidx ]
          end
          lidx = lidx+1;
        end

        # Transfer pairwise tables to the GPU
        d_bbs = CuArrays.CuArray( convert(Matrix{Cfloat}, cat(bbs..., dims=2)) )
        # Sum binaries (condition) and minimize
        CudaUtilsModule.condition_icm3(
          n, (1, h),
          d_unaries[k].buf, d_bbs.buf, d_Bs.buf, Cint(k-1), Cint(m), Cint(n) )
        CUDAdrv.synchronize(ctx)

        kidx = kidx + 1;
      end # for k = to_look_r
    end # for j = 1:icmiter

    newB = Array( d_Bs )
    newB = convert(Matrix{Int16}, newB')
    newB .+= 1

    # Keep only the codes that improved
    CudaUtilsModule.veccost2(n, (1, d), d_RX.buf, d_C.buf, d_Bs.buf, d_newcost.buf, Cint(d), Cint(m), Cint(n))
    CUDAdrv.synchronize(ctx)

    newcost = Array( d_newcost )

    areequal = newcost .== prevcost
    if V; @printf(" ILS iteration %d/%d done. ", i, maximum(ilsiters)); end
    if V; @printf("%5.2f%% new codes are equal. ", 100*sum(areequal)/n ); end

    arebetter = newcost .< prevcost
    if V; @printf("%5.2f%% new codes are better.\n", 100*sum(arebetter)/n ); end

    newB[:, .~arebetter] = B[:, .~arebetter]
    B = copy( newB )
    # end # @time

    # Check if this # of iterations was requested
    if i in ilsiters

      ithidx = findall( i .== ilsiters )[1]

      # Compute and save the objective
      obj = qerror( RX, B, C )
      # @show obj
      objs[ ithidx ] = obj
      # @show size(B)
      Bs[ ithidx ] = B

    end # end if i in ilsiters
  end # end for i=1:max(ilsiters)

  # CUBLAS.cublasDestroy_v2( CUBLAS.cublashandle )
  CudaUtilsModule.finit()

  destroy!(ctx)
  # end # do devlist

  if V; @printf(" Encoding done in %.2f seconds\n", (time_ns() -start_time)/1e9); end

  return Bs, objs
end

function encode_icm_cuda(
  RX::Matrix{Float32},         # in. The data to encode
  B::Matrix{Int16},            # in. Initial list of codes
  C::Vector{Matrix{Float32}},  # in. Codebooks
  ilsiters::Vector{Int64},     # in. ILS iterations to record Bs and obj function. Its max is the total number of iteration we will run.
  icmiter::Integer,            # in. Number of ICM iterations
  npert::Integer,              # in. Number of entries to perturb
  randord::Bool,               # in. Whether to randomize the order in which nodes are visited in ILS
  nsplits::Integer=2,          # in. Number of splits of the data (for limited memory GPUs)
  V::Bool=false)

  # TODO check that splits >= 1
  if nsplits == 1
    Bs, objs =  encode_icm_cuda_single(RX, B, C, ilsiters, icmiter, npert, randord, V)
    GC.gc()
    return Bs, objs
  end

  # Split the data
  d, n = size(RX)
  splits = splitarray(1:n, nsplits)
  nr = length(ilsiters)

  Bs   = Vector{Matrix{Int16}}(undef, nr)
  objs = zeros(Float32, nr)

  # Create storage space for the codes
  for i = 1:nr; Bs[i] = Matrix{Int16}(undef, size(B)); end

  # Run encoding in the GPU for each split
  for i = 1:nsplits
    aaBs, _ = encode_icm_cuda_single(RX[:,splits[i]], B[:,splits[i]], C, ilsiters, icmiter, npert, randord, V)
    GC.gc()
    for j = 1:nr
      # Save the codes
      Bs[j][:,splits[i]] = aaBs[j]
    end
  end

  # Compute the cost again
  for j = 1:nr
    objs[j] = qerror(RX, Bs[j], C)
  end

  GC.gc()
  return Bs, objs
end

"LSQ training but some things happen in the GPU"
function train_lsq_cuda(
  X::Matrix{T},         # d-by-n matrix of data points to train on.
  m::Integer,           # number of codebooks
  h::Integer,           # number of entries per codebook
  R::Matrix{T},         # init rotation
  B::Matrix{Int16},     # init codes
  C::Vector{Matrix{T}}, # init codebooks
  niter::Integer,       # number of optimization iterations
  ilsiter::Integer,     # number of ILS iterations to use during encoding
  icmiter::Integer,     # number of iterations of ICM
  randord::Bool,        # whether to use random order
  npert::Integer,       # The number of codes to perturb
  nsplits::Integer=1,   # The number of splits for icm encoding (for limited memory GPUs)
  V::Bool=false) where T <: AbstractFloat # whether to print progress

  if V
    println()
    println("**********************************************************************************************");
    println("Training LSQ GPU with $m codebooks, $npert perturbations, $icmiter icm iterations and random order = $randord");
    println("**********************************************************************************************");
  end

  d, n = size( X )

  # Initialize C
  RX = R' * X
  C = update_codebooks(RX, B, h, V, "fastbin")

  # Apply the rotation to the codebooks
  for i = 1:m; C[i] = R * C[i]; end
  if V; @printf("%3d %e \n", -2, qerror(X, B, C)); end

  # Initialize B
  B, _ = encode_icm_cuda(X, B, C, [ilsiter], icmiter, npert, randord, nsplits, V)
  B    = B[end]
  if V; @printf("%3d %e \n", -1, qerror(X, B, C)); end

  obj = zeros(T, niter)

  for iter = 1:niter
    obj[iter] = qerror(X, B, C)
    if V; @printf("%3d %e \n", iter, obj[iter]); end

    # Update the codebooks
    C = update_codebooks(X, B, h, V, "fastbin")

    # Update the codes B
    B, _ = encode_icm_cuda(X, B, C, [ilsiter], icmiter, npert, randord, nsplits, V)
    B    = B[end]
  end

  return C, B, obj
end

function experiment_lsq_cuda(
  Xt::Matrix{T}, # d-by-n. Data to learn codebooks from
  B::Matrix{T2}, # codes
  C::Vector{Matrix{T}}, # codebooks
  R::Matrix{T}, # rotation
  Xb::Matrix{T}, # d-by-n. Base set
  Xq::Matrix{T}, # d-by-n. Queries
  gt::Vector{UInt32}, # ground truth
  m::Integer,    # number of codebooks
  h::Integer,    # number of entries per codebook
  niter::Integer=25, # Number of C-B update updates
  ilsiter::Integer=8, # number of ILS iterations
  icmiter::Integer=4, # number of ICM iterations
  randord::Bool=true, # whether to explore the codes in random order
  npert::Integer=4, # numebr of codes to perturb in each ILS iterations
  knn::Integer=1000, # Compute recall @N for this value of N
  nsplits_train::Integer=1, # Number of splits for training data so GPU does not run out of memory
  nsplits_base::Integer=1, # Number of splits for training data so GPU does not run out of memory
  V::Bool=false) where {T <: AbstractFloat, T2 <: Integer} # whether to print progress

  # Train LSQ
  d, _ = size(Xt)
  @printf("Running CUDA LSQ training... ")
  C, B, train_error = Rayuela.train_lsq_cuda(Xt, m, h, R, B, C, niter, ilsiter, icmiter, randord, npert, nsplits_train, V)
  @printf("done\n")

  norms_B, norms_C = get_norms_codebook(B, C)

  # === Encode the base set ===
  B_base = convert(Matrix{Int16}, rand(1:h, m, size(Xb,2)))
  Bs_base, _ = Rayuela.encode_icm_cuda(Xb, B_base, C, [ilsiter * 4], icmiter, npert, randord, nsplits_base, V)
  B_base = Bs_base[end]
  base_error = qerror(Xb, B_base, C)
  if V; @printf("Error in base is %e\n", base_error); end

  # Compute and quantize the database norms
  B_base_norms, db_norms_X = quantize_norms( B_base, C, norms_C )
  db_norms     = vec( norms_C[ B_base_norms ] )

  if V; print("Querying m=$m ... "); end
  @time dists, idx = linscan_lsq(B_base, Xq, C, db_norms, Matrix{Float32}(1.0I, d, d), knn)
  # @time dists, idx = linscan_lsq(B_base, Xq, C, db_norms_X, eye(Float32, d), knn)
  if V; println("done"); end

  recall = eval_recall(gt, idx, knn)
  return C, B, R, train_error, B_base, recall
end

function experiment_lsq_cuda_query_base(
  Xt::Matrix{T}, # d-by-n. Data to learn codebooks from
  B::Matrix{T2}, # codes
  C::Vector{Matrix{T}}, # codebooks
  R::Matrix{T}, # rotation
  Xq::Matrix{T}, # d-by-n. Queries
  gt::Vector{UInt32}, # ground truth
  m::Integer,    # number of codebooks
  h::Integer,    # number of entries per codebook
  niter::Integer=25, # Number of C-B update updates
  ilsiter::Integer=8, # Number of ILS iterations
  icmiter::Integer=4, # Number of ICM iterations
  randord::Bool=true, # Whether to explore the codes in random order
  npert::Integer=4, # Number of codes to perturb in each ILS iterations
  knn::Integer=1000, # Compute recall @N for this value of N
  nsplits_train::Integer=1, # Number of splits for training data so GPU does not run out of memory
  V::Bool=false) where {T <: AbstractFloat, T2 <: Integer} # whether to print progress

  # Train LSQ
  d, _ = size(Xt)
  if V; @printf("Running CUDA LSQ training... "); end
  C, B, train_error = Rayuela.train_lsq_cuda(Xt, m, h, R, B, C, niter, ilsiter, icmiter, randord, npert, nsplits_train, V)
  if V; @printf("done\n"); end

  norms_B, norms_C = get_norms_codebook(B, C)
  db_norms         = vec(norms_C[ norms_B ])

  if V; print("Querying m=$m ... "); end
  @time dists, idx = linscan_lsq(B, Xq, C, db_norms, Matrix{Float32}(1.0*I, d, d), knn)
  if V; println("done"); end

  recall = eval_recall(gt, idx, knn)
  return C, B, R, train_error, recall
end

"Runs an lsq experiment/demo"
function experiment_lsq_cuda(
  Xt::Matrix{T}, # d-by-n. Data to learn codebooks from
  Xb::Matrix{T}, # d-by-n. Base set
  Xq::Matrix{T}, # d-by-n. Queries
  gt::Vector{UInt32}, # ground truth
  m::Integer,    # number of codebooks
  h::Integer,    # number of entries per codebook
  niter::Integer=25, # Number of C-B update updates
  ilsiter::Integer= 8, # number of ILS iterations
  icmiter::Integer=4, # number of ICM iterations
  randord::Bool=true, # whether to explore the codes in random order
  npert::Integer=4, # numebr of codes to perturb in each ILS iterations
  knn::Integer=1000,
  nsplits_train::Integer=1, # Number of splits for training data so GPU does not run out of memory
  nsplits_base::Integer=1, # Number of splits for training data so GPU does not run out of memory
  V::Bool=false) where T <: AbstractFloat # whether to print progress

  # OPQ initialization
  @printf("Running OPQ initialization... ")
  C, B, R, _ = train_opq(Xt, m, h, niter, "natural", V)
  @printf("done\n")

  # ChainQ (second initialization)
  # @printf("Running ChainQ initialization... ")
  # C, B, R, train_error = train_chainq(Xt, m, h, R, B, C, niter, V)
  # @printf("done\n")

  # Actual experiment
  experiment_lsq_cuda(Xt, B, C, R, Xb, Xq, gt, m, h, niter, ilsiter, icmiter, randord, npert, knn, nsplits_train, nsplits_base, V)
end

function experiment_lsq_cuda_query_base(
  Xt::Matrix{T}, # d-by-n. Data to learn codebooks from
  Xq::Matrix{T}, # d-by-n. Queries
  gt::Vector{UInt32}, # ground truth
  m::Integer,    # number of codebooks
  h::Integer,    # number of entries per codebook
  niter::Integer=25, # Number of C-B update updates
  ilsiter::Integer= 8, # number of ILS iterations
  icmiter::Integer= 4, # number of ICM iterations
  randord::Bool=true, # whether to explore the codes in random order
  npert::Integer= 4, # numebr of codes to perturb in each ILS iterations
  init::String="natural",
  niter_opq::Integer=25,
  noter_chainq::Integer=25,
  knn::Integer=1000,
  nsplits_train::Integer=1, # Number of splits for training data so GPU does not run out of memory
  V::Bool=false) where T <: AbstractFloat # whether to print progress

  # OPQ initialization
  if V; @printf("Running OPQ initialization... "); end
  C, B, R, opq_error = train_opq(Xt, m, h, niter_opq, init, V)
  if V; @printf("done\n"); end

  # ChainQ (second initialization)
  if V; @printf("Running ChainQ initialization... "); end
  C, B, R, chainq_error = train_chainq(Xt, m, h, R, B, C, niter_chainq, V)
  if V; @printf("done\n"); end

  # Actual experiment
  experiment_lsq_cuda_query_base(Xt, B, C, R, Xq, gt, m, h, niter, knn, nsplits_train, V), opq_error
end


@testset " Hydro Tests" begin
    PSI.activepower_variables(ps_model, generators_hg, 1:24)
    PSI.activepower_constraints(ps_model, generators_hg, PSI.HydroDispatchRunOfRiver, PM.DCPlosslessForm, 1:24)
    PSI.activepower_constraints(ps_model, generators_hg, PSI.HydroDispatchRunOfRiver, PM.StandardACPForm, 1:24)
    PSI.reactivepower_variables(ps_model, generators_hg, 1:24)
    PSI.reactivepower_constraints(ps_model, generators_hg, PSI.HydroDispatchRunOfRiver, PM.StandardACPForm, 1:24)
end

@testset " Hydro Tests" begin
    ps_model = PSI._canonical_model_init(length(sys5b.buses), nothing, PM.AbstractPowerFormulation, sys5b.time_periods)
    PSI.activepower_variables(ps_model, generators_hg, 1:24)
    PSI.commitment_variables(ps_model, generators_hg, 1:24);
    PSI.activepower_constraints(ps_model, generators_hg, PSI.HydroCommitmentRunOfRiver, PM.DCPlosslessForm, 1:24)
    PSI.activepower_constraints(ps_model, generators_hg, PSI.HydroCommitmentRunOfRiver, PM.StandardACPForm, 1:24)
    PSI.reactivepower_variables(ps_model, generators_hg, 1:24)
    PSI.reactivepower_constraints(ps_model, generators_hg, PSI.HydroCommitmentRunOfRiver, PM.StandardACPForm, 1:24)
end


#unum-test-addition.jl

#testing addition

################################################################################
## TESTING HELPER functions

#__carried_add
#double cell, double zero
test_array = Unums.ArrayNum{7}([z64, z64])
@test z64 == Unums.i64add!(z64, test_array, test_array)
@test test_array.a == [z64, z64]

@test o64 == Unums.i64add!(o64, test_array, test_array) #with a passthru carry
@test test_array.a == [z64, z64]

#double cell, less significant number adds in to carry
add_array = Unums.ArrayNum{7}([z64, f64])
test_array.a = [z64, o64]
@test z64 == Unums.i64add!(z64, test_array, add_array)
@test test_array.a == [o64, z64]

#double cell, double less significant number ff..ff
add_array.a = [z64, f64]
test_array.a = [z64, f64]
@test z64 == Unums.i64add!(z64, test_array, add_array)
@test test_array.a == [o64, ~o64]

#double cell, double upper ff..ff
add_array.a = [f64, z64]
test_array.a = [f64, z64]
@test o64 == Unums.i64add!(z64, test_array, add_array)
@test test_array.a == [~o64, z64]

#with a passthru carry
test_array.a = [f64, z64]
@test 2 == Unums.i64add!(o64, test_array, add_array)
@test test_array.a == [~o64, z64]

#create f's from whole cloth and pass it through
add_array.a = [0x9999_9999_9999_9999, f64]
test_array.a = [0x6666_6666_6666_6666, o64]
#@test 1 == Unums.__carried_add!(z64, add_array, test_array)
Unums.i64add!(z64, test_array, add_array)
@test test_array.a == [z64, z64]

#just let's make sure this works with even bigger arrays
test_array = Unums.ArrayNum{8}([f64, f64, f64, f64])
add_array = Unums.ArrayNum{8}([f64, f64, f64, f64])
@test 1 == Unums.i64add!(z64, test_array, add_array)
@test test_array.a == [f64, f64, f64, ~o64]

#test __sum_exact, which adds two exact sums, with magnitude(a) > magnitude(b)
wone = convert(Unum{4,6}, 1)
wtwo = convert(Unum{4,6}, 2)
wthr = convert(Unum{4,6}, 3)

@test wone + wone == wtwo
@test wtwo + wone == wthr

################################################################################
#unit tests discovered through debugging.

ten = convert(Unum{3,6}, 10)
fifteen = convert(Unum{3,6}, 15)
@test calculate(ten + fifteen) == 25

#=
=======
#__shift_after_add(carry, value) - resolves the result of a carry operation, and reports shift amt, and falloff.
@test Unums.__shift_after_add(UInt64(2), t64, z16) == (0x4000_0000_0000_0000, 1, z16)
@test Unums.__shift_after_add(UInt64(3), t64, z16) == (0xC000_0000_0000_0000, 1, z16)
@test Unums.__shift_after_add(UInt64(2), o64, z16) == (0x0000_0000_0000_0000, 1, Unums.UNUM_UBIT_MASK)
@test Unums.__shift_after_add(UInt64(3), o64, z16) == (0x8000_0000_0000_0000, 1, Unums.UNUM_UBIT_MASK)
@test Unums.__shift_after_add(UInt64(2), [z64,t64], z16) == ([z64, 0x4000_0000_0000_0000], 1, z16)
@test Unums.__shift_after_add(UInt64(3), [z64,t64], z16) == ([z64, 0xC000_0000_0000_0000], 1, z16)
@test Unums.__shift_after_add(UInt64(2), [o64,z64], z16) == ([z64, z64], 1, Unums.UNUM_UBIT_MASK)
@test Unums.__shift_after_add(UInt64(3), [o64,z64], z16) == ([z64, t64], 1, Unums.UNUM_UBIT_MASK)
=#

#test __sum_exact, which adds two exact sums, with magnitude(a) > magnitude(b)
wtwo  = Unum{4,6}(o64      ,z64,z16,z16      ,z16)
wfour = Unum{4,6}(UInt64(3),z64,z16,UInt16(1),z16)
wsix  = Unum{4,6}(UInt64(3),t64,z16,UInt16(1),z16)
@test Unums.sum_exact(wtwo, wtwo, 1, 1) == wfour   #one plus one is two
@test Unums.sum_exact(wfour, wtwo, 2, 1) == wsix    #one plus two is three

wbig =  Unum{4,6}(UInt64(0xd0), z64, z16,                   0x0007, z16)
wbigu = Unum{4,6}(UInt64(0xd0), z64, Unums.UNUM_UBIT_MASK,  0x0007, 0x003f)
wmed =  Unum{4,6}(UInt64(0xc0), z64, z16,                   0x0007, z16)
wmd2 =  Unum{4,6}(UInt64(0xbf), z64, z16,                   0x0007, z16)
whlf =  Unum{4,6}(UInt64(0x02), z64, z16,                   0x0002, 0x0001)
@test Unums.sum_exact(wbig, wtwo, 81, 1)  == wbigu
@test Unums.sum_exact(wmed, wtwo, 65, 1)  == Unum{4,6}(UInt64(0xc0), o64,                   z16,                  0x0007, 0x003f)
@test Unums.sum_exact(wmd2, wtwo, 64, 1)  == Unum{4,6}(UInt64(0xbf), UInt64(2),             z16,                  0x0007, 0x003e)
@test Unums.sum_exact(wmed, wmd2, 65, 64) == Unum{4,6}(UInt64(0xc0), 0x8000_0000_0000_0000, z16,                  0x0007, z16   )
@test Unums.sum_exact(wmed, whlf, 65, 0)  == Unum{4,6}(UInt64(0xc0), z64,                   Unums.UNUM_UBIT_MASK, 0x0007, 0x003f)

#subnormal mathematics
wsml = Unum{4,6}(z64, 0x8000_0000_0000_0000, z16, o16, z16   )
wtny = Unum{4,6}(z64, 0x0001_0000_0000_0000, z16, z16, 0x000F)
#println(Unums.__sum_exact(wsml, wtny, -1, -1))
@test Unums.sum_exact(wsml, wtny, 0, 0) == Unum{4,6}(z64, 0x8001_0000_0000_0000, z16, z16, 0x000F)
#note that wsml is also the same as whlf
@test wone == whlf + whlf
@test wone == wsml + wsml
@test wone == wsml + whlf

#don't forget to write a test case where we add a dominant 'strange subnormal'
#to a 'normal' float of lower magnitude.
wsml = Unum{4,6}(z64, 0x8000_0000_0000_0000, z16, o16, z16   )
wqrt = Unum{4,6}(o64, z64, z16, UInt16(2), z16)
@test wsml + wqrt == Unum{4,6}(z64, 0xc000_0000_0000_0000, z16, o16, o16)

#two-cell arithmetic, with one hell of a carry.
tbig = Unum{4,7}(UInt64(0b10), [f64, f64], z16, o16, UInt16(127))
tsma = Unum{4,7}(UInt64(0b10), [z64, o64], z16, o16, UInt16(127))
ttot = Unum{4,7}(UInt64(0b11), [t64, z64], z16, o16, z16        )
@test tbig + tsma == ttot

#sometimes adding an ulp and a non-ulp doesn't work.  Discovered by basic
#demonstration of the addition problem.

x = Unum{2,2}(32)
x += one(Unum{2,2})
x += one(Unum{2,2})
y = Unums.make_ulp!(Unum{2,2}(32))
y.fsize = 0x0002
@test x == y

x = Unum{2,2}(0x000000000000000C, 0x2000000000000000, 0x0001, 0x0003, 0x0003)
x += one(Unum{2,2})
b = Unum{2,2}(0x000000000000000C, 0x2000000000000000, 0x0001, 0x0003, 0x0002)
@test x == b

#adding two ulps sometimes doesn't work.  Discovered by basic demonstration of
#0.2 + 0.1 != 0.3
x = Unum{4,6}(2) / Unum{4,6}(10)
y = Unum{4,6}(1) / Unum{4,6}(10)
z = x + y

@test Unums.lub(z) > Unum{4,6}(0x0000000000000001, 0x3333333333333333, 0x0000, 0x0002, 0x003F)

x = Unum{4,6}(1) / Unum{4,6}(3)
z = x + x + x
@test Unums.lub(z) > one(Unum{4,6})

##############################################
## tests discovered by continuous testing.

#9 september 2015:  Having problems with some ubound addition. (throws error)
ctub1 = Unum{4,6}(0x0000000000000376,0xb282a906ed2d8f0c,0x0003,0x0009,0x003f)
ctub2 = Unum{4,6}(0x0000000000000376,0x3282a906ed2d8f01,0x0003,0x0009,0x003f)
ctu1 = Ubound(ctub1, ctub2)
ctu2 = Unum{4,6}(0x00000000000001cc,0x6beb9d225f1e6000,0x0001,0x0008,0x0032)
@test ctu1 + ctu2 == Ubound{4,6}(Unum{4,6}(0x0000000000000376,0xb282a906ed2d8f0c,0x0003,0x0009,0x003f),Unum{4,6}(0x0000000000000376,0x3282a906ed2d8f00,0x0003,0x0009,0x003f))

#resolved when an coding error was discovered:  UNUM_UBIT_MASK instead of UNUM_SIGN_MASK
#10 september 2015: (throws error)
ctub3 = Unum{4,6}(0x000000000000001d,0xde044b871cc5f67f,0x0003,0x0004,0x003f)
ctub4 = Unum{4,6}(0x000000000000001d,0xde044b871cc5f67d,0x0003,0x0004,0x003f)
ctu3 = Ubound{4,6}(ctub3,ctub4)
ctu4 = Unum{4,6}(0x00000000000001b8,0x1a757044fa76a000,0x0000,0x0008,0x0032)
@test ctu3 + ctu4 == Unum{4,6}(0x00000000000001b8,0x1a757044fa769fff,0x0001,0x0008,0x003f)
#resolved by adding a test to see if the two added values were very far apart.
#at the ubound level in addition to at the unum level. caused a revision in the
#previous test as well.

#11 september 2015: (throws error)
ctub5 = Unum{4,6}(0x00000000000000f1,0x3db8d7e07e3733ee,0x0001,0x0007,0x003f)
ctub6 = Unum{4,6}(0x00000000000000f1,0xbdb8d7e07e3733f3,0x0001,0x0007,0x003f)
ctu5 = Ubound(ctub5, ctub6)
ctu6 = Unum{4,6}(0x00000000000000f2,0x4410e89562546000,0x0002,0x0007,0x0032)

@test ctu5 + ctu6 == Ubound{4,6}(Unum{4,6}(0x00000000000000f1,0x4a68f94a46718c11,0x0003,0x0007,0x003f), Unum{4,6}(0x00000000000000f0,0x94d1f2948ce31818,0x0003,0x0007,0x003f))
#problem occurs due to an incorrect handling of trailing bits after shift in
#__diff_exact.


module KongYiji

import Base: size, split, display, read, write, first, stat, push!, length, iterate, ==, getindex, summary, collect, values, isless, get, eachmatch, in

using Pkg
using JLD2, FileIO
using Random, DataStructures, ProgressMeter, DelimitedFiles, DataFrames

export postable, h2vtable, v2htable, h2htable, hprtable, kwictable,
        ChTreebank, ZhuXian, posidsents, wordsents, rawsents,
        UselessTable, HMM, NGramHMM

#=
export generate!, train!, LM, LMHMM
=#

const Ti = UInt32
const Tv = Float32
const oo = Tv(Inf)
const EPS = Tv(1e-9)

include("utils.jl")

include("CtbTree.jl")
include("ChTreebank.jl")

include("ZhuXian.jl")

include("UselessTable.jl")
include("compress.jl")
include("AhoCorasickAutomaton.jl")

include("HmmUtils.jl")
include("HmmScoreTable.jl")
include("IcwbScoreTable.jl")
include("HMM.jl")
include("NGramHMM.jl")

#include("LM.jl")
#include("Heap.jl")
#include("LMHMM.jl")

end # module