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

1 Answer 1

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$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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