19 inline bool isFlagSet(uint32_t dbFlags, uint32_t flag) {
20 return (dbFlags & flag) != 0;
65 std::vector<int32_t> kVector(numBins+1);
66 decimal binWidth = (max - min) / numBins;
71 for (int32_t i = 0; i < (int32_t)values.size(); i++) {
73 assert(values[i] >= values[i-1]);
75 assert(values[i] >= min);
76 assert(values[i] <= max);
77 long thisBin = (long)ceil((values[i] - min) / binWidth);
79 assert(thisBin <= numBins);
81 for (
long bin = lastBin; bin < thisBin; bin++) {
86 for (
long bin = lastBin; bin <= numBins; bin++) {
87 kVector[bin] = values.size();
91 int32_t lastBinVal = -1;
92 for (
const int32_t &bin : kVector) {
93 assert(bin >= lastBinVal);
98 SerializePrimitive<int32_t>(ser, values.size());
99 SerializePrimitive<decimal>(ser, min);
100 SerializePrimitive<decimal>(ser, max);
101 SerializePrimitive<int32_t>(ser, numBins);
104 for (
const int32_t &bin : kVector) {
105 SerializePrimitive<int32_t>(ser, bin);
112 numValues = DeserializePrimitive<int32_t>(des);
113 min = DeserializePrimitive<decimal>(des);
114 max = DeserializePrimitive<decimal>(des);
115 numBins = DeserializePrimitive<int32_t>(des);
119 binWidth = (max - min) / numBins;
121 bins = DeserializeArray<int32_t>(des, numBins+1);
130 assert(maxQueryDistance > minQueryDistance);
131 if (maxQueryDistance >= max) {
132 maxQueryDistance = max -
DECIMAL(0.00001);
134 if (minQueryDistance <= min) {
135 minQueryDistance = min +
DECIMAL(0.00001);
137 if (minQueryDistance > max || maxQueryDistance < min) {
141 long lowerBin = BinFor(minQueryDistance);
142 long upperBin = BinFor(maxQueryDistance);
143 assert(upperBin >= lowerBin);
144 assert(upperBin <= numBins);
147 int lowerIndex = bins[lowerBin-1];
148 if (lowerIndex >= numValues) {
154 *upperIndex = bins[upperBin];
159 long KVectorIndex::BinFor(
decimal query)
const {
160 long result = (long)ceil((query - min) / binWidth);
162 assert(result <= numBins);
176 std::vector<KVectorPair> result;
177 for (int16_t i = 0; i < (int16_t)catalog.size(); i++) {
178 for (int16_t k = i+1; k < (int16_t)catalog.size(); k++) {
187 result.push_back(pair);
199 std::vector<int32_t> kVector(numBins+1);
204 std::vector<decimal> distances;
207 distances.push_back(pair.distance);
215 SerializePrimitive<int16_t>(ser, pair.index1);
216 SerializePrimitive<int16_t>(ser, pair.index2);
224 pairs = DeserializeArray<int16_t>(des, 2*index.
NumValues());
229 return num < low ? low : num > high ? high : num;
238 decimal minQueryDistance,
decimal maxQueryDistance,
const int16_t **end)
const {
242 long upperIndex = -1;
243 long lowerIndex = index.
QueryLiberal(minQueryDistance, maxQueryDistance, &upperIndex);
244 *end = &pairs[upperIndex * 2];
245 return &pairs[lowerIndex * 2];
249 decimal minQueryDistance,
decimal maxQueryDistance,
const int16_t **end)
const {
260 long liberalUpperIndex;
261 long liberalLowerIndex = index.
QueryLiberal(minQueryDistance, maxQueryDistance, &liberalUpperIndex);
265 while (liberalLowerIndex < liberalUpperIndex
266 && catalog[pairs[liberalLowerIndex*2]].spatial * catalog[pairs[liberalLowerIndex*2+1]].spatial >= maxQueryCos
268 { liberalLowerIndex++; }
271 while (liberalLowerIndex < liberalUpperIndex
273 && catalog[pairs[(liberalUpperIndex-1)*2]].spatial * catalog[pairs[(liberalUpperIndex-1)*2+1]].spatial <= minQueryCos
275 { liberalUpperIndex--; }
277 *end = &pairs[liberalUpperIndex * 2];
278 return &pairs[liberalLowerIndex * 2];
288 std::vector<decimal> result;
289 for (
int i = 0; i <
NumPairs(); i++) {
290 if (pairs[i*2] == star || pairs[i*2+1] == star) {
291 result.push_back(
AngleUnit(catalog[pairs[i*2]].spatial, catalog[pairs[i*2+1]].spatial));
320 assert(magicValue != 0);
322 int32_t curMagicValue = DeserializePrimitive<int32_t>(des);
323 if (curMagicValue == 0) {
326 uint32_t dbFlags = DeserializePrimitive<uint32_t>(des);
329 #ifdef LOST_FLOAT_MODE
331 std::cerr <<
"LOST was compiled in float mode. This database was serialized in double mode and is incompatible." << std::endl;
336 std::cerr <<
"LOST was compiled in double mode. This database was serialized in float mode and is incompatible." << std::endl;
341 uint32_t dbLength = DeserializePrimitive<uint32_t>(des);
342 assert(dbLength > 0);
343 DeserializePadding<uint64_t>(des);
344 const unsigned char *curSubDatabasePointer = DeserializeArray<unsigned char>(des, dbLength);
345 if (curMagicValue == magicValue) {
346 return curSubDatabasePointer;
357 SerializePrimitive<int32_t>(ser, multiDbEntry.magicValue);
358 SerializePrimitive<uint32_t>(ser, flags);
359 SerializePrimitive<uint32_t>(ser, multiDbEntry.bytes.size());
360 SerializePadding<uint64_t>(ser);
361 std::copy(multiDbEntry.bytes.cbegin(), multiDbEntry.bytes.cend(), std::back_inserter(ser->
buffer));
363 SerializePrimitive<int32_t>(ser, 0);
A data structure enabling constant-time range queries into fixed numerical data.
KVectorIndex(DeserializeContext *des)
Construct from serialized buffer.
long QueryLiberal(decimal minQueryDistance, decimal maxQueryDistance, long *upperIndex) const
Finds all the entries in the given range, and possibly a few just outside the range on the ends.
long NumValues() const
The number of data points in the data referred to by the kvector.
const unsigned char * SubDatabasePointer(int32_t magicValue) const
MultiDatabase memory layout:
long NumPairs() const
Exact number of stored pairs.
std::vector< decimal > StarDistances(int16_t star, const Catalog &) const
Return the distances from the given star to each star it's paired with in the database (for debugging...
PairDistanceKVectorDatabase(DeserializeContext *des)
Create the database from a serialized buffer.
static const int32_t kMagicValue
Magic value to use when storing inside a MultiDatabase.
const int16_t * FindPairsExact(const Catalog &, decimal min, decimal max, const int16_t **end) const
const int16_t * FindPairsLiberal(decimal min, decimal max, const int16_t **end) const
Return at least all the star pairs whose inter-star distance is between min and max.
std::vector< unsigned char > buffer
#define MULTI_DB_FLOAT_FLAG
A database that contains multiple databases This is almost always the database that is actually passe...
void SerializeKVectorIndex(SerializeContext *ser, const std::vector< decimal > &values, decimal min, decimal max, long numBins)
K-vector index layout.
decimal AngleUnit(const Vec3 &vec1, const Vec3 &vec2)
Calculate the inner angle, in radians, between two /unit/ vectors.
bool CompareKVectorPairs(const KVectorPair &p1, const KVectorPair &p2)
std::vector< KVectorPair > CatalogToPairDistances(const Catalog &catalog, decimal minDistance, decimal maxDistance)
pair K-vector database layout.
void SerializePairDistanceKVector(SerializeContext *ser, const Catalog &catalog, decimal minDistance, decimal maxDistance, long numBins)
Serialize a pair-distance KVector into buffer.
bool isFlagSet(uint32_t dbFlags, uint32_t flag)
std::vector< MultiDatabaseEntry > MultiDatabaseDescriptor
void SerializeMultiDatabase(SerializeContext *ser, const MultiDatabaseDescriptor &dbs, uint32_t flags)
decimal Clamp(decimal num, decimal low, decimal high)
Return the value in the range [low,high] which is closest to num.
std::vector< CatalogStar > Catalog