Adding Complexity

0 views
Skip to first unread message

Jonathan Lang

unread,
Apr 26, 2005, 11:48:49 PM4/26/05
to Perl 6 Language
As an exercise, I've been looking into what could be done in terms of
creating a complex numbers package that takes advantage of perl 6
technology. A couple of thoughts that I ran across:

When you take the square root of a number, you actually get one of two
possible answers (for instance, sqrt(1) actually gives either a 1 or a
-1). This sounds like an appropriate place to return an ajunction.
Extending this philosophy a bit, note that any time that a complex number
is raised to a rational power, you get a finite number of possible
answers, which could likewise be handled as an ajunction of a list of the
possible answers.

Admittedly, the list could conceivably get to be quite long: raising a
number to the 0.01 power, for instance, would result in a list of a
hundred possible solutions. And matters get even messier when the power
is irrational (such as pi), in which case the list becomes infinite in
length. IIRC, this is exactly what lazy lists are for.

So what happens when you apply a junction to a lazy list? Do you get a
"lazy junction"?

Jonathan "Dataweaver" Lang

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com

rott...@gmail.com

unread,
Apr 27, 2005, 10:20:58 AM4/27/05
to

Jonathan Lang wrote:
> When you take the square root of a number, you actually get one of
two
> possible answers (for instance, sqrt(1) actually gives either a 1 or
a
> -1). This sounds like an appropriate place to return an ajunction.
> Extending this philosophy a bit, note that any time that a complex
number
> is raised to a rational power, you get a finite number of possible
> answers, which could likewise be handled as an ajunction of a list of
the
> possible answers.

Maybe to avoid confusion these should be called sqrts and pows (e.g.
pows(1, 1/4) == 1|i|-1|-i).

Mark Reed

unread,
Apr 28, 2005, 10:47:36 AM4/28/05
to Thomas Sandlaß, Perl 6 Language

> Jonathan Lang wrote:
>> > When you take the square root of a number, you actually get one of two
>> > possible answers (for instance, sqrt(1) actually gives either a 1 or a
>> > -1).

Not quite. It¹s true that there are two possible square roots of any given
number, but sqrt(1) is defined as the positive one. The radical sign is
also defined as the positive one in standard mathematical notation, btw; you
have to put a +/- in front of it to get the ³junctive² value.

Thomas Sandlaß

unread,
Apr 28, 2005, 10:39:54 AM4/28/05
to Perl 6 Language
Jonathan Lang wrote:
> When you take the square root of a number, you actually get one of two
> possible answers (for instance, sqrt(1) actually gives either a 1 or a
> -1).

sqrt() is a function that maps its input domain into its output range.
As such multiple return values are at least not part of the standard
mathematical definition. But in Perl6 a junction is a single value :)
What you mean is to solve the equation x**2 == 1 which indeed has got
the two Int solutions -1 and 1 or the two Complex ones (1,0) and (-1,0).


> IIRC, this is exactly what lazy lists are for.

Essentially lazy lists are suspended closures. But I dought that arithmetic
between them is defined such that pi + pi would leazily calculate 6.28...


> So what happens when you apply a junction to a lazy list? Do you get a
> "lazy junction"?

I think so, by the law of laziness preservation ;)
--
TSa (Thomas Sandlaß)

Ingo Blechschmidt

unread,
Apr 28, 2005, 10:55:40 AM4/28/05
to perl6-l...@perl.org
Hi,

> Essentially lazy lists are suspended closures. But I dought that
> arithmetic between them is defined such that pi + pi would leazily
> calculate 6.28...

...which makes me wonder if it'd be good|cool|whatever to not only have
lazy lists, but also lazy *values*...: :))
my $pi = calc_pi_lazily();
say substr $pi, 0, 5; # calculates and outputs the
# first five digits of pi
say substr $pi, 0, 10000000; # calculates and outputs
# digits 0 to 10000000-1 of pi

my $sum = $pi * 2 + calc_e_lazily();
say substr $sum, 0, 100; # calculates and outputs the
# first 99 digits of 2pi + e

(Internally, this $pi could just be a Num::Lazy which hasa lazy @.digits
and which has an appropriate MMD entry for substr. But this is an
implementation detail.)


And:
my @ones = gather { take 1 while 1 };
my $ones = join "", @ones; # does not burn out!
say length $ones; # Inf

:)

--Ingo

--
Linux, the choice of a GNU | Memorize 1000 digits of pi
generation on a dual AMD | http://theory.cs.iitm.ernet.in/~arvindn/pi/
Athlon! |

Ingo Blechschmidt

unread,
Apr 28, 2005, 11:01:49 AM4/28/05
to perl6-l...@perl.org
Ingo Blechschmidt wrote:
> And:
> my @ones = gather { take 1 while 1 };
> my $ones = join "", @ones; # does not burn out!
> say length $ones; # Inf

s/length/chars/ of course.


--Ingo

--
Linux, the choice of a GNU | God said: tar xvjf universe.tar.gz - and
generation on a dual AMD | the Universe was! -- Thomas Watz
Athlon! | <twn...@gmx.de>

Luke Palmer

unread,
Apr 28, 2005, 9:44:54 AM4/28/05
to Ingo Blechschmidt, perl6-l...@perl.org
Ingo Blechschmidt writes:
> Hi,
>
> > Essentially lazy lists are suspended closures. But I dought that
> > arithmetic between them is defined such that pi + pi would leazily
> > calculate 6.28...
>
> ...which makes me wonder if it'd be good|cool|whatever to not only have
> lazy lists, but also lazy *values*...: :))

Then every expression that referenced lazy values would be lazy in terms
of them. And once you want to print X digits of the lazy answer, you
have to go back through the lazy values and caluclate to what precision
you need them. This is a job for a sophisticated mathematics library,
not for standard Perl. Perl (5 even) is powerful enough to implement
such a thing as a module.

Luke

Ingo Blechschmidt

unread,
Apr 28, 2005, 2:26:11 PM4/28/05
to perl6-l...@perl.org
Hi,

Luke Palmer wrote:
>> ...which makes me wonder if it'd be good|cool|whatever to not only
>> have lazy lists, but also lazy *values*...: :))
>
> Then every expression that referenced lazy values would be lazy in
> terms
> of them. And once you want to print X digits of the lazy answer, you
> have to go back through the lazy values and caluclate to what
> precision
> you need them.

this is (to a lesser extend) necessary for lazy arrays, too, isn't it?
my @nums = (1...);
my @foo = @nums.map:{ ... }; #1
my @bar = @foo .map:{ ... }; #2
my @baz = @bar .map:{ ... }; #3
# no map body executed
say @nums[0..10];
# map bodies of #1, #2, and #3 executed

> This is a job for a sophisticated mathematics library,
> not for standard Perl. Perl (5 even) is powerful enough to implement
> such a thing as a module.

Of course. IIRC, even Haskell doesn't support that out-of-the-box ;).


--Ingo

--
Linux, the choice of a GNU | Perfection is reached, not when there is no
generation on a dual AMD | longer anything to add, but when there is
Athlon! | no longer anything to take away.

Luke Palmer

unread,
Apr 28, 2005, 1:59:36 PM4/28/05
to Ingo Blechschmidt, perl6-l...@perl.org
Ingo Blechschmidt writes:
> Hi,
>
> Luke Palmer wrote:
> >> ...which makes me wonder if it'd be good|cool|whatever to not only
> >> have lazy lists, but also lazy *values*...: :))
> >
> > Then every expression that referenced lazy values would be lazy in
> > terms
> > of them. And once you want to print X digits of the lazy answer, you
> > have to go back through the lazy values and caluclate to what
> > precision
> > you need them.
>
> this is (to a lesser extend) necessary for lazy arrays, too, isn't it?
> my @nums = (1...);
> my @foo = @nums.map:{ ... }; #1
> my @bar = @foo .map:{ ... }; #2
> my @baz = @bar .map:{ ... }; #3
> # no map body executed
> say @nums[0..10];
> # map bodies of #1, #2, and #3 executed

Right. Computing how many of those you need is trivial for all of our
provided list operations. The question is:

my $pi = lazy_pi;
my $e = lazy_e;

my $epi = $e ** $pi;
say substr($epi, 0, 400);

How many digits of $pi and $e do we need to accurately compute e**pi to
400 digits? Our equation, using differential error analysis, is:

d($epi) == $e**$pi * ($pi/$e * d($e) + log($e) * d($pi))

Now, Perl has to solve that baby to see what values of d($e) and d($pi)
would give an acceptable d($epi). I don't believe that we've stated
that Mathematica will be embedded in Perl (yet :-).

Luke

Reply all
Reply to author
Forward
0 new messages