# How to define the Bernstein function like the built-in BernsteinBasis?

We know the Bernstein function defined as below:

$$B_{n,i}(u)=\binom n i u^i(1-u)^{n-i}$$

And we define $B_{n,i}(u)=0$ when $i<0$ or $i>n$

In addition, the first derivative of $B_{n,i}(u)$ has the below relationship:

$$B'_{n,i}(u)=n\left[B_{n-1,i-1}(u)-B_{n-1,i}(u)\right]$$

So I can utilize this equation to calculate the derivative of order $k$

$$B^{(k)}_{n,i}(u)=n(n-1)\cdots (n-k+1)\\ \left[\{B_{n-k,i-k}(u),\cdots,B_{n-k,i}(u)\} .coefficient\right]$$

Here,$coefficient$ has the style (1,-3,3,1),(1, -4, 6, -4, 1),etc

### Implementation

Bernstein[n_, i_, u_] /; i < 0 || i > n := 0
Bernstein[0, 0, u_] := 1
Bernstein[n_, i_, u_?NumericQ] := Binomial[n, i] u^i (1 - u)^(n - i)


The derivative of Bernstein

D[Bernstein[n_, i_, u_], {u_, k_}] ^:=
Module[{coeff, body},
coeff = Times @@ Array[n - # &, k, 0];
body =
Array[Bernstein[n - k, #, u] &, k + 1, i - k].
CoefficientList[(1 - u)^k, u];
coeff* body
]
(*=======================================*)
D[Bernstein[n_, i_, u_], u_] ^:= D[Bernstein[n, i, u], {u, 1}]


However, the Mathematica give me the warining information

Expand the expression

PiecewiseExpand[expr_] ^:=
expr /. Bernstein[n_, i_, u_Symbol] :>
Binomial[n, i] u^i (1 - u)^(n - i)


### Tesing

Successful case

Bernstein[3, 2, .4](*0.288*)

D[Bernstein[3, 2, u], u]

3 (Bernstein[2, 1, u] - Bernstein[2, 2, u])

D[Bernstein[3, 2, u], {u, 2}]

6 (Bernstein[1, 0, u] - 2 Bernstein[1, 1, u])


Failture

D[Bernstein[3, 2, u], u] // PiecewiseExpand


no expantion >_<

### Question

• How to fix the warining information about UpSetDelayed?
• Is it possible to implement the derivative of $B_{n,i}(u)$ by rule-based solution? I have a trial, but failed.

My trial

D[Berns[n_, i_, u_], {u_, k_}] ^:=
Do[
Bernstein[n, i, u] /.
Bernstein[x_, y_, z_] :>
x (Bernstein[x - 1, y - 1, u] - Bernstein[x - 1, y, z]), {k}]
(*failture*)


Built-in function

D[BernsteinBasis[6, 3, u], {u, 3}]


Obviously, the Mathematica utilizes a recursive method by observing the result.

## 1 Answer

Your use of UpSetDelayed had issues. The first problem is that it couldn't deal with the pattern corresponding to the differentiation variable and order in defining the derivative. Later, when defining the action of PiecewiseExpand, UpSetDelayed cannot work at all because it needs to be associated with BernsteinBasis (or some symbol) and not with the placeholder for an expression, given by the pattern expr_.

To fix the first issue, I would suggest not using UpSetDelayed at all and instead doing it this way:

Bernstein[n_, i_, u_] /; i < 0 || i > n := 0
Bernstein[0, 0, u_] := 1
Bernstein[n_, i_, u_?NumericQ] := Binomial[n, i] u^i (1 - u)^(n - i)

Bernstein[3, 2, .4]

(* ==> 0.288 *)

Derivative[0, 0, k_][Bernstein][n_, i_, u_] :=
Module[{coeff, body}, coeff = Times @@ Array[n - # &, k, 0];
body = Array[Bernstein[n - k, #, u] &, k + 1,
i - k].CoefficientList[(1 - u)^k, u];
coeff*body]

D[Bernstein[3, 2, u], u]

(* ==> 3 (Bernstein[2, 1, u] - Bernstein[2, 2, u]) *)

D[Bernstein[3, 2, u], {u, 2}]

(*
==> 3 (2 (Bernstein[1, 0, u] - Bernstein[1, 1, u]) -
2 Bernstein[1, 1, u])
*)

Simplify[%]

(* ==> 6 (Bernstein[1, 0, u] - 2 Bernstein[1, 1, u]) *)

bernsteinExpand =
Bernstein[n_, i_, u_Symbol] :> Binomial[n, i] u^i (1 - u)^(n - i);

D[Bernstein[3, 2, u], u] /. bernsteinExpand

(* ==> 3 (2 (1 - u) u - u^2) *)


Here I made the definition for Derivative with SetDelayed. This form is always arrived at when you try to do derivatives even with D, so there is no need for the second definition for the first derivative that you had in your approach.

The tests seem to work as expected. For the PieceWiseExpand, I couldn't see a reason why it should be used at all, and instead I defined a rule to make the desired replacement by appending /.bernsteinExpand to any given expression. I think if you want to give definitions for PiecewiseExpand, you'll have to Unprotect it first, and I didn't want to do that.

Edit in response to comment

In the tests, I used the D operator instead of Derivative. The form involving D is ultimately transformed into Derivative, and not vice versa. That's why it's more general to make definitions for Derivative than for D. However, when you test higher-order derivatives with D, then Mathematica executes them as repeated first-order derivatives. This can be seen using Trace:

Trace[D[f[x], {x, 2}]]


$\left\{\frac{\partial ^2f(x)}{\partial x^2},\left(f'\right)'(x),\left\{\left(f'\right)',f'' \right\},f''(x)\right\}$

For your application, this means that the call

D[Bernstein[3, 2, u], {u, 2}]


is broken up into two steps, tantamount to

D[Bernstein[3, 2, u], u]


followed by

D[%, u]


And as you can see by doing these two steps, this means that the definition for Derivative with k > 1 is not used. That's why I had to Simplify the result. Instead, if you ask for the Derivative in the more formal way, you get the direct route:

Derivative[0, 0, 2][Bernstein][3, 2, u]

6 (Bernstein[1, 0, u] - 2 Bernstein[1, 1, u])


This is the result you wanted. If you care about a more concise notation, you could modify all the above definitions so that Bernstein[n_,i_,u_] is replaced by Bernstein[n_,i_][u_]. Then you can type the derivatives as Bernstein[n,i]'[u], Bernstein[n,i]''[u] etc.

Simplify the code of the derivative of Bernstein basis

Derivative[0, 0, 1][Bernstein] :=
Function[{deg, idx, u},
Piecewise[
{{deg Bernstein[deg - 1, idx - 1, u], deg == idx},
{-deg Bernstein[deg - 1, idx, u], idx == 0}},
deg (Bernstein[deg - 1, idx - 1, u] - Bernstein[deg - 1, idx, u])]
];

• +1, Thanks a lot. However, I have a question. Why D[Bernstein[3, 2, u], {u, 2}] gives the result 3 (2 (Bernstein[1, 0, u] - Bernstein[1, 1, u]) - 2 Bernstein[1, 1, u]), rather than 6 (Bernstein[1, 0, u] - 2 Bernstein[1, 1, u]). Because in the function, I write down the latter style directly (coeff*body)
– xyz
Commented Apr 8, 2015 at 6:44
• @ShutaoTang I don't understand why you edited my answer. The added definition doesn't seem to have anything to do with what I said.
– Jens
Commented Jul 29, 2015 at 4:51
• sorry, @Jens maybe I should add the defintion in the bottom.
– xyz
Commented Jul 29, 2015 at 5:43
• @Shutao, I'm clearly missing the point of the explicit Piecewise[] as they are supposed to be implicit in the definition for the Bernstein functions. I don't have time to look at this in detail right now, but I did give you the correct general formula. You only have to specialize it to the first derivative case. Commented Jul 29, 2015 at 8:40
• @J. M. Yes, the formula you give me is right, namely,　$$B^{(k)}_{n,i}(u)=n(n-1)\cdots (n-k+1)\\ \left[\{B_{n-k,i-k}(u),\cdots,B_{n-k,i}(u)\} .coeffs\right]$$　Here,coeffs　has the style like(1,-3,3,1),(1, -4, 6, -4, 1) ,etc．
– xyz
Commented Jul 29, 2015 at 9:25