MathGroup Archive 1995

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Programming Options for Power Expand

  • To: mathgroup at christensen.cybernetics.net
  • Subject: [mg874] Re: [mg802] Programming Options for Power Expand
  • From: Allan Hayes <hay at haystack.demon.co.uk>
  • Date: Thu, 27 Apr 1995 01:46:38 -0400

In mg[802] JackGoldberg asks

> Should (and can!) one add options to a built in command?  I do  
not know
> the answer to whether one should.
The simple answers are: yes we can but whether we should depends on.

My partial answer mg[793] to his earlier mg[697] was rather  
inadaquate and misleading: Apologies to everyone.

In the following, after a short comment on PowerExpand, I add an  
option AA-> n (default AA -> 1) such that Plot[expr, range, AA->n]  
gives Plot[expr^n, range]; this turn out to be rather tricky, but  
the same kinds of problems will occur with othe system function.

Basic requirements of the code are
1. it should work as intended;
2. Options[ ] should give the options;
3. SetOptions[ ] should alter the options as usual;
4. other functions should not be affect in uninteded ways;
5  usage messages should be provided so that ? and ?? work 	
   properly-- I have not done this. below.
6. Option names should be protected

*** PowerExpand ***

PowerExpand does not have any options
In[1]:=
	Options[PowerExpand]
Out[1]=
	{}

It does  not check options but dummy options prevent it acting
In[2]:=
	PowerExpand[Sqrt[x^2],InverseTrig ->True]
Out[2]=
	      2
	Sqrt[x ]

All that  seems to be needed, besides defining the behaviour as   
Jack does , is to define  Options[PowerExpand].

In[3]:=
	Unprotect[PowerExpand];
In[4]:=
	Options[PowerExpand] =
		Join[{InverseTrig ->False}, Options[PowerExpand]];

add usage messages and protect.

In[5]:=
	Protect[InverseTrig];
	Protect[PowerExpand];

Some advantages of using an option rather than an extra parameter are 
	* options are identifiable elements
	* we can use Option and SetOptions
	* we can add extra options
	* options are called by name and we don't need to worry about 	
	their positions relative to others with different names.

*** Plot ***

Plot puts up some extra difficulties of its own by trying protect  
us (PowerExpand does not have these features)

In[7]:=
	Plot[x,{x,0,1}, AA->3]
	Plot::optx: Unknown option AA in Plot[x, {x, 0, 1}, AA -> 3].
Out[7]=
	Plot[x, {x, 0, 1}, AA -> 3]
OK, let's  add AA->3 to the options (as we must anyway); and keep a  
record of the present options.
In[8]:=
	originalopts = Options[Plot];
In[9]:=
	Unprotect[Plot];
	Options[Plot] = Union[{AA->3}, Options[Plot]];

But still we get
In[11]:=
	Plot[x,{x,0,1}, AA->3]
	Plot::optx: Unknown option AA in Plot[x, {x, 0, 1}, AA -> 3].
Out[11]=
	Plot[x, {x, 0, 1}, AA -> 3]
In[12]:=
	Plot[x,{x,0,1}]
	Plot::optx: Unknown option AA in Options[Plot].
Out[12]=
	Plot[x, {x, 0, 1}]
It seems that the internal checking is still using the system options. 

It looks like the final plotting has to be done with a modified  
input that does not have any of the added options and with  
Options[Plot]  temporarily stripped of its added options.

First, I restore the original options
In[13]:=
	Options[Plot] = originalopts;
	Protect[Plot];
Next,  the code.

In[15]:=

Off[General::spell1];
Module[{addopts,currentopts,gr,prtd},
	Unprotect[Plot];
	
	If[!ValueQ[def],(*store the initial options (not local)*)
		def = _ [Alternatives@@First/@Options[Plot], _]
	];
	
	addopts 	= {AA->1};
	Protect@@First/@addopts;
	Options[Plot] = Join[addopts,Options[Plot]	];
	(*we could keep only the first option with each name*)
	
	Plot[expr_, range_, opts___]/;
		DeleteCases[Options[Plot], def] =!={}:=
		With[{
			nexpr = expr^(AA/.{opts}/.Options[Plot]),
			nrange = range,
			nopts = Sequence@@Cases[{opts},def]
		},
		prtd = MemberQ[Attributes[Plot],Protected];
		Unprotect[Plot];
		currentopts = Options[Plot];
		
		Options[Plot] = Cases[currentopts,def];
		
		(*now evaluate the stripped down Plot[..]*)						
		gr = 	Plot[nexpr, nrange, nopts];	
		
		Options[Plot] = currentopts;
		If[prtd, Protect[Plot]];		
		gr
	];
	Protect[Plot];
]

Check

1. Works as intended.
In[17]:=
	Plot[x, {x,-1,1}]
Out[17]=
	-Graphics-

In[18]:=
	Plot[x, {x,-1,1}, AA -> 3]
Out[18]=
	-Graphics-

2. Options[Plot] give the options

In[19]:=
	Options[Plot]
Out[19]=
     	{AA -> 1, ........ DisplayFunction :> $DisplayFunction}

3. SetOptions[Plot, ...] alters the options.

In[20]:=
	SetOptions[Plot, AA->2]
Out[20]=
                              1
	{AA -> 2, ...........DefaultFont :> $DefaultFont,

  DisplayFunction :> $DisplayFunction}


4. Other functions unaffected
	
If some code  has used Plot its performance might be affected, for  
example if it checks options and uses the old list.

Comments:
Somethings might be done to make this more like the old Plot. For  
example it does not check for appropriate options

In[21]:=
	Plot[x, {x,-1,1}, BB -> 5]
Out[21]=
	-Graphics-
Allan Hayes,
hay at haystack.demon.co.uk


  • Prev by Date: Re: Lyapunov Equation
  • Next by Date: LinearSolve precision quirks (Was: Re: Lyapunov Equation)
  • Previous by thread: Re: Programming Options for Power Expand
  • Next by thread: Mathlink Question