My take on this is that magnover has the following needs:

  *
Accept all input types, real or complex
  *
Avoid input conversion of inputs
  *
Promote output to floating-point (similar in style to sumover) to avoid loss 
for many of a small integer type
  *
Constrain the output type to be real-only since that is mathematically correct

Currently magnover is:
pp_def('magnover',
  HandleBad => 1,
  Pars => "a(n); float+ [o]b();",
  GenericTypes => $A,

Which fails the last point.

abs2 is:
pp_def('abs2',
  GenericTypes=>$A,
  HandleBad => 1,
  Pars => 'a(); real [o]b()',

Which fails the third point, so could lose information for e.g. an 8-bit 
integer.

I think this is a real problem (if you'll forgive the pun). I propose an 
additional type-qualifier realfloatthat would have the effect of combining 
points 3 and 4, and change these two operations to use that. What do people 
think?

Luis, I will note that your code as written is vulnerable not only to what I 
believe is a bug in magnover; it wouldn't work when broadcasting, since 
comparison of multi-element ndarrays is forbidden. That may not be a problem 
for your application.

Best regards,
Ed
________________________________
From: Jörg Sommrey via pdl-devel <pdl-devel@lists.sourceforge.net>
Sent: 24 July 2025 21:44
To: Luis Mochan <moc...@icf.unam.mx>
Cc: perldl <pdl-devel@lists.sourceforge.net>; perldl 
<pdl-gene...@lists.sourceforge.net>
Subject: Re: [Pdl-devel] magnover

Hi Luis,

I'm not a PDL expert, just a hobbyist.  In my understanding, reducing
the set of GenericTypes will limit the generated type-loop to this set
and will cause any input arguments outside of this type set to be
converted first.  This would mean that a large integer vector will be
converted to float first and a large ndarray of higher dimensions
would be converted vector-wise.

An authoritative answer can be given by an expert only.

Regards,
-jo


On Thu 24 Jul 2025 10:08:03 PM CEST, Luis Mochan <moc...@icf.unam.mx> wrote:

> Hi Jörg,
> Thanks. It does work. I have a question: if the input is some large
> vector of some kind of integers, is it first converted to a float
> vector with this solution? Should the possible space wasted be a
> concern?
> Regards,
> Luis
>
>
>
> I guess, is that
>
> On Thu, Jul 24, 2025 at 07:19:50PM +0000, Jörg Sommrey wrote:
>> Hello Luis,
>>
>> probably this does the trick:
>>
>> pp_def('magnover',
>>   HandleBad => 1,
>>   Pars => "a(n); real [o]b();",
>>   GenericTypes => [qw(H C G E D F)],
>>
>>
>> Then in t/ufunc.t (line 106) the expected type just needs to be changed from
>> 'cdouble' to 'double'.
>>
>> Integer types will be promoted to float and complex types to their real
>> counterparts:
>>
>> say cdouble('[1+i, 1-i, -1+i, -1-i]')->magnover->info;
>> say sequence($_, 4)->magnover->info for byte, long, float, double;
>>
>> PDL: Double D []
>> PDL: Float D []
>> PDL: Float D []
>> PDL: Float D []
>> PDL: Double D []
>>
>> Regards,
>> -jo
>>
>>
>> On Thu 24 Jul 2025 06:36:39 PM CEST, Luis Mochan <moc...@icf.unam.mx> wrote:
>>
>> > On Wed, Jul 23, 2025 at 11:56:00AM +0000, Jörg Sommrey wrote:
>> > > Hello Luis,
>> > >
>> > > the results look fine when the expected types in the two
>> failing tests are
>> > > adjusted. Don't know if it would break any "real" code, maybe
>> "is_pdl" is
>> > > just too strict here.
>> >
>> > I believe there are good reasons for the qualifier float+ in the case
>> > of, for example, a vector of bytes: on one hand, the euclidean
>> > magnitude of a vector of integers is not necessarily integer: (3,4)->5
>> > but (1,1)->1.4142... On the other hand, the magnitude of a large
>> > vector of bytes may overflow a byte. Nevertheless, I expect the
>> > magnitude of a complex to be real, not a complex. A complex with a
>> > zero imaginary part works but wastes some time and space. Thus,
>> it would be
>> > ideal if one could specify both, float+ and real as qualifiers of the
>> > output of magnover, but that doesn't work. Is there an alternative for
>> > a more flexible way to determine the correct type of an output
>> > parameter based on that of the inputs? Meanwhile, I can simply
>> > take the real part of the magnitudes :)
>> >
>> > Regards,
>> > Luis
>> >
>> >
>> > >
>> > > t/ufunc.t:
>> > > is_pdl $empty->magnover, sbyte('BAD'), "bad flag gets set on empty
>> > > magnover";
>> > > is_pdl +(sequence(4)+i())->magnover, double(4.242640),
>> 'magnover correct for
>> > > complex';
>> > >
>> > > Best regards,
>> > > -jo
>> > >
>> > >
>> > > On Wed 23 Jul 2025 04:52:24 AM CEST, Luis Mochan
>> <moc...@icf.unam.mx> wrote:
>> > >
>> > > > Hello,
>> > > >
>> > > > In some of my programs I used the code such as
>> > > >
>> > > >     $abs=$cvec->abs2->sumover->sqrt;
>> > > >
>> > > > to get the magnitude of a vector $cvec. I just replaced it to
>> the cleaner
>> > > >
>> > > >     $abs=$cvec->magnover;
>> > > >
>> > > > But then my program failed when I made the comparison
>> > > >
>> > > >    if($abs > 0){...}
>> > > >
>> > > > with the message
>> > > >
>> > > >     Can't compare complex numbers at lib/PDL/PP.pm line 1445.
>> > > >
>> > > > It is true that we shouldn't compare complex numbers, except for
>> > > > equality, but, shouldn't the magnitude of a complex vector be a real
>> > > > number instead of a complex number (with zero imaginary part)?
>> > > >
>> > > > I tried to fix it by replacing the qualifier 'float+' in the pp_def of
>> > > > magnover in Ufunc.pd by the qualifier 'real', but then the tests fail
>> > > > as bytes are not converted to floats.
>> > > >
>> > > > Best regards,
>> > > >
>> > > > Luis
>> > >
>> > >
>> > >
>>
>>
>>




_______________________________________________
pdl-devel mailing list
pdl-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/pdl-devel
_______________________________________________
pdl-devel mailing list
pdl-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/pdl-devel

Reply via email to