9 replaced http://mathematica.stackexchange.com/ with https://mathematica.stackexchange.com/
source | link

Here, I will give a example that came from my answer. Please see herehere

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

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

8 edited tags
| link
    Notice removed Canonical answer required by xyz
    Bounty Ended with Mr.Wizard's answer chosen by xyz
7 added 167 characters in body; edited title
source | link

How to deal with error informationbad arguments when a function ownsfunction's UpValues is a pure-function?

Here, I will give a toy example as follows:

func[n,i,x], where n and i should be an integer like $1,2,3...$, and $i\leq n$

func[
  n_Integer?NonNegative, 
  i_Integer?NonNegative, x_] /; i <= n := i/n*x

Check the validness of argumentsthat came from my answer. Please see here

funcBernstein::invidx =
   
 "Index `1` should be a non-negative machine-sized integer betwwen `2` and `3`.";
func:
SyntaxInformation[Bernstein] = {"ArgumentsPattern" -> {_,_,_}};

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

(*normal cases*)
Bernstein[deg_Integer?NonNegative, "Numberidx_Integer?NonNegative, `1`u_?NumericQ] should/;
 be aidx non<= deg && 0 <= u <= 1 :=
 Binomial[deg, idx] u^idx (1 -negative machineu)^(deg -sized integer.";
idx)

func[n_IntegerBernstein[deg_Integer?NonNegative, i_Integeridx_Integer?NonNegative, x_u_?NumericQ] /;
  iidx <= deg && (u > n1 || u < 0) := 0

Throw the error-informations

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

func[n_expr : Bernstein[deg_ /; ! (IntegerQ[n]IntegerQ[deg] && NonNegative[n]NonNegative[deg]), i_idx_, x_]u_] /;
  (Message[funcMessage[Bernstein::intnm, n];Unevaluated[expr], 1]; False) := $Failed;

func[n_expr : Bernstein[deg_, i_idx_ /; ! (IntegerQ[i]IntegerQ[idx] && NonNegative[i]NonNegative[idx]), x_]u_] /;
  (Message[funcMessage[Bernstein::intnm, i];Unevaluated[expr], 2]; False) := $Failed;

(*check the number of arguments*)
func[args___]Bernstein[args___] /;
  ! ArgumentCountQ[funcArgumentCountQ[Bernstein, Length[{args}], 3, 3] && False := $Failed;    

Here, assuming that the func[] owns the following differential formula

$\frac d {dx}f(n,i,x)=n [f(n - 1, i - 1, x) - f(n - 1, i, x)]$The derivatives of Bernstein basis

funcBernstein /: Derivative[0, 0, 1][func]k_Integer?Positive][Bernstein] :=
 Function[{ndeg, iidx, xu},
  D[
   ndeg (func[nBernstein[deg - 1, iidx - 1, x]u] - func[nBernstein[deg - 1, iidx, x]u]),
   {u, k - 1}]
 ]

In my implementation, the func[] works well.

enter code here

However, the UpValues of func cannot deal with bad arguments.

TEST

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

enter image description here

For the case D[func[-4, 2, x], x], due to func[-4, 2, x] has bad argument, so it doesn't make sense. Namely, it should not own the answer.

enter image description here

For the built-in BSplineBasis[], Due to BSplineBasis[-4, 2, x] // PiecewiseExpandhas a valid input -4, so the PiecewiseExpand[] doesn't expand its mathematical expression rather than return the error information and the expression itself.enter image description here

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

To deal with bad arguments of UpValues, I need to checkthe arguments byAlthough 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 hereenter 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

How to deal with error information when a function owns UpValues?

Here, I will give a toy example as follows:

func[n,i,x], where n and i should be an integer like $1,2,3...$, and $i\leq n$

func[
  n_Integer?NonNegative, 
  i_Integer?NonNegative, x_] /; i <= n := i/n*x

Check the validness of arguments

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


func[n_Integer?NonNegative, i_Integer?NonNegative, x_?NumericQ] /;
  i > n && (Message[func::invidx, i, 0, n ]; False) := $Failed;

func[n_ /; ! (IntegerQ[n] && NonNegative[n]), i_, x_] /;
  (Message[func::intnm, n]; False) := $Failed;

func[n_, i_ /; ! (IntegerQ[i] && NonNegative[i]), x_] /;
  (Message[func::intnm, i]; False) := $Failed;

(*check the number of arguments*)
func[args___] /;
  ! ArgumentCountQ[func, Length[{args}], 3, 3] && False := $Failed;

Here, assuming that the func[] owns the following differential formula

$\frac d {dx}f(n,i,x)=n [f(n - 1, i - 1, x) - f(n - 1, i, x)]$

func /: Derivative[0, 0, 1][func] :=
 Function[{n, i, x},
    n (func[n - 1, i - 1, x] - func[n - 1, i, x])
  ]

In my implementation, the func[] works well.

enter code here

However, the UpValues of func cannot deal with bad arguments.

D[func[-4, 2, x], x]

enter image description here

For the case D[func[-4, 2, x], x], due to func[-4, 2, x] has bad argument, so it doesn't make sense. Namely, it should not own the answer.

enter image description here

For the built-in BSplineBasis[], Due to BSplineBasis[-4, 2, x] // PiecewiseExpandhas a valid input -4, so the PiecewiseExpand[] doesn't expand its mathematical expression rather than return the error information and the expression itself.

  • How to deal with error information when a function owns UpValues[]?

To deal with bad arguments of UpValues, I need to checkthe arguments by 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]
 ]

]

enter image description here

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

Here, I will give a 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

  • 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

6 added 429 characters in body
source | link
    Tweeted twitter.com/StackMma/status/688743923100037120
5 added 34 characters in body
source | link
    Notice added Canonical answer required by xyz
    Bounty Started worth 100 reputation by xyz
4 added 83 characters in body
source | link
3 added 83 characters in body
| link
2 added 83 characters in body
source | link
1
source | link