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