MathGroup Archive 1990

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

Search the Archive

Re: (1) Symbolic complex algebra in mathematica

  • To: mathgroup at yoda.ncsa.uiuc.edu
  • Subject: Re: (1) Symbolic complex algebra in mathematica
  • From: CAMERON at midd.cc.middlebury.edu
  • Date: Mon, 26 Nov 90 13:04 EDT

In a recent posting, Ken Yip (yip-ken at CS.YALE.EDU) said:

> I want to define a complex quantity "z = x + I y" so that
>
>         Re[z] ==> x
>         Im[z] ==> y
>         Conjugate[z] ==> x - I y
>
> etc.
> Mathematica doesn't seem to know how to do this even after I
> define x and y to be real by "x/: RealQ[x] = True".
> I tried to define some transformation rules, but then I couldn't find
> a way to specify the pattern variable to be of type real AND symbol.

(I took the liberty of reformatting.)


This calls for an answer in three parts:

> I want to define a complex quantity "z = x + I y" so that (...) etc.

I have attached a tiny package below that does what is requested here,
and a bit more.  I wrote it some time ago for a friend.  It relies
on two other packages, "ReIm.m" and "Trigonometry.m", both of which
are part of the standard Mma 1.2 distribution (in the "Algebra"
subdirectory of the "Packages" directory).  All I do is add a couple
of extra simplification rules to the ones in those two packages, in order
to cover a couple of cases that they seem to have missed.  I also define
a function "makereal" that makes it easy to declare a variable to be
real.  I've included a short session transcript below to illustrate
what the package does.

For the more advanced Mma users out there, I might point out that
the only tricky part of writing this was avoiding the Mma bug that
makes "Sqrt[a^2]" simplify to "a" for all expressions "a".
This bug bit me in a preliminary version of the simplification rule
for Abs.  I had to add the condition "imagpart =!= 0" to
that rule to keep Abs from disappearing around variables that had been
declared to be real via "makereal".  This happened because "Abs[a]"
got rewritten to "Sqrt[ Re[a]^2 + Im[a]^2 ]", which then became
"Sqrt[a^2]" (because if "a" is real then "Re[a]" is just "a" and
"Im[a]" is 0), and this in turn got rewritten (incorrectly!) to "a".
The extra condition prevents this rewriting rule for Abs from being
applied to quantities that are already known to be real.


> Mathematica doesn't seem to know how to do this even after I
> define x and y to be real by "x/: RealQ[x] = True".

"RealQ" is no longer used for this purpose, and hasn't been for ages
-- ever since the release of Mma 1.2 in August of 1989.  The function
"makereal" in the package below does it in the currently approved
fashion: "makereal[x]" results in "Re[x] ^:= x" and "Im[x] ^= 0".
If you are still using Mma 1.1 or earlier then you might want to
consider upgrading, as you are forgoing much functionality and
enduring many bugs that have been fixed.  (In fact, the code below
won't work in 1.1, although it could be rewritten to do so -- which
wouldn't help, since it relies on the 1.2 versions of "ReIm.m" and
"Trigonometry.m".)


> I tried to define some transformation rules, but then I couldn't find
> a way to specify the pattern variable to be of type real AND symbol.

If "RealQ" *were* still being used for this purpose, a pattern variable
could be restricted to match only real symbols by a pattern of the
form "x_Symbol?RealQ".  We can define "RealQ" and use it this way --
here's an example:

    RealQ[x_] := Im[x]===0

    foo[x_Symbol?RealQ] := StringJoin[ToString[x]," is a real symbol."]

    foo[x_Symbol] := StringJoin[ToString[x]," is not known to be real."]

    foo[x_] = "foo[] tests symbols only!";

Typing this into Mma gives the following results:

    In[9]:= makereal[a]

    In[10]:= foo[a]

    Out[10]= a is a real symbol.

    In[11]:= foo[z]

    Out[11]= z is not known to be real.

    In[12]:= foo[2+I]

    Out[12]= foo[] tests symbols only!


Here's the package (I call it "extraReIm.m"):
--------------------------------------------------------------------------

Needs["Algebra`ReIm`"]

Begin["Algebra`ReIm`Private`"]

`z

`realpart

`imagpart

Unprotect[Abs,Conjugate]

Conjugate[z_] := Block[ {realpart=Re[z],imagpart=Im[z]},
        realpart - I imagpart /;
        (Head[realpart]=!=Re)||(Head[imagpart]=!=Im)
]

Abs[z_] := Block[ {realpart=Re[z],imagpart=Im[z]},
        Sqrt[ realpart^2 + imagpart^2 ] /;
        ((Head[realpart]=!=Re)||(Head[imagpart]=!=Im))&&(imagpart=!=0)
]

Protect[Abs,Conjugate]

`y

Algebra`ReIm`makereal

makereal[z_] := ( Re[z] ^:= z ; Im[z] ^= 0 ; )

makereal[z__] := ( makereal /@ {z} ; )

makereal[] = Null

End[]

Needs["Algebra`Trigonometry`"]

Begin["Algebra`Trigonometry`Private`"]

`x

`y

Unprotect[ComplexToTrig]

ComplexToTrig[ Exp[x_+y__] ] := ComplexToTrig[Exp[x]] ComplexToTrig[Exp[y]]

Protect[ComplexToTrig]

End[]

Null
--------------------------------------------------------------------------

Here's a sample session to show what it does.
First, in In[1], I load the package.
Next, in In[2], I define "z" to be the expression "x + I y".
In[3] and In[4] show what Conjugate and Abs do if they don't
know that "x" and "y" are supposed to be real.
In[5] uses "makereal" to make "x" and "y" act like reals.
In[6] and In[7] show that Conjugate and Abs now do the right things.
In[8] and In[9] show that complex exponentials can be converted to
trigonometric expressions (this was a requirement of the friend for
whom I wrote the code) and In[10]--In[12] show that the resulting
expressions interact nicely with Re and Im (if the constituent
variables are known to be real).
--------------------------------------------------------------------------
Mathematica (NeXT) 1.2 (January 20, 1990) [With pre-loaded data]
by S. Wolfram, D. Grayson, R. Maeder, H. Cejtin,
   S. Omohundro, D. Ballman and J. Keiper
with I. Rivin and D. Withoff
Copyright 1988,1989,1990 Wolfram Research Inc.

In[1]:= << extraReIm.m

In[2]:= z = x + I y

Out[2]= x + I y

In[3]:= Conjugate[z]

Out[3]= Conjugate[x] + -I Conjugate[y]

In[4]:= Abs[z]

                             2                  2
Out[4]= Sqrt[(-Im[y] + Re[x])  + (Im[x] + Re[y]) ]

In[5]:= makereal[x,y]

In[6]:= Conjugate[z]

Out[6]= x + -I y

In[7]:= Abs[z]

              2    2
Out[7]= Sqrt[x  + y ]

In[8]:= ComplexToTrig[ E^(3 I k d) ]

Out[8]= Cos[3 d k] + I Sin[3 d k]

In[9]:= result = ComplexToTrig[ E^(2 I k d + I omega t) ]

Out[9]= (Cos[2 d k] + I Sin[2 d k]) (Cos[omega t] + I Sin[omega t])

In[10]:= makereal[d,k,omega,t]

In[11]:= Re[result]

Out[11]= Cos[2 d k] Cos[omega t] - Sin[2 d k] Sin[omega t]

In[12]:= Im[result]

Out[12]= Cos[omega t] Sin[2 d k] + Cos[2 d k] Sin[omega t]

In[13]:= Quit

--------------------------------------------------------------------------

Hope this is useful.

--Cameron Smith
  Mathematica Consultant
  CAMERON at MIDD.BITNET  --or--  cameron at midd.cc.middlebury.edu



  • Prev by Date: Re: Mathematica for NeXT, Unbundled Price
  • Next by Date: a==b and FixedPoint
  • Previous by thread: Re: Symbolic complex algebra in mathematica
  • Next by thread: a==b and FixedPoint