Create a sparse (possibly periodic) design matrix.
(u: Array, order: int, knots: Array, periodic: bool = False)
| 949 | |
| 950 | @njit |
| 951 | def designMatrix(u: Array, order: int, knots: Array, periodic: bool = False) -> COO: |
| 952 | """ |
| 953 | Create a sparse (possibly periodic) design matrix. |
| 954 | """ |
| 955 | |
| 956 | # extend the knots |
| 957 | u_, knots_ext, minspan, maxspan, deltaspan = _preprocess(u, order, knots, periodic) |
| 958 | |
| 959 | # number of parameter values |
| 960 | nu = len(u) |
| 961 | |
| 962 | # number of basis functions |
| 963 | nb = maxspan |
| 964 | |
| 965 | # chunk size |
| 966 | n = order + 1 |
| 967 | |
| 968 | # temp chunk storage |
| 969 | temp = np.zeros(n) |
| 970 | |
| 971 | # initialize the empty matrix |
| 972 | rv = COO( |
| 973 | i=np.empty(n * nu, dtype=np.int64), |
| 974 | j=np.empty(n * nu, dtype=np.int64), |
| 975 | v=np.empty(n * nu), |
| 976 | shape=(nu, len(knots) - 1 - (not periodic) * order), |
| 977 | ) |
| 978 | |
| 979 | # loop over parameter values |
| 980 | for i in range(nu): |
| 981 | ui = u_[i] |
| 982 | |
| 983 | # find the supporting span |
| 984 | span = nbFindSpan(ui, order, knots, minspan, maxspan) + deltaspan |
| 985 | |
| 986 | # evaluate non-zero functions |
| 987 | nbBasis(span, ui, order, knots_ext, temp) |
| 988 | |
| 989 | # update the matrix |
| 990 | rv.i[i * n : (i + 1) * n] = i |
| 991 | rv.j[i * n : (i + 1) * n] = ( |
| 992 | span - order + int(periodic) + np.arange(n) |
| 993 | ) % nb # NB: this is due to periodicity |
| 994 | rv.v[i * n : (i + 1) * n] = temp |
| 995 | |
| 996 | return rv |
| 997 | |
| 998 | |
| 999 | @njit |