2011-03-20 8 views
6

Quiero ser capaz de tener una gran matriz maestra y referirme a diferentes partes de la misma usando sub arrays. En este momento estoy usando índices de compensación para hacer esto, pero puede ser muy complicado hacerlo de esta manera.¿Puedo crear matrices secundarias en Fortran usando punteros?

¿Puedo tener una matriz maestra de dimensión (9) y 3 matrices secundarias de dimensión (3) de modo que sub_array1 apunte a los primeros 3 elementos de la matriz maestra, sub_array2 señale a los 3 elementos siguientes y sub_array3 señale a la últimos 3 elementos?

Por ejemplo, las matrices se definiría como tan:

integer, dimension(9) :: master_array 
integer, dimension(3) :: sub_array1, sub_array2, sub_array3 

La relación entre las matrices sería:

sub_array1(1) -> master_array(1) 
sub_array1(2) -> master_array(2) 
sub_array1(3) -> master_array(3) 

sub_array2(1) -> master_array(4) 
sub_array2(2) -> master_array(5) 
sub_array2(3) -> master_array(6) 

sub_array3(1) -> master_array(7) 
sub_array3(2) -> master_array(8) 
sub_array3(3) -> master_array(9) 

Además, es posible tener tipos de datos mezclados de modo que tenga una matriz secundaria de reales dentro de una matriz maestra más grande de enteros?

Gracias de antemano por la ayuda

Respuesta

11

sí, se puede utilizar absolutamente utilizan punteros para apuntar a las subregiones de una matriz. Esto puede ser muy útil en muchas situaciones, como para los cálculos de la plantilla para PDE:

program pointerviews 
    real, dimension(10), target :: alldata 
    real, dimension(:), pointer :: left 
    real, dimension(:), pointer :: centre 
    real, dimension(:), pointer :: right 

    alldata = (/ (i, i=1,10) /) 

    left => alldata(1:8) 
    right => alldata(3:10) 
    centre=> alldata(2:9) 


    print *, alldata 
    print *, left 
    print *, centre 
    print *, right 
    print *, (left - 2*centre + right) 
end program pointerviews 

punteros de matriz en FORTRAN son más que sólo una dirección, que contienen tamaño de la matriz, la zancada, y el tipo de información, también. Por lo que puede hacer las cosas aún más loco como esto (si estás acostumbrado a los punteros C) e incluyen pasos:

program pointerviews2 
    real, dimension(10), target :: alldata 
    real, dimension(:), pointer :: left 
    real, dimension(:), pointer :: centre 
    real, dimension(:), pointer :: right 

    alldata = (/ (i, i=1,10) /) 

    left => alldata(1:8:2) 
    right => alldata(3:10:2) 
    centre=> alldata(2:9:2) 

    print *, alldata 
    print *, left 
    print *, centre 
    print *, right 

    print *, 'Changing alldata(4) = 9999' 
    alldata(4) = 9999. 

    print *, alldata 
    print *, left 
    print *, centre 
    print *, right 

end program pointerviews2 

Usted pueden no, sin embargo, tienen regiones de una matriz que son de un tipo diferente de la resto de los datos, por definición. Tendrá que usar tipos derivados, o polimorfismo, si desea una variable que contenga datos de varios tipos.

+0

Gracias, esto es exactamente lo que estaba buscando. Estaba vagando si sabías algo sobre la programación de GPU y CUDA? Estoy tratando de hacer lo mismo para las matrices de memoria compartidas en CUDA, pero no parece posible ya que los atributos 'puntero' y 'objetivo' entran en conflicto con el atributo 'compartido' – Eddy

+0

Los punteros a la memoria compartida son un poco extraño incluso en CUDA C (aunque está bien en OpenCL); No tengo idea de cómo es el apoyo para ellos con pg fortran ... –

Cuestiones relacionadas