Questo è il comando funcalc che può essere eseguito nel provider di hosting gratuito OnWorks utilizzando una delle nostre numerose workstation online gratuite come Ubuntu Online, Fedora Online, l'emulatore online di Windows o l'emulatore online di MAC OS
PROGRAMMA:
NOME
funcalc - Calcolatrice Funtools (per tabelle binarie)
SINOSSI
calcolo funzionale [-n] [-a argstr] [-e expr] [-f file] [-l collegamento] [-p prog] [oname [colonne]]
VERSIONI
-a argstr # argomenti utente da passare al programma compilato
-e expr # espressione funcalc
-f file # file contenente l'espressione funcalc
-l libs # librerie da aggiungere al comando link
-n # restituisce il codice generato invece di compilarlo ed eseguirlo
-p prog # genera il programma denominato, nessuna esecuzione
-u # muore se una variabile non è dichiarata (non dichiarare automaticamente)
DESCRIZIONE
calcolo funzionale è un programma di calcolo che consente di costruire espressioni arbitrarie,
compilato ed eseguito su colonne in una tabella Funtools (tabella binaria FITS o evento raw
file). Funziona integrando le espressioni fornite dall'utente in un programma C modello, quindi
compilazione ed esecuzione del programma. calcolo funzionale le espressioni sono istruzioni C, sebbene alcune
sono supportate importanti semplificazioni (come la dichiarazione automatica delle variabili).
calcolo funzionale le espressioni possono essere specificate in tre modi: sulla riga di comando utilizzando -e
[espressione] switch, in un file utilizzando il -f [file] switch, o da stdin (se nessuno dei due -e
né -f è specificato). Naturalmente un file contenente calcolo funzionale le espressioni possono essere lette da
standard.
Ogni invocazione di calcolo funzionale richiede che un file di tabella Funtools di input venga specificato come
primo argomento della riga di comando. Il file di tabella Funtools di output è il secondo argomento facoltativo
argomento. È necessario solo se si sta creando un file FITS di output (ad esempio, nei casi in cui
, il calcolo funzionale espressione stampa solo valori, non è necessario alcun file di output). Se input e output
file sono entrambi specificati, un terzo argomento facoltativo può specificare l'elenco delle colonne da
attivare (utilizzando FunColumnActivate()). Nota che calcolo funzionale determina se farlo o meno
generare codice per scrivere un file di output in base alla presenza o assenza di un output
argomento file.
A calcolo funzionale l'espressione viene eseguita su ogni riga di una tabella ed è composta da uno o più C
istruzioni che operano sulle colonne di quella riga (eventualmente utilizzando variabili temporanee).
All'interno di un'espressione si fa riferimento a una colonna del corrente riga utilizzando la struttura C
sintassi corrente[nomecolonna]>, ad esempio cur->x, cur->pha, ecc. È possibile definire variabili scalari locali
utilizzando le dichiarazioni C all'inizio dell'espressione, oppure possono essere definite
automaticamente da calcolo funzionale (essere di tipo double). Quindi, ad esempio, uno scambio di colonne x
e y in una tabella può essere eseguito utilizzando uno dei seguenti equivalenti calcolo funzionale
espressioni:
doppia temperatura;
temp = cur->x;
cur->x = cur->y;
cur->y = temp;
o:
temp = cur->x;
cur->x = cur->y;
cur->y = temp;
Quando questa espressione viene eseguita utilizzando un comando come:
funcalc -f swap.expr itest.ev otest.ev
nel file risultante i valori delle colonne x e y saranno scambiati.
Per impostazione predefinita, il tipo di dati della variabile per una colonna è lo stesso del tipo di dati della
colonna come memorizzata nel file. Questo può essere modificato aggiungendo ":[dtype]" alla prima
riferimento a quella colonna. Nell'esempio precedente, per forzare l'output di x e y come valori double,
specificare esplicitamente il tipo 'D':
temp = cur->x:D;
cur->x = cur->y:D;
cur->y = temp;
Gli specificatori del tipo di dati seguono la sintassi standard della tabella FITS per definire le colonne utilizzando TFORM:
· A: caratteri ASCII
· B: carattere a 8 bit senza segno
· I: int con segno a 16 bit
· U: intero a 16 bit senza segno (non FITS standard)
· J: intero con segno a 32 bit
· V: intero a 32 bit senza segno (non FITS standard)
· E: float a 32 bit
· D: 64 bit in virgola mobile
· X: bit (trattati come un array di caratteri)
Si noti che solo il primo riferimento a una colonna dovrebbe contenere il tipo di dati esplicito
specificatore.
Naturalmente, è importante gestire correttamente il tipo di dati delle colonne. Uno dei
causa più frequente di errore in calcolo funzionale la programmazione è l'uso implicito di dati sbagliati
tipo per una colonna in un'espressione. Ad esempio, il calcolo:
dx = (cur->x - cur->y)/(cur->x + cur->y);
di solito deve essere eseguito utilizzando l'aritmetica in virgola mobile. Nei casi in cui x e y
le colonne sono numeri interi, questo può essere fatto leggendo le colonne come double usando un esplicito
specifica del tipo:
dx = (cur->x:D - cur->y:D)/(cur->x + cur->y);
In alternativa, è possibile farlo utilizzando il type-casting C nell'espressione:
dx = ((doppio)cur->x - (doppio)cur->y)/((doppio)cur->x + (doppio)cur->y);
Oltre ad accedere alle colonne nella riga corrente, è possibile fare riferimento anche a
precedente riga utilizzando prev-[nomecolonna]>, e al GENERAZIONE riga utilizzando prossimo-[nomecolonna]>. Nota che
if prev-[colname]> è specificato nel calcolo funzionale espressione, la prima riga non è
elaborato. Se prossimo-[colname]> è specificato nel calcolo funzionale espressione, l'ultima riga
non viene elaborato. In questo modo, prev e GENERAZIONE è garantito che puntino sempre a righe valide.
Ad esempio, per stampare i valori della colonna x corrente e della colonna y precedente,
utilizzare la funzione C fprintf in un calcolo funzionale espressione:
fprintf(stdout, "%d %d\n", cur->x, prev->y);
È possibile specificare nuove colonne utilizzando lo stesso corrente[nomecolonna]> sintassi aggiungendo la colonna
tipo (e specificatori facoltativi tlmin/tlmax/binsiz), separati da due punti. Ad esempio,
cur->avg:D definirà una nuova colonna di tipo double. Gli specificatori di tipo sono gli stessi di
utilizzato sopra per specificare nuovi tipi di dati per le colonne esistenti.
Ad esempio, per creare e generare una nuova colonna che rappresenta il valore medio di x e y
colonne, è possibile definire una nuova colonna "media":
curva->media:D = (cur->x + cur->y)/2.0
Si noti che il carattere finale ';' non è obbligatorio per le espressioni su una sola riga.
Come con la specifica del tipo di dati FITS TFORM, lo specificatore del tipo di dati della colonna può essere preceduto
tramite un conteggio numerico per definire un array, ad esempio, "10I" significa un vettore di 10 int brevi, "2E"
significa due float a precisione singola, ecc. Una nuova colonna deve essere definita solo una volta in un
calcolo funzionale espressione, dopo di che può essere utilizzata senza dover specificare nuovamente il tipo. Questo
include il riferimento agli elementi di una matrice di colonne:
curva->media[0]:2D = (cur->x + cur->y)/2.0;
curva->media[1] = (cur->x - cur->y)/2.0;
Il tipo di dati 'X' (bit) viene trattato come un array di caratteri di dimensione (numeric_count/8), ovvero,
16X viene elaborato come un array di caratteri a 2 byte. Ogni elemento dell'array a 8 bit viene elaborato separatamente:
corrente->stat[0]:16X = 1;
corrente->stat[1] = 2;
Qui viene creata una colonna a 16 bit con il bit più significativo impostato su 1 e il bit meno significativo impostato su 2.
Per impostazione predefinita, tutte le righe elaborate vengono scritte nel file di output specificato. Se si desidera
salta la scrittura di determinate righe, esegui semplicemente l'istruzione C "continue" alla fine
calcolo funzionale espressione, poiché la scrittura della riga viene eseguita subito dopo la
viene eseguita l'espressione. Ad esempio, per saltare la scrittura di righe la cui media è uguale a
valore x corrente:
curva->media[0]:2D = (cur->x + cur->y)/2.0;
curva->media[1] = (cur->x - cur->y)/2.0;
se(cur->avg[0] == cur->x )
continua;
Se non viene specificato alcun argomento del file di output su calcolo funzionale riga di comando, nessun file di output è
aperto e nessuna riga viene scritta. Questo è utile nelle espressioni che stampano semplicemente l'output
risultati invece di generare un nuovo file:
fpv = (cur->av3:D-cur->av1:D)/(cur->av1+cur->av2:D+cur->av3);
fbv = cur->av2/(cur->av1+cur->av2+cur->av3);
fpu = ((double)cur->au3-cur->au1)/((double)cur->au1+cur->au2+cur->au3);
fbu = cur->au2/(double)(cur->au1+cur->au2+cur->au3);
fprintf(stdout, "%f\t%f\t%f\t%f\n", fpv, fbv, fpu, fbu);
Nell'esempio sopra, utilizziamo sia la specifica esplicita del tipo (per le colonne "av") sia il tipo
casting (per le colonne "au") per garantire che tutte le operazioni vengano eseguite in double
precisione.
Quando viene specificato un file di output, la tabella di input selezionata viene elaborata e le righe di output
vengono copiati nel file di output. Si noti che il file di output può essere specificato come "stdout" in
per scrivere le righe di output sull'output standard. Se l'argomento del file di output è
una volta passato, è possibile passare anche un terzo argomento facoltativo per specificare quali colonne elaborare.
In una tabella binaria FITS, a volte è preferibile copiare tutte le altre estensioni FITS
anche al file di output. Questo può essere fatto aggiungendo un segno '+' al nome del
estensione nel nome del file di input. Vedere divertente per un esempio correlato.
calcolo funzionale funziona integrando l'espressione specificata dall'utente in un programma C modello
chiamato tabcalc.c. Il programma completato viene quindi compilato ed eseguito. Variabile
dichiarazioni che iniziano il calcolo funzionale le espressioni vengono inserite nella sezione di dichiarazione locale
del programma principale del modello. Tutte le altre righe vengono inserite nel programma principale del modello
ciclo di elaborazione interno. Altri dettagli della generazione del programma vengono gestiti automaticamente. Per
ad esempio, gli specificatori di colonna vengono analizzati per creare una struttura C per l'elaborazione delle righe, che è
passato a FunColumnSelect() e utilizzato in FunTableRowGet()Se viene utilizzata una variabile sconosciuta
nell'espressione, con conseguente errore di compilazione, la compilazione del programma viene ripetuta dopo
definendo la variabile sconosciuta come di tipo double.
Normalmente, calcolo funzionale il codice di espressione viene aggiunto a calcolo funzionale ciclo di elaborazione delle righe. È possibile
per aggiungere codice ad altre parti del programma inserendo questo codice all'interno di direttive speciali
della forma:
[nome della direttiva]
... il codice va qui ...
fine
Le direttive sono:
· globale aggiungere codice e dichiarazioni nello spazio globale, prima della routine principale.
· locale aggiungere dichiarazioni (e codice) subito dopo le dichiarazioni locali in main
· prima aggiungere il codice appena prima di entrare nel ciclo di elaborazione della riga principale
· dopo aggiungere il codice subito dopo essere usciti dal ciclo di elaborazione della riga principale
Quindi, quanto segue calcolo funzionale l'espressione dichiarerà le variabili globali e creerà la subroutine
chiamate subito prima e subito dopo il ciclo di elaborazione principale:
globale
doppio v1, v2;
doppio init(vuoto);
doppia finitura (doppia v);
fine
prima
v1 = init();
fine
... righe di processo, con calcoli utilizzando v1 ...
dopo
v2 = finitura(v1);
se( v2 < 0.0 ){
fprintf(stderr, "elaborazione fallita %g -> %g\n", v1, v2);
exit(1);
}
fine
Routine come dentro() e finire() sopra vengono passati al programma generato per il collegamento
usando il -l [collegamento direttive ...] switch. La stringa specificata da questo switch sarà
aggiunto alla riga di collegamento utilizzata per costruire il programma (prima della libreria funtools). Per
ad esempio, supponendo che dentro() e finire() sono nella libreria libmysubs.a nel
directory /opt/special/lib, utilizzare:
funcalc -l "-L/opt/special/lib -lmysubs" ...
Gli argomenti utente possono essere passati a un programma funcalc compilato utilizzando un argomento stringa per
Opzione "-a". La stringa deve contenere tutti gli argomenti utente. Ad esempio, per passare
gli interi 1 e 2, utilizzare:
funcalc -a "1 2" ...
Gli argomenti vengono memorizzati in un array interno e sono accessibili come stringhe tramite ARGV(n)
macro. Ad esempio, si consideri la seguente espressione:
locale
int pmin, pmax;
fine
prima
pmin=atoi(ARGV(0));
pmax=atoi(ARGV(1));
fine
if( (cur->pha >= pmin) && (cur->pha <= pmax) )
fprintf(stderr, "%d %d %d\n", cur->x, cur->y, cur->pha);
Questa espressione stamperà i valori x, y e pha per tutte le righe in cui è presente il valore pha
tra i due valori immessi dall'utente:
funcalc -a '1 12' -f foo snr.ev'[cir 512 512 .1]'
512 512 6
512 512 8
512 512 5
512 512 5
512 512 8
funcalc -a '5 6' -f foo snr.ev'[cir 512 512 .1]'
512 512 6
512 512 5
512 512 5
Si noti che è responsabilità dell'utente assicurarsi che il numero corretto di argomenti
vengono passati. La macro ARGV(n) restituisce NULL se un argomento richiesto è al di fuori dei limiti
del numero effettivo di argomenti, che di solito risulta in un SEGV se elaborato alla cieca. Per verificare
per il conteggio degli argomenti, utilizzare la macro ARGC:
locale
intero lungo seme=1;
doppio limite=0.8;
fine
prima
se( ARGC >= 1 ) seme = atol(ARGV(0));
se( ARGC >= 2 ) limite = atof(ARGV(1));
srand48(seme);
fine
se ( drand48() > limite ) continua;
La macro WRITE_ROW si espande in FunTableRowPut() chiamata che scrive la riga corrente.
può essere utilizzato per scrivere la riga più di una volta. Inoltre, la macro NROW si espande in
numero di riga attualmente in elaborazione. L'uso di queste due macro è mostrato di seguito
esempio:
se( cur->pha:I == cur->pi:I ) continua;
a = cur->pha;
cur->pha = cur->pi;
cur->pi = a;
cur->AVG:E = (cur->pha+cur->pi)/2.0;
cur->NR:I = NROW;
se( NROW < 10 ) SCRIVI_RIGA;
Se l' -p [programma] switch è specificato, l'espressione non viene eseguita. Piuttosto, l'
l'eseguibile generato viene salvato con il nome del programma specificato per un uso successivo.
Se l' -n switch è specificato, l'espressione non viene eseguita. Piuttosto, il codice generato
viene scritto su stdout. Questo è particolarmente utile se si desidera generare un file scheletro
e aggiungi il tuo codice, o se hai bisogno di controllare gli errori di compilazione. Nota che il commento
all'inizio dell'output fornisce il comando del compilatore necessario per compilare il programma su quello
piattaforma. (Il comando può cambiare da piattaforma a piattaforma a causa dell'uso di
diverse librerie, switch del compilatore, ecc.)
Come menzionato in precedenza, calcolo funzionale dichiarerà automaticamente una variabile scalare (come
double) se quella variabile è stata utilizzata ma non dichiarata. Questa funzionalità è implementata
utilizzando uno script sed denominato funcalc.sed, che elabora l'output del compilatore per rilevare un
errore di variabile non dichiarata. Questo script è stato inizializzato con l'errore appropriato
informazioni per gcc e per cc sulle piattaforme Solaris, DecAlpha e SGI. Se trovi che
la dichiarazione automatica degli scalari non funziona sulla tua piattaforma, controlla questo script sed;
potrebbe essere necessario aggiungere o modificare alcuni dei messaggi di errore rilevati.
Per mantenere l'analisi lessicale di calcolo funzionale espressioni (ragionevolmente) semplici, abbiamo scelto
accettare alcune limitazioni su come vengono posizionati accuratamente i commenti C, gli spazi e le nuove righe
nel programma generato. In particolare, i commenti associati alle variabili locali dichiarate
all'inizio di un'espressione (cioè, non in un locale...fine blocco) di solito finirà
nel ciclo interno, non con le dichiarazioni locali:
/* questo commento finirà nel posto sbagliato (ad esempio, nel ciclo interno) */
doppia a; /* anche nel posto sbagliato */
/* questo sarà nel posto giusto (ciclo interno) */
if( cur->x:D == cur->y:D ) continue; /* anche nel posto giusto */
a = cur->x;
cur->x = cur->y;
cur->y = a;
curva->media:E = (cur->x+cur->y)/2.0;
Allo stesso modo, spazi e nuove righe a volte vengono omessi o aggiunti in modo apparentemente arbitrario.
maniera. Naturalmente, nessuno di questi difetti stilistici incide sulla correttezza del
codice generato.
Perché calcolo funzionale deve analizzare l'espressione dell'utente utilizzando i file di dati passati
riga di comando, i file di input devono essere aperti e letti due volte: una volta durante il programma
generazione e una volta durante l'esecuzione. Di conseguenza, non è possibile utilizzare stdin per
file di input: calcolo funzionale non può essere utilizzato come filtro. Valuteremo la rimozione di questa restrizione
più tardi.
Insieme ai commenti C, calcolo funzionale le espressioni possono avere commenti interni di una sola riga che sono
non passati al programma C generato. Questi commenti interni iniziano con #
carattere e continua fino alla nuova riga:
double a; # questo non viene passato al file C generato
# né questo è
a = cur->x;
cur->x = cur->y;
cur->y = a;
/* questo commento viene passato al file C */
curva->media:E = (cur->x+cur->y)/2.0;
Come accennato in precedenza, le colonne di input vengono normalmente identificate in base al loro utilizzo all'interno
il ciclo di eventi interno. Ci sono rari casi in cui potresti voler leggere una colonna e
elaborarlo al di fuori del ciclo principale. Ad esempio, qsort potrebbe utilizzare una colonna nel suo ordinamento
routine di confronto che non viene elaborata all'interno del ciclo interno (e quindi non
implicitamente specificato come una colonna da leggere). Per garantire che tale colonna venga letta da
ciclo di eventi, utilizzare il esplicito parola chiave. Gli argomenti di questa parola chiave specificano le colonne che
dovrebbero essere letti nella struttura del record di input anche se non sono menzionati nel
ciclo interno. Ad esempio:
pi pha esplicito
garantirà che le colonne pi e pha vengano lette per ogni riga, anche se non lo sono
elaborato nel ciclo di eventi interno. Il esplicito la dichiarazione può essere posizionata ovunque.
Infine, nota quello calcolo funzionale attualmente lavora su espressioni che coinvolgono tabelle binarie FITS e
file di eventi raw. Valuteremo l'aggiunta del supporto per le espressioni di immagini in un secondo momento,
se c'è richiesta di tale supporto da parte della comunità.
Utilizzare funcalc online utilizzando i servizi onworks.net