Exploring Analyic Geometry with Mathematica® |
|||||
| Home | Contents | Commands | Packages | Explorations | Reference |
| Tour | Lines | Circles | Conics | Analysis | Tangents |
D2DExpressions2D
The package D2DExpressions2D provides functions for querying Mathematica expressions.
Initialization
BeginPackage["D2DExpressions2D`", {"D2DMaster2D`", "D2DNumbers2D`"}];
D2DExpressions2D::usage=
"D2DExpressions2D is a package for querying Mathematica expressions.";
IsApproximate2D::usage=
"IsApproximate2D[expr] returns 'True' if the expression contains approximate real numbers, or if the evaluation will eventually be approximated using the 'N' function.";
IsComplex2D::usage=
"IsComplex2D[expr,(tol)] returns 'True' if the expression evaluates to a complex number; IsComplex2D[List,(tol)] and IsComplex2D[List,Or,(tol)] return 'True' if any expressions in the list evaluate to complex numbers; IsComplex2D[List,And,(tol)] returns 'True' if all the expressions in the list evaluate to complex numbers; the default tolerance, if omitted, is 10^(-10).";
IsNegative2D::usage=
"IsNegative2D[expr,(tol)] returns 'True' if the expression is negative; otherwise, returns 'False'; IsNegative2D[List,(tol)] and IsNegative2D[List,Or,(tol)] return 'True' if any expressions in the list are negative; IsNegative2D[List,And,(tol)] returns 'True' if all the expressions in the list are negative; the default tolerance, if omitted, is 10^(-10).";
IsNumeric2D::usage=
"IsNumeric2D[expr,(tol)] returns 'True' if the expression consists of atoms that can be evaluated to real numbers; IsNumeric2D[expr,funcName,(tol)] provides the same function with a message; the default tolerance, if omitted, is 10^(-10).";
IsReal2D::usage=
"IsReal2D[expr,(tol)] returns 'True' if the expression is real-valued; otherwise, returns 'False'; the default tolerance, if omitted, is 10^(-10).";
IsScalar2D::usage=
"IsScalar2D[expr] returns 'True' if the expression appears to be a scalar (not a List, object, or complex number); otherwise, returns 'False'.";
IsScalarPair2D::usage=
"IsScalarPair2D[{expr1,expr2}] returns 'True' if both expressions in a list appear to be a scalars (not a Lists, objects, or complex numbers); otherwise, returns 'False'.";
IsTinyImaginary2D::usage=
"IsTinyImaginary2D[expr,(tol)] returns 'True' if any complex numbers in the expression have tiny imaginary parts; the default tolerance, if omitted, is 10^(-10).";
IsZero2D::usage=
"IsZero2D[expr,(tol)] returns 'True' if the expression is zero; otherwise, returns 'False'; IsZero2D[List,(tol)] and IsZero2D[List,Or,(tol)] return 'True' if any expressions in the list are zero; IsZero2D[List,And,(tol)] returns 'True' if all the expressions in the list are zero; the default tolerance, if omitted, is 10^(-10).";
IsZeroOrNegative2D::usage=
"IsZeroOrNegative2D[expr,(tol)] returns 'True' if the expression is zero or negative; otherwise, returns 'False'; IsZeroOrNegative2D[List,(tol)] and IsZeroOrNegative2D[List,Or,(tol)] return 'True' if any expressions in the list are zero or negative; IsZeroOrNegative2D[List,And,(tol)] returns 'True' if all the expressions in the list are zero or negative; the default tolerance, if omitted, is 10^(-10).";
Begin["`Private`"];
Utilities
Chop
The built-in Mathematica function Chop issues an error message if the tolerance is zero. These modifications to the Chop function allow a zero tolerance to be specified. Executed when the package is loaded.
protected=Unprotect[Chop];
Chop[expr_,0] := expr;
Chop[expr_,0.] := expr;
Protect[Evaluate[protected]];
Random Evaluation
The private function RandomEvaluation$2D substitutes random numbers for the non-numeric symbols in the expression and applies the N function to the result. This is useful for determining whether a symbolic expression represents some specific numerical value (such as zero). There is a small probability that an erroneous conclusion may be reached if an unfortunate combination of random numbers arises.
RandomEvaluation$2D[expr_] :=
Module[{atoms,symbols,rules},
atoms=Level[N[expr],{-1}];
symbols=Union[Select[atoms,(Head[#]===Symbol)&]];
rules=Map[Rule[#,RandomReal[{0.1,0.9}]]&,symbols];
N[expr /. rules] ];
Tolerance
The private function Tolerance$2D[tol] returns tol if it is a valid tolerance value; otherwise, issues a warning message and returns the default tolerance value,
. The special cases are provided to improve the performance of heavily used tolerance values.
D2DExpressions2D::badTol=
"The tolerance `1` is not a valid tolerance specification; the default tolerance, 10^(-10), will be used.";
Tolerance$2D[10^(-10)] := 10^(-10);
Tolerance$2D[0] := 0;
Tolerance$2D[tol_] :=
If[TrueQ[N[tol]>=0],
tol,
Message[D2DExpressions2D::badTol,tol];10^(-10)];
Number Queries
Approximate Query
Format: IsApproximate2D[expr]
Returns True if any of the atoms in an expression are approximate real numbers or if the N function will eventually be applied to the expression; otherwise, returns False.
IsApproximate2D[expr_] :=
(Not[FreeQ[expr,_Real]] || Stack[N[___]]=!={});
Complex Query
Format: IsComplex2D[expr,(tol)]
Returns True if an expression evaluates numerically to a complex number; otherwise returns False. The heavily used cases are provided to improve performance. The default tolerance, if omitted or invalid, is
.
IsComplex2D[n_Real,tol_:(10^(-10))] := False;
IsComplex2D[n_Integer,tol_:(10^(-10))] := False;
IsComplex2D[n_Rational,tol_:(10^(-10))] := False;
IsComplex2D[sym_Symbol,tol_:(10^(-10))] := False;
IsComplex2D[n_Complex,tol_:(10^(-10))] := Abs[Im[n]]>Tolerance$2D[tol];
IsComplex2D[expr_,tol_:(10^(-10))] :=
Module[{n,tol1},
tol1=Tolerance$2D[tol];
n=Chop[N[expr],tol1];
Head[n]===Complex ] /;
(Head[expr] =!= List);
Complex Query (List)
Format: IsComplex2D[exprList,Or|And,(tol)]
With the default option, Or, returns True if any expression in the list evaluates to a complex number; with the And option, returns True if all the expressions in the list evaluate to complex numbers; otherwise, returns False. The default tolerance, if omitted, is
.
IsComplex2D[expr_List,bool_:Or,tol_:(10^(-10))] :=
Module[{tol1},
tol1=Tolerance$2D[tol];
bool @@ Map[IsComplex2D[#,tol1]&,expr] ] /;
(bool==And || bool==Or);
Numeric Query
Format: IsNumeric2D[expr,(tol)]
Returns True if all the atoms in an expression can be evaluated to real numbers; otherwise, returns False. The default tolerance, if omitted, is
.
IsNumeric2D[expr_,tol_:(10^(-10))] :=
Not[MemberQ[Chop[expr//N,Tolerance$2D[tol]],
(_Symbol | _Complex | _String),{-1}]] /;
(Head[tol] =!= Symbol);
Numeric Query (with Message)
Format: IsNumeric2D[expr,funcName]
Returns True if all the atoms in an expression can be evaluated to real numbers; otherwise, returns False. Issues a message with the function name if the result is False.
IsNumeric2D::notNumeric=
"The `1` function requires numerical arguments; symbolic arguments are not allowed.";
IsNumeric2D[expr_,funcName_Symbol,tol_:(10^(-10))] :=
If[IsNumeric2D[expr,Tolerance$2D[tol]],
True,
Message[IsNumeric2D::notNumeric,funcName];False];
Real Query
Format: IsReal2D[expr,(tol)]
Returns True if an expression can be evaluated to a real number; otherwise, returns False. A complex number with an insignificant imaginary component will return True. The default tolerance, if omitted, is
.
IsReal2D[expr_Real,___] := True;
IsReal2D[expr_Integer,___] := True;
IsReal2D[expr_Symbol,___] := False;
IsReal2D[expr_Rational,___] := True;
IsReal2D[expr_Complex,tol_:(10^(-10))] :=
Chop[Im[expr]//N,Tolerance$2D[tol]]===0;
IsReal2D[expr_,tol_:(10^(-10))] :=
Module[{n},
n=Chop[N[expr],Tolerance$2D[tol]];
(NumberQ[n] && (Im[n]==0))];
Scalar Query
Format: IsScalar2D[n]
Returns True if an expression appears to be a scalar quantity--that is, it cannot be recognized as Null, a list, a complex number or a Descarta2D object; otherwise, returns False. The special cases for Real, Integer and Symbol are provided to improve the performance of heavily used queries.
IsScalar2D[_Real] := True;
IsScalar2D[_Integer] := True;
IsScalar2D[_Symbol] := True;
IsScalar2D[_List] := False;
IsScalar2D[_?IsComplex2D] := False;
IsScalar2D[Null] := False;
IsScalar2D[expr_] := False /;
MemberQ[ObjectNames2D[],ToString[Head[expr]]];
IsScalar2D[expr_] := False /;
Not[FreeQ[expr,_Pattern]];
IsScalar2D[expr_] := True;
Scalar Pair Query
Format: IsScalarPair2D[{
,
}]
Returns True if a list of two expressions appears to be as Null, a scalar pair--that is, neither expression can be recognized as a list, a complex number or a valid Descarta2D object; otherwise, returns False.
IsScalarPair2D[{n1_,n2_}] := IsScalar2D[n1] && IsScalar2D[n2];
IsScalarPair2D[___] := False;
Tiny Imaginary Query
Format: IsTinyImaginary2D[expr,(tol)]
Returns True if any atoms in an expression involve complex numbers with tiny imaginary parts; otherwise, returns False. The default tolerance, if omitted, is
.
IsTinyImaginary2D[expr_,tol_:(10^(-10))] :=
Module[{tol1},
tol1=Tolerance$2D[tol];
Or @@ Map[(Head[#]===Complex && Chop[Im[#],tol1]===0)&,
Level[expr,{-1}]] ];
Sign Queries
Negative Query
Format: IsNegative2D[expr,(tol)]
Returns True if a number is numerically negative; otherwise returns False. The default tolerance, if omitted, is
.
IsNegative2D[expr_,tol_:(10^(-10))] :=
Module[{n},
n=Chop[N[expr],Tolerance$2D[tol]];
If[MemberQ[{Real,Integer},Head[n]], n<0, False] ] /;
(Head[expr] =!= List);
Negative Query (List)
Format: IsNegative2D[exprList,Or|And,(tol)]
With the default option, Or, returns True if any expression in the list is numerically negative; with the And option, returns True if all the expressions in the list are numerically negative; otherwise, returns False. The default tolerance, if omitted, is
.
IsNegative2D[expr_List,bool_:Or,tol_:(10^(-10))] :=
Module[{tol1},
tol1=Tolerance$2D[tol];
bool @@ Map[IsNegative2D[#,tol1]&,expr] ] /;
(bool==And || bool==Or);
Zero Query
Format: IsZero2D[expr,(tol)]
Returns True if an expression is numerically zero; otherwise returns False. The heavily used cases are provided as special cases to improve performance. The default tolerance, if omitted or invalid, is
.
IsZero2D[n_Real,tol_:(10^(-10))] := (Abs[n]<=Tolerance$2D[tol]);
IsZero2D[n_Integer,tol_:(10^(-10))] := (Abs[n]<=Tolerance$2D[tol]);
IsZero2D[expr_Symbol,tol_:(10^(-10))] := False;
IsZero2D[n_Complex,tol_:(10^(-10))] :=
Module[{tol1},
tol1=Tolerance$2D[tol];
(Abs[Re[n]]<=tol1 && Abs[Im[n]]<=tol1)];
IsZero2D[h_[___],tol_:(10^(-10))] := False /;
MemberQ[ObjectNames2D[],ToString[h]];
IsZero2D[expr_,tol_:(10^(-10))] :=
Module[{n,tol1},
tol1=Tolerance$2D[tol];
n=Chop[N[expr],tol1];
If[MemberQ[{Real,Integer,Complex},Head[n]],
IsZero2D[n,tol1],
Chop[RandomEvaluation$2D[n],tol1]===0] ] /;
(Head[expr] =!= List);
Zero Query (List)
Format: IsZero2D[exprList,Or|And,(tol)]
With the default option, Or, returns True if any expression in the list is numerically zero; with the And option, returns True if all the expressions in the list are numerically zero; otherwise, returns False. The default tolerance, if omitted, is
.
IsZero2D[expr_List,bool_:Or,tol_:(10^(-10))] :=
Module[{tol1},
tol1=Tolerance$2D[tol];
bool @@ Map[IsZero2D[#,tol1]&,expr] ] /;
(bool==And || bool==Or);
Zero or Negative Query
Format: IsZeroOrNegative2D[expr,(tol)]
Returns True if the expression is numerically zero or negative; otherwise, returns False. The default tolerance, if omitted, is
.
IsZeroOrNegative2D[expr_,tol_:(10^(-10))] :=
Module[{tol1},
tol1=Tolerance$2D[tol];
(IsZero2D[expr,tol1] || IsNegative2D[expr,tol1])] /;
(Head[expr] =!= List);
Zero or Negative Query (List)
Format: IsZeroOrNegative2D[exprList,Or|And,(tol)]
With the default option, Or, returns True if any expression in the list is numerically zero or negative; with the And option, returns True if all the expressions in the list are numerically zero or negative; otherwise, returns False. The default tolerance, if omitted, is
.
IsZeroOrNegative2D[expr_List,bool_:Or,tol_:(10^(-10))] :=
Module[{tol1},
tol1=Tolerance$2D[tol];
bool @@ Map[IsZeroOrNegative2D[#,tol1]&,expr] ] /;
(bool==And || bool==Or);
Epilogue
End[ ]; (* end of "`Private" *)
EndPackage[ ]; (* end of "D2DExpressions2D`" *)