diff --git a/src/lib.rs b/src/lib.rs
index e8a903a3e0d1823106be391dd357807c9d1def34..ef097f0457437baed34d9ccb62455f041d1cb36b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,4 +2,5 @@
 
 mod abc;
 mod dense;
+mod pwm;
 mod seq;
diff --git a/src/pwm.rs b/src/pwm.rs
new file mode 100644
index 0000000000000000000000000000000000000000..3ade48b6a86dd67927869bcb91096e7fd02b27a1
--- /dev/null
+++ b/src/pwm.rs
@@ -0,0 +1,36 @@
+use super::abc::Alphabet;
+use super::abc::Symbol;
+use super::dense::DenseMatrix;
+use super::seq::EncodedSequence;
+
+#[derive(Clone, Debug)]
+pub struct CountMatrix<A: Alphabet, const K: usize> {
+    pub alphabet: A,
+    pub data: DenseMatrix<u32, K>,
+}
+
+impl<A: Alphabet, const K: usize> CountMatrix<A, K> {
+    pub fn from_sequences<'seq, I>(sequences: I) -> Result<Self, ()>
+    where
+        I: IntoIterator<Item = &'seq EncodedSequence<A>>,
+    {
+        let mut data = None;
+        for seq in sequences {
+            let mut d = match data.as_mut() {
+                Some(d) => d,
+                None => {
+                    data = Some(DenseMatrix::new(seq.len()));
+                    data.as_mut().unwrap()
+                }
+            };
+            for (i, x) in seq.data.iter().enumerate() {
+                d[i][x.as_index()] += 1;
+            }
+        }
+
+        Ok(Self {
+            alphabet: A::default(),
+            data: data.unwrap_or_else(|| DenseMatrix::new(0)),
+        })
+    }
+}