Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

s29 and Complex numbers

7 views
Skip to first unread message

Jonathan Lang

unread,
Feb 23, 2006, 4:47:29 AM2/23/06
to perl6language,
If you're going to have versions of sqrt in S29 that deal with Complex
numbers, you ought to do likewise with a number of other functions:

multi sub abs (: Complex ?$x = $CALLER::_ ) returns Num
should return the magnitude of a complex number. abs($x) :=
$x.magnitude, or whatever the appropriate method for extracting the
magnitude of a Complex number is. (I'm unaware of the exact
terminology used within Complex, or even if it has been established
yet.)

multi sub sign (: Complex ?$x = $CALLER::_) returns Complex
Since I would expect $x == sign($x) * abs($x) to be true for Nums,
the sign of a complex number would logically be a unitary complex
number, or zero if $x is zero: sign($x) := ($x == 0) ?? 0 :: $x /
abs($x). Thus, this would be distinct from $x.angle, or whatever it's
called, which would return a Num representing the direction as
measured in radians, degrees, etc.

multi sub exp (: Complex ?$exponent = $CALLER::_, Complex +$base)
returns Complex
multi sub log (: Complex ?$exponent = $CALLER::_, Complex +$base)
returns Complex
multi sub func (: Complex ?$x = $CALLER::_, +$base) returns Complex
(where func is any trig-related function)
IIRC, raising a base to a Complex exponent raises the base's
absolute value by the real component of the exponent, and rotates its
angle (as measured in radians) by the imaginary component.
All of the trig functions can be aliased to expressions using exp
and log. This may be useful for the purpose of defining the Complex
versions.
All of these functions, as well as sqrt, need to restrict the range
of valid return values: frex, sqrt ought to always return something
with either a positive real component or a zero real component and a
non-negative imaginary component.
(Another possibility would be to return a list of every possible
result when in list context, with the result that you'd get in scalar
context being element zero of the list. This even has its uses wrt
sqrt(Num), providing a two-element list of the positive and negative
roots, in that order. This option would apply to sqrt, exp, log, and
the trig functions.)
This has implications for the infix:<**> operator as well.

--
Jonathan "Dataweaver" Lang

David Green

unread,
Feb 28, 2006, 5:47:12 AM2/28/06
to perl6-l...@perl.org
On 2/23/06, Jonathan Lang wrote:
> (Another possibility would be to return a list of every possible
>result when in list context, with the result that you'd get in scalar
>context being element zero of the list. This even has its uses wrt
>sqrt(Num), providing a two-element list of the positive and negative
>roots, in that order. This option would apply to sqrt, exp, log, and
>the trig functions.)

I was thinking functions like sqrt would return a disjunction... I
suppose it's probably still most useful to return a single scalar by
default, so there would be some pragma via which you could choose to
get lists or to get junctions when there's more than one possible
result.

(Perhaps if you <use Complex>, the default might be to return
junctions or lists on the grounds that you're trying to be more
mathematical?)

-David

Mark A. Biggar

unread,
Feb 28, 2006, 10:22:07 AM2/28/06
to David Green, perl6-l...@perl.org

For the complex trig functions the result set is infinite with no
obvious order to return the list in even lazily that provides anything
useful. The results are all of the form A + (B + 2*pi*N)i where N can
be any integer. It is worth much more effort to just return a
consistent principle value and getting the branch cuts and the handling
of signed zero correct then to worry about trying to return multiple
values in these cases. For a through discussion see either the Ada or
Common Lisp reference manuals.

Mark Biggar


--
ma...@biggar.org
mark.a...@comcast.net

Jonathan Lang

unread,
Feb 28, 2006, 12:33:04 PM2/28/06
to Mark A. Biggar, perl6-l...@perl.org
Mark A. Biggar wrote:
> For the complex trig functions the result set is infinite with no
> obvious order to return the list in even lazily that provides anything
> useful.

Technically, the result set is one element (the principle value),
since a mathematical function - by definition - produces a single


result for any given input. That said:

> The results are all of the form A + (B + 2*pi*N)i where N can
> be any integer.

A lazy list would be feasible if you order it based on N, as long as
you're not forbidden from using negative indices for anything other
than reverse indexing.

> It is worth much more effort to just return a
> consistent principle value and getting the branch cuts and the handling
> of signed zero correct then to worry about trying to return multiple
> values in these cases.

Agreed. That's why my mention of list context for these things was
phrased as an afterthought: such a thing is doable, and I believe that
it might even be practical (once the other issues you mention above
are dealt with); but it's more "this would be nice" than "we need
this".

Furthermore, a list context approach would be an extension of the
functions' built-in capabilities: scalar context would give you the
principle value, while list context would give you every possible
value. This means that you could add list-context capabilities at
some later date (through either packages or revisions) without
damaging code developed in the meantime. You can't do this with the
junction approach, as (last I checked) a junction is a scalar; you'd
have to replace the "return the principle result" behavior with
"return a junction" behavior.

Finally, it's easy to go from list context to junction: just place the
math function in a junctive function ("any", "all", etc.). This makes
it easy to distinguish between "sqrt($x)" (which returns the principle
value) and "any sqrt($x)" (which returns a disjunction of every
possible result): more flexible and more readable than trying for
implicit junctional return values.

--
Jonathan Lang

Doug McNutt

unread,
Feb 28, 2006, 1:24:58 PM2/28/06
to perl6-l...@perl.org
At 09:33 -0800 2/28/06, Jonathan Lang wrote:
>Technically, the result set is one element (the principle value),
>since a mathematical function - by definition - produces a single
>result for any given input.

Please be careful of "definitions" like that. Computer science has quite different ideas about mathematics than those of chalkboard algebra.

x^(1/2) is a multivalued function and x^2 is a single valued function but they are both pow(x ,y). The likes of yacc have other ideas causing -2^2 to become +4 (thankfully not in perl) and sqrt(x) to become single valued positive definite. -2^(1/2) is not the same as -sqrt(2) in some implementations.

Worse, the kB sometimes means 1024 bytes because computer science chose not to use a century old definition but that's OT.

Perhaps "The perl definition of function is a subroutine that returns a single result which is the same type as the arguments" or something more precise that wouldn't rule out int( ) as a function. Perhaps "returns a single value appropriate for the context at invocation".

--

Applescript syntax is like English spelling:
Roughly, but not thoroughly, thought through.

Jonathan Lang

unread,
Feb 28, 2006, 2:07:23 PM2/28/06
to Doug McNutt, perl6-l...@perl.org
Doug McNutt wrote:

> Jonathan Lang wrote:
> >Technically, the result set is one element (the principle value),
> >since a mathematical function - by definition - produces a single
> >result for any given input.
>
> Please be careful of "definitions" like that. Computer science has quite
> different ideas about mathematics than those of chalkboard algebra.

...which is why I specified "mathematical function"; I was
intentionally referring to the chalkboard algebra meaning. But I can
see where the confusion came from.

> x^(1/2) is a multivalued function and x^2 is a single valued
> function but they are both pow(x ,y).

Actually, that's an interesting point: I didn't find a pow() function
in the s29 draft. There was an exp() function which could do the same
thing, albeit with the arguments in reverse order: exp($exp, $base) :=
$base ** $exp; but if you want to do a function that places the
arguments the other way around, you apparently have to say something
like "infix:<**> ($base, $exp)".

I'd recommend adding a pow() function such that pow($base, $exp) :=
$base ** $exp; it's redundant, but it's a very useful bit of
redundancy.

> The likes of yacc have
> other ideas causing -2^2 to become +4 (thankfully not in
> perl)

Oh? Last I checked, prefix:<-> was a higher-priority operator than
infix:<**>; so -2**2 is equivalent to (-2)**2, not -(2**2).

> and sqrt(x) to become single valued positive definite.
> -2^(1/2) is not the same as -sqrt(2) in some implementations.

I should hope not.

That said, I really hope that "sqrt($x)" will effectively be the same
as "$x ** 0.5": I want both of them to return a single value in scalar
context, and for each to behave like the other when in list context.

--
Jonathan "Dataweaver" Lang

0 new messages