def dbfunsop(n, u, p, U): """Computes values, rows and cols for an operator (a sparse matrix) of the form :math:`dB_{ij}=\\partial_{u_j} B_{i,p}(u_j)` For perfomance and flexibility reasons the sparse matrix is to be constructed out of the return values, e.g. `scipy.sparse.csc_matrix(vals, rows, cols)` Parameters: n (int) : derivative order u (np.array(float)) : evaluation point(s) p (int) : basis function degree U (np.array(float)) : knot vector Returns: (float, (int, int)) : (values, (rows, cols)) """ nkts = U.size nbfuns = nkts - p - 1 npts = u.size rows, cols, vals = [], [], [] for j in range(0, npts): span = fspan(u[j], p, U) dB_i = dbfuns(span, n, u[j], p, U) for i in range(0, p + 1): rows.append(span - p + i) cols.append(j) vals.append(dB_i[n, i]) shape = (nbfuns, npts) return (np.array(vals), (np.array(rows), np.array(cols))), shape
def dbfunsmat(n, u, p, U): """Computes a matrix of the form :math:`dB_{ij}`, where :math:`i=0\\ldots p` and for each :math:`j` th column the row :math:`i` of the matrix corresponds to the value of :math:`(\\mathrm{span}(u_j)-p+i)` th bspline basis function :math:`n` th derivative at :math:`u_j`. Parameters: n (int) : derivative order u (np.array(float)) : evaluation point(s) p (int) : basis function degree U (np.array(float)) : knot vector Returns: np.array(float) : matrix :math:`dB_{ij}` """ nkts = U.size nbfuns = nkts - p - 1 npts = u.size dBij = np.zeros((p + 1, npts)) for j in range(0, npts): span = fspan(u[j], p, U) dB_i = dbfuns(span, n, u[j], p, U) for i in range(0, p + 1): dBij[i, j] = dB_i[n, i] return dBij
def ktsinsop(n, u, p, U): """Computes the multi-knot insertion operator :math:`A_{ij}` in the form of a sparse matrix, which is returned together with the new knot vector. The operation is to be evalated as :math:`\\tilde{P}_{ij} = P_{ik} A_{kj}` Parameters: n (int) : number of basis functions defined on the knot vector u (np.array(float)) : evaluation points p (int) : basis degree U (np.array(float)) : knot vector Returns: scipy.sparse.csc_matrix() : operator :math:`A_{ij}` np.array(float) : updated knot vector """ A = eye(n, format='csc') for ui in u: i = fspan(ui, p, U) A = A * csc_matrix(kntinsop(i, n, ui, p, U)) n += 1 U = np.insert(U, i + 1, ui) return A, U
s2 = j r = float(p) for k in range(1, n + 1): for j in range(0, p + 1): ders[k][j] *= r r *= (p - k) return ders if __name__ == '__main__': from tensiga.iga.fspan import fspan from tensiga.iga.dbfun import * n = 3 u = 5. / 2 p = 2 U = np.array([0, 0, 0, 1, 2, 3, 4, 4, 5, 5, 5], dtype=np.float64) i = fspan(u, p, U) print('Single call:') print(dbfuns(i, n, u, p, U)) print(' ') print('One by one computation:') dB22 = dbfun(i - p + 0, n, u, p, U) dB32 = dbfun(i - p + 1, n, u, p, U) dB42 = dbfun(i - p + 2, n, u, p, U) print(np.stack([dB22, dB32, dB42], axis=-1))