comp.lang.ada
 help / color / mirror / Atom feed
* Why does this work? (overloads)
@ 2007-02-07  4:39 Jerry
  2007-02-07  6:45 ` AW: " Grein, Christoph (Fa. ESG)
  2007-02-07 19:02 ` Jeffrey R. Carter
  0 siblings, 2 replies; 23+ messages in thread
From: Jerry @ 2007-02-07  4:39 UTC (permalink / raw)


(1) Why does the following work?
(2) Have I done something stupid or dangerous?

I have written some overloads to +, -, * / to make doing some vector-
matrix
calculations look more algebraic. I have also made some overloads to
allow
some element-by-element operations so that I can do Matlab-like
things,
such as "multiplying" two vectors of the same length and getting a
vector
back.

So here are a few lines of code with a couple declarations from the
G.3 Annex of Ada 2005. Note that the line that I originally wrote to
test
some of these overloads was this, involving some complex entities
  H := Two_Pi / (Two_Pi + j * Two_Pi * f * x);
(j = sqrt(-1.0)) but I think the simplified line for H below captures
the
essence of my question.


Here are a few lines of code.


-- From a-ngrear.ads (Ada 2005, Generic Real Arrays
-- instanciated with Long_Float)...
type Real_Vector is array (Integer range <>) of Real'Base; -- Vectors
function "*" (Left, Right : Real_Vector) return Real'Base; -- Inner
product


-- From some of my own overloads...
function "*" (x, y : Real_Vector) return Real_Vector; -- element-by-
element
function "+" (a : Long_Float; x : Real_Vector) return Real_Vector;


-- Some declarations...
f, x, H : Real_Vector(0 .. NN - 1);
a : Long_Float;


-- And finally, two lines of calculation...
H := 1.0 + f * x; -- Adds scalar, 1.0, to a vector using my overload
above.
a := 1.0 + f * x; -- Adds scalar, 1.0, to another scalar, an inner
product.


I get the results that I expected but I feel a little lucky.

Why when calculating H doesn't the compiler interpret f * x as an
inner
product then generate an error, after adding 1.0, when trying to make
the
assignment to H which is a vector?

Obviously the compiler figures out which of the * operators to use
depending on the assigned-to variable. Is this reliable for more
complicated
calculations? I wonder if it is possible to create an ambiguity that
would
be resolved "in the wrong way" and I would get incorrect results.

Regards,
Jerry

 ___
/o|o\
 (o)




^ permalink raw reply	[flat|nested] 23+ messages in thread

* AW: Why does this work? (overloads)
  2007-02-07  4:39 Why does this work? (overloads) Jerry
@ 2007-02-07  6:45 ` Grein, Christoph (Fa. ESG)
  2007-02-07  7:07   ` Jerry
  2007-02-07 19:09   ` AW: " Jeffrey R. Carter
  2007-02-07 19:02 ` Jeffrey R. Carter
  1 sibling, 2 replies; 23+ messages in thread
From: Grein, Christoph (Fa. ESG) @ 2007-02-07  6:45 UTC (permalink / raw)
  To: Jerry, comp.lang.ada

> H := 1.0 + f * x; -- Adds scalar, 1.0, to a vector using my overload
> above.
> a := 1.0 + f * x; -- Adds scalar, 1.0, to another scalar, an inner
> product.

This feature is called overloading.

For a problematic example, consider X := A*B*C; where all four are
vectors.

Is it (A*B) inner product * C resulting in vector or
      (A*B) vector        * C resulting in vector.
The compiler can't tell and will reject the code.



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07  6:45 ` AW: " Grein, Christoph (Fa. ESG)
@ 2007-02-07  7:07   ` Jerry
  2007-02-07  7:26     ` AW: " Grein, Christoph (Fa. ESG)
  2007-02-07 19:09   ` AW: " Jeffrey R. Carter
  1 sibling, 1 reply; 23+ messages in thread
From: Jerry @ 2007-02-07  7:07 UTC (permalink / raw)


On Feb 6, 11:45 pm, "Grein, Christoph (Fa. ESG)"
<Christoph.Gr...@eurocopter.com> wrote:
> > H := 1.0 + f * x; -- Adds scalar, 1.0, to a vector using my overload
> > above.
> > a := 1.0 + f * x; -- Adds scalar, 1.0, to another scalar, an inner
> > product.
>
> This feature is called overloading.
>
> For a problematic example, consider X := A*B*C; where all four are
> vectors.
>
> Is it (A*B) inner product * C resulting in vector or
>       (A*B) vector        * C resulting in vector.
> The compiler can't tell and will reject the code.

Hmm.... You're right, of course. Plus, (A*B) matrix * C where A*B is
taken as an outer product. The compiler did reject it, so at least
(with this example) I can't generate incorrect results, but I have to
tweak my code.

I wish that I could define new operators. I suppose there's always the
ugly:

        type Math_Operator is ('+', '-', '*', '/');
        function el(Left : Real_Vector; op : Math_Operator; Right :
Real_Vector) return Real_Vector is


Jerry




^ permalink raw reply	[flat|nested] 23+ messages in thread

* AW: Why does this work? (overloads)
  2007-02-07  7:07   ` Jerry
@ 2007-02-07  7:26     ` Grein, Christoph (Fa. ESG)
  2007-02-07 20:43       ` Jerry
  0 siblings, 1 reply; 23+ messages in thread
From: Grein, Christoph (Fa. ESG) @ 2007-02-07  7:26 UTC (permalink / raw)
  To: comp.lang.ada

In my vector code, I do not define cross, inner and outer products via
operator "*" overloading exactly because of these ambiguities.



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07  4:39 Why does this work? (overloads) Jerry
  2007-02-07  6:45 ` AW: " Grein, Christoph (Fa. ESG)
@ 2007-02-07 19:02 ` Jeffrey R. Carter
  2007-02-07 19:21   ` Adam Beneschan
  2007-02-07 20:53   ` Jerry
  1 sibling, 2 replies; 23+ messages in thread
From: Jeffrey R. Carter @ 2007-02-07 19:02 UTC (permalink / raw)


Jerry wrote:
> (1) Why does the following work?

Because Ada was designed so you can do this.

> (2) Have I done something stupid or dangerous?

No.

> 
> -- From a-ngrear.ads (Ada 2005, Generic Real Arrays
> -- instanciated with Long_Float)...
> type Real_Vector is array (Integer range <>) of Real'Base; -- Vectors
> function "*" (Left, Right : Real_Vector) return Real'Base; -- Inner
> product
> 
> -- From some of my own overloads...
> function "*" (x, y : Real_Vector) return Real_Vector; -- element-by-
> element
> function "+" (a : Long_Float; x : Real_Vector) return Real_Vector;
> 
> -- Some declarations...
> f, x, H : Real_Vector(0 .. NN - 1);

Note that in mathematics, matrices and vectors are indexed from 1. 1 .. 
NN also avoids the common error of forgetting the "- 1".

> a : Long_Float;
> 
> -- And finally, two lines of calculation...
> H := 1.0 + f * x; -- Adds scalar, 1.0, to a vector using my overload
> above.
> a := 1.0 + f * x; -- Adds scalar, 1.0, to another scalar, an inner
> product.
> 
> Why when calculating H doesn't the compiler interpret f * x as an
> inner
> product then generate an error, after adding 1.0, when trying to make
> the
> assignment to H which is a vector?

Because the context of overload resolution for "+" (ARM 8.6) doesn't 
allow this if there is another interpretation that isn't an error. The 
expected type of the result of "+" is a Vector for H, so the result of 
"+" must be a Vector. The only "+" that takes a real left operand and 
returns a Vector takes a Vector right operand. Therefore, the expected 
type of F * X is a Vector, and the only candidate for that is your "*".

Similar resolution takes place for A. The expected type of "+" is 
Long_Float. The only "+" that takes a real left operand and returns a 
Long_Float is the predefined "+" for Long_Float. Therefore, the expected 
type of F * X is Long_Float, and the only candidate for that is the 
inner product.

> Obviously the compiler figures out which of the * operators to use
> depending on the assigned-to variable. Is this reliable for more
> complicated
> calculations? I wonder if it is possible to create an ambiguity that
> would
> be resolved "in the wrong way" and I would get incorrect results.

No. You can create an ambiguity, but then the compiler must reject it.

An example:

procedure Ambiguous is
    type T is array (Integer range <>) of Integer;

    function F return T; -- F1
    function F (I : Integer) return Integer; -- F2

    function F return T is
       -- null;
    begin -- F
       return T'(5 => 7);
    end F;

    function F (I : Integer) return Integer is
       -- null;
    begin -- F
       return I + 2;
    end F;

    V : Integer := F (5); --???
begin -- Ambiguous
    null;
end Ambiguous;

Is the call to F a call to F1, with the result indexed by 5, or a call 
to F2 with a parameter of 5? I can't tell, and neither can the compiler. 
GNAT says

ambiguous.adb:19:19: ambiguous expression (cannot resolve "F")
ambiguous.adb:19:19: possible interpretation at line 5
ambiguous.adb:19:19: possible interpretation at line 4

You should be able to say

V := T'(F) (5);

to indicate a call to F1, but GNAT complains, saying a binary operator 
is expected between ')' and '('. This seems to be a compiler error. 
T'(F) should be a value of type T, which can then be indexed. After all, 
you can say

X : constant T := T'(F);

V : Integer := X (5);

You can say

V := F (I => 5);

to indicate a call to F2.

-- 
Jeff Carter
"No one is to stone anyone until I blow this whistle,
do you understand? Even--and I want to make this
absolutely clear--even if they do say, 'Jehovah.'"
Monty Python's Life of Brian
74



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: AW: Why does this work? (overloads)
  2007-02-07  6:45 ` AW: " Grein, Christoph (Fa. ESG)
  2007-02-07  7:07   ` Jerry
@ 2007-02-07 19:09   ` Jeffrey R. Carter
  2007-02-07 21:13     ` Jerry
  1 sibling, 1 reply; 23+ messages in thread
From: Jeffrey R. Carter @ 2007-02-07 19:09 UTC (permalink / raw)


Grein, Christoph (Fa. ESG) wrote:
> 
> For a problematic example, consider X := A*B*C; where all four are
> vectors.
> 
> Is it (A*B) inner product * C resulting in vector or
>       (A*B) vector        * C resulting in vector.
> The compiler can't tell and will reject the code.

You can tell the compiler, though:

Long_Float'(A * B) * C
Vector'(A * B)     * C
Matrix'(A * B)     * C

-- 
Jeff Carter
"No one is to stone anyone until I blow this whistle,
do you understand? Even--and I want to make this
absolutely clear--even if they do say, 'Jehovah.'"
Monty Python's Life of Brian
74



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07 19:02 ` Jeffrey R. Carter
@ 2007-02-07 19:21   ` Adam Beneschan
  2007-02-07 19:25     ` Adam Beneschan
                       ` (2 more replies)
  2007-02-07 20:53   ` Jerry
  1 sibling, 3 replies; 23+ messages in thread
From: Adam Beneschan @ 2007-02-07 19:21 UTC (permalink / raw)


On Feb 7, 11:02 am, "Jeffrey R. Carter" <jrcar...@acm.org> wrote:

> You should be able to say
>
> V := T'(F) (5);
>
> to indicate a call to F1, but GNAT complains, saying a binary operator
> is expected between ')' and '('. This seems to be a compiler error.
> T'(F) should be a value of type T, which can then be indexed. After all,
> you can say
>
> X : constant T := T'(F);
>
> V : Integer := X (5);

No, the compiler is right.  The problem here is that the syntax of Ada
says that an index can be applied to a "name", but a qualified
expression is not a "name".  I griped about this in AI05-0003.  See
http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI05s/AI05-0003-1.TXT?
rev=1.1

                     -- Adam




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07 19:21   ` Adam Beneschan
@ 2007-02-07 19:25     ` Adam Beneschan
  2007-02-08  0:51       ` Jeffrey R. Carter
  2007-02-07 23:12     ` Robert A Duff
  2007-02-08  0:49     ` Jeffrey R. Carter
  2 siblings, 1 reply; 23+ messages in thread
From: Adam Beneschan @ 2007-02-07 19:25 UTC (permalink / raw)


On Feb 7, 11:21 am, "Adam Beneschan" <a...@irvine.com> wrote:

> No, the compiler is right.  The problem here is that the syntax of Ada
> says that an index can be applied to a "name", but a qualified
> expression is not a "name".  I griped about this in AI05-0003.
> See
> http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI05s/AI05-0003-1.TXT?
> rev=1.1

Sigh...  Google Groups messed up my link.  I think this has to do with
changes they made for their latest and greatest version; it seems like
every time they improve it, it gets worse.

Please note that the last portion of the URL is AI05-0003-1.TXT?
rev=1.1

Or just go to

http://www.ada-auth.org/AI05-SUMMARY.HTML

and click on AI05-0003.

                          -- Adam


>                      -- Adam





^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07  7:26     ` AW: " Grein, Christoph (Fa. ESG)
@ 2007-02-07 20:43       ` Jerry
  0 siblings, 0 replies; 23+ messages in thread
From: Jerry @ 2007-02-07 20:43 UTC (permalink / raw)


Grein, Christoph wrote:
> In my vector code, I do not define cross, inner and outer products via
> operator "*" overloading exactly because of these ambiguities.

I thought about doing that, or _not_  implementing the element-by-
element versions. Interestingly, Ada 2005 implements inner and outer
products for you if you use Ada.Numerics.Generic_Real_Arrays or
Ada.Numerics.Generic_Complex_Arrays.




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07 19:02 ` Jeffrey R. Carter
  2007-02-07 19:21   ` Adam Beneschan
@ 2007-02-07 20:53   ` Jerry
  2007-02-08  0:53     ` Jeffrey R. Carter
  1 sibling, 1 reply; 23+ messages in thread
From: Jerry @ 2007-02-07 20:53 UTC (permalink / raw)


Jeffrey R. Carter wrote:
> Jerry wrote:
> > (1) Why does the following work?
>
> Because Ada was designed so you can do this.
>
> > (2) Have I done something stupid or dangerous?
>
> No.
>
Excellent. I knew there was some reason that I was using Ada ;).
>
> > -- Some declarations...
> > f, x, H : Real_Vector(0 .. NN - 1);
>
> Note that in mathematics, matrices and vectors are indexed from 1. 1 ..
> NN also avoids the common error of forgetting the "- 1".
>
Yes, but  time series are usually indexed from 0. Sometimes, the FFT
of a time series is indexed from 0 and sometimes -NN/2 .. NN/2-1. When
one uses a time series in a vector or matrix, conundrums obviously
arise, not only in computer code but in print. I once figured out how
to make Pascal let me have it both ways by declaring both types, one
type indexed 0..NN-1 and the other 1..NN, and then I set a pointer of
one type to an array originally declared with another type. I'm
guessing that Ada doesn't allow this, however.

> Because the context of overload resolution for "+" (ARM 8.6) doesn't
> allow this if there is another interpretation that isn't an error.

Thanks for the great explanation.

Jerry




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07 19:09   ` AW: " Jeffrey R. Carter
@ 2007-02-07 21:13     ` Jerry
  2007-02-07 21:33       ` Ludovic Brenta
  2007-02-07 21:36       ` Randy Brukardt
  0 siblings, 2 replies; 23+ messages in thread
From: Jerry @ 2007-02-07 21:13 UTC (permalink / raw)


Jeffrey R. Carter wrote:
> Grein, Christoph (Fa. ESG) wrote:
> > For a problematic example, consider X := A*B*C; where all four are
> > vectors.
>
> > Is it (A*B) inner product * C resulting in vector or
> >       (A*B) vector        * C resulting in vector.
> > The compiler can't tell and will reject the code.
>
> You can tell the compiler, though:
>
> Long_Float'(A * B) * C
> Vector'(A * B)     * C
> Matrix'(A * B)     * C
>
Pretty cool. What is this feature called so that I can study it?
Jerry




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07 21:13     ` Jerry
@ 2007-02-07 21:33       ` Ludovic Brenta
  2007-02-07 21:36       ` Randy Brukardt
  1 sibling, 0 replies; 23+ messages in thread
From: Ludovic Brenta @ 2007-02-07 21:33 UTC (permalink / raw)


Jerry writes:
>> Long_Float'(A * B) * C
>> Vector'(A * B)     * C
>> Matrix'(A * B)     * C
>>
> Pretty cool. What is this feature called so that I can study it?
> Jerry

These are "qualified expressions", see ARM 4.7

-- 
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 23+ messages in thread

* RE: Why does this work? (overloads)
  2007-02-07 21:13     ` Jerry
  2007-02-07 21:33       ` Ludovic Brenta
@ 2007-02-07 21:36       ` Randy Brukardt
  1 sibling, 0 replies; 23+ messages in thread
From: Randy Brukardt @ 2007-02-07 21:36 UTC (permalink / raw)
  To: comp.lang.ada

Jerry asks:

> > You can tell the compiler, though:
> >
> > Long_Float'(A * B) * C
> > Vector'(A * B)     * C
> > Matrix'(A * B)     * C
> >
> Pretty cool. What is this feature called so that I can study it?

Qualified expressions, 4.7 in the RM.

          Randy.




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07 19:21   ` Adam Beneschan
  2007-02-07 19:25     ` Adam Beneschan
@ 2007-02-07 23:12     ` Robert A Duff
  2007-02-08  0:49     ` Jeffrey R. Carter
  2 siblings, 0 replies; 23+ messages in thread
From: Robert A Duff @ 2007-02-07 23:12 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> writes:

> On Feb 7, 11:02 am, "Jeffrey R. Carter" <jrcar...@acm.org> wrote:
>
>> You should be able to say
>>
>> V := T'(F) (5);
>>
>> to indicate a call to F1, but GNAT complains, saying a binary operator
>> is expected between ')' and '('. This seems to be a compiler error.
>> T'(F) should be a value of type T, which can then be indexed. After all,
>> you can say
>>
>> X : constant T := T'(F);
>>
>> V : Integer := X (5);
>
> No, the compiler is right.  The problem here is that the syntax of Ada
> says that an index can be applied to a "name", but a qualified
> expression is not a "name".  I griped about this in AI05-0003.  See
> http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI05s/AI05-0003-1.TXT?
> rev=1.1

Right -- it's a language bug, not a compiler bug.

- Bob



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07 19:21   ` Adam Beneschan
  2007-02-07 19:25     ` Adam Beneschan
  2007-02-07 23:12     ` Robert A Duff
@ 2007-02-08  0:49     ` Jeffrey R. Carter
  2 siblings, 0 replies; 23+ messages in thread
From: Jeffrey R. Carter @ 2007-02-08  0:49 UTC (permalink / raw)


Adam Beneschan wrote:
> 
> No, the compiler is right.  The problem here is that the syntax of Ada
> says that an index can be applied to a "name", but a qualified
> expression is not a "name".  I griped about this in AI05-0003.  See
> http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI05s/AI05-0003-1.TXT?
> rev=1.1

OK. Thanks for the clarification. An intermediate value is needed, then, 
to call the version that returns an array.

-- 
Jeff Carter
"It's all right, Taggart. Just a man and a horse being hung out there."
Blazing Saddles
34



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07 19:25     ` Adam Beneschan
@ 2007-02-08  0:51       ` Jeffrey R. Carter
  0 siblings, 0 replies; 23+ messages in thread
From: Jeffrey R. Carter @ 2007-02-08  0:51 UTC (permalink / raw)


Adam Beneschan wrote:
> On Feb 7, 11:21 am, "Adam Beneschan" <a...@irvine.com> wrote:
> 
>> http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI05s/AI05-0003-1.TXT?
>> rev=1.1
> 
> Sigh...  Google Groups messed up my link.  I think this has to do with
> changes they made for their latest and greatest version; it seems like
> every time they improve it, it gets worse.
> 
> Please note that the last portion of the URL is AI05-0003-1.TXT?
> rev=1.1

Not an improvement, I'm afraid. Try, "The last portion of the URL is

AI05-0003-1.TXT?rev=1.1

"

-- 
Jeff Carter
"It's all right, Taggart. Just a man and a horse being hung out there."
Blazing Saddles
34



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-07 20:53   ` Jerry
@ 2007-02-08  0:53     ` Jeffrey R. Carter
  2007-02-08 10:40       ` Jerry
  0 siblings, 1 reply; 23+ messages in thread
From: Jeffrey R. Carter @ 2007-02-08  0:53 UTC (permalink / raw)


Jerry wrote:
>>
> Yes, but  time series are usually indexed from 0. Sometimes, the FFT
> of a time series is indexed from 0 and sometimes -NN/2 .. NN/2-1. When
> one uses a time series in a vector or matrix, conundrums obviously
> arise, not only in computer code but in print. I once figured out how
> to make Pascal let me have it both ways by declaring both types, one
> type indexed 0..NN-1 and the other 1..NN, and then I set a pointer of
> one type to an array originally declared with another type. I'm
> guessing that Ada doesn't allow this, however.

No pointers needed:

A : Vector (0 .. N - 1);
B : Vector (1 .. A'Length);

A := B;
B := A;

This is called sliding.

-- 
Jeff Carter
"It's all right, Taggart. Just a man and a horse being hung out there."
Blazing Saddles
34



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-08  0:53     ` Jeffrey R. Carter
@ 2007-02-08 10:40       ` Jerry
  2007-02-08 11:34         ` Georg Bauhaus
                           ` (4 more replies)
  0 siblings, 5 replies; 23+ messages in thread
From: Jerry @ 2007-02-08 10:40 UTC (permalink / raw)


Jeffrey R. Carter wrote:
> Jerry wrote:
>
> > Yes, but  time series are usually indexed from 0. Sometimes, the FFT
> > of a time series is indexed from 0 and sometimes -NN/2 .. NN/2-1. When
> > one uses a time series in a vector or matrix, conundrums obviously
> > arise, not only in computer code but in print. I once figured out how
> > to make Pascal let me have it both ways by declaring both types, one
> > type indexed 0..NN-1 and the other 1..NN, and then I set a pointer of
> > one type to an array originally declared with another type. I'm
> > guessing that Ada doesn't allow this, however.
>
> No pointers needed:
>
> A : Vector (0 .. N - 1);
> B : Vector (1 .. A'Length);
>
> A := B;
> B := A;
>
> This is called sliding.
>
Good point. However, it uses twice the memory, and worse, changes made
in A are not reflected in B without repeating the assignment A := B
(correct?) and vice versa. My Pascal trick had neither of these
problems yet carried boundary checking using either name.

Maybe there's a way to do this using unrestricted_access variables of
GNAT.

Jerry




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-08 10:40       ` Jerry
@ 2007-02-08 11:34         ` Georg Bauhaus
  2007-02-08 12:05         ` AW: " Grein, Christoph (Fa. ESG)
                           ` (3 subsequent siblings)
  4 siblings, 0 replies; 23+ messages in thread
From: Georg Bauhaus @ 2007-02-08 11:34 UTC (permalink / raw)


On Thu, 2007-02-08 at 02:40 -0800, Jerry wrote:
> Jeffrey R. Carter wrote:
> > Jerry wrote:
> >
> > > Yes, but  time series are usually indexed from 0. Sometimes, the FFT
> > > of a time series is indexed from 0 and sometimes -NN/2 .. NN/2-1. When
> > > one uses a time series in a vector or matrix, conundrums obviously
> > > arise, not only in computer code but in print. I once figured out how
> > > to make Pascal let me have it both ways by declaring both types, one
> > > type indexed 0..NN-1 and the other 1..NN, and then I set a pointer of
> > > one type to an array originally declared with another type. I'm
> > > guessing that Ada doesn't allow this, however.
> >
> > No pointers needed:
> >
> > A : Vector (0 .. N - 1);
> > B : Vector (1 .. A'Length);
> >
> > A := B;
> > B := A;
> >
> > This is called sliding.
> >
> Good point. However, it uses twice the memory, and worse, changes made
> in A are not reflected in B without repeating the assignment A := B
> (correct?) and vice versa. My Pascal trick had neither of these
> problems yet carried boundary checking using either name.

Not sure whether it is what you are after, but you could either use
pointers to a common unconstrained array type, or simply slice renaming
if possible:

with Ada.Text_IO; use Ada;
procedure sp is

    type Index is range 0 .. 666;

    type A is array (Index range <>) of Float;

    c: A(0 .. 3);
    x: A renames c(0 .. 2);
    y: A renames c(1 .. 3);

    function "*"(v, w: A) return Float;
      -- sum of products of pairwise matching components of `v` and `w`
      -- pre: v'length = w'length

    function "*"(v, w: A) return Float is
        result: Float := 0.0;
        j: Index := w'first;
    begin
        pragma assert(v'length = w'length);
        for k in v'range loop
            result := result + v(k) * w(j);
            j := j + 1;
        end loop;
        return result;
    end "*";

    package FIO is new Text_IO.Float_IO(Float);

begin
    FIO.Default_Aft := 2; FIO.Default_Exp := 0;
    c := (1.0, 3.2, 3.7, 2.4);
    FIO.Put(x * y); Text_IO.new_line;
    c(2) := 1.0;
    FIO.Put(x * y); Text_IO.new_line;
    x(2) := -1.3;
    FIO.Put(x * y); Text_IO.new_line;
    y(2) := +1.3;
    FIO.Put(x * y); Text_IO.new_line;
end sp;





^ permalink raw reply	[flat|nested] 23+ messages in thread

* AW: Why does this work? (overloads)
  2007-02-08 10:40       ` Jerry
  2007-02-08 11:34         ` Georg Bauhaus
@ 2007-02-08 12:05         ` Grein, Christoph (Fa. ESG)
  2007-02-08 18:52         ` Jeffrey R. Carter
                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 23+ messages in thread
From: Grein, Christoph (Fa. ESG) @ 2007-02-08 12:05 UTC (permalink / raw)
  To: comp.lang.ada

Try this. Not very elegant, but works.

with Ada.Exceptions;

with Ada.Text_IO, Ada.Float_Text_IO;
use  Ada.Text_IO, Ada.Float_Text_IO;

with Ada.Unchecked_Conversion;

procedure Test_it is

  N: constant := 10;

  type Vector is array (Integer range <>) of Float;
  -- Fat pointers don't work (include bounds).
  -- type Vector_Ptr is access all Vector;
  -- subtype Vector_Ptr_1   is Vector_Ptr (  1 .. N      );
  -- subtype Vector_Ptr_101 is Vector_Ptr (101 .. N + 100);

  -- Thin pointers (don't include bounds):
  type Vector_Ptr_1   is access all Vector (  1 .. N      );
  type Vector_Ptr_101 is access all Vector (101 .. N + 100);

  function Convert is new
    Ada.Unchecked_Conversion (Vector_Ptr_1, Vector_Ptr_101);

  X: aliased Vector (1 .. N);  -- constrained nominal subtype
  P: Vector_Ptr_1   := X'Access;
  Q: Vector_Ptr_101 := Convert (P);

begin

  for i in X'Range loop
    X (i) := Float (i);
  end loop;

  for i in P'Range loop
    Put (Integer'Image (i));  Put (P (i));  New_Line;
  end loop;

  for i in Q'Range loop
    Put (Integer'Image (i));  Put (Q (i));  New_Line;
  end loop;

exception
  when Exc: others =>
    Put_Line ("Unexpected exception " &
              Ada.Exceptions.Exception_Name (Exc));

end Test_it;

-----Ursprüngliche Nachricht-----
Jerry wrote:

Good point. However, it uses twice the memory, and worse, changes made
in A are not reflected in B without repeating the assignment A := B
(correct?) and vice versa. My Pascal trick had neither of these
problems yet carried boundary checking using either name.

Maybe there's a way to do this using unrestricted_access variables of
GNAT.

Jerry




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-08 10:40       ` Jerry
  2007-02-08 11:34         ` Georg Bauhaus
  2007-02-08 12:05         ` AW: " Grein, Christoph (Fa. ESG)
@ 2007-02-08 18:52         ` Jeffrey R. Carter
  2007-02-09  0:56         ` Jerry
  2007-02-09  1:27         ` tmoran
  4 siblings, 0 replies; 23+ messages in thread
From: Jeffrey R. Carter @ 2007-02-08 18:52 UTC (permalink / raw)


Jerry wrote:
>>
> Good point. However, it uses twice the memory, and worse, changes made
> in A are not reflected in B without repeating the assignment A := B
> (correct?) and vice versa. My Pascal trick had neither of these
> problems yet carried boundary checking using either name.

Right. But your Pascal trick is an abomination. You can do the same 
thing in Ada using overlays, but it's not recommended. There's probably 
also a way with access types. Something like (not tested)

type Vector is array (Natural range <>) of Real;

Max : constant := ...;

subtype Zero_Based is Vector (0 .. Max - 1);
subtype One_Based  is Vector (1 .. Max    );

type Zero_Ptr is access all Zero_Based;
type One_Ptr  is access all One_Based;

V : aliased Zero_Based;

ZP : Zero_Ptr := V'access;

function To_One is new Ada.Unchecked_Deallocation
    (Source = Zero_Ptr, Target => One_Ptr);

OP : One_Ptr := To_One (ZP);

I wouldn't recommend it.

-- 
Jeff Carter
"What I wouldn't give for a large sock with horse manure in it."
Annie Hall
42



^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-08 10:40       ` Jerry
                           ` (2 preceding siblings ...)
  2007-02-08 18:52         ` Jeffrey R. Carter
@ 2007-02-09  0:56         ` Jerry
  2007-02-09  1:27         ` tmoran
  4 siblings, 0 replies; 23+ messages in thread
From: Jerry @ 2007-02-09  0:56 UTC (permalink / raw)


Jerry wrote:
> Good point. However, it uses twice the memory, and worse, changes made
> in A are not reflected in B without repeating the assignment A := B
> (correct?) and vice versa. My Pascal trick had neither of these
> problems yet carried boundary checking using either name.
>
> Maybe there's a way to do this using unrestricted_access variables of
> GNAT.

Thanks for all the great ideas, everyone.

Jerry




^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Why does this work? (overloads)
  2007-02-08 10:40       ` Jerry
                           ` (3 preceding siblings ...)
  2007-02-09  0:56         ` Jerry
@ 2007-02-09  1:27         ` tmoran
  4 siblings, 0 replies; 23+ messages in thread
From: tmoran @ 2007-02-09  1:27 UTC (permalink / raw)


> > to make Pascal let me have it both ways by declaring both types, one
> > type indexed 0..NN-1 and the other 1..NN, and then I set a pointer of
> > one type to an array originally declared with another type. I'm
> > guessing that Ada doesn't allow this, however.
  You can convert an access to one thing to an access to another using
Unchecked_Conversion.  You can also declare A, then declare B and
for B'address use A'address.



^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2007-02-09  1:27 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-07  4:39 Why does this work? (overloads) Jerry
2007-02-07  6:45 ` AW: " Grein, Christoph (Fa. ESG)
2007-02-07  7:07   ` Jerry
2007-02-07  7:26     ` AW: " Grein, Christoph (Fa. ESG)
2007-02-07 20:43       ` Jerry
2007-02-07 19:09   ` AW: " Jeffrey R. Carter
2007-02-07 21:13     ` Jerry
2007-02-07 21:33       ` Ludovic Brenta
2007-02-07 21:36       ` Randy Brukardt
2007-02-07 19:02 ` Jeffrey R. Carter
2007-02-07 19:21   ` Adam Beneschan
2007-02-07 19:25     ` Adam Beneschan
2007-02-08  0:51       ` Jeffrey R. Carter
2007-02-07 23:12     ` Robert A Duff
2007-02-08  0:49     ` Jeffrey R. Carter
2007-02-07 20:53   ` Jerry
2007-02-08  0:53     ` Jeffrey R. Carter
2007-02-08 10:40       ` Jerry
2007-02-08 11:34         ` Georg Bauhaus
2007-02-08 12:05         ` AW: " Grein, Christoph (Fa. ESG)
2007-02-08 18:52         ` Jeffrey R. Carter
2007-02-09  0:56         ` Jerry
2007-02-09  1:27         ` tmoran

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox