diff --git a/experiments/cdc_4-boudaries.py b/experiments/cdc_4-boudaries.py
index 60a4df1573b81da4fe8d4f29185042e293559308..3fbcff8e9c939159c2d0909ec2750a14ac5fdf77 100755
--- a/experiments/cdc_4-boudaries.py
+++ b/experiments/cdc_4-boudaries.py
@@ -21,8 +21,27 @@ LadderGadget = lambda k: CyclicLadder().gadget(k)
 ladders = list(map(LadderGadget, range(2, 8)))
 gadgets = [ l.permute((1,) + p) 
   for l in ladders for p in permutations([2, 3, 4]) ]
+
 M = parameter_matrix(CircuitDoubleCover, gadgets)
+pivot_rows = M.pivot_rows()
+
+gadgets = [ gadgets[i] for i in pivot_rows ]
+MM = parameter_matrix(CircuitDoubleCover, gadgets)
+
+B, J = edge_model_join_matrix(CircuitDoubleCover, 4, boundaries=True)
+p = J.pivot_rows()
 
 if __name__ == "__main__":
-  print("Matrix of size %i with rank %i" % (M.nrows(), M.rank()))
+  print("Circuit double covers -- 4-boundaries:")
+  print("Lower bound: Matrix of size %i with rank %i" % (M.nrows(), len(pivot_rows)))
+  print("  Pivot rows: %s" % (pivot_rows,))
+  print("  Rank of reduced matrix: %i" % (MM.rank(),))
+  print("Upper bound: Join matrix of size %i with rank %i" % (J.nrows(), J.rank()))
+  print("  Pivot rows: %s" % (p,))
+  print("  Idependent boundaries:")
+  for i in p: print("    %s" % (B[i],))
+  print("\n  Unused boundaries:")
+  for i in range(J.nrows()):
+    if i not in p: print("    %s" % (B[i],))
+
 
diff --git a/experiments/cdc_5-boudaries.py b/experiments/cdc_5-boudaries.py
new file mode 100755
index 0000000000000000000000000000000000000000..ccc0ddd1daf5714aa8ad8bfafa022b8c4849c538
--- /dev/null
+++ b/experiments/cdc_5-boudaries.py
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+
+"""
+Calculate a lower bound on the number of 4-boundaries
+of a linear representation of the number of circuit double
+covers.
+
+It uses cyclic ladder gadgets with sizes 2 up to 7 with
+permutations of all half-edges except the first one.
+This gives matrix of size 36 with rank 21.
+"""
+
+import sys, os
+sys.path.append(os.path.dirname(__file__) + "/..")
+
+from itertools import permutations
+from graph_tools.all import *
+
+
+def LadderGadget(k):
+  g = CyclicLadder().gadget(k)
+  return Gadget.join([g, CUBIC_VERTEX], [((1, 1), (2, 1))],
+    [(2,2), (2,3), (1,2), (1,3), (1,4)])
+
+ladders = list(map(LadderGadget, range(2, 8)))
+gadgets = [ l.permute((1,) + p) 
+  for l in ladders for p in permutations([2, 3, 4, 5])  ] + [
+  l.permute((3,) + p) for l in ladders for p in permutations([1, 2, 4, 5])  ] + [
+  l.permute((4,) + p) for l in ladders for p in permutations([1, 2, 3, 5])  ] + [
+  l.permute((5,) + p) for l in ladders for p in permutations([1, 2, 3, 4])  ]
+
+M = parameter_matrix(CircuitDoubleCover, gadgets, threads=None)
+pivot_rows = M.pivot_rows()
+
+J = edge_model_join_matrix(CircuitDoubleCover, 5, threads=None)
+
+if __name__ == "__main__":
+  print("Circuit double covers -- 5-boundaries:")
+  print("Matrix of size %i with rank %i" % (M.nrows(), M.rank()))
+  print("  Pivot rows: %s" % (pivot_rows,))
+  print("Upper bound: Join matrix of size %i with rank %i" % (J.nrows(), J.rank()))
+