# How to optimize my own BezierFunction?

A few months ago, I asked a question about the implementation of Bezier surface. Please see here for a full detail.

I also know that BezierFunction[] is built-in in Wolfram Language.

BezierFunction[array]

represents a Bézier function for a surface or high-dimensional manifold.

Owing to that I have been learning the NURBS theory, and I have implemented a variety of algorithms in my package CAGD.

Here, thanks for J.M.'s explanation about the definition of high-dimensional Bezier function.

So I implemented the CAGDBezierFunction[] as follows:

CAGDBezierFunction[array_, dim_][args__] :=
Fold[
#2.#1 &, array,
BernsteinBasis[#1, Range[0, #1], #2] & @@@ Thread@{dim, {args}}]

CAGDBezierFunction[array_] :=
CAGDBezierFunction[array, Most@Dimensions[array] - 1]

pts = RandomReal[1, {10, 10, 2, 1}];
BezierFunction[pts][0.1, 0.2, 0.2]
CAGDBezierFunction[pts][0.1, 0.2, 0.2]
(*{0.701598}*)


However, when I visualize this function via ContourPlot3D[], it is very time-consuming.

f = BezierFunction[pts]
ContourPlot3D[f[u, v, w], {u, 0, 1}, {v, 0, 1}, {w, 0, 1}, Mesh -> None] // AbsoluteTiming ContourPlot3D[
CAGDBezierFunction[pts, {9, 9, 1}][u, v, w],
{u, 0, 1}, {v, 0, 1}, {w, 0, 1}, Mesh -> None] So my question is :

• Is it possible to optimize the user-defined function CAGDBezierFunction[]?
• Is the programming language of Mathematica a high performance language?

Update:

Thanks for bill s's suggestion: PlotPoints -> 3 • What happens if you set Evaluated -> True in your second ContourPlot3D? – J. M.'s technical difficulties Feb 23 '16 at 10:38
• @J.M. I cannot achieve the graph when it ran for 5 min:( – xyz Feb 23 '16 at 10:51
• You can speed it up quite a bit by using fewer starting points, i.e., using PlotPoints -> 3 speeds it up by a factor of about 20. – bill s Apr 14 '16 at 14:53
• @bills Thanks a bunch. It is very useful:) – xyz Apr 14 '16 at 15:30
• And faster yet again with PlotPoints -> 2. I don't think it can go down to 1. – bill s Apr 14 '16 at 15:37

Here is a comparison of your function (adequately post-processed via PiecewiseExpand[] and Expand[]) compiled to "C" and "WVM" with SystemBezierFunction[]:

exs = Join[{#,
Compile[{{x, _Real}, {y, _Real}, {z, _Real}},
Evaluate[Expand@PiecewiseExpand[CAGDBezierFunction[pts][x, y, z],
Thread[0 < {x, y, z} < 1]]],
CompilationTarget -> #, RuntimeOptions -> "EvaluateSymbolically" -> False]} & /@
{"C", "WVM"}, {{System, BezierFunction[pts]}}];

Grid[Join[{{"Timing", "Result"}},
Timing@ContourPlot3D[#[][u, v, w], {u, 0, 1}, {v, 0, 1}, {w, 0, 1},
Mesh -> None, PlotLabel -> #[]] & /@ exs],
Frame -> All] RuntimeOptions -> "EvaluateSymbolically" -> False` was suggested by xzczd in a (now deleted) comment.