ho iniziato da poco a usare il C++ e sto tentando di integrare due
toolkit in modo da sfruttare le funzioni di entrambi. Finora pochi
problemi, ma ora mi trovo nella situazione seguente. Ho una funzione
definita come
bool observe(const WordID* dataword)
in cui WordID č
typedef uint32_t WordID;
Il punto č che devo passare a questa funzione dei dati che non sono
unsigned int 32 bit. Quello che ho č una serie di *coppie* di valori di
tipo size_t:
(size_t pid1, size_t oid1), (size_t pid2, size_t oid2),...
Ogni coppia č unica e univocamente definita dai due size_t che la
compongono.
Esiste un modo per passare a observe una coppia del genere? Da quanto ho
letto su linux size_t puň essere piů grande di uint32_t, quindi
figuriamoci DUE size_t... Avete in mente una soluzione alla cosa?
Pensavo a qualcosa tipo concatenare i due size_t in una stringa e poi
trasformare questa in uint32_t, ma che succede se i due size_t
concatenati generano un numero > 2^32? Oppure, forse potrei ridefinire
WordID in modo da avere
typedef uint64_t WordID
quindi concatenare i due size_t e trasformarli in uint64_t.
Oppure un qualche tipo di cast? Non so, spero possiate aiutarmi
Ciao Giuseppe
scusa, ma dato che la funzione non si aspetta un passaggio
byvalue ma un pointer, che problemi ci sarebbero a definire
una tua struct contenente i due size_t, e poi passargli
l'indirizzo ?
>
> in cui WordID è
>
> typedef uint32_t WordID;
>
> Il punto è che devo passare a questa funzione dei dati che non sono
> unsigned int 32 bit. Quello che ho è una serie di *coppie* di valori di
> tipo size_t:
>
> (size_t pid1, size_t oid1), (size_t pid2, size_t oid2),...
da come la prospetti qui, il tuo problema a rigori potrebbe
non avere neppure una soluzione univoca, nel senso che la
funzione si aspetta un dato con una certa profondità di bit
e tu pare che debba lavorare con una profondità ben
maggiore, e a quel punto chiedi se sia possibile mappare il
tuo più vasto insieme nel dato richiesti, più piccolo, e in
modo lossless ... ovviamente in questi termini il problema
non ha soluzione (nemmeno se crei un algoritmo di
conversione, non può essere univoco, ma viene detto degenere).
Tuttavia la documentazione di observe non è sufficiente.
Il fatto che richieda un pointer invece che un uint32
byvalue, cosa sottintende ? Che lo debba scrivere ? Che
accetta in realtà anche array di interi ? Se è la seconda
sei a posto (non capisco come desuma la dimensione
dell'array cmq)
ciao
Soviet
>
>
> Ogni coppia è unica e univocamente definita dai due size_t che la
> compongono.
> Esiste un modo per passare a observe una coppia del genere? Da quanto ho
> letto su linux size_t può essere più grande di uint32_t, quindi
bool insert(const WordID* ngram, int len, int event_idx, int code);
e fra l'altro ha una gemella chiamata
bool query(const WordID* ngram, int len, int event_idx, int* code, int max);
Ho tralasciato gli altri parametri nella mia mail precedente perche non
credo sia lě il problema, sono dati che ho (len = 1 per me, code = 0,
ecc ecc.)
Queste due funzioni sono di un oggetto, un bloom filter, che crea una
struttura dati utilizzata per effettuare dei set membership test. I dati
che inserisci tramite insert (ngram) vengono processati da un certo
numero di hash, le quali mettono a 1 ognuna un bit in un array di bit
(bit che sono tutti inizialmente a 0). Ngram viene gettato via dopo
l'insert.
Quando poi fai la query() con un certo ngram, usi le stesse hash, che
punteranno agli stessi bit di prima: se sono tutti a 1, desumi che
l'oggetto era stato inserito: altrimente, se anche solo un bit č zero,
l'oggetto non era stato inserito dalla insert().
Quindi, WordID* ngram non viene modificato, ma solo letto e "hashato"
(perdona l'inglesismo rozzo). Credo sia questo il motivo per cui non va
by value.
Il punto č che i dati che devo "hashare" tramite insert() e poi
verificare con query() non sono un puntatore a uint32_t (non ho dati in
quel formato) bensi due indici, ognuno size_t, che mi interessa inserire
insieme nella struttura: il punto č che voglio testare, col Bloom
Filter, la loro presenza contemporanea nella struttura. Di qui il problema.
Sono veramente poco esperto di C++ quindi non saprei se accetta array di
interi. Spero perň tu possa capirci qualcosa di piů dando un'occhiata
alle funzioni:
//INSERT================
bool LogFreqBloomFilter::insert(const WordID* ngram, int len, int
event_idx, int code) {
// insert code to filter using appropriate hash functions
assert(optimised_ && !full_);
int idx = 0;
int insertions = alpha_[len - 1] + (code * k_[len - 1]);
while (idx < insertions) {
assert(filter_->setBit(hashes_[event_idx][idx]->hash(ngram, len)));
++idx;
}
inserted_ += insertions;
full_ = inserted_ > t_; // indicate to caller if full
return !full_;
}
//QUERY==============
bool LogFreqBloomFilter::query(const WordID* ngram, int len, int
event_idx, int* code, int max) {
// query filter for this ngram map to code on basis of num of hash
functions that test true
int idx = 0;
// determine the maximum number of hashes given upper bound 'max'
on 'code'
int max_idx = std::min(max_hashes_[event_idx], alpha_[len - 1] +
(max * k_[len - 1]));
while (idx < max_idx) {
if(!filter_->testBit(hashes_[event_idx][idx]->hash(ngram, len)))
break;
++idx;
}
Il cuore delle due procedure credo sia quella chiamata ad hash(). ti
riporto anche quella funzione
inline T hash(const WordID* ngram, int len) {
// get hash of sequence of 'ngram'
int pos = 0;
T value = ((a_[pos] * ngram[len - 1]) + b_[pos]);// % m_;
while (++pos < len)
value = (value + (a_[pos] * ngram[len - 1 - pos]) + b_[pos]);// % m_;
// return hash value for complete sequence
return value;
}
inline bool hash(const WordID* ngram, int len, T* value) {
// get hash of sequence of 'ngram'
int pos = 0;
*value = ((a_[pos] * ngram[len - 1]) + b_[pos]);// % m_;
while (++pos < len)
*value = (*value + (a_[pos] * ngram[len - 1 - pos]) + b_[pos]);// % m_;
// return hash value for complete sequence
return true;
}
Ti riporto anche un esempio che indica come viene chiamata insert nel
programma base:
bool RandLM::build(InputData* data) { //vedi randlmpreproc.h
//...
NgramFile* ngrams = dynamic_cast<NgramFile*>(data);
return buildFromNgrams(ngrams);
}
==>>>
bool RandLM::buildFromNgrams(NgramFile* ngrams){
//...
storeNgram(&ngram[0], len, value)
//...
}
==>>>
bool CountRandLM::storeNgram(const WordID* ngram, int len, Value value) {
//...
return struct_->insert(ngram, len, kMainEventIdx,
log_quantiser_->getCode(count));
//...
}
Dove struct č un puntatore all'oggetto bloomfilter che ti dicevo. In
quell' ngram che vedi vorrei riuscire a ficcarci una coppia di size_t.
Che dirti grazie ancora, spero che questo sia sufficiente. Fammi sapere
Ciao
Giuseppe