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, "D2DExpressions2D_1.gif".  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 "D2DExpressions2D_2.gif".

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 "D2DExpressions2D_3.gif".

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 "D2DExpressions2D_4.gif".

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 "D2DExpressions2D_5.gif".

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[{"D2DExpressions2D_6.gif","D2DExpressions2D_7.gif"}]
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 "D2DExpressions2D_8.gif".

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 "D2DExpressions2D_9.gif".

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 "D2DExpressions2D_10.gif".

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 "D2DExpressions2D_11.gif".

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 "D2DExpressions2D_12.gif".

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 "D2DExpressions2D_13.gif".

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 "D2DExpressions2D_14.gif".

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`" *)


Copyright © 1999-2007 Donald L. Vossler, Descarta2D Publishing
www.Descarta2D.com