Home > Archive > Fortran > April 2006 > passing only the real parts of a complex array to a function
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
passing only the real parts of a complex array to a function
|
|
| Kamaraju Kusumanchi 2006-04-26, 7:04 pm |
| I want to solve Ax=B where A is a real matrix. But x and B are complex
numbers. I am using IMSL libraries to do LU decomposition and then solve
the resulting system. In IMSL, the LU decomposition is done by 'dlfcrg'
and the backward substitution is done by 'dlfirg'. dlfirg needs x and B
to be real. But in my case x and B are complex. So I thought I would
call dlfirg two times - once by passing {real(x), real(B)} and then
passing {aimag(x), aimag(B)} in the second call. But this method is not
working. Any other ideas?
In my program, x and B are declared as complex arrays. These arrays are
very large so if possible I do not want to make multiple copies of them.
I have also written small sample program to explain my problem better.
Any suggestions are most welcome.
program complex_array
! increment function works on arrays declared as real. But
! does not work on real(complex array) and aimag(complex array)
implicit none
integer, parameter :: DP = kind(1.0D0)
integer, parameter :: DPC = kind((1.0D0, 1.0D0))
real(DP) :: a(3)
complex(DPC) :: b(3)
a(1) = 1.0_DP
a(2) = 2.0_DP
a(3) = 3.0_DP
write(*,*) a; write(*,*)
call increment(a)
write(*,*) a; write(*,*)
b(1) = (5.0_DP, 6.0_DP)
b(2) = (7.0_DP, 8.0_DP)
b(3) = (9.0_DP, 10.0_DP)
write(*,*) b
write(*,*) real(b, DP)
write(*,*) aimag(b); write(*,*)
call increment(real(b, DP))
write(*,*) b
write(*,*) real(b, DP)
write(*,*) aimag(b); write(*,*)
call increment(aimag(b))
write(*,*) b
write(*,*) real(b, DP)
write(*,*) aimag(b); write(*,*)
contains
subroutine increment(p)
implicit none
real(DP) :: p(3)
p(:) = p(:) + 1.0_DP
end subroutine increment
end program complex_array
regards
raju
--
http://kamaraju.googlepages.com/cornell-bazaar
http://groups.google.com/group/cornell-bazaar/about
| |
| glen herrmannsfeldt 2006-04-26, 7:04 pm |
| Kamaraju Kusumanchi <kk288@cornell.edu> wrote:
(snip)
> call increment(real(b, DP))
(snip)
> subroutine increment(p)
> implicit none
> real(DP) :: p(3)
> p(:) = p(:) + 1.0_DP
> end subroutine increment
When a subroutine is called with an expression instead
of a variable (scalar or array) the called routine can't
change the argument, and even if it was allowed, that wouldn't
change the components of the expression.
Even PL/I pseudo-variables won't do this, though you
can do some other interesting things with IMAG() in PL/I, one
of my favorite being a DO variable:
X=0;
DO imag(x)=1 TO 100;
PUT SKIP LIST(X,SQRT(X));
END;
in PL/I will print a table of square roots of imaginary
numbers, but it won't work as a subroutine argument.
(At least I don't think it will.)
Use a temporary array, assign the values to it, pass that
array, and then get the returned values out.
-- glen
| |
| Michael Metcalf 2006-04-26, 7:04 pm |
|
"Kamaraju Kusumanchi" <kk288@cornell.edu> wrote in message
news:e2odu9$51r$1@ruby.cit.cornell.edu...
> subroutine increment(p)
> implicit none
real(DP), intent(inout) :: p(3) <----------------------
> p(:) = p(:) + 1.0_DP
> end subroutine increment
> end program complex_array
This sample program is missing the intent attribute for p. When added, it
doesn't compile. This is because you're passing an expression to increment,
not a variable. Perhaps the only way out is to cheat by using equivalence of
temp(2,3) to b, and pass temp(1,:) and temp(2,:)?
Regards,
Mike Metcalf
|
|
|
|
|