diff --git a/aesara/tensor/__init__.py b/aesara/tensor/__init__.py
index af894fa98..787bd4871 100644
--- a/aesara/tensor/__init__.py
+++ b/aesara/tensor/__init__.py
@@ -134,6 +134,9 @@ from aesara.tensor.extra_ops import (  # noqa
     squeeze,
     unique,
     unravel_index,
+    linspace,
+    logspace,
+    geomspace,
 )
 from aesara.tensor.shape import (  # noqa
     reshape,
diff --git a/aesara/tensor/extra_ops.py b/aesara/tensor/extra_ops.py
index 9db12b045..d054f5d46 100644
--- a/aesara/tensor/extra_ops.py
+++ b/aesara/tensor/extra_ops.py
@@ -1636,6 +1636,29 @@ class BroadcastTo(Op):
 broadcast_to_ = BroadcastTo()
 
 
+def geomspace(start, end, steps, base=10.0):
+    from aesara.tensor.math import log
+
+    start = at.as_tensor_variable(start)
+    end = at.as_tensor_variable(end)
+    return base ** linspace(log(start) / log(base), log(end) / log(base), steps)
+
+
+def logspace(start, end, steps, base=10.0):
+    start = at.as_tensor_variable(start)
+    end = at.as_tensor_variable(end)
+    return base ** linspace(start, end, steps)
+
+
+def linspace(start, end, steps):
+    start = at.as_tensor_variable(start)
+    end = at.as_tensor_variable(end)
+    arr = at.arange(steps)
+    arr = at.shape_padright(arr, max(start.ndim, end.ndim))
+    multiplier = (end - start) / (steps - 1)
+    return start + arr * multiplier
+
+
 def broadcast_to(
     x: TensorVariable, shape: Union[TensorVariable, Tuple[Variable]]
 ) -> TensorVariable:

diff --git a/tests/tensor/test_extra_ops.py b/tests/tensor/test_extra_ops.py
index a6aa85cb0..ce57ae6ae 100644
--- a/tests/tensor/test_extra_ops.py
+++ b/tests/tensor/test_extra_ops.py
@@ -36,6 +36,9 @@ from aesara.tensor.extra_ops import (
     diff,
     fill_diagonal,
     fill_diagonal_offset,
+    geomspace,
+    linspace,
+    logspace,
     ravel_multi_index,
     repeat,
     searchsorted,
@@ -65,6 +68,11 @@ from aesara.utils import LOCAL_BITWIDTH, PYTHON_INT_BITWIDTH
 from tests import unittest_tools as utt
 
 
+def set_test_value(x, v):
+    x.tag.test_value = v
+    return x
+
+
 def test_cpu_contiguous():
     a = fmatrix("a")
     i = iscalar("i")
@@ -1222,3 +1230,28 @@ def test_broadcast_arrays():
 
     assert np.array_equal(x_bcast_val, x_bcast_exp)
     assert np.array_equal(y_bcast_val, y_bcast_exp)
+
+
+@pytest.mark.parametrize(
+    "start, stop, num_samples",
+    [
+        (1, 10, 50),
+        (np.array([5, 6]), np.array([[10, 10], [10, 10]]), 25),
+        (1, np.array([5, 6]), 30),
+    ],
+)
+def test_space_ops(start, stop, num_samples):
+    z = linspace(start, stop, num_samples)
+    aesara_res = function(inputs=[], outputs=z)()
+    numpy_res = np.linspace(start, stop, num=num_samples)
+    assert np.allclose(aesara_res, numpy_res)
+
+    z = logspace(start, stop, num_samples)
+    aesara_res = function(inputs=[], outputs=z)()
+    numpy_res = np.logspace(start, stop, num=num_samples)
+    assert np.allclose(aesara_res, numpy_res)
+
+    z = geomspace(start, stop, num_samples)
+    aesara_res = function(inputs=[], outputs=z)()
+    numpy_res = np.geomspace(start, stop, num=num_samples)
+    assert np.allclose(aesara_res, numpy_res)

Implement Op for `linspace` and similar numpy functions
The following numpy functions don't have to counterpart in Aesara:
* [linspace](https://numpy.org/doc/stable/reference/generated/numpy.linspace.html)
* [logspace](https://numpy.org/doc/stable/reference/generated/numpy.logspace.html)
* [geomspace](https://numpy.org/doc/stable/reference/generated/numpy.geomspace.html)

I am not familiar with all of them, so some might not make sense, or they might be low priority.
`linspace` would definitely be nice to have.
tests/tensor/test_extra_ops.py::test_cpu_contiguous tests/tensor/test_extra_ops.py::TestSearchsortedOp::test_searchsortedOp_on_sorted_input tests/tensor/test_extra_ops.py::TestSearchsortedOp::test_searchsortedOp_wrong_side_kwd tests/tensor/test_extra_ops.py::TestSearchsortedOp::test_searchsortedOp_on_no_1d_inp tests/tensor/test_extra_ops.py::TestSearchsortedOp::test_searchsortedOp_on_float_sorter tests/tensor/test_extra_ops.py::TestSearchsortedOp::test_searchsortedOp_on_int_sorter tests/tensor/test_extra_ops.py::TestSearchsortedOp::test_searchsortedOp_on_right_side tests/tensor/test_extra_ops.py::TestSearchsortedOp::test_infer_shape tests/tensor/test_extra_ops.py::TestSearchsortedOp::test_grad tests/tensor/test_extra_ops.py::TestDiffOp::test_diffOp tests/tensor/test_extra_ops.py::TestDiffOp::test_output_type[x_type0] tests/tensor/test_extra_ops.py::TestDiffOp::test_output_type[x_type1] tests/tensor/test_extra_ops.py::TestDiffOp::test_output_type[x_type2] tests/tensor/test_extra_ops.py::TestDiffOp::test_output_type[x_type3] tests/tensor/test_extra_ops.py::TestDiffOp::test_infer_shape tests/tensor/test_extra_ops.py::TestDiffOp::test_grad tests/tensor/test_extra_ops.py::TestDiffOp::test_grad_not_implemented tests/tensor/test_extra_ops.py::TestSqueeze::test_op tests/tensor/test_extra_ops.py::TestSqueeze::test_infer_shape tests/tensor/test_extra_ops.py::TestSqueeze::test_grad tests/tensor/test_extra_ops.py::TestSqueeze::test_var_interface tests/tensor/test_extra_ops.py::TestSqueeze::test_axis tests/tensor/test_extra_ops.py::TestCompress::test_op tests/tensor/test_extra_ops.py::TestRepeat::test_basic tests/tensor/test_extra_ops.py::TestRepeat::test_grad tests/tensor/test_extra_ops.py::TestRepeat::test_broadcastable tests/tensor/test_extra_ops.py::TestBartlett::test_perform tests/tensor/test_extra_ops.py::TestBartlett::test_infer_shape tests/tensor/test_extra_ops.py::TestFillDiagonal::test_infer_shape tests/tensor/test_extra_ops.py::TestFillDiagonalOffset::test_gradient tests/tensor/test_extra_ops.py::TestFillDiagonalOffset::test_infer_shape tests/tensor/test_extra_ops.py::test_to_one_hot tests/tensor/test_extra_ops.py::TestUnique::test_basic_vector[x0-inp0-None] tests/tensor/test_extra_ops.py::TestUnique::test_basic_vector[x1-inp1-None] tests/tensor/test_extra_ops.py::TestUnique::test_basic_vector[x2-inp2-0] tests/tensor/test_extra_ops.py::TestUnique::test_basic_vector[x3-inp3-0] tests/tensor/test_extra_ops.py::TestUnique::test_basic_vector[x4-inp4--1] tests/tensor/test_extra_ops.py::TestUnique::test_basic_vector[x5-inp5--1] tests/tensor/test_extra_ops.py::TestUnique::test_infer_shape[x0-inp0-None] tests/tensor/test_extra_ops.py::TestUnique::test_infer_shape[x2-inp2-0] tests/tensor/test_extra_ops.py::TestUnique::test_infer_shape[x3-inp3-0] tests/tensor/test_extra_ops.py::TestUnique::test_infer_shape[x4-inp4--1] tests/tensor/test_extra_ops.py::TestUnique::test_infer_shape[x5-inp5--1] tests/tensor/test_extra_ops.py::test_broadcast_shape_symbolic[s1_vals0-s2_vals0-exp_res0] tests/tensor/test_extra_ops.py::test_broadcast_shape_symbolic[s1_vals1-s2_vals1-exp_res1] tests/tensor/test_extra_ops.py::test_broadcast_shape_symbolic[s1_vals2-s2_vals2-exp_res2] tests/tensor/test_extra_ops.py::TestBroadcastTo::test_avoid_useless_scalars tests/tensor/test_extra_ops.py::TestBroadcastTo::test_avoid_useless_subtensors tests/tensor/test_extra_ops.py::TestBroadcastTo::test_perform tests/tensor/test_extra_ops.py::TestBroadcastTo::test_gradient[<lambda>-input_dims0] tests/tensor/test_extra_ops.py::TestBroadcastTo::test_gradient[<lambda>-input_dims1] tests/tensor/test_extra_ops.py::TestBroadcastTo::test_gradient[<lambda>-input_dims2] tests/tensor/test_extra_ops.py::TestBroadcastTo::test_gradient[<lambda>-input_dims3] tests/tensor/test_extra_ops.py::TestBroadcastTo::test_infer_shape tests/tensor/test_extra_ops.py::TestBroadcastTo::test_inplace tests/tensor/test_extra_ops.py::test_broadcast_arrays tests/tensor/test_extra_ops.py::test_space_ops[1-10-50] tests/tensor/test_extra_ops.py::test_space_ops[start1-stop1-25] tests/tensor/test_extra_ops.py::test_space_ops[1-stop2-30]