diff --git a/src/FiniteStateAutomata.jl b/src/FiniteStateAutomata.jl
index 02dfe841977dd42ef442671f77048fe6d58181bb..1ada8976ab4f1303a4d0090af73b4b6c5c11c2c5 100644
--- a/src/FiniteStateAutomata.jl
+++ b/src/FiniteStateAutomata.jl
@@ -13,6 +13,7 @@ export
     # concrete types
     AcyclicFSA,
     FSA,
+    DenseFSA,
 
     # Accessors / properties
     α,
@@ -39,6 +40,7 @@ export
 
 include("abstractfsa.jl")
 include("fsa.jl")
+include("dense_fsa.jl")
 include("ops.jl")
 
 end
diff --git a/src/dense_fsa.jl b/src/dense_fsa.jl
new file mode 100644
index 0000000000000000000000000000000000000000..2032bed42552deb1c7d912f85e243e637a7a6931
--- /dev/null
+++ b/src/dense_fsa.jl
@@ -0,0 +1,37 @@
+struct DenseFSA{K, L} <: AbstractAcyclicFSA{K, L}
+    H::AbstractMatrix{K}
+    Σ::AbstractVector{L}
+    ρ::K
+end
+
+α(G::DenseFSA) = begin
+    L = length(G.Σ)
+    N = size(G.H, 2)
+    S = L * (N-1)
+    sparsevec(1:L, G.H[:, 1], S)
+end
+T(G::DenseFSA{K}) where K = begin
+    rows = []
+    cols = []
+    vals = K[]
+    L = length(G.Σ)
+    N = size(G.H, 2)
+    S = L * (N - 1)
+    for n in 2:N - 1
+        v = repeat(G.H[:, n], L) # flatten
+        r = [(n-2)*L + i for i in 1:L for _ in 1:L]
+        c = [(n-1)*L + i for _ in 1:L for i in 1:L]
+        rows = vcat(rows, r)
+        cols = vcat(cols, c)
+        vals = vcat(vals, v)
+    end
+    sparse(rows, cols, vals, S, S)
+end
+ω(G::DenseFSA) = begin
+    L = length(G.Σ)
+    N = size(G.H, 2)
+    S = L*(N - 1)
+    sparsevec(S - L + 1:S, G.H[:, N], S)
+end
+ρ(G::DenseFSA) = G.ρ
+λ(G::DenseFSA) = repeat(G.Σ, size(G.H, 2) - 1)