Syntax question regarding matrix definition 
Author Message
 Syntax question regarding matrix definition

Hi

 I am sure that I am missing something pretty simple in the code that
follows.

 While working with matrices, I defined the following type :

         type matrix
                        complex elem
                     end type matrix

 in a module that defines basic matrix operations. However, when I try to
define a constant (identity matrix) :

 type(matrix), dimension(2,2), parameter ::
eyematrix=reshape((/1.0_dpc,0.0_dpc,0.0_dpc,1.0_dpc/),(/2,2/))

[ Here : dpc = KIND((1.0D0,1.0D0)), NR style]

 I get the following compilation error with IFC :

 fortcom: Error: probvars.f90, line 7: The assignment operation or the
binary expression operation is invalid for the data types of the two
operands.

 Using cmplx(1.0,0.0) instead of 1.0_dpc does not change things.

 What am I missing ?

Thanks.



Sat, 25 Aug 2007 04:14:27 GMT  
 Syntax question regarding matrix definition
Hi

 I am sure that I am missing something pretty simple in the code that
follows.

 While working with matrices, I defined the following type :

         type matrix
                        complex elem
                     end type matrix

 in a module that defines basic matrix operations. However, when I try to
define a constant (identity matrix) :

 type(matrix), dimension(2,2), parameter ::
eyematrix=reshape(( / 1.0_dpc,0.0_dpc,0.0_dpc,1.0_dpc /),( / 2,2 / ))

(my newsreader might be missing some /'s above)

[ Here : dpc = KIND((1.0D0,1.0D0)), NR style]

 I get the following compilation error with IFC :

 fortcom: Error: probvars.f90, line 7: The assignment operation or the
binary expression operation is invalid for the data types of the two
operands.

 Using cmplx(1.0,0.0) instead of 1.0_dpc does not change things.

 What am I missing ?

Thanks.



Sat, 25 Aug 2007 04:32:41 GMT  
 Syntax question regarding matrix definition


Quote:
>          type matrix
>                         complex elem
>                      end type matrix
...
>  type(matrix), dimension(2,2), parameter ::
> eyematrix=reshape((/1.0_dpc,0.0_dpc,0.0_dpc,1.0_dpc/),(/2,2/))
...
>  fortcom: Error: probvars.f90, line 7: The assignment operation or the
> binary expression operation is invalid for the data types of the two
> operands.
...
>  What am I missing ?

Just look at the types of the things on both sides of the equals.  On
the left-hand side, you have an array of type matrix.  On the right-hand
size you have an array of type real (or complex in your other attempt).  
Type(matrix) is not the same thing as real or complex; nor is there an
intrinsic assignment for such a conversion.

What you are missing is that a derived type is a distinct type all of
its own.  It is not just the type of its components, even if it has only
a single component.  Your type(matrix) is a derived type with a complex
component; that is not the same thing as the whole thing being complex.

The most "obvious" way to fix this is, admitedly sort of verbose and
ugly.  Replace each instance of 1.0_dpc above with a derived type
constructor matrix(cmplx(1.0,0.0)) or something of the sort.

One might be tempted instead to introduce intermediate named constants
like

  type(matrix) :: one_element = matrix(cmplx(1.0,0.0))

--
Richard Maine                       |  Good judgment comes from experience;
email: my first.last at org.domain  |  experience comes from bad judgment.
org: nasa, domain: gov              |        -- Mark Twain



Sat, 25 Aug 2007 04:47:05 GMT  
 Syntax question regarding matrix definition
As usual, very helpful :)

Quote:

> Just look at the types of the things on both sides of the equals.  On
> the left-hand side, you have an array of type matrix.  On the right-hand
> size you have an array of type real (or complex in your other attempt).

I guess I overlooked the obvious.

Quote:
> Type(matrix) is not the same thing as real or complex; nor is there an
> intrinsic assignment for such a conversion.

Could I define one ?

I tried the following next (I want to exhaust other possibilities before I
resort to the verbose way you pointed out) :

(*)
        subroutine matrix_element_from_complex(X,z)
          complex, intent(in) :: z
          type(matrix), intent(out) :: X

          X%elem=z
        end subroutine matrix_element_from_complex

in the module that defines matrices as a module procedure in the interface
assignment(=).

Above, X%elem is definitely complex, as is z.
( type matrix
           complex elem
        end type matrix)

If I were to subsequently code,

type(matrix), dimension(2,2) :: eyematrix

and subsequently write

eyematrix(1,1)=1.0_dpc,

shouldn't the above work ?

eyematrix(1,1) is of type matrix, and 1.0_dpc is complex and the assignment
operator above (*) should take care of this, or no ?

The array assignment using reshape() is but a shorthand way of doing such
assignments. I tried the above, but it did not work for the code segment I
produced in my first post in the thread.



Sat, 25 Aug 2007 05:07:06 GMT  
 Syntax question regarding matrix definition

Quote:

>   [code to define such an assignment elided]

>> eyematrix(1,1)=1.0_dpc,

>> shouldn't the above work ?

> Yep.  Looks ok at least to my quick glance.  You might possibly want to
> declare it elemental for more flexibility (so it can apply to arrays
> like the one in your reshape example), but it looks ok as is.

Well, I tried to compile the following code :

        subroutine getkroneckerdelta(A)
            type(matrix), intent(out), dimension(:,:) :: A

            integer(i4b) :: n1,n2,i,j

            n1=size(A,1)
            n2=size(A,2)

            A(:,:)=0.0_dpc

            forall(i=1:n1,j=1:n2,i.eq.j)
               A(i,j)=1.0_dpc
            end forall

          end subroutine getkroneckerdelta

 as a work around for the intrinsic assignment. The compiler (IFC) complains
about this code segment :

fortcom: Error: mathematicalconstants.f90, line 31: The assignment operation
or the binary expression operation is invalid for the data types of the two
operands.   [0.0]
            A(:,:)=0.0_dpc
-------------------^
fortcom: Error: mathematicalconstants.f90, line 34: The assignment operation
or the binary expression operation is invalid for the data types of the two
operands.   [1.0]
               A(i,j)=1.0_dpc
----------------------^
compilation aborted for mathematicalconstants.f90 (code 1)

 even though I had defined the assignment as :

         elemental subroutine matrix_element_from_complex(X,z)
            complex, intent(in) :: z
            type(matrix), intent(out) :: X

            X%elem=z
                end subroutine matrix_element_from_complex

with

   interface assignment(=)
           module procedure
matrix_element_from_complex,complex_from_matrix_element,matrix_from_complex,&
                matrix_from_matrix
        end interface

 What could I be missing now ?



Sat, 25 Aug 2007 07:22:18 GMT  
 Syntax question regarding matrix definition

Quote:
>  What could I be missing now ?

Richard & I both told you.  In fortran:

C:\LF9556\James\clf\type_test>type type_test.f90
module mykinds
   implicit none
   integer, parameter :: sp = kind(1.0)
   integer, parameter :: dpc = kind((1.0d0,1.0d0))
end module mykinds

module generic
   use mykinds
   implicit none
   interface sub
      module procedure sub_sp, sub_dpc
   end interface sub
   contains
      subroutine sub_sp(x)
         complex(sp), intent(in) :: x

         write(*,*) 'You are right and I am wrong.'
      end subroutine sub_sp

      subroutine sub_dpc(x)
         real(dpc), intent(in) :: x

         write(*,*) 'I am right and you are wrong.'
      end subroutine sub_dpc
end module generic

program type_test
   use mykinds
   use generic
   implicit none

   call sub(1.0_dpc)
end program type_test

C:\LF9556\James\clf\type_test>lf95 -f95 type_test
[snip]

C:\LF9556\James\clf\type_test>type_test
I am right and you are wrong.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Sat, 25 Aug 2007 09:09:15 GMT  
 Syntax question regarding matrix definition

Quote:

> eyematrix(1,1) is of type matrix, and 1.0_dpc is complex and the assignment
> operator above (*) should take care of this, or no ?

No.  1.0_dpc is double-precision real.

To explain why: KIND(A) where A is real returns an integer that
describes what type of real number A is; KIND(A) where A is complex
returns an integer that describes what type of complex number A is.  The
returned integer does not, however, contain any information about
whether A is real or complex.

- Brooks

--
The "bmoses-nospam" address is valid; no unmunging needed.



Sat, 25 Aug 2007 09:44:18 GMT  
 Syntax question regarding matrix definition

Quote:

> Ok. So there is really no way to define constants involving derived data
> types from standard available types.

No. I would not say that was an accurate statement. Defining derived
type objects (including constants) is exactly what structure
constructors do.  So yes, you can define a derived-type constant from
intrinsic types.  See the example in my earlier post where I defined a
derived-type constant named one_element (I think that's what I called
it). The syntax for doing so can be a bit painful, but that doesn't
justify "is really no way".

--
Richard Maine
email: my last name at domain
domain: summertriangle dot net



Sat, 25 Aug 2007 10:21:24 GMT  
 Syntax question regarding matrix definition

Quote:

>             A(:,:)=0.0_dpc
....
>  even though I had defined the assignment as :

>          elemental subroutine matrix_element_from_complex(X,z)
>             complex, intent(in) :: z

Why does this surprise you? You define assignment for assigning a complex
to a type(matrix). Then you try to use it to assign a real to a type
matrix.  If you want to define an assignment from reals to type(matrix),
you can do that, but it won't happen automatically.

I can think of 2 reasons why you might expect this to work (but both
would be wrong.  :-().

1. Perhaps you think that since you have defined a complex to type(matrix)
   assignment, and the compiler intrinsically knows how to to real to complex,
   it will but those 2 together.  That won't happen.  (Life could get far
   more complicated if one expecvted the compiler to start automatically
   chaining things lik ethat).

2. Are you perhaps thinking that the _dpc makes the 0.0_dpc a complex?
   It does not.  As I mentioned before, dpc is the same as your dp.
   They are both just numbers.  It doesn't matter how you got the numbers;
   all that matters is the result value.  Depending on your compiler, dpc
   is probably either 2 or 8. It does *NOT* retain some special property
   of being a 2 or 8 that implies complex.  Complex kind numbers are not
   distinct from real ones.

--
Richard Maine
email: my last name at domain
domain: summertriangle dot net



Sat, 25 Aug 2007 10:32:11 GMT  
 Syntax question regarding matrix definition

Quote:


>>             A(:,:)=0.0_dpc
> ....
>>  even though I had defined the assignment as :

>>          elemental subroutine matrix_element_from_complex(X,z)
>>             complex, intent(in) :: z

> Why does this surprise you? You define assignment for assigning a complex
> to a type(matrix). Then you try to use it to assign a real to a type
> matrix.  If you want to define an assignment from reals to type(matrix),
> you can do that, but it won't happen automatically.

My bad. It was a result of bad programming practice. I have replaced it with
cmplx(0.0_dp,0.0_dp), and it works now as expected.

There are still places in my code where it does not work, but I am huntin
down the issues.

Quote:

> I can think of 2 reasons why you might expect this to work (but both
> would be wrong.  :-().

> 1. Perhaps you think that since you have defined a complex to type(matrix)
>    assignment, and the compiler intrinsically knows how to to real to
>    complex,
>    it will but those 2 together.  That won't happen.  (Life could get far
>    more complicated if one expecvted the compiler to start automatically
>    chaining things lik ethat).

That was not the reason. But your comments are very well put.

Quote:

> 2. Are you perhaps thinking that the _dpc makes the 0.0_dpc a complex?
>    It does not.  As I mentioned before, dpc is the same as your dp.

I was not thinking this per se, but it was a sort of reflexive coding
developed over many weeks of bad programming practice (motivated perhaps by
a too literal study of NR code, but I should know better).

This has been an object lesson to me to be a little more critical of code I
read, even if it is called NR :)



Sat, 25 Aug 2007 10:50:47 GMT  
 Syntax question regarding matrix definition

Quote:
> My bad. It was a result of bad programming practice. I have replaced it
with
> cmplx(0.0_dp,0.0_dp), and it works now as expected.

This works only because cmplx(0.0_dp,0.0_dp) is a default complex
expression.  If you wanted a complex(kind=dp) expression, you
would write cmplx(0.0_dp,0.0_dp,dp), or even cmplx(0,kind=dp).
Complex literals can acquire their kind type parameter from
one of their real components (if either are real) but the cmplx
intrinsic always returns a default complex value unless the KIND
optional argument is present with a value different from kind(1.0).

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Sat, 25 Aug 2007 12:09:48 GMT  
 Syntax question regarding matrix definition

Quote:



>>>             A(:,:)=0.0_dpc
>> ....
>>>  even though I had defined the assignment as :

>>>          elemental subroutine matrix_element_from_complex(X,z)
>>>             complex, intent(in) :: z

>> Why does this surprise you? You define assignment for assigning a complex
>> to a type(matrix). Then you try to use it to assign a real to a type
>> matrix.  If you want to define an assignment from reals to type(matrix),
>> you can do that, but it won't happen automatically.

> My bad. It was a result of bad programming practice. I have replaced it with
> cmplx(0.0_dp,0.0_dp), and it works now as expected.

It probably works because 0.0 is not different between single and
double precision.  What you would need in general is:

      cmplx(<literal>_dp, <literal>_dp, dp)

Because that third optional argument is easy to forget and can
yield invisible wrong answers if you forget it, I write my own
operator and get the thing to work much better:

   z = 0.1_dp +.i. 0.1_dp

The .i. operator is a unary (prefix) operator that's overloaded to
apply to either double or single precision, and either REAL or
COMPLEX.  The result is a COMPLEX of the same KIND as
the argument whose value is SQRT(-1.0) time the argument.
As of F95, it can even be used in initialization expressions.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies."   --  C. A. R. Hoare



Sat, 25 Aug 2007 12:04:00 GMT  
 Syntax question regarding matrix definition

Quote:
> As of F95, it can even be used in initialization expressions.

You must be handling it in a preprocessor of some sort if
it works for you in initialization expressions.  It can't
even work in specification expressions in f95 or f03:

"A restricted expression is an expression in which each operation
is intrinsic and ..."

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Sat, 25 Aug 2007 12:33:43 GMT  
 Syntax question regarding matrix definition

Quote:



>> As of F95, it can even be used in initialization expressions.

> You must be handling it in a preprocessor of some sort if
> it works for you in initialization expressions.  It can't
> even work in specification expressions in f95 or f03:

> "A restricted expression is an expression in which each operation
> is intrinsic and ..."

And.... Finish the quote:

   "... and each primary is
   [...]
   (9) A reference to a specification function where each argument is a
restricted expression,
   [...] "

A specification function can be any PURE function that is not intrinsic,
not an internal function, not a statement function, does not have a procedure
dummy argument, and is not recursive.

However, you are right, I was just looking at the wrong part of the
standard.  Initialization expressions can't reference (non-intrinsic)
functions of any kind. :-(

And yes, I do usually process that operator with a preprocessor.  I just
thought I was doing so unnecessarily.  :-(

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies."   --  C. A. R. Hoare



Sat, 25 Aug 2007 13:01:36 GMT  
 Syntax question regarding matrix definition

Quote:

> > You must be handling it in a preprocessor of some sort if
> > it works for you in initialization expressions.  It can't
> > even work in specification expressions in f95 or f03:
> > "A restricted expression is an expression in which each operation
> > is intrinsic and ..."
> And.... Finish the quote:
>    "... and each primary is
>    [...]
>    (9) A reference to a specification function where each argument is a
> restricted expression,
>    [...] "
> A specification function can be any PURE function that is not intrinsic,
> not an internal function, not a statement function, does not have a
procedure
> dummy argument, and is not recursive.

It doesn not matter that the underlying function is a specification
function, only that it is being invoked through a non-intrinsic
operation.

Quote:
> However, you are right, I was just looking at the wrong part of the
> standard.  Initialization expressions can't reference (non-intrinsic)
> functions of any kind. :-(

Even in the wrong part of the standard I am right, and that was my
point!  An expression like 12.0 + .i. 5.0 contains a defined
operation.  I can't seem to make anybody understand me lately -- is
my English backwards dubbed or something?  In Fortran:

module defined
   implicit none
   interface operator(.i.)
      module procedure eye
   end interface operator(.i.)
   contains
      pure function eye(x)
         integer, intent(in) :: x
         integer eye

         eye = 2*x
      end function eye
end module defined

module spec
   use defined
   implicit none
   contains
      function specs(x)
         character(*), intent(in) :: x
         integer specs(3 + .i. len(x))
         integer j

         specs = (/(j,j=1,size(specs))/)
      end function specs
end module spec

program test
   use defined
   use spec
   implicit none

   write(*,*) specs('This')
end program test

C:\LF9556\James\clf\defined_spec>lf95 -f95 defined_spec
[snip]

Compiling file defined_spec.f90.
Compiling program unit defined at line 1:
Compiling program unit spec at line 14:
 Module subprogram name(specs)
  2009-S: "defined_spec.f90", line 21: Invalid array specifier, type
parameter v
alue or character length specified for specs.
Compiling program unit test at line 27:
  1370-S: "defined_spec.f90", line 30: Module spec is not available.
  2018-S: "defined_spec.f90", line 33: When IMPLICIT NONE is specified,
specs mu
st be declared in a type declaration statement.
Encountered 3 errors, 0 warnings in file defined_spec.f90.

Quote:
> And yes, I do usually process that operator with a preprocessor.  I just
> thought I was doing so unnecessarily.  :-(

Necessary even for specification expressions as shown above.
LF95 rejects this and if a compiler can't warn about this
nonconformance a bug report is in order.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Sat, 25 Aug 2007 14:48:36 GMT  
 
 [ 17 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Beginner question regarding multiple definitions for 1 register.

2. Two questions regarding J's syntax and semantics

3. regarding matrix inversion using complex numbers

4. Suggested modifications to syntax definition in OOSC

5. Current language definition (Algebraic syntax)

6. pl1 syntax definition

7. Syntax - Definition for C modules

8. Seeking extend-syntax definition for record-case construct

9. Syntax definition in conditional

10. where can I find abstract syntax definition of Fortran

11. Does Prolog have an unambiguous syntax definition?

12. Local definitions without excessive syntax ?

 

 
Powered by phpBB® Forum Software