Repository: vprusso/toqito

Issue:
Add seeds to the randomness-related function
Currently, the functions in `toqito/rand` don't take a seed. It could be useful to add the functionality. This would also allow to remove the skips in the doctests.

Hints from issue comments:
@purva-thakre: Yes, this has been on my todos for a while. Thank you for the issue!@vprusso: Yes, great capture, @tnemoz ! Agree with @purva-thakre !

Solution patch:
diff --git a/poetry.lock b/poetry.lock
index a538b688d..4f5d36e7d 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -471,21 +471,6 @@ files = [
     {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
 ]
 
-[[package]]
-name = "dill"
-version = "0.3.9"
-description = "serialize all of Python"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a"},
-    {file = "dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"},
-]
-
-[package.extras]
-graph = ["objgraph (>=1.7.2)"]
-profile = ["gprof2dot (>=2022.7.29)"]
-
 [[package]]
 name = "distlib"
 version = "0.3.9"
@@ -1167,17 +1152,6 @@ files = [
     {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
 ]
 
-[[package]]
-name = "pbr"
-version = "6.1.0"
-description = "Python Build Reasonableness"
-optional = false
-python-versions = ">=2.6"
-files = [
-    {file = "pbr-6.1.0-py2.py3-none-any.whl", hash = "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a"},
-    {file = "pbr-6.1.0.tar.gz", hash = "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24"},
-]
-
 [[package]]
 name = "pep8"
 version = "1.7.1"
@@ -1414,20 +1388,6 @@ pytest = ">=4.6"
 [package.extras]
 testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"]
 
-[[package]]
-name = "python-dateutil"
-version = "2.9.0.post0"
-description = "Extensions to the standard Python datetime module"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
-files = [
-    {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
-    {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
-]
-
-[package.dependencies]
-six = ">=1.5"
-
 [[package]]
 name = "pyyaml"
 version = "6.0.2"
@@ -1537,44 +1497,6 @@ files = [
 numpy = ">=1.7"
 scipy = ">=0.13.2"
 
-[[package]]
-name = "qiskit"
-version = "1.2.4"
-description = "An open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives."
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "qiskit-1.2.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:1cdabddeed74956ac22db8b11b3479044a305b0895b142198f11a75e745aa079"},
-    {file = "qiskit-1.2.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9daad1c3a0608c4a32a03112d0650cc51ced2cab16479703230acedafafa0548"},
-    {file = "qiskit-1.2.4-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:3394ec724adeb481c02b050ac6e5929ca5e1f91ab94a1d571dadf0c702d6967e"},
-    {file = "qiskit-1.2.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:124777b0d9caf40932e02d1d2c6be3a12ff058990e6ae55f45a315a9a51da75b"},
-    {file = "qiskit-1.2.4-cp38-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c8d9fa7fdb0cf7727f27a1881cc9f9be7de2b6aaf7cab6861686e1a6e34d6c8"},
-    {file = "qiskit-1.2.4-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3a973089d54f379006df8ae9b0d406e909e02b11a9390b3e2f50aefd5e8070eb"},
-    {file = "qiskit-1.2.4-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:409b43d48e33e5bbc316fd85f44f29a71db2d5ff802affabc5ee355fe9573d7e"},
-    {file = "qiskit-1.2.4-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a66303ab4f939080ca0b8c4102040a89417a99f2621978c7bca8b1d5f6c6e103"},
-    {file = "qiskit-1.2.4-cp38-abi3-win32.whl", hash = "sha256:93aa20398c5ab79adb4baf89a76d034a7c608fcc5bcbbd77355314378583e56a"},
-    {file = "qiskit-1.2.4-cp38-abi3-win_amd64.whl", hash = "sha256:87175e179bbaa3d2e280f14fe90efa77d6d7521d58ee5afd9528ec6716a6d8e6"},
-    {file = "qiskit-1.2.4.tar.gz", hash = "sha256:3f30b1fc6c66dec240428991da75cc6c35cc75152baff8daf3f8ca71b60684e8"},
-]
-
-[package.dependencies]
-dill = ">=0.3"
-numpy = ">=1.17,<3"
-python-dateutil = ">=2.8.0"
-rustworkx = ">=0.15.0"
-scipy = ">=1.5"
-stevedore = ">=3.0.0"
-symengine = ">=0.11,<0.14"
-sympy = ">=1.3"
-typing-extensions = "*"
-
-[package.extras]
-all = ["qiskit[crosstalk-pass,csp-layout-pass,qasm3-import,visualization]"]
-crosstalk-pass = ["z3-solver (>=4.7)"]
-csp-layout-pass = ["python-constraint (>=1.4)"]
-qasm3-import = ["qiskit-qasm3-import (>=0.1.0)"]
-visualization = ["Pillow (>=4.2.1)", "matplotlib (>=3.3)", "pydot", "pylatexenc (>=1.4)", "seaborn (>=0.9.0)"]
-
 [[package]]
 name = "readthedocs-sphinx-ext"
 version = "2.2.5"
@@ -1639,35 +1561,6 @@ files = [
     {file = "ruff-0.6.9.tar.gz", hash = "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2"},
 ]
 
-[[package]]
-name = "rustworkx"
-version = "0.15.1"
-description = "A python graph library implemented in Rust"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "rustworkx-0.15.1-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:6cd4496d3298cd3205c03545e48cc37d21e0455d57752af801d3fb250452d590"},
-    {file = "rustworkx-0.15.1-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:cb518f5649e62d753e29ca1e57290c8f58adbebcd154dc3159f4a36ebfa1e2b7"},
-    {file = "rustworkx-0.15.1-cp38-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac68ae2515ece22ba3ef56f3d16ad6bf707955f650d623190b2e7d706c6dc92"},
-    {file = "rustworkx-0.15.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b903edec1d803704b499959f9d6f6119cdda63b9b64194a4b4307e506b112f0"},
-    {file = "rustworkx-0.15.1-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2c97a56ff8a0f6c273a83e26e627c72207442b4252aa550acad0bff42caac40"},
-    {file = "rustworkx-0.15.1-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:241c502532e348ba89200823326dba30de4df4b886cb2fd5a140b359ff124bb3"},
-    {file = "rustworkx-0.15.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e5f4156f46fa03177c9b0580450eab87786063495d48b457762a5bdd20c55e2"},
-    {file = "rustworkx-0.15.1-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7834ab34748db6214ec3b3836b996b23882dc83184234e6d346d6bb85fd58ae5"},
-    {file = "rustworkx-0.15.1-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ce53f173fed16e1d51d9df9f23475a16c981b03bf1a412d991c75a70db6b1dc1"},
-    {file = "rustworkx-0.15.1-cp38-abi3-win32.whl", hash = "sha256:308bc76a01bcae9af4602d8b9ed58021df37dd0bb5a7b2e3831ae53c5e234ff0"},
-    {file = "rustworkx-0.15.1-cp38-abi3-win_amd64.whl", hash = "sha256:89077382633e918d2392772f53b9d6d30eee51eb536f8d38ee195c212b2f0427"},
-    {file = "rustworkx-0.15.1.tar.gz", hash = "sha256:0e0cc86599f979285b2ab9c357276f3272f3fcb3b2df5651a6bf9704c570d4c1"},
-]
-
-[package.dependencies]
-numpy = ">=1.16.0,<3"
-
-[package.extras]
-all = ["matplotlib (>=3.0)", "pillow (>=5.4)"]
-graphviz = ["pillow (>=5.4)"]
-mpl = ["matplotlib (>=3.0)"]
-
 [[package]]
 name = "scipy"
 version = "1.14.1"
@@ -2016,71 +1909,6 @@ pure-eval = "*"
 [package.extras]
 tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"]
 
-[[package]]
-name = "stevedore"
-version = "5.3.0"
-description = "Manage dynamic plugins for Python applications"
-optional = false
-python-versions = ">=3.8"
-files = [
-    {file = "stevedore-5.3.0-py3-none-any.whl", hash = "sha256:1efd34ca08f474dad08d9b19e934a22c68bb6fe416926479ba29e5013bcc8f78"},
-    {file = "stevedore-5.3.0.tar.gz", hash = "sha256:9a64265f4060312828151c204efbe9b7a9852a0d9228756344dbc7e4023e375a"},
-]
-
-[package.dependencies]
-pbr = ">=2.0.0"
-
-[[package]]
-name = "symengine"
-version = "0.13.0"
-description = "Python library providing wrappers to SymEngine"
-optional = false
-python-versions = "<4,>=3.8"
-files = [
-    {file = "symengine-0.13.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:259fd4111c7a70c72bdff5686de1949e8132baeb612eacdaf8837720c6fe449b"},
-    {file = "symengine-0.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:44f2eb28a1e36db0bbd6679435412f79da9743bf9c1cb3eff25e0c343b7ddd48"},
-    {file = "symengine-0.13.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d141712fa14d9138bd19e64b10392f850c68d88cd7db29f1bda33e32d1095559"},
-    {file = "symengine-0.13.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:830226d933bfcdb93546e4062541627d9a3bc7a178a63fb16c002eb5c5221938"},
-    {file = "symengine-0.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a08090163819a0bbfa97d64bd2d8dac2c5268147ed9c242799d7f7e8728a6f4e"},
-    {file = "symengine-0.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:1e435dcd8ed25e4c7c21ab1c0376be910efc7f35da76d532367df27b359f0358"},
-    {file = "symengine-0.13.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:da0eba7e106095cdce88eb275c8a9d7c4586ad88f229394c53e1184155c00745"},
-    {file = "symengine-0.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b0c175f4f895a73a925508af03faf7efd6cad8593256bbdb5346bd996d3ec5c8"},
-    {file = "symengine-0.13.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e58d1e2abd08381aa0cf24c88c0e8b7f592df92619b51e32d36835fbd2dd6ae8"},
-    {file = "symengine-0.13.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1db745f2c7a3c5e83510cf4decb43201f43552dfb05ad8af9787c89708be9ede"},
-    {file = "symengine-0.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2572c98b09ac284db6ecff63f6170461194dc94c4209afd34c092ec67873d85"},
-    {file = "symengine-0.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:12727f02a2919f005aee48e68e0cbb70cf857b19385857b4d985d1c9b075f620"},
-    {file = "symengine-0.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cf91d24f1bfd6d53228593c7804dd106b71b19674d5afc4fa322d516e1793bdd"},
-    {file = "symengine-0.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5615b7eb68890917abd390ebb10434a949165f6064741c1a8cc345fee14e855"},
-    {file = "symengine-0.13.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb92bdf0890de264abaeacbfbdbd4dd7444b94057bd47958d913b662e549ad8a"},
-    {file = "symengine-0.13.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3bce486fbc0b87970ed1b10ca9d5cafb1fd6b66382fe631261d83592851d7e"},
-    {file = "symengine-0.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7e6bae9cfcdde2775d92fbb0abe3ef04e32f65ebc4c2d164ca33f4da202d4a7"},
-    {file = "symengine-0.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:bced0a1dbdb94737c299384c85ddbad6944ce8dadc334f7bb8dbbd8f6c965807"},
-    {file = "symengine-0.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d34df77971538e4c29f2d8e5ef7f459c2179465e6cdb7dfd48b79b87ecd8f4d"},
-    {file = "symengine-0.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ab2661d9b18867e7c6edbfa7a74b8b0a2a694bd24aa08003dc3214f77cb9d6f2"},
-    {file = "symengine-0.13.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53f27b9013878ee4419d8e853664d8ae4b68419e3f4b9b5b7f503d32bf904755"},
-    {file = "symengine-0.13.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:27987f75ce08c64f453e2b9b74fec6ffc5ca418c4deca0b75580979d4a4e242a"},
-    {file = "symengine-0.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9ea9410330ea15ed4137d7a0a3c43caccacb71490e18036ce5182d08c93baf8"},
-    {file = "symengine-0.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:5031eb7a5c6675d5195bb57f93cc7d9ac5a7a9a826d4ad6f6b2927746ed7e6e6"},
-    {file = "symengine-0.13.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ce0e5dfb19943bcf3e44a4485bcac4c5533ba3705c63083494eed0b3bf246076"},
-    {file = "symengine-0.13.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c3b77dc54bf1181f6bd3b3338c4e6e5973a8b0fa20a189d15563ef5626e57b04"},
-    {file = "symengine-0.13.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca7c3f6c168f6f5b06b421833c3d3baae56067a94b671bdffbe09b8e4fefd9be"},
-    {file = "symengine-0.13.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:847523de682416811bacb3ad11507e663b3522fbb35cd27184757e9956d0eaf0"},
-    {file = "symengine-0.13.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2fc1b7d96426463f0c9011e9fb88459d906477c1baa8a996dde6fb2bfa99d4"},
-    {file = "symengine-0.13.0-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:6e371bb2da3867085779c1c21bbb1c85f9634c76c8a76c08562ea113e3dfcd85"},
-    {file = "symengine-0.13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cf7c62478b19683d54e4d93faa5b89303beae25db0c503a105a70d266dc99fa9"},
-    {file = "symengine-0.13.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdb21158cf3e2ba87e441f21ecc7724f108b8db17c0fd1880f9f531602bab1f3"},
-    {file = "symengine-0.13.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1848d366b359ff69ef5dac148b30ca04c7339a7d3bcab28419d411e68c0cc011"},
-    {file = "symengine-0.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:242f817e890a0a50d52ed6b2bfd1aad19636a58db700c7995bbe1ceeaebd9d08"},
-    {file = "symengine-0.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:af79cf2b9645fb55216850185987b2e9347db71e42e87b6402e4bbd41710b316"},
-    {file = "symengine-0.13.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:17ae9d1c781a60ac48d07fa30f39a2d237f9da95e9e81f6a24b1c16908e9cad2"},
-    {file = "symengine-0.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5264157a95f6d09dd044cee6abcbc176e649c487638b7f32199f387f37ad82a5"},
-    {file = "symengine-0.13.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f01a6d0829b4881d5f831ae7848eb0d82b80d8b46b5689f1bf27069672370f75"},
-    {file = "symengine-0.13.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35ec68b11c2df2be1a236d0c028edb5b331909b16666d7a9fe99a4a5810afec7"},
-    {file = "symengine-0.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4357fed87083e8719fcffd8bd0e7ddd16172e319343362512f681e472ac5668"},
-    {file = "symengine-0.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:a41be31816e5e51e9063bf26de07faf3751de7a133dbbec149632de702a28e18"},
-    {file = "symengine-0.13.0.tar.gz", hash = "sha256:ab83a08897ebf12579702c2b71ba73d4732fb706cc4291d810aedf39c690c14c"},
-]
-
 [[package]]
 name = "sympy"
 version = "1.13.3"
diff --git a/pyproject.toml b/pyproject.toml
index 31fada5e3..75c7a0db4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -24,7 +24,6 @@ numpy = "2.1.2"
 scipy = "1.14.1"
 scs = "3.2.7"
 picos = "2.4.17"
-qiskit = "1.2.4"
 
 
 [tool.poetry.group.dev.dependencies]
diff --git a/toqito/rand/random_circulant_gram_matrix.py b/toqito/rand/random_circulant_gram_matrix.py
index 4e92ea99f..3823f1de0 100644
--- a/toqito/rand/random_circulant_gram_matrix.py
+++ b/toqito/rand/random_circulant_gram_matrix.py
@@ -3,7 +3,7 @@
 import numpy as np
 
 
-def random_circulant_gram_matrix(dim: int) -> np.ndarray:
+def random_circulant_gram_matrix(dim: int, seed: int | None = None) -> np.ndarray:
     r"""Generate a random circulant Gram matrix of specified dimension.
 
     A circulant matrix is a square matrix where the elements of each row are identical to the elements of the
@@ -38,6 +38,16 @@ def random_circulant_gram_matrix(dim: int) -> np.ndarray:
            [0.04257471, 0.21058986, 0.42351891, 0.21058986],
            [0.21058986, 0.04257471, 0.21058986, 0.42351891]])
 
+    It is also possible to pass a seed to this function for reproducibility.
+
+    >>> from toqito.rand import random_circulant_gram_matrix
+    >>> circulant_matrix = random_circulant_gram_matrix(4, seed=42)
+    >>> circulant_matrix
+    array([[ 0.69220011, -0.02116047,  0.12407687, -0.02116047],
+           [-0.02116047,  0.69220011, -0.02116047,  0.12407687],
+           [ 0.12407687, -0.02116047,  0.69220011, -0.02116047],
+           [-0.02116047,  0.12407687, -0.02116047,  0.69220011]])
+
 
     References
     ==========
@@ -46,13 +56,16 @@ def random_circulant_gram_matrix(dim: int) -> np.ndarray:
 
     :param dim: int
         The dimension of the circulant matrix to generate.
+    :param seed: int | None
+        A seed used to instantiate numpy's random number generator.
 
     :return: numpy.ndarray
         A `dim` x `dim` real, symmetric, circulant matrix.
 
     """
+    gen = np.random.default_rng(seed=seed)
     # Step 1: Generate a random diagonal matrix with non-negative entries
-    diag_mat = np.diag(np.random.rand(dim))
+    diag_mat = np.diag(gen.random(dim))
 
     # Step 2: Construct the normalized DFT matrix
     dft_mat = np.fft.fft(np.eye(dim)) / np.sqrt(dim)
diff --git a/toqito/rand/random_density_matrix.py b/toqito/rand/random_density_matrix.py
index e1dab718f..7299f2f55 100644
--- a/toqito/rand/random_density_matrix.py
+++ b/toqito/rand/random_density_matrix.py
@@ -10,6 +10,7 @@ def random_density_matrix(
     is_real: bool = False,
     k_param: list[int] | int = None,
     distance_metric: str = "haar",
+    seed: int | None = None,
 ) -> np.ndarray:
     r"""Generate a random density matrix.
 
@@ -74,6 +75,21 @@ def random_density_matrix(
     >>> is_density(bures_mat)
     np.True_
 
+    It is also possible to pass a seed to this function for reproducibility.
+
+    >>> from toqito.rand import random_density_matrix
+    >>> seeded = random_density_matrix(2, seed=42)
+    >>> seeded
+    array([[0.82448019+0.j        , 0.14841568-0.33318114j],
+           [0.14841568+0.33318114j, 0.17551981+0.j        ]])
+
+    We can once again verify that this is in fact a valid density matrix using the
+    :code:`is_density` function from :code:`toqito` as follows
+
+    >>> from toqito.matrix_props import is_density
+    >>> is_density(seeded)
+    np.True_
+
 
     :param dim: The number of rows (and columns) of the density matrix.
     :param is_real: Boolean denoting whether the returned matrix will have all
@@ -83,20 +99,22 @@ def random_density_matrix(
                             density matrix. This metric is either the Haar
                             measure or the Bures measure. Default value is to
                             use the Haar measure.
+    :param seed: A seed used to instantiate numpy's random number generator.
     :return: A :code:`dim`-by-:code:`dim` random density matrix.
 
     """
+    gen = np.random.default_rng(seed=seed)
     if k_param is None:
         k_param = dim
 
     # Haar / Hilbert-Schmidt measure.
-    gin = np.random.rand(dim, k_param)
+    gin = gen.random((dim, k_param))
 
     if not is_real:
-        gin = gin + 1j * np.random.randn(dim, k_param)
+        gin = gin + 1j * gen.standard_normal((dim, k_param))
 
     if distance_metric == "bures":
-        gin = random_unitary(dim, is_real) + np.identity(dim) @ gin
+        gin = random_unitary(dim, is_real, seed=seed) + np.identity(dim) @ gin
 
     rho = gin @ np.array(gin).conj().T
 
diff --git a/toqito/rand/random_ginibre.py b/toqito/rand/random_ginibre.py
index 9356d1967..1fd9492c9 100644
--- a/toqito/rand/random_ginibre.py
+++ b/toqito/rand/random_ginibre.py
@@ -3,7 +3,7 @@
 import numpy as np
 
 
-def random_ginibre(dim_n: int, dim_m: int) -> np.ndarray:
+def random_ginibre(dim_n: int, dim_m: int, seed: int | None = None) -> np.ndarray:
     r"""Generate a Ginibre random matrix :cite:`WikiCircLaw`.
 
     Generates a random :code:`dim_n`-by-:code:`dim_m` Ginibre matrix.
@@ -23,6 +23,12 @@ def random_ginibre(dim_n: int, dim_m: int) -> np.ndarray:
     array([[0.39166472-1.54657971j, 0.36538245+0.23324642j],
            [0.50103695-0.25857737j, 0.8357054 +0.31404353j]])
 
+    It is also possible to pass a seed to this function for reproducibility.
+
+    >>> from toqito.rand import random_ginibre
+    >>> random_ginibre(2, 2, seed=42)
+    array([[ 0.21546751-1.37959021j, -0.73537981-0.92077996j],
+           [ 0.53064913+0.09039682j,  0.66507969-0.22361728j]])
 
 
     References
@@ -33,7 +39,9 @@ def random_ginibre(dim_n: int, dim_m: int) -> np.ndarray:
 
     :param dim_n: The number of rows of the Ginibre random matrix.
     :param dim_m: The number of columns of the Ginibre random matrix.
+    :param seed: A seed used to instantiate numpy's random number generator.
     :return: A :code:`dim_n`-by-:code:`dim_m` Ginibre random density matrix.
 
     """
-    return (np.random.randn(dim_n, dim_m) + 1j * np.random.randn(dim_n, dim_m)) / np.sqrt(2)
+    gen = np.random.default_rng(seed=seed)
+    return (gen.standard_normal((dim_n, dim_m)) + 1j * gen.standard_normal((dim_n, dim_m))) / np.sqrt(2)
diff --git a/toqito/rand/random_orthonormal_basis.py b/toqito/rand/random_orthonormal_basis.py
index 91ed9cbb7..cf03829fc 100644
--- a/toqito/rand/random_orthonormal_basis.py
+++ b/toqito/rand/random_orthonormal_basis.py
@@ -4,7 +4,7 @@
 from toqito.rand import random_unitary
 
 
-def random_orthonormal_basis(dim: int, is_real: bool = False) -> list[np.ndarray]:
+def random_orthonormal_basis(dim: int, is_real: bool = False, seed: int | None = None) -> list[np.ndarray]:
     r"""Generate a real random orthonormal basis of given dimension :math:`d`.
 
     The basis is generated from the columns of a random unitary matrix of the same dimension
@@ -21,6 +21,13 @@ def random_orthonormal_basis(dim: int, is_real: bool = False) -> list[np.ndarray
     array([ 0.23965404, -0.58538248,  0.187136  ,  0.75158061]),
     array([ 0.658269  ,  0.25243989, -0.69118291,  0.158815  ])]
 
+    It is also possible to add a seed for reproducibility.
+
+    >>> from toqito.rand import random_orthonormal_basis
+    >>> random_orthonormal_basis(2, is_real=True, seed=42)
+    [array([0.66954664, 0.74277002]), array([-0.74277002,  0.66954664])]
+
+
     References
     ==========
     .. bibliography::
@@ -28,7 +35,9 @@ def random_orthonormal_basis(dim: int, is_real: bool = False) -> list[np.ndarray
 
     dim: int
         Number of elements in the random orthonormal basis.
+    seed: int | None
+        A seed used to instantiate numpy's random number generator.
 
     """
-    random_mat = random_unitary(dim, is_real)
+    random_mat = random_unitary(dim, is_real, seed)
     return [random_mat[:, i] for i in range(dim)]
diff --git a/toqito/rand/random_povm.py b/toqito/rand/random_povm.py
index 7fa3d5c29..732e2ac03 100644
--- a/toqito/rand/random_povm.py
+++ b/toqito/rand/random_povm.py
@@ -3,7 +3,7 @@
 import numpy as np
 
 
-def random_povm(dim: int, num_inputs: int, num_outputs: int) -> np.ndarray:
+def random_povm(dim: int, num_inputs: int, num_outputs: int, seed: int | None = None) -> np.ndarray:
     """Generate random positive operator valued measurements (POVMs) :cite:`WikiPOVM`.
 
     Examples
@@ -40,6 +40,33 @@ def random_povm(dim: int, num_inputs: int, num_outputs: int) -> np.ndarray:
     [[1.+0.j, 0.+0.j],
      [0.+0.j, 1.+0.j]]
 
+     It is also possible to add a seed for reproducibility.
+
+    >>> from toqito.rand import random_povm
+    >>> import numpy as np
+    >>>
+    >>> dim, num_inputs, num_outputs = 2, 2, 2
+    >>> povms = random_povm(dim, num_inputs, num_outputs, seed=42)
+    >>> povms
+    array([[[[ 0.22988028+0.j,  0.77011972+0.j],
+             [ 0.45021752+0.j,  0.54978248+0.j]],
+    <BLANKLINE>
+            [[-0.23938341+0.j,  0.23938341+0.j],
+             [ 0.32542956+0.j, -0.32542956+0.j]]],
+    <BLANKLINE>
+    <BLANKLINE>
+           [[[-0.23938341+0.j,  0.23938341+0.j],
+             [ 0.32542956+0.j, -0.32542956+0.j]],
+    <BLANKLINE>
+            [[ 0.83184406+0.j,  0.16815594+0.j],
+             [ 0.61323275+0.j,  0.38676725+0.j]]]])
+
+    We can once again verify that this constitutes a valid set of POVM elements as checking that
+    these operators all sum to the identity operator.
+
+    >>> np.round(povms[:, :, 0, 0] + povms[:, :, 0, 1])
+    array([[ 1.+0.j, -0.+0.j],
+           [-0.+0.j,  1.+0.j]])
 
     References
     ==========
@@ -51,11 +78,13 @@ def random_povm(dim: int, num_inputs: int, num_outputs: int) -> np.ndarray:
     :param dim: The dimensions of the measurements.
     :param num_inputs: The number of inputs for the measurement.
     :param num_outputs: The number of outputs for the measurement.
+    :param seed: A seed used to instantiate numpy's random number generator.
     :return: A set of `dim`-by-`dim` POVMs of shape `(dim, dim, num_inputs, num_outputs)`.
 
     """
     povms = []
-    gram_vectors = np.random.normal(size=(num_inputs, num_outputs, dim, dim))
+    gen = np.random.default_rng(seed=seed)
+    gram_vectors = gen.normal(size=(num_inputs, num_outputs, dim, dim))
     for input_block in gram_vectors:
         normalizer = sum(np.array(output_block).T.conj() @ output_block for output_block in input_block)
         u_mat, d_mat, _ = np.linalg.svd(normalizer)
diff --git a/toqito/rand/random_state_vector.py b/toqito/rand/random_state_vector.py
index a7837fb41..ab3b000e2 100644
--- a/toqito/rand/random_state_vector.py
+++ b/toqito/rand/random_state_vector.py
@@ -6,7 +6,12 @@
 from toqito.states import max_entangled
 
 
-def random_state_vector(dim: list[int] | int, is_real: bool = False, k_param: int = 0) -> np.ndarray:
+def random_state_vector(
+        dim: list[int] | int,
+        is_real: bool = False,
+        k_param: int = 0,
+        seed: int | None = None
+) -> np.ndarray:
     r"""Generate a random pure state vector.
 
     Examples
@@ -30,15 +35,33 @@ def random_state_vector(dim: list[int] | int, is_real: bool = False, k_param: in
     >>> is_pure(dm)
     True
 
+    It is also possible to pass a seed for reproducibility.
+
+    >>> from toqito.rand import random_state_vector
+    >>> vec = random_state_vector(2, seed=42)
+    >>> vec
+    array([[0.54521054+0.60483621j],
+           [0.30916633+0.49125839j]])
+
+    We can once again verify that this is in fact a valid state vector by computing the
+    corresponding density matrix of the vector and checking if the density matrix is pure.
+
+    >>> from toqito.state_props import is_pure
+    >>> dm = vec.conj().T @ vec
+    >>> is_pure(dm)
+    True
+
 
 
     :param dim: The number of rows (and columns) of the unitary matrix.
     :param is_real: Boolean denoting whether the returned matrix has real
                     entries or not. Default is :code:`False`.
     :param k_param: Default 0.
+    :param seed: A seed used to instantiate numpy's random number generator.
     :return: A :code:`dim`-by-:code:`dim` random unitary matrix.
 
     """
+    gen = np.random.default_rng(seed=seed)
     # Schmidt rank plays a role.
     if 0 < k_param < np.min(dim):
         # Allow the user to enter a single number for dim.
@@ -50,12 +73,12 @@ def random_state_vector(dim: list[int] | int, is_real: bool = False, k_param: in
         # get a Schmidt rank `<= k_param` state.
         psi = max_entangled(k_param, True, False).toarray()
 
-        a_param = np.random.rand(dim[0] * k_param, 1)
-        b_param = np.random.rand(dim[1] * k_param, 1)
+        a_param = gen.random((dim[0] * k_param, 1))
+        b_param = gen.random((dim[1] * k_param, 1))
 
         if not is_real:
-            a_param = a_param + 1j * np.random.rand(dim[0] * k_param, 1)
-            b_param = b_param + 1j * np.random.rand(dim[1] * k_param, 1)
+            a_param = a_param + 1j * gen.random((dim[0] * k_param, 1))
+            b_param = b_param + 1j * gen.random((dim[1] * k_param, 1))
 
         mat_1 = np.kron(psi.conj().T, np.identity(int(np.prod(dim))))
         mat_2 = swap(
@@ -68,7 +91,7 @@ def random_state_vector(dim: list[int] | int, is_real: bool = False, k_param: in
         return np.divide(ret_vec, np.linalg.norm(ret_vec))
 
     # Schmidt rank is full, so ignore it.
-    ret_vec = np.random.rand(dim, 1)
+    ret_vec = gen.random((dim, 1))
     if not is_real:
-        ret_vec = ret_vec + 1j * np.random.rand(dim, 1)
+        ret_vec = ret_vec + 1j * gen.random((dim, 1))
     return np.divide(ret_vec, np.linalg.norm(ret_vec))
diff --git a/toqito/rand/random_states.py b/toqito/rand/random_states.py
index 96811a7bf..de548fb0c 100644
--- a/toqito/rand/random_states.py
+++ b/toqito/rand/random_states.py
@@ -1,15 +1,13 @@
-"""Generate random quantum states using Qiskit."""
+"""Generate random quantum states."""
 
 import numpy as np
-from qiskit.quantum_info.states.random import random_statevector
 
 
-def random_states(n: int, d: int) -> list[np.ndarray]:
+def random_states(n: int, d: int, seed: int | None = None) -> list[np.ndarray]:
     r"""Generate a list of random quantum states.
 
-    This function utilizes Qiskit's `random_statevector` to generate a list of quantum states,
-    each of a specified dimension. The states are valid quantum states distributed according
-    to the Haar measure.
+    This function generates a list of quantum states, each of a specified dimension. The states are
+    valid quantum states distributed according to the Haar measure.
 
     Examples
     ==========
@@ -33,16 +31,37 @@ def random_states(n: int, d: int) -> list[np.ndarray]:
            [-0.27852449+0.39980357j],
            [ 0.17033502+0.18562365j]])]
 
+    It is also possible to pass a seed to this function for reproducibility.
+
+    >>> from toqito.rand import random_states
+    >>> states = random_states(3, 4, seed=42)
+    >>> states
+    [array([[ 0.13830446+0.0299699j ],
+           [-0.47202619+0.51163029j],
+           [ 0.34061349+0.21219233j],
+           [ 0.42690188-0.39001418j]]), array([[-0.71489214+0.1351165j ],
+           [-0.47714049-0.35135073j],
+           [ 0.04684288+0.32187898j],
+           [-0.11587661-0.01829369j]]), array([[-0.00827473-0.0910465j ],
+           [-0.42013238-0.33536439j],
+           [ 0.43311201+0.60211343j],
+           [ 0.38307005-0.07610726j]])]
+
 
 
     :param n: int
         The number of random states to generate.
     :param d: int
         The dimension of each quantum state.
+    :param seed: int | None
+        A seed used to instantiate numpy's random number generator.
 
     :return: list[numpy.ndarray]
         A list of `n` numpy arrays, each representing a d-dimensional quantum state as a
         column vector.
 
     """
-    return [random_statevector(d).data.reshape(-1, 1) for _ in range(n)]
+    gen = np.random.default_rng(seed=seed)
+    samples = gen.normal(size=(n, d)) + 1j * gen.normal(size=(n, d))
+    samples /= np.linalg.norm(samples, axis=1)[:, np.newaxis]
+    return [sample.reshape(-1, 1) for sample in samples]
diff --git a/toqito/rand/random_unitary.py b/toqito/rand/random_unitary.py
index d586b5473..485585b40 100644
--- a/toqito/rand/random_unitary.py
+++ b/toqito/rand/random_unitary.py
@@ -3,7 +3,11 @@
 import numpy as np
 
 
-def random_unitary(dim: list[int] | int, is_real: bool = False) -> np.ndarray:
+def random_unitary(
+        dim: list[int] | int,
+        is_real: bool = False,
+        seed: int | None = None
+) -> np.ndarray:
     """Generate a random unitary or orthogonal matrix :cite:`Ozols_2009_RandU`.
 
     Calculates a random unitary matrix (if :code:`is_real = False`) or a random real orthogonal
@@ -62,6 +66,20 @@ def random_unitary(dim: list[int] | int, is_real: bool = False) -> np.ndarray:
     >>> is_unitary(mat)
     True
 
+    It is also possible to pass a seed to this function for reproducibility.
+
+    >>> from toqito.matrix_props import is_unitary
+    >>> seeded = random_unitary(2, seed=42)
+    >>> seeded
+    array([[0.34074554-0.85897194j, 0.32146645+0.20668575j],
+           [0.37801036+0.05628362j, 0.30953006-0.87070745j]])
+
+    And once again, we can verify that this matrix generated is a valid unitary matrix.
+
+    >>> from toqito.matrix_props import is_unitary
+    >>> is_unitary(seeded)
+    True
+
     References
     ==========
     .. bibliography::
@@ -71,9 +89,12 @@ def random_unitary(dim: list[int] | int, is_real: bool = False) -> np.ndarray:
     :param dim: The number of rows (and columns) of the unitary matrix.
     :param is_real: Boolean denoting whether the returned matrix has real
                     entries or not. Default is :code:`False`.
+    :param seed: A seed used to instantiate numpy's random number generator.
     :return: A :code:`dim`-by-:code:`dim` random unitary matrix.
 
     """
+    gen = np.random.default_rng(seed=seed)
+
     if isinstance(dim, int):
         dim = [dim, dim]
 
@@ -81,10 +102,10 @@ def random_unitary(dim: list[int] | int, is_real: bool = False) -> np.ndarray:
         raise ValueError("Unitary matrix must be square.")
 
     # Construct the Ginibre ensemble.
-    gin = np.random.rand(dim[0], dim[1])
+    gin = gen.random((dim[0], dim[1]))
 
     if not is_real:
-        gin = gin + 1j * np.random.rand(dim[0], dim[1])
+        gin = gin + 1j * gen.standard_normal((dim[0], dim[1]))
 
     # QR decomposition of the Ginibre ensemble.
     q_mat, r_mat = np.linalg.qr(gin)


Test patch:
diff --git a/toqito/rand/tests/test_random_circulant_gram_matrix.py b/toqito/rand/tests/test_random_circulant_gram_matrix.py
index 86640d203..5359367fd 100644
--- a/toqito/rand/tests/test_random_circulant_gram_matrix.py
+++ b/toqito/rand/tests/test_random_circulant_gram_matrix.py
@@ -38,3 +38,30 @@ def test_random_circulant_gram_matrix(dim):
     # all eigenvalues are non-negative.
     eigenvalues = np.linalg.eigvalsh(circulant_matrix)
     assert_array_almost_equal((eigenvalues >= 0), True)
+
+@pytest.mark.parametrize(
+    "dim,expected",
+    [
+        (
+            2,
+            np.array([
+                [0.36808644, 0.31426542],
+                [0.31426542, 0.36808644]
+            ])
+        ),
+(
+            5,
+            np.array([
+                [0.26336209, 0.08518132, 0.12431357, 0.12431357, 0.08518132],
+                [0.08518132, 0.26336209, 0.08518132, 0.12431357, 0.12431357],
+                [0.12431357, 0.08518132, 0.26336209, 0.08518132, 0.12431357],
+                [0.12431357, 0.12431357, 0.08518132, 0.26336209, 0.08518132],
+                [0.08518132, 0.12431357, 0.12431357, 0.08518132, 0.26336209]
+            ])
+        ),
+    ]
+)
+def test_random_circulant_gram_matrix_with_seed(dim, expected):
+    """Test that the random_circulant_gram_matrix produces expected inputs with a seed."""
+    mat = random_circulant_gram_matrix(dim, seed=123)
+    assert_array_almost_equal(mat, expected)
diff --git a/toqito/rand/tests/test_random_density_matrix.py b/toqito/rand/tests/test_random_density_matrix.py
index b92c51d20..f1e79ef08 100644
--- a/toqito/rand/tests/test_random_density_matrix.py
+++ b/toqito/rand/tests/test_random_density_matrix.py
@@ -2,6 +2,7 @@
 
 import numpy as np
 import pytest
+from numpy.ma.testutils import assert_array_almost_equal
 
 from toqito.matrix_props import is_density, is_positive_semidefinite
 from toqito.rand import random_density_matrix
@@ -48,3 +49,63 @@ def test_random_density_matrix(dim, is_real, distance_metric):
         assert np.all(np.isreal(dm)), "Matrix should be real"
     else:
         assert np.any(np.iscomplex(dm)), "Matrix should be complex"
+
+@pytest.mark.parametrize(
+    "dim, is_real, k_param, distance_metric, expected",
+    [
+        # Generate random non-real density matrix.
+        (
+            2,
+            False,
+            None,
+            "haar",
+            np.array([
+                [0.67842043+0.j, -0.04636114+0.29398703j],
+                [-0.04636114-0.29398703j, 0.32157957+0.j]
+            ])
+        ),
+        # Generate random real density matrix.
+        (
+            2,
+            True,
+            None,
+            "haar",
+            np.array([
+                [0.85019307, 0.29087271],
+                [0.29087271, 0.14980693]
+            ])
+        ),
+        # Random non-real density matrix according to Bures metric.
+        (
+            2,
+            False,
+            None,
+            "bures",
+            np.array([
+                [0.60005221+0.j, -0.00344727+0.16976473j],
+                [-0.00344727-0.16976473j, 0.39994779+0.j]
+            ])
+        ),
+        # Generate random non-real density matrix all params.
+        (
+            2,
+            True,
+            2,
+            "haar",
+            np.array([
+                [0.85019307, 0.29087271],
+                [0.29087271, 0.14980693]
+            ])
+        ),
+    ],
+)
+def test_seed(dim, is_real, k_param, distance_metric, expected):
+    """Test that the function produces the expected output using a seed."""
+    dm = random_density_matrix(
+        dim,
+        is_real,
+        k_param=k_param,
+        distance_metric=distance_metric,
+        seed=123
+    )
+    assert_array_almost_equal(dm, expected)
diff --git a/toqito/rand/tests/test_random_ginibre.py b/toqito/rand/tests/test_random_ginibre.py
index 394b64dcb..6797bc28f 100644
--- a/toqito/rand/tests/test_random_ginibre.py
+++ b/toqito/rand/tests/test_random_ginibre.py
@@ -2,6 +2,7 @@
 
 import numpy as np
 import pytest
+from numpy.ma.testutils import assert_array_almost_equal
 
 from toqito.rand import random_ginibre
 
@@ -13,6 +14,32 @@ def test_random_ginibre_dims(dim_n, dim_m):
     gin_mat = random_ginibre(dim_n, dim_m)
     np.testing.assert_equal(gin_mat.shape, (dim_n, dim_m))
 
+@pytest.mark.parametrize(
+    "dim_n, dim_m, expected",
+    [
+        (
+            2,
+            3,
+            np.array([
+                [-0.69941441-0.45004776j, -0.26006444+0.38321809j, 0.91070069-0.22386679j],
+                [0.13716063-0.22796353j, 0.65070151+0.06870767j, 0.408074-1.07899574j]
+            ])
+        ),
+        (
+            2,
+            2,
+            np.array([
+                [-0.69941441+0.65070151j, -0.26006444+0.408074j],
+                [0.91070069-0.45004776j, 0.13716063+0.38321809j]
+            ])
+        ),
+    ]
+)
+def test_seed(dim_n, dim_m, expected):
+    """Test that the function returns the expected output when seeded."""
+    gin_mat = random_ginibre(dim_n, dim_m, seed=123)
+    assert_array_almost_equal(gin_mat, expected)
+
 
 @pytest.mark.parametrize(
     "dim_n, dim_m",
diff --git a/toqito/rand/tests/test_random_orthonormal_basis.py b/toqito/rand/tests/test_random_orthonormal_basis.py
index cc9a0d419..9a11de8ed 100644
--- a/toqito/rand/tests/test_random_orthonormal_basis.py
+++ b/toqito/rand/tests/test_random_orthonormal_basis.py
@@ -2,6 +2,7 @@
 
 import numpy as np
 import pytest
+from numpy.ma.testutils import assert_array_almost_equal
 
 from toqito.matrix_props import is_orthonormal
 from toqito.rand import random_orthonormal_basis
@@ -15,3 +16,28 @@ def test_random_orth_basis_int_dim(input_dim, bool):
     assert len(gen_basis) == input_dim
     assert is_orthonormal(np.array(gen_basis))
 
+@pytest.mark.parametrize(
+    "dim, is_real, expected",
+    [
+        (
+            2,
+            False,
+            [
+                np.array([0.51345691+0.6924564j, 0.16581665-0.47892689j]),
+                np.array([0.38709015+0.32715034j, -0.08796944+0.85755189j])
+            ]
+        ),
+(
+            2,
+            True,
+            [
+                np.array([0.95160818, 0.30731397]),
+                np.array([-0.30731397, 0.95160818])
+            ]
+        ),
+    ]
+)
+def test_seed(dim, is_real, expected):
+    """Test that the function returns the expected output when seeded."""
+    basis = random_orthonormal_basis(dim, is_real, seed=123)
+    assert_array_almost_equal(basis, expected)
diff --git a/toqito/rand/tests/test_random_povm.py b/toqito/rand/tests/test_random_povm.py
index 34250f860..61dc0ffde 100644
--- a/toqito/rand/tests/test_random_povm.py
+++ b/toqito/rand/tests/test_random_povm.py
@@ -2,6 +2,7 @@
 
 import numpy as np
 import pytest
+from numpy.ma.testutils import assert_array_almost_equal
 
 from toqito.rand import random_povm
 
@@ -24,3 +25,40 @@ def test_random_povm_validity(dim, num_inputs, num_outputs):
     for i in range(num_inputs):
         sum_povms = sum(povms[:, :, i, j] for j in range(num_outputs))
         assert np.allclose(sum_povms, np.identity(dim))
+
+@pytest.mark.parametrize(
+    "dim, num_inputs, num_outputs, expected",
+    [
+        (
+            2,
+            2,
+            2,
+            np.array([
+                [
+                    [
+                        [0.68105648+0.j, 0.31894352+0.j],
+                        [0.46623871+0.j, 0.53376129+0.j]
+                    ],
+                    [
+                        [0.01373155+0.j, -0.01373155+0.j],
+                        [0.42523981+0.j, -0.42523981+0.j]
+                    ]
+                ],
+                [
+                    [
+                        [0.01373155+0.j, -0.01373155+0.j],
+                        [0.42523981+0.j, -0.42523981+0.j]
+                    ],
+                    [
+                        [0.04748388+0.j, 0.95251612+0.j],
+                        [0.47081969+0.j, 0.52918031+0.j]
+                    ]
+                ]
+            ])
+        )
+    ]
+)
+def test_seed(dim, num_inputs, num_outputs, expected):
+    """Test that the function returns the expected output when seeded."""
+    povms = random_povm(dim=dim, num_inputs=num_inputs, num_outputs=num_outputs, seed=123)
+    assert_array_almost_equal(povms, expected)
diff --git a/toqito/rand/tests/test_random_state_vector.py b/toqito/rand/tests/test_random_state_vector.py
index f000dc6af..4966d9b77 100644
--- a/toqito/rand/tests/test_random_state_vector.py
+++ b/toqito/rand/tests/test_random_state_vector.py
@@ -1,6 +1,7 @@
 """Test random_state_vector."""
-
+import numpy as np
 import pytest
+from numpy.ma.testutils import assert_array_almost_equal
 
 from toqito.rand import random_state_vector
 from toqito.state_props import is_pure
@@ -27,3 +28,59 @@ def test_random_state_vector(dim, is_real, k_param):
     vec = random_state_vector(dim=dim, is_real=is_real, k_param=k_param).reshape(-1, 1)
     mat = vec @ vec.conj().T
     assert is_pure(mat)
+
+@pytest.mark.parametrize(
+    "dim, is_real, k_param, expected",
+    [
+        (
+            2,
+            False,
+            0,
+            np.array([
+                [0.91920422+0.29684938j],
+                [0.07250293+0.24836943j]
+            ])
+        ),
+        (
+            2,
+            False,
+            1,
+            np.array([
+                -0.01113702 + 0.61768143j,
+                0.07125721 + 0.20424701j,
+                -0.68156797 + 0.21116929j,
+                -0.19827006 + 0.15202896j
+            ])
+        ),
+        (
+            [2, 2],
+            False,
+            1,
+            np.array([
+                -0.01113702 + 0.61768143j,
+                0.07125721 + 0.20424701j,
+                -0.68156797 + 0.21116929j,
+                -0.19827006 + 0.15202896j
+            ])
+        ),
+        (
+            2,
+            True,
+            1,
+            np.array([0.76458086, 0.63971337, 0.06030689, 0.05045788])
+        ),
+        (
+            2,
+            True,
+            0,
+            np.array([
+                [0.99690375],
+                [0.07863154]
+            ])
+        ),
+    ],
+)
+def test_seed(dim, is_real, k_param, expected):
+    """Test that the function returns the expected output when seeded."""
+    vec = random_state_vector(dim, is_real=is_real, k_param=k_param, seed=123)
+    assert_array_almost_equal(vec, expected)
diff --git a/toqito/rand/tests/test_random_states.py b/toqito/rand/tests/test_random_states.py
index f7a37ac13..9825e96f3 100644
--- a/toqito/rand/tests/test_random_states.py
+++ b/toqito/rand/tests/test_random_states.py
@@ -2,6 +2,7 @@
 
 import numpy as np
 import pytest
+from numpy.ma.testutils import assert_array_almost_equal
 
 from toqito.rand import random_states
 from toqito.state_props import is_pure
@@ -35,3 +36,78 @@ def test_random_states(num_states, dim):
         dm = np.outer(state, np.conj(state))
         # Verify each state is pure.
         assert is_pure(dm)
+
+@pytest.mark.parametrize(
+    "num_states, dim, expected",
+    [
+        # Test with a single quantum state of dimension 2.
+        (
+            1,
+            2,
+            [
+                np.array([
+                    [-0.59005974+0.76831103j],
+                    [-0.2194029 +0.11571532j]
+                ])
+            ]
+        ),
+        # Test with multiple quantum states of the same dimension.
+        (
+            3,
+            2,
+            [
+                np.array([
+                    [-0.73471584-0.47276295j],
+                    [-0.27319062+0.40256019j]
+                ]),
+                np.array([
+                    [0.93422522-0.22964955j],
+                    [0.14070366-0.23385211j]
+                ]),
+                np.array([
+                    [0.49063955+0.0518067j],
+                    [0.30769445-0.81358038j]
+                ])
+            ]
+        ),
+        # Test with a single quantum state of higher dimension.
+        (
+            1,
+            4,
+            [
+                np.array([
+                    [-0.45679821+0.42498307j],
+                    [-0.16985205+0.26651935j],
+                    [0.5947925-0.29393305j],
+                    [0.0895817+0.25028557j]
+                ])
+            ]
+        ),
+        # Test with multiple quantum states of higher dimension.
+        (
+            2,
+            4,
+            [
+                np.array([
+                    [-0.42755142-0.13684957j],
+                    [-0.15897716-0.13935391j],
+                    [0.55671053+0.04200094j],
+                    [0.08384617-0.65958915j]
+                ]),
+                np.array([
+                    [0.4213706+0.5458888j],
+                    [0.26425386-0.30728968j],
+                    [-0.29143454+0.45801996j],
+                    [0.24815808+0.06242098j]
+                ])
+            ]
+        ),
+    ],
+)
+def test_seed(num_states, dim, expected):
+    """Test that the function returns the expected output when seeded."""
+    states = random_states(num_states, dim, seed=123)
+    assert len(states) == len(expected)
+
+    for state, expected_state in zip(states, expected):
+        assert_array_almost_equal(state, expected_state)
diff --git a/toqito/rand/tests/test_random_unitary.py b/toqito/rand/tests/test_random_unitary.py
index 664e65053..fa4b2beb4 100644
--- a/toqito/rand/tests/test_random_unitary.py
+++ b/toqito/rand/tests/test_random_unitary.py
@@ -1,6 +1,7 @@
 """Test random_unitary."""
-
+import numpy as np
 import pytest
+from numpy.ma.testutils import assert_array_almost_equal
 
 from toqito.matrix_props import is_unitary
 from toqito.rand import random_unitary
@@ -32,3 +33,29 @@ def test_non_square_dims(dim_n, dim_m, is_real):
     if dim_n != dim_m:
         with pytest.raises(ValueError, match="Unitary matrix must be square."):
             random_unitary(dim=[dim_n, dim_m], is_real=is_real)
+
+@pytest.mark.parametrize(
+    "dim, is_real, expected",
+    [
+        (
+            2,
+            False,
+            np.array([
+                [0.51345691+0.6924564j, 0.38709015+0.32715034j],
+                [0.16581665-0.47892689j, -0.08796944+0.85755189j]
+            ])
+        ),
+        (
+            2,
+            True,
+            np.array([
+                [0.95160818, -0.30731397],
+                [0.30731397,  0.95160818]
+            ])
+        ),
+    ]
+)
+def test_seed(dim, is_real, expected):
+    """Test that the function returns the expected output when seeded."""
+    mat = random_unitary(dim=dim, is_real=is_real, seed=123)
+    assert_array_almost_equal(mat, expected)