Group Abstract Group Abstract

Message Boards Message Boards

2
|
4.6K Views
|
0 Replies
|
2 Total Likes
View groups...
Share
Share this post:

How to deal with bad arguments when a function's UpValues is pure-function?

Posted 10 years ago

In practice, I need to define the UpValues of a user-defined function. For instance, the operation of function like differential formula , expansion and so on.

Here, I will give an example that came from my answer. Please see here

Bernstein::invidx = 
 "Index `1` should be a non-negative machine-sized integer betwwen `2` and `3`.";

SyntaxInformation[Bernstein] = {"ArgumentsPattern" -> {_,_,_}};

SetAttributes[Bernstein, NumericFunction]
(*special cases*)
Bernstein[0, 0, u_?NumericQ] := 1
Bernstein[0, 0, u_Symbol] := 1

(*normal cases*)
Bernstein[deg_Integer?NonNegative, idx_Integer?NonNegative, u_?NumericQ] /;
  idx <= deg && 0 <= u <= 1 :=
 Binomial[deg, idx] u^idx (1 - u)^(deg - idx)

Bernstein[deg_Integer?NonNegative, idx_Integer?NonNegative, u_?NumericQ] /;
  idx <= deg && (u > 1 || u < 0) := 0

Throw the error-informations

Bernstein[deg_Integer?NonNegative, idx_Integer?NonNegative, u_] /;
  idx > deg && (Message[Bernstein::invidx, idx, 0, deg - 1]; False) := $Failed;

expr : Bernstein[deg_ /; ! (IntegerQ[deg] && NonNegative[deg]), idx_, u_] /;
 (Message[Bernstein::intnm, Unevaluated[expr], 1]; False) := $Failed;

expr : Bernstein[deg_, idx_ /; ! (IntegerQ[idx] && NonNegative[idx]), u_] /;
 (Message[Bernstein::intnm, Unevaluated[expr], 2]; False) := $Failed;

Bernstein[args___] /;
 ! ArgumentCountQ[Bernstein, Length[{args}], 3, 3] && False := $Failed;    

The derivatives of Bernstein basis

Bernstein /: Derivative[0, 0, k_Integer?Positive][Bernstein] :=
 Function[{deg, idx, u},
  D[
   deg (Bernstein[deg - 1, idx - 1, u] - Bernstein[deg - 1, idx, u]),
   {u, k - 1}]
 ]

TEST

D[Bernstein[3, -2, x], x]
D[Bernstein[3, -2, x], {x, 2}]

enter image description here

Question

  • How to deal with bad arguments when a function's UpValues is a pure-function? Namely, throw the error information and then return the symbol $Failed.

Although Mr.Wizard given me a solution that using If[]

func /: Derivative[0, 0, 1][func] :=
 Function[{n, i, x},
  If[MatchQ[n, _Integer?NonNegative] && MatchQ[i, _Integer?NonNegative] && i <= n,
   n (func[n - 1, i - 1, x] - func[n - 1, i, x]),
   Defer@func[n, i, x]
 ]
]

However, which leads to another issue.

enter image description here

In fact, the built-in BSplineBasis[] also ingnore this problem.

knots = {0, 0, 0, 0, 1/3, 2/3, 1, 1, 1, 1};
D[BSplineBasis[{3, knots}, 7, x], {x, 2}]

enter image description here

POSTED BY: Shutao Tang
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard