diff --git a/neet/automata.py b/neet/automata.py
index aaa9971..e94dfd7 100644
--- a/neet/automata.py
+++ b/neet/automata.py
@@ -182,7 +182,7 @@ class ECA(object):
 
         return True
 
-    def _unsafe_update(self, lattice):
+    def _unsafe_update(self, lattice, index=None):
         """
         Update the state of the ``lattice``, in place, without
         checking the validity of the arguments.
@@ -194,13 +194,25 @@ class ECA(object):
             >>> ca = ECA(30)
             >>> xs = [0,0,1,0,0]
             >>> ca._unsafe_update(xs)
+            [0, 1, 1, 1, 0]
             >>> xs
             [0, 1, 1, 1, 0]
             >>> ca.boundary = (0,1)
             >>> ca._unsafe_update(xs)
-            >>> xs
             [1, 1, 0, 0, 0]
 
+        ::
+
+            >>> ca = ECA(30)
+            >>> xs = [0,0,1,0,0]
+            >>> ca._unsafe_update(xs, index=1)
+            [0, 1, 1, 0, 0]
+            >>> xs
+            [0, 1, 1, 0, 0]
+            >>> ca.boundary = (0,1)
+            >>> ca._unsafe_update(xs, index=-1)
+            [0, 1, 1, 0, 1]
+
         ::
 
             >>> xs = [0,0,2,0,0]
@@ -210,6 +222,8 @@ class ECA(object):
 
         :param lattice: the one-dimensional sequence of states
         :type lattice: sequence
+        :param index: the index to update (or None)
+        :type index: int
         :returns: the updated lattice
         """
         if self.boundary:
@@ -219,15 +233,33 @@ class ECA(object):
             left  = lattice[-1]
             right = lattice[0]
         code = self.code
-        d = 2 * left + lattice[0]
-        for i in range(1, len(lattice)):
-            d = 7 & (2 * d + lattice[i])
-            lattice[i-1] = 1 & (code >> d)
-        d = 7 & (2 * d + right)
-        lattice[-1] = 1 & (code >> d)
+        if index is None:
+            d = 2 * left + lattice[0]
+            for i in range(1, len(lattice)):
+                d = 7 & (2 * d + lattice[i])
+                lattice[i-1] = 1 & (code >> d)
+            d = 7 & (2 * d + right)
+            lattice[-1] = 1 & (code >> d)
+        else:
+            if index < 0:
+                index += len(lattice)
+
+            if index == 0:
+                d = left
+            else:
+                d = lattice[index-1]
+
+            d = 2 * d + lattice[index]
+
+            if index + 1 == len(lattice):
+                d = 2 * d + right
+            else:
+                d = 2 * d + lattice[index+1]
+
+            lattice[index] = 1 & (code >> (7 & d))
         return lattice
 
-    def update(self, lattice):
+    def update(self, lattice, index=None):
         """
         Update the state of the ``lattice`` in place.
 
@@ -237,13 +269,13 @@ class ECA(object):
 
             >>> ca = ECA(30)
             >>> xs = [0,0,1,0,0]
-            >>> ca.update(xs)
+            >>> ca.update(xs, index=1)
+            [0, 1, 1, 0, 0]
             >>> xs
-            [0, 1, 1, 1, 0]
-            >>> ca.boundary = (0,1)
-            >>> ca.update(xs)
-            >>> xs
-            [1, 1, 0, 0, 0]
+            [0, 1, 1, 0, 0]
+            >>> ca.boundary = (1,1)
+            >>> ca.update(xs, index=-1)
+            [0, 1, 1, 0, 1]
 
         ::
 
@@ -257,13 +289,22 @@ class ECA(object):
             Traceback (most recent call last):
                 ...
             ValueError: invalid value "2" in lattice
+            >>> ca.update(xs, index=5)
+            Traceback (most recent call last):
+                  ...
+            IndexError: list index out of range
 
         :param lattice: the one-dimensional sequence of states
         :type lattice: sequence
+        :param index: the index to update (or None)
+        :type index: int
         :returns: the updated lattice
         :raises ValueError: if ``lattice`` is empty
         :raises TypeError: if ``lattice`` is not iterable
         :raises ValueError: unless :math:`lattice[i] \in \{0,1\}` for all :math:`i`
+        :raises IndexError: if ``index is not None and index > len(states)``
         """
         ECA.check_lattice(lattice)
-        return self._unsafe_update(lattice)
+        if index is not None and index < -len(lattice):
+            raise(IndexError("lattice index out of range"))
+        return self._unsafe_update(lattice, index)

Add an optional index argument to network update methods
This adds ability for asynchronous updating
diff --git a/test/test_automata.py b/test/test_automata.py
index fcee65b..52d3cf0 100644
--- a/test/test_automata.py
+++ b/test/test_automata.py
@@ -260,3 +260,51 @@ class TestECA(unittest.TestCase):
         eca.update(lattice)
         self.assertTrue(np.array_equal([1,1,0,0,0], lattice))
 
+
+    def test_update_index_error(self):
+        eca = ca.ECA(30)
+        with self.assertRaises(IndexError):
+            eca.update([0,0], index=2)
+
+        with self.assertRaises(IndexError):
+            eca.update([0,0], index=-3)
+
+
+    def test_update_index(self):
+        eca = ca.ECA(30, (1,1))
+
+        lattice = [0,0,0,0,0]
+        eca.update(lattice, index=0)
+        self.assertEqual([1,0,0,0,0], lattice)
+
+        lattice = [0,0,0,0,0]
+        eca.update(lattice, index=1)
+        self.assertEqual([0,0,0,0,0], lattice)
+
+        lattice = [0,0,0,0,0]
+        eca.update(lattice, index=-1)
+        self.assertEqual([0,0,0,0,1], lattice)
+
+        lattice = [0,0,1,0,0]
+        eca.update(lattice, index=1)
+        self.assertEqual([0,1,1,0,0], lattice)
+
+
+    def test_update_index_numpy(self):
+        eca = ca.ECA(30, (1,1))
+
+        lattice = np.asarray([0,0,0,0,0])
+        eca.update(lattice, index=0)
+        self.assertTrue(np.array_equal([1,0,0,0,0], lattice))
+
+        lattice = np.asarray([0,0,0,0,0])
+        eca.update(lattice, index=1)
+        self.assertTrue(np.array_equal([0,0,0,0,0], lattice))
+
+        lattice = np.asarray([0,0,0,0,0])
+        eca.update(lattice, index=-1)
+        self.assertTrue(np.array_equal([0,0,0,0,1], lattice))
+
+        lattice = np.asarray([0,0,1,0,0])
+        eca.update(lattice, index=1)
+        self.assertTrue(np.array_equal([0,1,1,0,0], lattice))

pip install -e .
parse_log_pytest
requirements.txt
nose nose-cov pytest
apt-get update apt-get install -y gcc
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
cov-core==1.15.0
coverage==7.8.0
exceptiongroup==1.2.2
iniconfig==2.1.0
-e git+https://github.com/ELIFE-ASU/Neet.git@27902597953c9188545e4f0543f14dd6d180952f#egg=neet
networkx==3.2.1
nose==1.3.7
nose-cov==1.6
numpy==2.0.2
packaging==24.2
pluggy==1.5.0
pytest==8.3.5
tomli==2.2.1

name: Neet
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - cov-core==1.15.0
      - coverage==7.8.0
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - networkx==3.2.1
      - nose==1.3.7
      - nose-cov==1.6
      - numpy==2.0.2
      - packaging==24.2
      - pluggy==1.5.0
      - pytest==8.3.5
      - tomli==2.2.1
prefix: /opt/conda/envs/Neet

test/test_automata.py::TestECA::test_update_index test/test_automata.py::TestECA::test_update_index_error test/test_automata.py::TestECA::test_update_index_numpy
test/test_automata.py::TestECA::test_check_lattice_list test/test_automata.py::TestECA::test_check_lattice_numpy test/test_automata.py::TestECA::test_check_lattice_string test/test_automata.py::TestECA::test_fail_init test/test_automata.py::TestECA::test_init test/test_automata.py::TestECA::test_invalid_boundary test/test_automata.py::TestECA::test_invalid_code test/test_automata.py::TestECA::test_invalid_lattice_state_update test/test_automata.py::TestECA::test_is_network test/test_automata.py::TestECA::test_is_not_fixed_sized test/test_automata.py::TestECA::test_lattice_empty_update test/test_automata.py::TestECA::test_state_space test/test_automata.py::TestECA::test_update_closed test/test_automata.py::TestECA::test_update_long_time_closed test/test_automata.py::TestECA::test_update_long_time_open test/test_automata.py::TestECA::test_update_numpy test/test_automata.py::TestECA::test_update_open
neet/automata.py
neet/automata.py