[C] mathSuite v5.70 - Progetto di Analisi e Calcolo Numerico
Salve ragazzi, non ho trovato una sezione più apposita di questa per postare un mio progetto; in caso non lo fosse, prego mod e admin di scusarmi in quanto sono nuovo nel forum.
Vorrei mostrarvi un mio progetto, che ormai mando avanti da più di un anno, riguardante un Ambiente di Analisi e Calcolo Numerico, mathSuite.
La pagina principale del progetto è:
mathSuite PROJECT Official Page
Riporto una descrizione sommaria in italiano:
In futuro verrà ulteriormente espanso, e magari troverò delle basilari API OpenSource per quanto riguarda il Calcolo Simbolico ed introdurre inoltre un sistema molto più avanzato di Integrazione delle Funzioni basato su Espansioni in Serie, e Plotting 3D avanzato con OpenGL o qualche altra libreria (tipo GSL) magari, ma per ora la priorità è effettuare un porting in ambiente mobile (mathSMART).
Il progetto è completamente open-source. Se qualcuno è interessato a saperne di più posti tranquillamente qui o mi contatti in PVT
Regards, Wesker.
[size=150]mathSuite - Powerful Calculus Environment and Matrices Handling Engine[/size]
Vorrei mostrarvi un mio progetto, che ormai mando avanti da più di un anno, riguardante un Ambiente di Analisi e Calcolo Numerico, mathSuite.
La pagina principale del progetto è:
mathSuite PROJECT Official Page
Riporto una descrizione sommaria in italiano:
mathSuite è una potente suite di calcolo completa scritta interamente in C che permette principalmente di effettuare complessi calcoli e manipolare i valori tramite variabili e di tenere traccia delle operazioni tramite dei logs. Racchiunde un set di funzioni tali da coprire calcoli trigonometrici, statistici, euristici, geometrici, algebrici e tanto altro...
Particolare sforzo alla realizzazione del programma è stato concentrato sul sistema di Gestione delle Matrici.
Le Matrici sono gli elementi principali per questo programma, di conseguenza numerose operazioni di Algebra Lineare sono state dedicate a questo tipo fondamentale. Esempi di queste operazioni sono:
- Fattorizzazione LU;
- Decomposizione in Valori Singolari (SVD);
- Prodotto e Somma tra Matrici;
- Prodotto di Kronecker tra Matrici;
- Calcolo del Determinante;
- Calcolo del Rango;
- Controllo Indice di Condizionamento;
- Tanto altro ancora...
Non mancano delle chicche a carattere generale, generalmente risiedenti nel programma Calcolatore Avanzato come:
- Operazioni tra numeri complessi;
- Risolutore di Sistemi Lineari;
- Integratore di Funzioni pre-caricate;
- Fit Equazioni Rette;
- Fit Equazioni Curve Paraboliche.
E' anche possibile, dalle ultime versioni, operare in Algebre Diverse da quella dei Numeri Reali. E' per esempio perfettamente possibile eseguire un prodotto di Kronecker tra due Matrici Sedenioniche (i cui elementi sono sedenioni!!), a patto che ovviamente si inseriscano sedici matrici, ognuna contenente i coefficienti delle parti immaginarie via via.
Inoltre, il programma accetta senza problemi in ingresso (nella Riga di Comando) dei comandi, che a loro volta accettano determinati parametri. Questa feature permette l'esecuzione in sequenza di più comandi del programma, configurandosi come un vero e proprio linguaggio di scripting, se utilizzato nella maniera giusta.
Download link: https://sourceforge.net/projects/mathsuite/files/latest/download
Pagina Facebook: https://www.facebook.com/mathsuite
Altri link utili:
https://code.google.com/p/mathsuite/
https://github.com/DekraN/mathSuite
Compatibilità: Windows 2000+. (Su ambienti Unix-like è necessario ricompilarlo, i sorgenti sono completamente aperti).
- NON richiede installazione, soltanto la copia della cartella mathSuite sul Desktop o qualsiasi altra cartella.
In futuro verrà ulteriormente espanso, e magari troverò delle basilari API OpenSource per quanto riguarda il Calcolo Simbolico ed introdurre inoltre un sistema molto più avanzato di Integrazione delle Funzioni basato su Espansioni in Serie, e Plotting 3D avanzato con OpenGL o qualche altra libreria (tipo GSL) magari, ma per ora la priorità è effettuare un porting in ambiente mobile (mathSMART).
Il progetto è completamente open-source. Se qualcuno è interessato a saperne di più posti tranquillamente qui o mi contatti in PVT

Regards, Wesker.
Risposte
Sono curioso, cercando velocemente non l'ho trovato (sul sito). Come hai definito il tipo matrice?
"vict85":
Sono curioso, cercando velocemente non l'ho trovato (sul sito). Come hai definito il tipo matrice?
Di norma è una doppia referenza di tipo base "ityp" (dunque ityp **). ityp è definito di default come double, anche se in futuro conto di aumentare la precisione in virgola mobile.
Perché non una singola referenza come fanno in lapack e similari?
Puramente per motivi temporali, di velocità di scrittura del codice e di leggibilità. Non so sinceramente se questo influisca sulla velocità, ma a me è parso più comodo utilizzare questo sistema anziché operare direttamente con l'aritmetica dei puntatori
In realtà scrivere come dici tu è più complesso in definitiva: è vero che l'accesso agli elementi è più complesso da scrivere (in C, in C++ il problema viene risolto con dell'overload di operatori) ma la gestione della memoria lo è meno. E ci si abitua presto. Insomma le cose si compensano. Inoltre è probabilmente più lento il tuo metodo. Tieni conto che se passi un array multidimensionale a[n][m] statico a una funzione questo viene visto come un puntatore e non un puntatore di puntatori.
Purtroppo non posso farlo andare sul mio pc (ho linux), ma leggendo il codice mi piace come progetto.
E' simile a quello che volevo fare di tesi, anche se il mio progetto sarà posto ad un livello più basso (incentrato sullo studio di lexer e parser da usare per il calcolo simbolico).
Ti consiglio se riesci di rendere il programma più portabile per farlo compilare su altri sistemi. L'input e l'output con Latex non sarebbe male
E' simile a quello che volevo fare di tesi, anche se il mio progetto sarà posto ad un livello più basso (incentrato sullo studio di lexer e parser da usare per il calcolo simbolico).
Ti consiglio se riesci di rendere il programma più portabile per farlo compilare su altri sistemi. L'input e l'output con Latex non sarebbe male

"vict85":
In realtà scrivere come dici tu è più complesso in definitiva: è vero che l'accesso agli elementi è più complesso da scrivere (in C, in C++ il problema viene risolto con dell'overload di operatori) ma la gestione della memoria lo è meno. E ci si abitua presto. Insomma le cose si compensano. Inoltre è probabilmente più lento il tuo metodo. Tieni conto che se passi un array multidimensionale a[n][m] statico a una funzione questo viene visto come un puntatore e non un puntatore di puntatori.
Beh una volta scritte le API sulla gestione della memoria relativa alle matrici, che sarebbero semplicemente due funzioni, questa non è più un problema.
Sì, molto probabilmente hai ragione sulla velocità, in quanto renderebbe la memoria del programma meno segmentata credo ed è comunque sempre un livello di referenza in meno.
Grazie mille per il consiglio comunque, mi hai orientato verso una parziale ristrutturazione dei metodi di accesso alle matrici.
@sapo: Ti ringrazio, in effetti una volta che il motore di calcolo è completato ci si può sbizzarrire come vuole, il peggio è passato

Scusate il doppio post, ma volevo ringraziare mille volte vict85 per il suo prezioso consiglio.
Ho riscritto completamente il codice del programma, il che non è stata una passeggiata ma ne è valsa veramente la pena. Oltre ad una sensibile diminuzione dell'eseguibile, di circa il 4.1%, probabilmente relativo alla memorizzazione dei metadati dei blocchi di memoria aggiuntivi che allocavo, la velocità di elaborazione delle matrici, complice anche la qualificazione "restrict" che ho applicato a molti argomenti delle funzioni che le trattano, è aumentata notevolmente.
https://sourceforge.net/projects/mathsuite/
Ho riscritto completamente il codice del programma, il che non è stata una passeggiata ma ne è valsa veramente la pena. Oltre ad una sensibile diminuzione dell'eseguibile, di circa il 4.1%, probabilmente relativo alla memorizzazione dei metadati dei blocchi di memoria aggiuntivi che allocavo, la velocità di elaborazione delle matrici, complice anche la qualificazione "restrict" che ho applicato a molti argomenti delle funzioni che le trattano, è aumentata notevolmente.
https://sourceforge.net/projects/mathsuite/
Prego.
Una cosa, che non so se hai fatto e che può migliorare le prestazione, è usare il ciclo corretto. È una cosa che si trova su qualsiasi libro di programmazione parallela quindi forse l'hai fatto. Ma lo scrivo perché magari a qualcuno interessa. Molti algoritmi BLAS3, come per esempio il prodotto matriciale o la decomposizione LU, si basano su un ciclo comunemente segnato come ijk. Nel caso del prodotto matriciale si ha
D'altra parte ci sono 6 possibili modi di permutare i coefficienti che producono lo stesso risultato. Si noti che ijk è un prodotto riga per colonna. Quindi legge A per righe (C-style), B per colonne (Fortran-Style) e C per righe. Quello che è necessario per migliorare le performance è leggere tutto per righe (o per colonne se hai scritto le matrici alla Fortran).
Il ciclo che lo fa è, se non ricordo male, il seguente:
Questo metodo è ulteriormente migliorabile, ma usare il ciclo sbagliato può peggiorare le performance sensibilmente. Non sono comunque un esperto e le mie conoscenze non vanno troppo più in là.
Una cosa, che non so se hai fatto e che può migliorare le prestazione, è usare il ciclo corretto. È una cosa che si trova su qualsiasi libro di programmazione parallela quindi forse l'hai fatto. Ma lo scrivo perché magari a qualcuno interessa. Molti algoritmi BLAS3, come per esempio il prodotto matriciale o la decomposizione LU, si basano su un ciclo comunemente segnato come ijk. Nel caso del prodotto matriciale si ha
for(i=0; i != A_row; ++i) for(j=0; j != B_col; ++j) { c[i][j] = 0 for(k=0; k != A_col; ++k) C[i][j] += A[i][k] * B[k][j]; }
D'altra parte ci sono 6 possibili modi di permutare i coefficienti che producono lo stesso risultato. Si noti che ijk è un prodotto riga per colonna. Quindi legge A per righe (C-style), B per colonne (Fortran-Style) e C per righe. Quello che è necessario per migliorare le performance è leggere tutto per righe (o per colonne se hai scritto le matrici alla Fortran).
Il ciclo che lo fa è, se non ricordo male, il seguente:
for(i=0; i != A_row; ++i) for(j=0; j != B_col; ++j) c[i][j] = 0; for(i=0; i != A_row; ++i) for(k=0; k != A_col; ++k) for(j=0; j != B_col; ++j) C[i][j] += A[i][k] * B[k][j];
Questo metodo è ulteriormente migliorabile, ma usare il ciclo sbagliato può peggiorare le performance sensibilmente. Non sono comunque un esperto e le mie conoscenze non vanno troppo più in là.
A dire la verità non ci avevo pensato di eseguire il prodotto ikj anziché ijk. Ricordavo comunque di averlo appreso da qualche parte, sebbene non lo abbia mai implementato, anche se curiosamente qualche meta-funzione del prodotto tra matrici che ho scritto, aveva già i due cicli for invertiti. Ad ogni modo ho già uppato il codice ulteriormente ottimizzato, il prossimo passo è la compilazione under Linux.
Ti ringrazio ancora.
Ti ringrazio ancora.
Scusate ancora il doppio post.
Se a qualcuno interessa, ho effettuato correttamente il porting del progetto su Linux.
Sulla pagina di SourceForge: https://sourceforge.net/projects/mathsuite/
ho uppato l'archivio che contiene sia la versione Win32 che quella Linux, ove al suo interno vi è i medesimi sorgenti e l'eseguibile già compilato su tale ambiente.
Se a qualcuno interessa, ho effettuato correttamente il porting del progetto su Linux.
Sulla pagina di SourceForge: https://sourceforge.net/projects/mathsuite/
ho uppato l'archivio che contiene sia la versione Win32 che quella Linux, ove al suo interno vi è i medesimi sorgenti e l'eseguibile già compilato su tale ambiente.
ciao, ho incontrato qualche problemino nella compilazione e uso su linux:
$1)$ il makefile cerca di piazzare i file .o in obj/Release, ma questa cartella non è già presente in src.
Ti consiglio di aggiungere al makefile un pezzettino di codice che controlla l'esistenza della cartella e la crea in caso contrario (usando il comando mkdir -p nomecartella").
$2)$ Dovresti assicurarti che la libreria libxml2 sia già installata. Per fare questo puoi usare un file configure (http://en.wikipedia.org/wiki/Configure_script).
$3)$ La compilazione mette il file binario creato nella cartella src invece che in mathSuite, rendendolo ineseguibile (non trova autorun.lf).
$4)$ Inserendo l'operazione richiesta (qualunque), il programma dopo il calcolo torna subito al menu senza mostrare il risultato (magari è uno sleep con tempo sbagliato o un loop staller configurato male).
Basta semplicemente che l'utente torni su nel terminale per vedere il risultato, ma se il tuo sistema operativo va direttamente con la shell (cosa improbabile ma non impossibile), effettivamente non puoi vedere il risultato.
Inoltre dovresti dedicare secondo me un (bel) pò di tempo a creare un'interfaccia grafica per il programma, di modo da renderne più semplice l'uso.
p.s. invece che scrivere lunghe righe di makefile, tipo
usa i separatori di linea
che rendono il codice molto più leggibile, debuggabile ed ampliabile
$1)$ il makefile cerca di piazzare i file .o in obj/Release, ma questa cartella non è già presente in src.
Ti consiglio di aggiungere al makefile un pezzettino di codice che controlla l'esistenza della cartella e la crea in caso contrario (usando il comando mkdir -p nomecartella").
$2)$ Dovresti assicurarti che la libreria libxml2 sia già installata. Per fare questo puoi usare un file configure (http://en.wikipedia.org/wiki/Configure_script).
$3)$ La compilazione mette il file binario creato nella cartella src invece che in mathSuite, rendendolo ineseguibile (non trova autorun.lf).
$4)$ Inserendo l'operazione richiesta (qualunque), il programma dopo il calcolo torna subito al menu senza mostrare il risultato (magari è uno sleep con tempo sbagliato o un loop staller configurato male).
Basta semplicemente che l'utente torni su nel terminale per vedere il risultato, ma se il tuo sistema operativo va direttamente con la shell (cosa improbabile ma non impossibile), effettivamente non puoi vedere il risultato.
Inoltre dovresti dedicare secondo me un (bel) pò di tempo a creare un'interfaccia grafica per il programma, di modo da renderne più semplice l'uso.
p.s. invece che scrivere lunghe righe di makefile, tipo
OBJ = obj/Release/main.o obj/Release/adv_calc.o obj/Release/algebra.o obj/Release/cols_manager.o obj/Release/envs_manager.o ... etc etc
usa i separatori di linea
OBJ = obj/Release/main.o \ obj/Release/adv_calc.o \ obj/Release/algebra.o \ obj/Release/cols_manager.o \ obj/Release/envs_manager.o \ obj/Release/ext_math.o \ obj/Release/geometry.o \ obj/Release/layouts_manager.o \ obj/Release/lists_manager.o \ obj/Release/logs_manager.o \ obj/Release/mat_manager.o \ obj/Release/mss_manager.o \ obj/Release/lf_manager.o \ obj/Release/programs.o \ obj/Release/settings.o \ obj/Release/syslog_manager.o \ obj/Release/expreval.o \ obj/Release/exprfunc.o \ obj/Release/exprinit.o \ obj/Release/exprmem.o \ obj/Release/exprobj.o \ obj/Release/exprpars.o \ obj/Release/exprutil.o \ obj/Release/exprval.o
che rendono il codice molto più leggibile, debuggabile ed ampliabile
"sapo93":
ciao, ho incontrato qualche problemino nella compilazione e uso su linux:
$1)$ il makefile cerca di piazzare i file .o in obj/Release, ma questa cartella non è già presente in src.
Ti consiglio di aggiungere al makefile un pezzettino di codice che controlla l'esistenza della cartella e la crea in caso contrario (usando il comando mkdir -p nomecartella").
$2)$ Dovresti assicurarti che la libreria libxml2 sia già installata. Per fare questo puoi usare un file configure (http://en.wikipedia.org/wiki/Configure_script).
$3)$ La compilazione mette il file binario creato nella cartella src invece che in mathSuite, rendendolo ineseguibile (non trova autorun.lf).
$4)$ Inserendo l'operazione richiesta (qualunque), il programma dopo il calcolo torna subito al menu senza mostrare il risultato (magari è uno sleep con tempo sbagliato o un loop staller configurato male).
Basta semplicemente che l'utente torni su nel terminale per vedere il risultato, ma se il tuo sistema operativo va direttamente con la shell (cosa improbabile ma non impossibile), effettivamente non puoi vedere il risultato.
Inoltre dovresti dedicare secondo me un (bel) pò di tempo a creare un'interfaccia grafica per il programma, di modo da renderne più semplice l'uso.
p.s. invece che scrivere lunghe righe di makefile, tipo
OBJ = obj/Release/main.o obj/Release/adv_calc.o obj/Release/algebra.o obj/Release/cols_manager.o obj/Release/envs_manager.o ... etc etc
usa i separatori di linea
OBJ = obj/Release/main.o \ obj/Release/adv_calc.o \ obj/Release/algebra.o \ obj/Release/cols_manager.o \ obj/Release/envs_manager.o \ obj/Release/ext_math.o \ obj/Release/geometry.o \ obj/Release/layouts_manager.o \ obj/Release/lists_manager.o \ obj/Release/logs_manager.o \ obj/Release/mat_manager.o \ obj/Release/mss_manager.o \ obj/Release/lf_manager.o \ obj/Release/programs.o \ obj/Release/settings.o \ obj/Release/syslog_manager.o \ obj/Release/expreval.o \ obj/Release/exprfunc.o \ obj/Release/exprinit.o \ obj/Release/exprmem.o \ obj/Release/exprobj.o \ obj/Release/exprpars.o \ obj/Release/exprutil.o \ obj/Release/exprval.o
che rendono il codice molto più leggibile, debuggabile ed ampliabile
Ti ringrazio dei preziosi consigli.
Per quanto riguarda il punto 4, semplicemente l'opzione booleana del programma "Request Programs Repetitions" era disattiva. Ma può tranquillamente essere riattivata tramite l'apposita sezione del programma. Ad ogni modo ho prontamente uppato una versione del setting.xml dove di default è attiva.
Per quanto riguarda il makefile, purtroppo sono nuovo in ambiente GCC Linux, ci saranno sicuramente innumerevoli altre possibilità che sfrutterò con una prossima release.