6
$\begingroup$

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

enter image description here

ContourPlot3D[
 CAGDBezierFunction[pts, {9, 9, 1}][u, v, w], 
 {u, 0, 1}, {v, 0, 1}, {w, 0, 1}, Mesh -> None]

enter image description here

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

enter image description here

$\endgroup$
  • $\begingroup$ What happens if you set Evaluated -> True in your second ContourPlot3D? $\endgroup$ – J. M. is away Feb 23 '16 at 10:38
  • $\begingroup$ @J.M. I cannot achieve the graph when it ran for 5 min:( $\endgroup$ – xyz Feb 23 '16 at 10:51
  • 2
    $\begingroup$ 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. $\endgroup$ – bill s Apr 14 '16 at 14:53
  • $\begingroup$ @bills Thanks a bunch. It is very useful:) $\endgroup$ – xyz Apr 14 '16 at 15:30
  • $\begingroup$ And faster yet again with PlotPoints -> 2. I don't think it can go down to 1. $\endgroup$ – bill s Apr 14 '16 at 15:37
7
$\begingroup$

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

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[#[[2]][u, v, w], {u, 0, 1}, {v, 0, 1}, {w, 0, 1}, 
                       Mesh -> None, PlotLabel -> #[[1]]] & /@ exs], 
  Frame -> All]

![enter image description here

RuntimeOptions -> "EvaluateSymbolically" -> False was suggested by xzczd in a (now deleted) comment.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.