Repository: scipy/scipy

Issue:
BUG: ValueError: setting an array element with a sequence for make_smoothing_spline
### Describe your issue.

When using [scipy.interpolate.make_smoothing_spline](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.make_smoothing_spline.html#scipy.interpolate.make_smoothing_spline) if you pass inputs of length less that 5 you get value error, values of the inputs does not affect this. If I increase length to 5 and bigger the problem disappears.

### Reproducing Code Example

```python
x = np.arange(4)
y = np.ones(4)
spl = make_smoothing_spline(x, y)
```


### Error message

```shell
ValueError: setting an array element with a sequence.
```


### SciPy/NumPy/Python version and system information

```shell
1.10.1 1.21.0 sys.version_info(major=3, minor=8, micro=5, releaselevel='final', serial=0)
Build Dependencies:
  blas:
    detection method: cmake
    found: true
    include directory: unknown
    lib directory: unknown
    name: OpenBLAS
    openblas configuration: unknown
    pc file directory: unknown
    version: 0.3.18
  lapack:
    detection method: cmake
    found: true
    include directory: unknown
    lib directory: unknown
    name: OpenBLAS
    openblas configuration: unknown
    pc file directory: unknown
    version: 0.3.18
Compilers:
  c:
    commands: cc
    linker: ld.bfd
    name: gcc
    version: 10.2.1
  c++:
    commands: c++
    linker: ld.bfd
    name: gcc
    version: 10.2.1
  cython:
    commands: cython
    linker: cython
    name: cython
    version: 0.29.33
  fortran:
    commands: gfortran
    linker: ld.bfd
    name: gcc
    version: 10.2.1
  pythran:
    include directory: /tmp/pip-build-env-q2fwe5jt/overlay/lib/python3.8/site-packages/pythran
    version: 0.12.1
Machine Information:
  build:
    cpu: x86_64
    endian: little
    family: x86_64
    system: linux
  cross-compiled: false
  host:
    cpu: x86_64
    endian: little
    family: x86_64
    system: linux
Python Information:
  path: /opt/python/cp38-cp38/bin/python
  version: '3.8'
```



Discussion:
Thank you for reporting @rudimytro. Indeed this is due to 

```python
for i in range(1, 4):
    X[i, 2: -2] = X_bspl[i: i - 4, 3: -3][np.diag_indices(n - 4)]
```

`n-4` is causing the issue here. Seems like we should add some input validation for a minimal size for `x, y`.
@egorz734 thoughts? 
@rudimytro, thank you for reporting this bug.

> Thank you for reporting @rudimytro. Indeed this is due to
> 
> ```python
> for i in range(1, 4):
>     X[i, 2: -2] = X_bspl[i: i - 4, 3: -3][np.diag_indices(n - 4)]
> ```
> 
> `n-4` is causing the issue here. Seems like we should add some input validation for a minimal size for `x, y`.

This part of the code is related to transforming the design matrix according to a special basis of natural B-Splines used to solve the problem of creating a smoothing spline.
This transformation goes as follows: the first 2 elements of the new basis are created using the first 3 elements of an old one and the same is made for the last 2 elements of the new basis and last 3 elements of an old one. All other elements remain the same. This transformation is disscussed here [link, only in Russian](https://lms.hse.ru/ap_service.php?getwork=1&guid=18F684EE-D07D-4D4F-80CF-10A9E361BCD6&roistat_visit=9135346), page 25 (formula 2.1.7).

In case when `n=4` it turns out that there are no elements to remain the same (there are no central elements, only 2 from both of the edges). Thus, the selected part of the code should not be applied to the case when `n=4`.

However, for now, I suppose that the assert `n > 4` will be enough.
@egorz734 just a note that we don't use `assert` for control flow in SciPy. Plain `if` and then raise a descriptive exception is enforced.

Resolving patch:
diff --git a/scipy/interpolate/_bsplines.py b/scipy/interpolate/_bsplines.py
--- a/scipy/interpolate/_bsplines.py
+++ b/scipy/interpolate/_bsplines.py
@@ -1877,9 +1877,9 @@ def make_smoothing_spline(x, y, w=None, lam=None):
     Parameters
     ----------
     x : array_like, shape (n,)
-        Abscissas.
+        Abscissas. `n` must be larger than 5.
     y : array_like, shape (n,)
-        Ordinates.
+        Ordinates. `n` must be larger than 5.
     w : array_like, shape (n,), optional
         Vector of weights. Default is ``np.ones_like(x)``.
     lam : float, (:math:`\lambda \geq 0`), optional
@@ -1980,6 +1980,9 @@ def make_smoothing_spline(x, y, w=None, lam=None):
     t = np.r_[[x[0]] * 3, x, [x[-1]] * 3]
     n = x.shape[0]
 
+    if n <= 4:
+        raise ValueError('``x`` and ``y`` length must be larger than 5')
+
     # It is known that the solution to the stated minimization problem exists
     # and is a natural cubic spline with vector of knots equal to the unique
     # elements of ``x`` [3], so we will solve the problem in the basis of


Test patch:
diff --git a/scipy/interpolate/tests/test_bsplines.py b/scipy/interpolate/tests/test_bsplines.py
--- a/scipy/interpolate/tests/test_bsplines.py
+++ b/scipy/interpolate/tests/test_bsplines.py
@@ -1560,6 +1560,13 @@ def test_invalid_input(self):
         with assert_raises(ValueError):
             make_smoothing_spline(x_dupl, y)
 
+        # x and y length must be larger than 5
+        x = np.arange(4)
+        y = np.ones(4)
+        exception_message = "``x`` and ``y`` length must be larger than 5"
+        with pytest.raises(ValueError, match=exception_message):
+            make_smoothing_spline(x, y)
+
     def test_compare_with_GCVSPL(self):
         """
         Data is generated in the following way: