Newsgroup: it.comp.lang.c
Titolo: Passare un array da c a fortran

Ciao.
Avrei il seguente problema.
Non essendo riuscito a trovare una libreria scritta in c in grado di
calcolare gli autovalori di una matrice complessa non simmetrica, sono
dovuto ricorrere alla libreira Lapack.
Esiste una clapack ma dalle prove fatte ho verificato che su macchine
a 64 bit non funzionano bene.
L'unica soluzione e' ricorrere alle LAPACK.
La prima domanda allora e' la piu' banale, per caso conoscete sw open
source in c in grado di calcolare autovalori ed autovettori di matrici
complesse non simmetrice?
Se la risposta alla prima domanda e' no ritorniamo al subject di
questa richiesta.
C e fortran immagazzinano gli array il primo per righe il secondo per
colonne.
Sarebbe possibile trovare un'allocazione in c (magari con qualche modo
furbo) in grado di consentirmi di utilizzare in c
gli indici in modo naturale a[i][j] = riga i e colonna j ma che in
fortran venga passata correttamente per colonne?
Spero di essere stato chiaro.
In ogni caso grazie


A prima vista sembra la classica richiesta da botte-piena/moglie-
ubriaca :-)
Al momento non mi vengono in mente soluzioni totalmente trasparenti (a
meno quindi di defines, funzioni o almeno un po' di computazione), ma
non ho mai lavorato sull'interazione fortan/C, per la quale mi
sembrerebbe strano non fosse mai stato affrontato il problema.. su
questa quindi passo :-)
Ciao!


GSL
C'e' qualcosa:
    * Real Symmetric Matrices
    * Complex Hermitian Matrices
    * Real Nonsymmetric Matrices
    * Real Generalized Symmetric-Definite Eigensystems
    * Complex Generalized Hermitian-Definite Eigensystems
    * Real Generalized Nonsymmetric Eigensystems
    * Sorting Eigenvalues and Eigenvectors
    * Eigenvalue and Eigenvector Examples
    * Eigenvalue and Eigenvector References
Ma non c'e' il caso generale di Matrice complessa non simmetrica...

 
In C se fai a[i][j] si **assume** che a sia un array di puntatori.
Questo **non è quello che vuoi**.
Devi allocare un array normale, avente dimensioni nrows*ncols, e poi 
scriverti le tue funzioni per accedere ai singoli elementi.
Ciao   Manlio

 complesse non simmetrice?
Forse CLAPACK non e' ottimizzato bene.  Potresti provare a usare le
librerie matematiche di Intel/AMD, a seconda di che processore hai.
Quelle sono molto ottimizzate e molto efficienti.  Ma non mi ricordo
che licenze hanno... mi ricordo che qualche anno fa avevo usato la
libreria di AMD per uso personale su linux, ed era gratuita.  Puoi
dare un'occhiata.
Pleg

 simmetrice?
su due piedi non ce l'ho e non posso controllare, ma
Numerical Recipes in C è un testo free in PDF dove c'è un
capitolo su autovalori e autovettori. Forse lì una routine
adatta o adattabile la potresti trovare.
-- 
Ci sono tre modi con cui gli industriali possono perdere
enormi capitali: le donne, il gioco e gli ingegneri.
Il primo è il più piacevole; il secondo è il più rapido;
il terzo è il più sicuro.

 complesse non simmetrice?
Ciao, non è complicato utilizzare le routines LAPACK, i punti chiave
sono che il Fortran usa il passaggio di parametri per riferimento (che
tradotto in C vuol dire passare puntatori alle variabili) e utilizza
l'ordine column-major per la memorizzazione di matrici:
http://seehuhn.de/pages/linear
http://seehuhn.de/pages/matrixfn
qui dell'altro materiale:
http://www.physics.orst.edu/~rubin/nacphy/lapack/cprogp.html
[questo è una specie di supplemento sulle differenze di storage in
memoria per gli array del FORTRAN e del C, ma le altre considerazioni
sono specifiche per le librerie Intel]:
http://software.intel.com/sites/products/documentation/hpc/composerxe/en-us/mklxe/mkl_userguide_lnx/MKL_UG_coding_calls/Calling_LAPACK_BLAS_and_CBLAS_Routines_from_C_Language.htm
Naturalmente sai che per il calcolo di autovalori e autovettori
puoi riccorrere a diversi metodi. Alcuni di questi passano attraverso
delle trasformazioni, per esempio le trasformazioni di Givens e
Householder per l'iterazione QR in forma base o in forma di Hessenberg.
In ogni caso ci sono funzioni nella libreria GSL che ti possono rendere
tutto piu facile:
http://www.gnu.org/software/gsl/manual/html_node/Linear-Algebra.html
Dai un'occhiata anche alle librerie ATLAS.
http://math-atlas.sourceforge.net/
-- 
Non puoi insegnare qualcosa ad un uomo. You cannot teach a man anything.
Lo puoi solo aiutare   --  Galileo  Galilei  --   You can only help him
a scoprirla dentro di sé.                        discover it in himself.
Vincenzo Mercuri

 Vincenzo Mercuri
Grazei a tutti.
In seintesi, riassumo cosa sono riuscito ad ottenere.
Sostanzialmente, prima si alloca un vettore unico in cui verra
memorizzata la matrice per colonne (quindi dimensione righexcolenne)
poi si alloca un puntatore doppio in cui verranno inseriti i puntatori
alle varie colonne, posizionandovi, rispettivamente, le locazioni di
memoria del vettore precedente corrispondente agli inizi delle
colonne.
Il tutto ha uno svantaggio, per indirizzare l'elemento posizionato
alla riga r ed alla colonna c, devo scrivere mat[c][r] (poco naturale
e possibile fonte di errori).
Un define  riallinea il tutto.
Di seguito l'esempio completo:
=======start c code =============
#include <stdio.h>
#include <stdlib.h>
#define  col  3
#define  row  4
#define MAT(i,j) mat[j][i]
main()
{
   int **mat;
   int i,j;
   int r=row,c=col;
   mat = (int **)malloc(col*sizeof(int*));
   mat[0] = (int *)malloc(row*col*sizeof(int));
   for(i=1; i<col; i++)
     mat[i] = mat[i-1]+row;
   MAT(0,0) = 1;  MAT(0,1) = 2; MAT(0,2) = 3;
   MAT(1,0) = 4;  MAT(1,1) = 5; MAT(1,2) = 6;
   MAT(2,0) = 7;  MAT(2,1) = 8; MAT(2,2) = 9;
   MAT(3,0) =10;  MAT(3,1) =11; MAT(3,2) =12;
   sub_(&r,&c,mat[0]);
   free(mat[0]);
   free(mat);
}
=========== stop c code =======
===== start fortran code=========
         subroutine sub(r,c,a)
         integer r,c
         integer a(r,c)
         write(*,1000)a(1,1),a(1,2),a(1,3)
         write(*,1000)a(2,1),a(2,2),a(2,3)
         write(*,1000)a(3,1),a(3,2),a(3,3)
         write(*,1000)a(4,1),a(4,2),a(4,3)
1000     format(4x,I2,3x,I2,3x,I2)
         return
         end
======stop fortran code
non era ESATTAMENTE quello che volevo fare ma a volte bisogna
accontentarsi