Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
            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))