# Attached Documents

#### mercurial patch (logilab-hmm.patch)

```# HG changeset patch
# User John Gill <swfiua@gmail.com>
# Date 1365509628 10800
# Node ID 5ed184be02907b895e7bb4956ff67cf63285e4a3
# Parent  d0001349c7ebe557c726d68699451c0cc0dda313
Add generator, generate_observations() so observations can be simulated
using the generator and fix the simulate() method to use the new
generator.

diff --git a/hmm.py b/hmm.py
--- a/hmm.py
+++ b/hmm.py
@@ -396,26 +396,36 @@
k += 1
return indices

-    def simulate( self, length, show_hidden = 0 ):
-        """generates a random sequence of observations of given length
-        if show_hidden is true, returns a liste of (state,observation)"""
+    def generate_observations( self, show_hidden = 0 ):
+        """ Generator to generate a random sequence of observations.
+
+        If show_hidden is true, yields a list of (state,observation)
+        """
cumA = cumsum( self.A, 1 )
cumB = cumsum( self.B, 0 )
r0 = random()
state = searchsorted( cumsum(self.pi, 0), r0)
-        seq = []
-        states = []
-
-        for i in xrange(length):
-            states.append(state)
+
+        while True:
r1 = random()
symbol = self.omega_O[ searchsorted( cumB[:, state], r1 ) ]
if show_hidden:
-                seq.append( (self.omega_X[state], symbol) )
+                yield (self.omega_X[state], symbol)
else:
-                seq.append(symbol)
+                yield symbol
r2 = random()
state = searchsorted( cumA[state, :], r2 )
+
+
+    def simulate( self, length, show_hidden = 0 ):
+        """generates a random sequence of observations of given length
+        if show_hidden is true, returns a liste of (state,observation)"""
+        seq = []
+        for ix, item in enumerate(self.generate_observations(show_hidden)):
+            if ix == length:
+                break
+            seq.append(item)
+
return seq

def analyze( self, observations ):
```