Computes all nonzero basis functions and their derivatives based on Algorithm A2.3 in the NURBS Book [^1].
Return value, real :: ders(j,k)  and , is the th derivative of the function , where  is the knot span of , by using the following equation,
Remarks;
To avoids memory usage as much as possible in the computiation, two local arrays "a" and "ndu" introduced;
a(0:1,0:p), stores the two most recently computed rows,  and ;  
 depend on the  but not the  and utilize the knot differences seen in the lower triangle part of the ndu(0:p,0:p) matrix by using  and  functions  
ndu(0:p,0:p), stores the basis functions and knot differences on its upper and lower triangle, respectively;
| ndu array (See example) | 
Note: This algorithm applies to rational basis functions.
Let , , and . Then , and the array becomes
Now compute and ; with in Eq. (2.10), we have
Now , and all use knot differences which are not in the array, but they are multiplied respectively by , , and , which are also not in the array. These terms are defined to be zero, and we are left with
To check these values, recall from Cox-de Boor formula that on . The computation of , , and is analogous.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(basis), | intent(in) | :: | me | |||
| real(kind=wp), | intent(in) | :: | u | Given value  | 
  
||
| integer, | intent(in) | :: | n | Number of derivatives ()  | 
  
||
| real(kind=wp), | intent(out) | :: | ders(0:me%p,0:n) | 
  | 
  
||
| integer, | intent(in), | optional | :: | span | Knot span where lies on  | 
  
        pure subroutine DersBasisFuns(me,u,n,ders,span)
            class(basis), intent(in)            :: me
            real(wp),   intent(in)              :: u            !< Given \( u \) value
            integer,    intent(in)              :: n            !< Number of derivatives (\(n \leq p\))
            integer,    intent(in), optional    :: span         !< Knot span where \( u \) lies on
            real(wp),   intent(out)             :: ders(0:me%p, 0:n)    !<
                                                !< $$ = \begin{bmatrix} {N_{i - p,p}^{(0)}(u)} & \cdots &{N_{i - p,p}^{(k)}(u)}\\
                                                !< \vdots & \ddots & \vdots \\ {N_{i,p}^{(0)}(u)} & \cdots &{N_{i,p}^{(k)}(u)} \end{bmatrix} $$  
            !locals
            integer :: i    !< Knot span index
            integer :: j, k, r, s1, s2, rk, pk, j1, j2
            real(wp) :: saved, temp, d
            real(wp) :: left(me%p), right(me%p)
            real(wp) :: ndu(0:me%p,0:me%p), a(0:1,0:me%p)
            
            ders = 0.0_wp
            associate( p => me%p, Ui => me%kv ) !get rid of % signs
            ! set the knot span
            if(present(span))then
                i = span
            else
                i = me%FindSpan(u)
            end if
                
            ndu(0,0) = 1.0_wp
            do j = 1, p
                left(j)  = u - Ui(i+1-j)
                right(j) = Ui(i+j) - u
                saved = 0.0_wp
                do r = 0, j-1
                    !/* Lower triangle */
                    ndu(j,r) = right(r+1) + left(j-r) 
                    temp = ndu(r,j-1) / ndu(j,r)
                    !/* Upper triangle */
                    ndu(r,j) = saved + right(r+1) * temp
                    saved = left(j-r) * temp
                end do
                ndu(j,j) = saved
            end do
            
            !/* Load the basis functions */
            ders(:,0) = ndu(:,p)
            
            !/* This section computes the derivatives (Eq. [2.9]) */
            do r = 0, p !/* Loop over function index */
                s1 = 0; s2 = 1 !/* Alternate rows in array a */
                a(0,0) = 1.0_wp
                !/* Loop to compute kth derivative */
                do k = 1, n
                    d = 0.0_wp
                    rk = r-k; pk = p-k;
                    if (r >= k) then
                        a(s2,0) = a(s1,0) / ndu(pk+1,rk)
                        d =  a(s2,0) * ndu(rk,pk)
                    end if
                    if (rk > -1) then
                        j1 = 1
                    else
                        j1 = -rk
                    end if
                    if (r-1 <= pk) then
                        j2 = k-1
                    else
                        j2 = p-r
                    end if
                    do j = j1, j2
                        a(s2,j) = (a(s1,j) - a(s1,j-1)) / ndu(pk+1,rk+j)
                        d =  d + a(s2,j) * ndu(rk+j,pk)
                    end do
                    if (r <= pk) then
                        a(s2,k) = - a(s1,k-1) / ndu(pk+1,r)
                        d =  d + a(s2,k) * ndu(r,pk)
                    end if
                    ders(r,k) = d
                    j = s1; s1 = s2; s2 = j !/* Switch rows */
                end do
            end do
            !/* Multiply through by the correct factors */
            !/* (Eq. [2.9]) */
            r = p
            do k = 1, n
                ders(:,k) = ders(:,k) * r
                r = r * (p-k)
            end do
            end associate
        end subroutine DersBasisFuns