comp.lang.ada
 help / color / mirror / Atom feed
* Incorrect error?
@ 2011-07-18  8:47 ldries46
  2011-07-18  9:45 ` stefan-lucks
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: ldries46 @ 2011-07-18  8:47 UTC (permalink / raw)


I'm using Ada.Numerics.Generic_Real_Arrays. While Compiling I got the 
following error message:

65:21     expected type "Ada.Numerics.Generic_Real_Arrays.Real_Vector" from 
instance at line 6
65:21     found type "Ada.Numerics.Generic_Real_Arrays.Real_Matrix" from 
instance at line 6

As can be seen Cross, a and b declared as Real_Vector .
What do I do wrong?

L. Dries

Code:

package Float_Arrays is new Ada.Numerics.Generic_Real_Arrays (float);
use Float_Arrays;

function Volume (ObjID : integer; Obj : ptrS_Object) return float is
   ok     : boolean;
   n      : integer := 1;
   Volume : float;
   a      : Real_Vector(0 .. 2);
   b      : Real_Vector(0 .. 2);
   X0     : Real_Vector(0 .. 2);
   X1     : Real_Vector(0 .. 2);
   X2     : Real_Vector(0 .. 2);
   cross  : Real_Vector(0 .. 2);
   nA     : Real_Vector(0 .. 2);
   p      : ptrNode_Object;
   TempS  : ptrS_Object;
   TempT  : ptrTriangle_Object;
begin
   TempS := Obj;
   while n /= ObjID loop
      n := n + 1;
      TempS := TempS.next;
      if TempS = null then
         declare
            NO_NODE_OBJECT : exception;
         begin
            raise NO_NODE_OBJECT;
         end;
      end if;
   end loop;
   n := TempS.PosFaces(0);
   TempT := stT_Object;
   ok := TempT = null;
   while not ok loop
      if TempT.nr = n then
         ok := true;
      else
         TempT := TempT.next;
         ok := TempT = null;
      end if;
   end loop;
   while n < TempS.PosFaces(1) loop
      p := GetPoint(TempT.P1);
      X0(0) := p.pRectangular(x);
      X0(1) := p.pRectangular(y);
      X0(2) := p.pRectangular(z);
      p := GetPoint(TempT.P2);
      X1(0) := p.pRectangular(x);
      X1(1) := p.pRectangular(y);
      X1(2) := p.pRectangular(z);
      p := GetPoint(TempT.P3);
      X2(0) := p.pRectangular(x);
      X2(1) := p.pRectangular(y);
      X2(2) := p.pRectangular(z);
      a := X1 - X0; -- VecSub( a, X1, X0 );
      b := X2 - X0; -- VecSub( b, X2, X0 );
     Cross := a * b; -- VecCross( a, b, Cross ); 
<---------------- line 65 the cursor is standing just before *
      nA := Cross * 0.5; -- VecMultScalar( nA, Cross, 0.5 );
      -- Volume = Volume + fabs(VecDot( X0, nA ));
      Volume := Volume + X0(0)*nA(0) + X0(1)*nA(1) + X0(2)*nA(2);
      n := n + 1;
   end loop;
   Volume := Volume/3.0;
   return Volume;
end Volume;




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

* Re: Incorrect error?
  2011-07-18  8:47 Incorrect error? ldries46
@ 2011-07-18  9:45 ` stefan-lucks
  2011-07-18 10:10   ` Georg Bauhaus
  2011-07-18 10:40   ` AdaMagica
  2011-07-18 10:39 ` Nicholas Collin Paul de Glouceſter
  2011-07-18 15:58 ` Adam Beneschan
  2 siblings, 2 replies; 10+ messages in thread
From: stefan-lucks @ 2011-07-18  9:45 UTC (permalink / raw)


On Mon, 18 Jul 2011, ldries46 wrote:

[...]
>   a      : Real_Vector(0 .. 2);
>   b      : Real_Vector(0 .. 2);
>   cross  : Real_Vector(0 .. 2);
> begin
[...]
>     Cross := a * b; -- VecCross( a, b, Cross ); <---------------- line 65 the

Why do you expect the product of two vectors to be an vector? 

Mathematical convention knows the "inner product" of two vectors (a 
single real value) and the "outer product" (a matrix).  

Ada.Numerics.Generic_Real_Arrays actually provides both:

   function "*"   (Left, Right : Real_Vector) return Real'Base;
   function "*"   (Left, Right : Real_Vector) return Real_Matrix;

So if M is a Real_Matrix(0..2,0..2) and F a float, you can write either

   M := a * b;  -- outer product 

or 
 
   F := a * b;  -- inner product

but not

  Cross := a * b; -- there is no such "*" defined in Ada.Num.Gen_Re_Arr. 

Please don't ask me why the inner product is of type "Real'Base", instead 
of "Real". I'd like to know that myself. ;-)
  
BTW, the error messages are not very helpful (at least not until you have 
seen many of them and are able to translate them for yourself):

>65:21     expected type "Ada.Numerics.Generic_Real_Arrays.Real_Vector" 
>          from instance at line 6
>65:21     found type "Ada.Numerics.Generic_Real_Arrays.Real_Matrix" from 
>          instance at line 6

This really means is that there is no function "*" with two Real_Vector 
parameters as the input and returning a Real_Vector in scope. 



-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




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

* Re: Incorrect error?
  2011-07-18  9:45 ` stefan-lucks
@ 2011-07-18 10:10   ` Georg Bauhaus
  2011-07-18 11:46     ` ldries46
  2011-07-18 10:40   ` AdaMagica
  1 sibling, 1 reply; 10+ messages in thread
From: Georg Bauhaus @ 2011-07-18 10:10 UTC (permalink / raw)


On 18.07.11 11:45, stefan-lucks@see-the.signature wrote:
> On Mon, 18 Jul 2011, ldries46 wrote:
> 
> [...]
>>   a      : Real_Vector(0 .. 2);
>>   b      : Real_Vector(0 .. 2);
>>   cross  : Real_Vector(0 .. 2);
>> begin
> [...]
>>     Cross := a * b; -- VecCross( a, b, Cross ); <---------------- line 65 the
> 
> Why do you expect the product of two vectors to be an vector? 

For a vector product, if a ⨯ b is to be one, I find the expectation
quite justified.  Confusion is what we get in return for Ada overloading
ASCII punctuation, in this case "*".  ;-)  (Wolfram's title is
"cross product", http://mathworld.wolfram.com/CrossProduct.html
IIUC.)




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

* Re: Incorrect error?
  2011-07-18  8:47 Incorrect error? ldries46
  2011-07-18  9:45 ` stefan-lucks
@ 2011-07-18 10:39 ` Nicholas Collin Paul de Glouceſter
  2011-07-18 15:58 ` Adam Beneschan
  2 siblings, 0 replies; 10+ messages in thread
From: Nicholas Collin Paul de Glouceſter @ 2011-07-18 10:39 UTC (permalink / raw)


L. Dries <bertus.dries@Planet.NL> sent on July 18th, 2011:
|--------------------------------------------------------------------------------|
|"I'm using Ada.Numerics.Generic_Real_Arrays. While Compiling I got the following|
|error message:                                                                  |
|                                                                                |
|65:21     expected type "Ada.Numerics.Generic_Real_Arrays.Real_Vector" from     |
|instance at line 6                                                              |
|65:21     found type "Ada.Numerics.Generic_Real_Arrays.Real_Matrix" from        |
|instance at line 6                                                              |
|                                                                                |
|As can be seen Cross, a and b declared as Real_Vector .                         |
|What do I do wrong?                                                             |
|                                                                                |
|L. Dries                                                                        |
|                                                                                |
|[..]                                                                            |
|  a      : Real_Vector(0 .. 2);                                                 |
|  b      : Real_Vector(0 .. 2);                                                 |
|[..]                                                                            |
|  cross  : Real_Vector(0 .. 2);                                                 |
|[..]                                                                            |
|     a := X1 - X0; -- VecSub( a, X1, X0 );                                      |
|     b := X2 - X0; -- VecSub( b, X2, X0 );                                      |
|    Cross := a * b; -- VecCross( a, b, Cross ); <---------------- line 65 the   |
|cursor is standing just before *                                                |
|[..]"                                                                           |
|--------------------------------------------------------------------------------|


The product of a 3x1 vector and a 1x3 vector is a 3x3 matrix.
The product of a 3x1 vector and a 3x1 vector can not exist.
You are trying to assign a 2d matrix (that is a * b) to a variable
declared to be a 1d vector.



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

* Re: Incorrect error?
  2011-07-18  9:45 ` stefan-lucks
  2011-07-18 10:10   ` Georg Bauhaus
@ 2011-07-18 10:40   ` AdaMagica
  2011-07-18 12:39     ` Dmitry A. Kazakov
  2011-07-18 12:45     ` stefan-lucks
  1 sibling, 2 replies; 10+ messages in thread
From: AdaMagica @ 2011-07-18 10:40 UTC (permalink / raw)


Overloading in this way might be seen as unfortunate.

> Ada.Numerics.Generic_Real_Arrays actually provides both:
>
>    function "*" (Left, Right : Real_Vector) return Real'Base;
>    function "*" (Left, Right : Real_Vector) return Real_Matrix;

So if you have three vectors, what should A * B * C mean? Even with
parentheses, it's awkward to read. Now image we have a third function

function "*" (Left, Right : Real_Vector) return Real_Vector;

BTW: What would such a function return for vectors of less or more
than 3 dimensions?

Why is 'Base the return value? You might instantiate the package with
a constrained subtype of Float. 'Base is the unconstrained range. Thus
as long as you stay in the base range, the operators will not
propagate exceptions.



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

* Re: Incorrect error?
  2011-07-18 10:10   ` Georg Bauhaus
@ 2011-07-18 11:46     ` ldries46
  0 siblings, 0 replies; 10+ messages in thread
From: ldries46 @ 2011-07-18 11:46 UTC (permalink / raw)


I just was converting a C++ program with the function VecCross The 
suggestion in that program was that a Cross vector was the result of a 
vector product.

L. Dries


"Georg Bauhaus"  schreef in bericht 
news:4e240690$0$6538$9b4e6d93@newsspool4.arcor-online.net...

On 18.07.11 11:45, stefan-lucks@see-the.signature wrote:
> On Mon, 18 Jul 2011, ldries46 wrote:
>
> [...]
>>   a      : Real_Vector(0 .. 2);
>>   b      : Real_Vector(0 .. 2);
>>   cross  : Real_Vector(0 .. 2);
>> begin
> [...]
>>     Cross := a * b; -- VecCross( a, b, Cross ); <---------------- line 65 
>> the
>
> Why do you expect the product of two vectors to be an vector?

For a vector product, if a ⨯ b is to be one, I find the expectation
quite justified.  Confusion is what we get in return for Ada overloading
ASCII punctuation, in this case "*".  ;-)  (Wolfram's title is
"cross product", http://mathworld.wolfram.com/CrossProduct.html
IIUC.) 




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

* Re: Incorrect error?
  2011-07-18 10:40   ` AdaMagica
@ 2011-07-18 12:39     ` Dmitry A. Kazakov
  2011-07-18 12:45     ` stefan-lucks
  1 sibling, 0 replies; 10+ messages in thread
From: Dmitry A. Kazakov @ 2011-07-18 12:39 UTC (permalink / raw)


On Mon, 18 Jul 2011 03:40:59 -0700 (PDT), AdaMagica wrote:

> Overloading in this way might be seen as unfortunate.
> 
>> Ada.Numerics.Generic_Real_Arrays actually provides both:
>>
>> � �function "*" (Left, Right : Real_Vector) return Real'Base;
>> � �function "*" (Left, Right : Real_Vector) return Real_Matrix;
> 
> So if you have three vectors, what should A * B * C mean? Even with
> parentheses, it's awkward to read.

There is one or more transpose operation missing, e.g.

   A * Transpose (B) * C
   Transpose (A) * Transpose (B) * C
   Transpose (A) * B * Transpose (C)

etc

> Now image we have a third function
> 
> function "*" (Left, Right : Real_Vector) return Real_Vector;

Ah, but vector product has the x-notation. Was introduction of Unicode in
Ada for nothing? (:-))

   function "�" (Left, Right : Real_Vector) return Real_Matrix;
 
> BTW: What would such a function return for vectors of less or more
> than 3 dimensions?

It is also well defined in mathematics, but the problem is same as with
measurement units. The constraints on the matrix dimensions of the
arguments statically determine the constraints of the result matrix
product. One cannot express this in the Ada's type system, otherwise than
by a massive set of overloaded subprograms, which, like for the case of
measurement units, is not a solution. We need some universal mechanism to
describe such cases based on subtypes with static checks of those when the
constraints are static.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Incorrect error?
  2011-07-18 10:40   ` AdaMagica
  2011-07-18 12:39     ` Dmitry A. Kazakov
@ 2011-07-18 12:45     ` stefan-lucks
  2011-07-18 13:24       ` stefan-lucks
  1 sibling, 1 reply; 10+ messages in thread
From: stefan-lucks @ 2011-07-18 12:45 UTC (permalink / raw)


[-- Attachment #1: Type: TEXT/PLAIN, Size: 2516 bytes --]

On Mon, 18 Jul 2011, AdaMagica wrote:

> Overloading in this way might be seen as unfortunate.
> 
> > Ada.Numerics.Generic_Real_Arrays actually provides both:
> >
> > � �function "*" (Left, Right : Real_Vector) return Real'Base;
> > � �function "*" (Left, Right : Real_Vector) return Real_Matrix;
> 
> So if you have three vectors, what should A * B * C mean? Even with
> parentheses, it's awkward to read. 

I would always prefer to write such an expression with parenthesis. So 
look at the expression (A * B) * C, where A, B, and C are vectors.  
 -> A * B is either a matrix M or a number N. 
 -> M * C would be a vector. 
 -> N * C would also be a vector. 
 ===> The result type is a vector. 

But wait a minute! There are two different results (either "M * C2 or "N * 
C"), and we don't know which is the correct one. So the compiler should 
reject this.

The issue is that the result type of "A * B" is different from the types 
of A and B. But, as strange as it seems, this is what generations of 
Mathematicians and Engineers seem to have found convenient for their work. 

I am sure, they where able to understand such expressions from context, 
and to provide the context if necessary. Most authors would probably 
prefer to write 

   "M * C with the matrix M being A * B" 

instead of "(A * B) * C" with or without "(", ")". They would thus provide 
the type information, much like any Ada programmer would (have to) do.

> Now image we have a third function
> function "*" (Left, Right : Real_Vector) return Real_Vector;
> 
> BTW: What would such a function return for vectors of less or more
> than 3 dimensions?

It should raise an exception, exactly like 

  function "+" (Left, Right : Real_Vector) return Real_Vector;

from the Ada.Numerics.Generic_Real_Array package. 

I hope the "aspect specifications" from Ada 2012 will allow to specify 
that the vector dimensions fit. In an ideal world (or maybe in Ada 2017), 
the compiler would then statically reject the program if the vector 
dimensions don't fit.

> Why is 'Base the return value? You might instantiate the package with
> a constrained subtype of Float. 'Base is the unconstrained range. Thus
> as long as you stay in the base range, the operators will not
> propagate exceptions.

Ah, that makes sense! Thank you!


-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------

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

* Re: Incorrect error?
  2011-07-18 12:45     ` stefan-lucks
@ 2011-07-18 13:24       ` stefan-lucks
  0 siblings, 0 replies; 10+ messages in thread
From: stefan-lucks @ 2011-07-18 13:24 UTC (permalink / raw)


On Mon, 18 Jul 2011, stefan-lucks@see-the.signature wrote:

> On Mon, 18 Jul 2011, AdaMagica wrote:
> 
> > So if you have three vectors, what should A * B * C mean? Even with
> > parentheses, it's awkward to read. 
> 
> I would always prefer to write such an expression with parenthesis. So 
> look at the expression (A * B) * C, where A, B, and C are vectors.  
>  -> A * B is either a matrix M or a number N. 
>  -> M * C would be a vector. 
>  -> N * C would also be a vector. 
>  ===> The result type is a vector. 
> 
> But wait a minute! There are two different results (either "M * C2 or "N * 
> C"), and we don't know which is the correct one. So the compiler should 
> reject this.

Sorry, I meant  (either "M * C or "N * C")!

-- 
------ Stefan Lucks   --  Bauhaus-University Weimar  --   Germany  ------
               Stefan dot Lucks at uni minus weimar dot de
------  I  love  the  taste  of  Cryptanalysis  in  the  morning!  ------




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

* Re: Incorrect error?
  2011-07-18  8:47 Incorrect error? ldries46
  2011-07-18  9:45 ` stefan-lucks
  2011-07-18 10:39 ` Nicholas Collin Paul de Glouceſter
@ 2011-07-18 15:58 ` Adam Beneschan
  2 siblings, 0 replies; 10+ messages in thread
From: Adam Beneschan @ 2011-07-18 15:58 UTC (permalink / raw)


On Jul 18, 1:47 am, "ldries46" <bertus.dr...@planet.nl> wrote:
> I'm using Ada.Numerics.Generic_Real_Arrays. While Compiling I got the
> following error message:
>
> 65:21     expected type "Ada.Numerics.Generic_Real_Arrays.Real_Vector" from
> instance at line 6
> 65:21     found type "Ada.Numerics.Generic_Real_Arrays.Real_Matrix" from
> instance at line 6
>
> As can be seen Cross, a and b declared as Real_Vector .
> What do I do wrong?

As others have said, you're trying to do something that isn't
defined.  There is no "*" operation in Generic_Real_Arrays that takes
two Real_Vector arguments and returns a Real_Vector.

However, I think the error message GNAT is reporting is wrong, and
this should be reported as a GNAT bug.  It's no wonder you were
confused.  If there were just one function like this:

   function Product (Left : Real_Vector; Right : Real_Matrix) return
Real_Vector;

and you tried

   Cross := Product (A, B);

GNAT would say "expected type Real_Matrix ... found type Real_Vector",
which is pretty clear.  Changing "Product" to "*" and using it as an
operator causes GNAT to generate a different message "there is no
applicable operator".  But in the actual package, there are eight
definitions of "*", and the error message GNAT produces doesn't make
sense for any of them, since it's implying that you're actually using
a Real_Matrix as a parameter, when of course you aren't.

                                        -- Adam





> L. Dries
>
> Code:
>
> package Float_Arrays is new Ada.Numerics.Generic_Real_Arrays (float);
> use Float_Arrays;
>
> function Volume (ObjID : integer; Obj : ptrS_Object) return float is
>    ok     : boolean;
>    n      : integer := 1;
>    Volume : float;
>    a      : Real_Vector(0 .. 2);
>    b      : Real_Vector(0 .. 2);
>    X0     : Real_Vector(0 .. 2);
>    X1     : Real_Vector(0 .. 2);
>    X2     : Real_Vector(0 .. 2);
>    cross  : Real_Vector(0 .. 2);
>    nA     : Real_Vector(0 .. 2);
>    p      : ptrNode_Object;
>    TempS  : ptrS_Object;
>    TempT  : ptrTriangle_Object;
> begin
>    TempS := Obj;
>    while n /= ObjID loop
>       n := n + 1;
>       TempS := TempS.next;
>       if TempS = null then
>          declare
>             NO_NODE_OBJECT : exception;
>          begin
>             raise NO_NODE_OBJECT;
>          end;
>       end if;
>    end loop;
>    n := TempS.PosFaces(0);
>    TempT := stT_Object;
>    ok := TempT = null;
>    while not ok loop
>       if TempT.nr = n then
>          ok := true;
>       else
>          TempT := TempT.next;
>          ok := TempT = null;
>       end if;
>    end loop;
>    while n < TempS.PosFaces(1) loop
>       p := GetPoint(TempT.P1);
>       X0(0) := p.pRectangular(x);
>       X0(1) := p.pRectangular(y);
>       X0(2) := p.pRectangular(z);
>       p := GetPoint(TempT.P2);
>       X1(0) := p.pRectangular(x);
>       X1(1) := p.pRectangular(y);
>       X1(2) := p.pRectangular(z);
>       p := GetPoint(TempT.P3);
>       X2(0) := p.pRectangular(x);
>       X2(1) := p.pRectangular(y);
>       X2(2) := p.pRectangular(z);
>       a := X1 - X0; -- VecSub( a, X1, X0 );
>       b := X2 - X0; -- VecSub( b, X2, X0 );
>      Cross := a * b; -- VecCross( a, b, Cross );
> <---------------- line 65 the cursor is standing just before *
>       nA := Cross * 0.5; -- VecMultScalar( nA, Cross, 0.5 );
>       -- Volume = Volume + fabs(VecDot( X0, nA ));
>       Volume := Volume + X0(0)*nA(0) + X0(1)*nA(1) + X0(2)*nA(2);
>       n := n + 1;
>    end loop;
>    Volume := Volume/3.0;
>    return Volume;
> end Volume;




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

end of thread, other threads:[~2011-07-18 15:58 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-18  8:47 Incorrect error? ldries46
2011-07-18  9:45 ` stefan-lucks
2011-07-18 10:10   ` Georg Bauhaus
2011-07-18 11:46     ` ldries46
2011-07-18 10:40   ` AdaMagica
2011-07-18 12:39     ` Dmitry A. Kazakov
2011-07-18 12:45     ` stefan-lucks
2011-07-18 13:24       ` stefan-lucks
2011-07-18 10:39 ` Nicholas Collin Paul de Glouceſter
2011-07-18 15:58 ` Adam Beneschan

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