Files
secondo/Algebras/SymbolicTrajectoryBasic/SymbolicTrajectoryBasicAlgebra.h
2026-01-23 17:03:45 +08:00

4072 lines
105 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
//[TOC] [\tableofcontents]
split from the SymbolicTrajectoryAlgebra in April 2020.
*/
#include "Algebras/TemporalUnit/TemporalUnitAlgebra.h"
#include "StandardTypes.h"
#include "Stream.h"
#include "Algebras/FText/FTextAlgebra.h"
#include "Algebras/Temporal/TemporalAlgebra.h"
#include "Algebras/Collection/CollectionAlgebra.h"
#include "Algebras/Trie/InvertedFile.h"
namespace stj {
enum LabelFunction {TRIVIAL, EDIT};
enum DistanceFunction {FIRST, LAST, FIRST_LAST, ALL, ALL_DURATION,
ALL_INTERVALS, EQUAL_LABELS, COSINUS_SIM, TF_IDF};
enum DistanceFunSym {ERROR = -1, EQUALLABELS, PREFIX, SUFFIX, PREFIXSUFFIX};
template<class F, class S>
class NewPair {
public:
NewPair() {}
NewPair(const F f, const S s) : first(f), second(s) {}
F first;
S second;
bool operator==(const NewPair& np) const {
return (first == np.first && second == np.second);
}
bool operator!=(const NewPair& np) const {
return !(*this == np);
}
bool operator<(const NewPair& np) const {
if (first == np.first) {
return second < np.second;
}
return first < np.first;
}
void set(const F& f, const S& s) {
first = f;
second = s;
}
void operator=(const NewPair& np) {
set(np.first, np.second);
}
friend std::ostream& operator<<(std::ostream& os, const NewPair& np) {
os << "(" << np.first << ", " << np.second << ")";
return os;
}
void Print(std::ostream& os) const {
os << *this;
}
template<class X>
void copy2ndFrom(const X newValue) {
assert(sizeof(S) == sizeof(X));
memcpy((void*)&second, &newValue, sizeof(S));
}
};
template<class F, class S, class T>
class NewTriple {
public:
NewTriple() {}
NewTriple(F f, S s, T t) : first(f), second(s), third(t) {}
F first;
S second;
T third;
bool operator==(const NewTriple& nt) const {
return (first == nt.first && second == nt.second && third = nt.third);
}
bool operator<(const NewTriple& nt) const {
if (first < nt.first) {
return true;
}
if (first == nt.first) {
if (second < nt.second) {
return true;
}
if (second == nt.second) {
return third < nt.third;
}
}
return false;
}
friend std::ostream& operator<<(std::ostream& os, const NewTriple& nt) {
os << nt.first << ", " << nt.second << ", " << nt.third;
return os;
}
};
struct SymbolicUnit {
public:
SymbolicUnit() {}
SymbolicUnit(unsigned int p, unsigned int r) : iv(true), pos(p) {}
temporalalgebra::SecInterval iv;
unsigned int pos;
};
struct ExtSymbolicUnit : public SymbolicUnit {
ExtSymbolicUnit() {}
ExtSymbolicUnit(unsigned int p, unsigned int r) : SymbolicUnit(p,r), ref(r) {}
unsigned int ref;
};
struct BasicDistanceFuns {
static double distance(const std::string& str1, const std::string& str2,
const LabelFunction lf = TRIVIAL);
static double distance(const std::pair<std::string, unsigned int>& val1,
const std::pair<std::string, unsigned int>& val2,
const LabelFunction lf = TRIVIAL);
static double distance(const std::set<std::string>& values1,
const std::set<std::string>& values2, const LabelFunction lf = EDIT);
static double distance(std::set<std::pair<std::string,
unsigned int> >& values1,
std::set<std::pair<std::string,
unsigned int> >& values2, const LabelFunction lf = EDIT);
};
struct RecodeFun {
#ifdef RECODE
static bool recode(const std::string &src, const std::string &from,
const std::string &to, std::string &result);
#endif
};
class Labels;
/*
\section{Class ~Label~}
*/
class Label : public Attribute {
public:
friend class Labels;
typedef SymbolicUnit unitelem;
typedef std::string base;
typedef Labels coll;
Label() {}
Label(const std::string& text) : Attribute(true), value(8) {SetValue(text);}
Label(const Label& rhs);
explicit Label(const bool def) : Attribute(def), value(8) {}
~Label() {}
void Clean() {
if (value.getSize() > 0) {value.clean();}}
void Destroy() {value.destroy();}
void GetValue(std::string &text) const;
std::string GetLabel() const {return GetValue();}
std::string GetValue() const;
unsigned int GetRef() const {return 0;}
void GetValues(std::set<std::string>& values) const;
static void buildValue(const std::string& text,
const unitelem& unit,base& result);
static ListExpr getList(const std::string& text) {
return nl->TextAtom(text);
}
void Set(const bool def, const std::string &text) {
std::string newText = text;
std::replace(newText.begin(), newText.end(), '\'', '`');
SetDefined(def); SetValue(newText);
}
void SetValue(const std::string &text);
Label& operator=(const Label& lb) {CopyFrom(&lb); return *this;}
bool operator==(const Label& lb) const;
bool operator==(const std::string& text) const;
double Distance(const Label& lb, const LabelFunction lf = EDIT) const;
void InsertLabels(std::vector<std::string>& result) const;
void InsertLabels(std::set<std::string>& result) const;
void UpdateFrequencies(InvertedFile& inv, std::vector<double>& fv) const;
static bool readValueFrom(ListExpr LE, std::string& text, unitelem& unit);
bool ReadFrom(ListExpr LE, ListExpr typeInfo);
ListExpr ToListExpr(ListExpr typeInfo);
static bool CheckKind(ListExpr type, ListExpr& errorInfo);
static int SizeOfObj() {return sizeof(Label);}
static ListExpr Property();
static const std::string BasicType() {return "label";}
static const bool checkType(const ListExpr type);
void CopyFrom(const Attribute* right);
int NumOfFLOBs() const {return 1;}
Flob *GetFLOB(const int i) {assert(i == 0); return &value;}
int Compare(const Attribute* arg) const;
size_t Sizeof() const {return sizeof(*this);}
bool Adjacent(const Attribute*) const {return false;}
Attribute* Clone() const {return new Label(*this);}
size_t HashValue() const {return value.getSize();}
std::ostream& Print(std::ostream& os) const;
protected:
Flob value;
};
/*
\section{Class ~Labels~}
*/
class Labels : public Attribute {
public:
typedef SymbolicUnit unitelem;
typedef unsigned int arrayelem;
typedef std::string base;
typedef Label single;
Labels() {}
explicit Labels(const bool defined) : Attribute(defined), values(8), pos(1) {}
Labels(const Labels& src, const bool sort = false);
~Labels() {}
Labels& operator=(const Labels& src);
bool operator==(const Labels& src) const;
void Append(const Label &lb);
void Append(const std::string& text);
void Append(const std::set<std::string>& values);
void Destroy() {values.destroy(); pos.destroy();}
int GetNoValues() const {return pos.Size();}
int GetNoComponents() const {return GetNoValues();}
size_t GetLength() const {return values.getSize();}
void Get(int i, Label& lb) const;
void GetValue(int i, std::string& text) const;
void GetValues(std::set<std::string>& values) const;
static void getRefToLastElem(const int size, unsigned int& result);
static unsigned int getFlobPos(const arrayelem elem);
static void valuesToListExpr(const std::set<std::string>& values,
ListExpr& result);
static void getString(const ListExpr& list, std::string& result);
static void getElemFromList(const ListExpr& list, const unsigned int size,
unsigned int& result);
static void buildValue(const std::string& text, const unsigned int pos,
std::string& result);
static void printArrayElem(const arrayelem e) {cout << "print " << e << endl;}
const bool IsEmpty() const {return GetNoValues() == 0;}
void Clean() {values.clean(); pos.clean();}
bool Contains(const std::string& text) const;
bool Intersects(const Labels &lbs) const;
void Union(const std::set<std::string>& values1,
const std::set<std::string>& values2);
void Intersection(const std::set<std::string>& values1,
const std::set<std::string>& values2);
void Minus(const std::set<std::string>& values1,
const std::set<std::string>& values2);
#ifdef RECODE
bool Recode(const std::string& from, const std::string& to, Labels& result);
#endif
friend std::ostream& operator<<(std::ostream& os, const Labels& lbs);
double Distance(const Labels& lbs, const LabelFunction lf = EDIT) const;
void InsertLabels(std::vector<std::string>& result) const;
void InsertLabels(std::set<std::string>& result) const;
void UpdateFrequencies(InvertedFile& inv, std::vector<double>& fv) const;
int NumOfFLOBs() const {return 2;}
Flob *GetFLOB(const int i);
int Compare(const Attribute*) const;
bool Adjacent(const Attribute*) const {return false;}
Attribute *Clone() const {return new Labels(*this);}
size_t Sizeof() const {return sizeof(*this);}
std::ostream& Print(std::ostream& os) const {return (os << *this);}
static ListExpr Property();
static bool CheckKind(ListExpr type, ListExpr& errorInfo);
static bool checkType(ListExpr t) {return listutils::isSymbol(t,BasicType());}
ListExpr ToListExpr(ListExpr typeInfo);
bool ReadFrom(ListExpr LE, ListExpr typeInfo);
static int SizeOfObj() {return sizeof(Labels);}
static const std::string BasicType() {return Label::BasicType() + "s";}
void CopyFrom(const Attribute* right) {*this = *((Labels*)right);}
size_t HashValue() const;
protected:
Flob values;
DbArray<unsigned int> pos;
};
class Places;
/*
\section{Class ~Place~}
*/
class Place : public Label {
public:
friend class Places;
typedef ExtSymbolicUnit unitelem;
typedef std::pair<std::string, unsigned int> base;
typedef Places coll;
Place() : Label() {}
Place(const std::pair<std::string, unsigned int>& v) :
Label(v.first), ref(v.second) {}
Place(const Place& rhs) : Label(rhs.IsDefined()) {CopyFrom(&rhs);}
explicit Place(const bool def) : Label(def), ref(0) {}
~Place() {}
void Set(const bool defined, const std::pair<std::string,
unsigned int>& value);
void SetValue(const std::pair<std::string, unsigned int>& value);
void SetRef(const unsigned int value) {ref = value;}
void GetValue(std::pair<std::string, unsigned int>& value) const;
std::string GetLabel() const {return Label::GetLabel();}
void GetValues(std::set<std::pair<std::string, unsigned int> >& values) const;
static void buildValue(const std::string& text,
const unitelem& unit,base& result);
static ListExpr getList(const base& value);
unsigned int GetRef() const {return ref;}
Place& operator=(const Place& p);
bool operator==(const Place& p) const;
bool operator==(const std::pair<std::string, unsigned int>& value) const;
double Distance(const Place& p, const LabelFunction lf = EDIT) const;
static ListExpr Property();
static int SizeOfObj() {return sizeof(Place);}
static bool CheckKind(ListExpr type, ListExpr& errorInfo);
static const std::string BasicType() {return "place";}
static bool checkType(ListExpr t) {return listutils::isSymbol(t,BasicType());}
int NumOfFLOBs() const {return Label::NumOfFLOBs();}
Flob* GetFLOB(const int i) {return Label::GetFLOB(i);}
size_t Sizeof() const {return sizeof(*this);}
int Compare(const Attribute* arg) const;
bool Adjacent(const Attribute *arg) const {return false;}
Attribute *Clone() const {return new Place(*this);}
size_t HashValue() const {return Label::HashValue() * ref;}
virtual void CopyFrom(const Attribute* right) {*this = *((Place*)right);}
ListExpr ToListExpr(ListExpr typeInfo);
static bool readValueFrom(ListExpr LE, std::string& text, unitelem& unit);
bool ReadFrom(ListExpr LE, ListExpr typeInfo);
protected:
unsigned int ref;
};
/*
\section{Class ~Places~}
*/
class Places : public Attribute {
public:
typedef ExtSymbolicUnit unitelem;
typedef NewPair<unsigned int, unsigned int> arrayelem;
typedef std::pair<std::string, unsigned int> base;
typedef Place single;
Places() {}
Places(const int n) : Attribute(n > 0), values(8), posref(n) {}
Places(const Places& rhs, const bool sort = false);
explicit Places(const bool def) : Attribute(def), values(8), posref(1) {}
~Places() {}
void Append(const base& value);
void Append(const Place& pl);
void Append(const std::set<base>& values);
void Destroy() {values.destroy(); posref.destroy();}
int GetNoValues() const {return posref.Size();}
int GetNoComponents() const {return GetNoValues();}
size_t GetLength() const {return values.getSize();}
void Get(const int i, Place& pl) const;
void GetValue(int i, base& val) const;
void GetValues(std::set<base>& values) const;
bool IsEmpty() const {return (GetNoValues() == 0);}
bool Contains(const base& val) const;
bool Intersects(const Places &pls) const;
void Union(const std::set<base>& values1, const std::set<base>& values2);
void Intersection(const std::set<base>& values1,
const std::set<base>& values2);
void Minus(const std::set<base>& values1, const std::set<base>& values2);
void Clean() {values.clean(); posref.clean();}
static void getRefToLastElem(const int size, arrayelem& result);
static unsigned int getFlobPos(const arrayelem elem);
static void valuesToListExpr(const std::set<base>& values, ListExpr& result);
static void getString(const ListExpr& list, std::string& result);
static void getElemFromList(const ListExpr& list, const unsigned int size,
arrayelem& result);
static void buildValue(const std::string& text,
const arrayelem pos, base& result);
static void printArrayElem(const arrayelem e) {cout << e.first << " "
<< e.second;}
void operator=(const Places& p);
bool operator==(const Places& p) const;
double Distance(const Places& p, const LabelFunction lf = EDIT) const;
void InsertLabels(std::vector<std::string>& result) const;
void InsertLabels(std::set<std::string>& result) const;
void UpdateFrequencies(InvertedFile& inv, std::vector<double>& fv) const;
static ListExpr Property();
static int SizeOfObj() {return sizeof(Places);}
static bool CheckKind(ListExpr type, ListExpr& errorInfo);
static const std::string BasicType() {return Place::BasicType() + "s";}
static bool checkType(ListExpr t) {return listutils::isSymbol(t,BasicType());}
int NumOfFLOBs() const {return 2;}
Flob* GetFLOB(const int i);
size_t Sizeof() const {return sizeof(*this);}
int Compare(const Attribute* arg) const;
bool Adjacent(const Attribute *arg) const {return false;}
Attribute *Clone() const {return new Places(*this);}
size_t HashValue() const;
virtual void CopyFrom(const Attribute* right) {*this = *((Places*)right);}
ListExpr ToListExpr(ListExpr typeInfo);
bool ReadFrom(ListExpr LE, ListExpr typeInfo);
protected:
Flob values;
DbArray<NewPair<unsigned int, unsigned int> > posref;
};
/*
\section{Class ~IBasic~}
*/
template<class B>
class IBasic : public temporalalgebra::Intime<B> {
public:
IBasic() {}
explicit IBasic(const Instant& inst, const B& val);
explicit IBasic(const IBasic& rhs);
IBasic(const bool def) : temporalalgebra::Intime<B>(def) {}
~IBasic() {}
static ListExpr Property();
static int SizeOfObj() {return sizeof(IBasic<B>);}
static bool CheckKind(ListExpr type, ListExpr& errorInfo);
static const std::string BasicType() {return "i" + B::BasicType();}
static bool checkType(ListExpr t) {return listutils::isSymbol(t,BasicType());}
int NumOfFLOBs() const {return this->value.NumOfFLOBs();}
Flob* GetFLOB(const int i) {return this->value.GetFLOB(i);}
size_t Sizeof() const {return sizeof(*this);}
ListExpr ToListExpr(ListExpr typeInfo);
bool ReadFrom(ListExpr LE, ListExpr typeInfo);
void Val(B& result) const;
};
/*
\section{Class ~IBasics~}
*/
template<class B>
class IBasics : public temporalalgebra::Intime<B> {
public:
IBasics() {}
explicit IBasics(const Instant& inst, const B& values);
IBasics(const IBasics& rhs) : temporalalgebra::Intime<B>(rhs) {}
IBasics(const bool def) : temporalalgebra::Intime<B>(def) {}
static ListExpr Property();
static int SizeOfObj() {return sizeof(IBasics<B>);}
static bool CheckKind(ListExpr type, ListExpr& errorInfo);
static const std::string BasicType() {return "i" + B::BasicType();}
static bool checkType(ListExpr t) {return listutils::isSymbol(t,BasicType());}
int NumOfFLOBs() const {return this->value.NumOfFLOBs();}
Flob* GetFLOB(const int i) {return this->value.GetFLOB(i);}
size_t Sizeof() const {return sizeof(*this);}
ListExpr ToListExpr(ListExpr typeInfo);
bool ReadFrom(ListExpr LE, ListExpr typeInfo);
void Val(B& result) const;
};
/*
\section{Class ~UBasic~}
*/
template<class B>
class UBasic : public temporalalgebra::ConstTemporalUnit<B> {
public:
UBasic() : temporalalgebra::ConstTemporalUnit<B>(true) {}
explicit UBasic(bool def) : temporalalgebra::ConstTemporalUnit<B>(def) {}
explicit UBasic(const temporalalgebra::SecInterval &iv, const B& val);
UBasic(const temporalalgebra::Interval<datetime::DateTime>& iv,
const B& b1, const B& b2);
UBasic(const UBasic& ub);
~UBasic() {}
bool operator==(const UBasic<B>& rhs) const;
static ListExpr Property();
static int SizeOfObj() {return sizeof(UBasic<B>);}
static bool CheckKind(ListExpr type, ListExpr& errorInfo);
static const std::string BasicType() {return "u" + B::BasicType();}
static bool checkType(ListExpr t) {return listutils::isSymbol(t,BasicType());}
int NumOfFLOBs() const {return this->constValue.NumOfFLOBs();}
Flob* GetFLOB(const int i) {return this->constValue.GetFLOB(i);}
size_t Sizeof() const {return sizeof(*this);}
ListExpr ToListExpr(ListExpr typeInfo);
bool ReadFrom(ListExpr LE, ListExpr typeInfo);
void Initial(IBasic<B>& result) const;
void Final(IBasic<B>& result) const;
void GetInterval(temporalalgebra::SecInterval& result) const;
};
/*
\section{Class ~UBasics~}
*/
template<class B>
class UBasics : public temporalalgebra::ConstTemporalUnit<B> {
public:
UBasics() : temporalalgebra::ConstTemporalUnit<B>(true) {}
UBasics(const temporalalgebra::SecInterval& iv, const B& values);
UBasics(const UBasics& rhs) : temporalalgebra::ConstTemporalUnit<B>(rhs) {}
explicit UBasics(const bool def) :
temporalalgebra::ConstTemporalUnit<B>(def) {}
static ListExpr Property();
static int SizeOfObj() {return sizeof(UBasics<B>);}
static bool CheckKind(ListExpr type, ListExpr& errorInfo);
static const std::string BasicType() {return "u" + B::BasicType();}
static bool checkType(ListExpr t) {return listutils::isSymbol(t,BasicType());}
int NumOfFLOBs() const {return this->constValue.NumOfFLOBs();}
Flob* GetFLOB(const int i) {return this->constValue.GetFLOB(i);}
size_t Sizeof() const {return sizeof(*this);}
ListExpr ToListExpr(ListExpr typeInfo);
bool ReadFrom(ListExpr LE, ListExpr typeInfo);
void Initial(IBasics<B>& result) const;
void Final(IBasics<B>& result) const;
void GetInterval(temporalalgebra::SecInterval& result) const;
};
class MLabel;
/*
\section{Class ~MBasic~}
*/
template<class B>
class MBasic : public Attribute {
public:
typedef B base;
MBasic() {}
explicit MBasic(unsigned int n) : Attribute(n>0), values(1024), units(n),
noChars(0) {}
explicit MBasic(const MBasic& mb);
~MBasic() {}
static ListExpr Property();
static int SizeOfObj() {return sizeof(MBasic<B>);}
static bool CheckKind(ListExpr type, ListExpr& errorInfo);
static const std::string BasicType() {return "m" + B::BasicType();}
static bool checkType(ListExpr t) {return listutils::isSymbol(t,BasicType());}
int NumOfFLOBs() const {return 2;}
Flob* GetFLOB(const int i);
size_t Sizeof() const {return sizeof(*this);}
int Compare(const Attribute *arg) const;
Attribute* Clone() const {return new MBasic<B>(*this);}
bool Adjacent(const Attribute *arg) const {return false;}
size_t HashValue() const;
MBasic<B>& operator=(const MBasic<B>& src);
void CopyFrom(const Attribute *arg);
ListExpr unitToListExpr(const int i);
ListExpr ToListExpr(ListExpr typeInfo);
bool readUnitFrom(ListExpr LE);
bool ReadFrom(ListExpr LE, ListExpr typeInfo);
int GetNoChars() const {return noChars;}
void serialize(size_t &size, char *&bytes) const;
static MBasic<B>* deserialize(const char *bytes);
int Position(const Instant& inst, const bool ignoreClosedness = false) const;
int FirstPosFrom(const Instant& inst) const;
int LastPosUntil(const Instant& inst) const;
void Get(const int i, UBasic<B>& result) const;
void GetInterval(const int i, temporalalgebra::SecInterval& result) const;
void GetInterval(temporalalgebra::SecInterval& result) const;
void GetDuration(datetime::DateTime& result) const;
void GetBasic(const int i, B& result) const;
void GetValue(const int i, typename B::base& result) const;
bool IsEmpty() const {return units.Size() == 0;}
int GetNoComponents() const {return units.Size();}
bool IsValid() const;
void Clear() {values.clean(); units.clean(); noChars = 0;}
void StartBulkLoad() {assert(IsDefined());}
void EndBulkLoad(const bool sort = true, const bool checkvalid = true);
void Add(const temporalalgebra::SecInterval& iv, const B& value);
void Add(const UBasic<B>& ub);
void MergeAdd(const UBasic<B>& ub);
bool Passes(const B& basic) const;
template<class T>
bool Passes(const T& value) const;
void At(const B& basic, MBasic<B>& result) const;
template<class T>
void At(const T& value, MBasic<B>& result) const;
void DefTime(temporalalgebra::Periods& per) const;
void AtInstant(const Instant& inst, IBasic<B>& result) const;
void AtPeriods(const temporalalgebra::Periods& per, MBasic<B>& result) const;
void Initial(IBasic<B>& result) const;
void Final(IBasic<B>& result) const;
void InitialInstant(Instant& result) const;
void FinalInstant(Instant& result) const;
void Inside(const typename B::coll& coll,
temporalalgebra::MBool& result) const;
void Fill(MBasic<B>& result, datetime::DateTime& duration) const;
void Concat(const MBasic<B>& src1, const MBasic<B>& src2);
void Compress(MBasic<B>& result) const;
void GetPart(const int from, const int to, MBasic<B>& result);
#ifdef RECODE
void Recode(const std::string& from, const std::string& to,MBasic<B>& result);
#endif
NewPair<int, int> LongestCommonSubsequence(const MBasic<B>& mb);
std::ostream& Print(std::ostream& os) const;
double Distance_FIRST(const MBasic<B>& mb) const;
double Distance_LAST(const MBasic<B>& mb) const;
double Distance_FIRST_LAST(const MBasic<B>& mb, const LabelFunction lf) const;
double Distance_ALL(const MBasic<B>& mb, const LabelFunction lf) const;
double Distance_ALL_DURATION(const MBasic<B>& mb, const LabelFunction lf)
const;
double Distance_ALL_INTERVALS(const MBasic<B>& mb, const LabelFunction lf)
const;
double Distance_EQUAL_LABELS(const MBasic<B>& mb, const LabelFunction lf)
const;
double Distance_COSINUS_SIM(const MBasic<B>& mb);
double Distance_TF_IDF(const MBasic<B>& mb);
double Distance(const MBasic<B>& mb, const DistanceFunction df = ALL,
const LabelFunction lf = TRIVIAL, const double threshold = 1.0) const;
int CommonPrefixSuffix(const MBasic<B>& mb, const bool prefix);
double DistanceSym(const MBasic<B>& mb, const DistanceFunSym distfun);
void InsertLabels(std::vector<std::string>& result) const;
void InsertLabels(std::set<std::string>& result) const;
void FrequencyVector(InvertedFile& inv, std::vector<double>& fv,
const bool useIdf = false) const;
protected:
Flob values;
DbArray<typename B::unitelem> units;
int noChars;
};
/*
\section{Class ~MBasics~}
*/
template<class B>
class MBasics : public Attribute {
public:
typedef B base;
MBasics() {}
explicit MBasics(int n) : Attribute(n > 0), values(8), units(n), pos(1),
noChars(0) {}
explicit MBasics(const MBasics& mbs);
~MBasics() {}
static ListExpr Property();
static int SizeOfObj() {return sizeof(MBasics<B>);}
static bool CheckKind(ListExpr type, ListExpr& errorInfo);
static const std::string BasicType() {return "m" + B::BasicType();}
static bool checkType(ListExpr t);
int NumOfFLOBs() const {return 3;}
Flob* GetFLOB(const int i);
size_t Sizeof() const {return sizeof(*this);}
int Compare(const Attribute* arg) const;
bool Adjacent(const Attribute *arg) const {return false;}
Attribute *Clone() const;
size_t HashValue() const {return pos.Size() * units.Size();}
void CopyFrom(const Attribute* right) {*this = *((MBasics<B>*)right);}
MBasics<B>& operator=(const MBasics<B>& src);
ListExpr ToListExpr(ListExpr typeInfo);
bool ReadFrom(ListExpr LE, ListExpr typeInfo);
void Destroy() {values.destroy(); units.destroy(); pos.destroy();}
int getUnitEndPos(const int i) const;
ListExpr valuesToListExpr(int start, int end);
ListExpr unitToListExpr(int i);
bool readValues(ListExpr valuelist);
bool readUnit(ListExpr unitlist);
int GetNoChars() const {return noChars;}
void serialize(size_t &size, char *&bytes) const;
static MBasics<B>* deserialize(const char *bytes);
int Position(const Instant& inst, const bool ignoreClosedness = false) const;
int FirstPosFrom(const Instant& inst) const;
int LastPosUntil(const Instant& inst) const;
void Get(const int i, UBasics<B>& result) const;
void GetBasics(const int i, B& result) const;
bool IsEmpty() const {return units.Size() == 0;}
void GetValues(const int i, std::set<typename B::base>& result) const;
void GetInterval(const int i, temporalalgebra::SecInterval& result) const;
void GetInterval(temporalalgebra::SecInterval& result) const;
int GetNoComponents() const {return units.Size();}
int GetNoValues() const {return pos.Size();}
void Clear();
void StartBulkLoad() {assert(IsDefined());}
void EndBulkLoad(const bool sort = true, const bool checkvalid = true);
bool IsValid() const;
void Add(const UBasics<B>& ut);
void Add(const temporalalgebra::SecInterval& iv, const B& values);
void MergeAdd(const UBasics<B>& ut);
void MergeAdd(const temporalalgebra::SecInterval& iv, const B& values);
bool Passes(const typename B::single& sg) const;
bool Passes(const B& bs) const;
template<class T>
bool Passes(const T& value) const;
void At(const typename B::single& sg, MBasics<B>& result) const;
void At(const B& bs, MBasics<B>& result) const;
template<class T>
void At(const T& value, MBasics<B>& result) const;
void DefTime(temporalalgebra::Periods& per) const;
void AtInstant(const Instant& inst, IBasics<B>& result) const;
void AtPeriods(const temporalalgebra::Periods& per, MBasics<B>& result) const;
void Initial(IBasics<B>& result) const;
void Final(IBasics<B>& result) const;
void InitialInstant(Instant& result) const;
void FinalInstant(Instant& result) const;
void Fill(MBasics<B>& result, datetime::DateTime& duration) const;
void Concat(const MBasics<B>& src1, const MBasics<B>& src2);
void Compress(MBasics<B>& result) const;
#ifdef RECODE
void Recode(const std::string& from,const std::string& to,MBasics<B>& result);
#endif
std::ostream& Print(std::ostream& os) const;
double Distance_FIRST_LAST(const MBasics<B>& mbs,
const LabelFunction lf) const;
double Distance_ALL(const MBasics<B>& mbs, const LabelFunction lf) const;
double Distance(const MBasics<B>& mbs, const DistanceFunction df = ALL,
const LabelFunction lf = TRIVIAL, const double threshold = 1.0) const;
int CommonPrefixSuffix(const MBasics<B>& mbs, const bool prefix);
double DistanceSym(const MBasics<B>& mbs, const DistanceFunSym distfun);
void InsertLabels(std::vector<std::string>& result) const;
void InsertLabels(std::set<std::string>& result) const;
void FrequencyVector(InvertedFile& inv, std::vector<double>& fv,
const bool useIdf = false) const;
protected:
Flob values;
DbArray<SymbolicUnit> units;
DbArray<typename B::arrayelem> pos;
int noChars;
};
/*
\section{Class ~MLabel~}
*/
class MLabel : public MBasic<Label> {
public:
MLabel() {}
MLabel(unsigned int n) : MBasic<Label>(n) {}
void createML(const int size, const int number,
std::vector<std::string>& labels);
void convertFromMString(const temporalalgebra::MString& source);
};
class MLabels : public MBasics<Labels> {
public:
MLabels() {}
MLabels(unsigned int n) : MBasics<Labels>(n) {}
};
class MPlace : public MBasic<Place> {
public:
MPlace() {}
MPlace(unsigned int n) : MBasic<Place>(n) {}
};
class MPlaces : public MBasics<Places> {
public:
MPlaces() {}
MPlaces(unsigned int n) : MBasics<Places>(n) {}
};
typedef IBasic<Label> ILabel;
typedef IBasic<Place> IPlace;
typedef IBasics<Labels> ILabels;
typedef IBasics<Places> IPlaces;
typedef UBasic<Label> ULabel;
typedef UBasic<Place> UPlace;
typedef UBasics<Labels> ULabels;
typedef UBasics<Places> UPlaces;
// typedef MBasics<Labels> MLabels;
// typedef MBasic<Place> MPlace;
// typedef MBasics<Places> MPlaces;
/*
\section{Implementation of Class ~IBasic~}
\subsection{Constructors}
*/
template<class B>
IBasic<B>::IBasic(const Instant& inst, const B& val) :
temporalalgebra::Intime<B>(inst, val) {
SetDefined(inst.IsDefined() && val.IsDefined());
}
template<class B>
IBasic<B>::IBasic(const IBasic& rhs) :
temporalalgebra::Intime<B>(rhs.instant, rhs.value) {
SetDefined(rhs.IsDefined());
}
/*
\subsection{Function ~Property~}
*/
template<class B>
ListExpr IBasic<B>::Property() {
if (BasicType() == "ilabel") {
return gentc::GenProperty("-> DATA", BasicType(), "(<instant> <label>)",
"(\"2014-02-26\" \'Dortmund\')");
}
if (BasicType() == "iplace") {
return gentc::GenProperty("-> DATA", BasicType(), "(<instant> <place>)",
"(\"2014-02-18\" (\'Dortmund\' 1909))");
}
return gentc::GenProperty("-> DATA", BasicType(), "Error: invalid type.", "");
}
/*
\subsection{Function ~CheckKind~}
*/
template<class B>
bool IBasic<B>::CheckKind(ListExpr type, ListExpr& errorInfo) {
return nl->IsEqual(type, IBasic<B>::BasicType());
}
/*
\subsection{Function ~ToListExpr~}
*/
template<class B>
ListExpr IBasic<B>::ToListExpr(ListExpr typeInfo) {
if (!temporalalgebra::Intime<B>::IsDefined()) {
return nl->SymbolAtom(Symbol::UNDEFINED());
}
return nl->TwoElemList(this->instant.ToListExpr(false),
this->value.ToListExpr(nl->Empty()));
}
/*
\subsection{Function ~ReadFrom~}
*/
template<class B>
bool IBasic<B>::ReadFrom(ListExpr LE, ListExpr typeInfo) {
this->SetDefined(false);
if (listutils::isSymbolUndefined(LE)) {
return true;
}
if (!nl->HasLength(LE, 2)) {
return false;
}
if (this->instant.ReadFrom(nl->First(LE), nl->Empty()) &&
this->value.ReadFrom(nl->Second(LE), nl->Empty())) {
this->SetDefined(this->instant.IsDefined() && this->value.IsDefined());
return true;
}
return false;
}
/*
\subsection{Function ~Val~}
*/
template<class B>
void IBasic<B>::Val(B& result) const {
if (!this->IsDefined()) {
result.SetDefined(false);
return;
}
result.CopyFrom(&(this->value));
}
/*
\section{Implementation of Class ~IBasics~}
\subsection{Constructors}
*/
template<class B>
IBasics<B>::IBasics(const Instant& inst, const B& values) :
temporalalgebra::Intime<B>(inst, values) {}
/*
\subsection{Function ~Property~}
*/
template<class B>
ListExpr IBasics<B>::Property() {
if (B::BasicType() == Labels::BasicType()) {
return gentc::GenProperty("-> DATA", BasicType(), "(<instant> <labels>)",
"(\"2014-02-18\" (\"Dortmund\" \"Mailand\"))");
}
if (B::BasicType() == Places::BasicType()) {
return gentc::GenProperty("-> DATA", BasicType(), "(<instant> <places>)",
"(\"2014-02-18\" ((\"Dortmund\" 1909) (\"Mailand\" 1899)))");
}
return gentc::GenProperty("-> DATA", BasicType(), "Error: invalid type.", "");
}
/*
\subsection{Function ~CheckKind~}
*/
template<class B>
bool IBasics<B>::CheckKind(ListExpr type, ListExpr& errorInfo) {
return nl->IsEqual(type, IBasics<B>::BasicType());
}
/*
\subsection{Function ~ToListExpr~}
*/
template<class B>
ListExpr IBasics<B>::ToListExpr(ListExpr typeInfo) {
if (!this->IsDefined()) {
return nl->SymbolAtom(Symbol::UNDEFINED());
}
return nl->TwoElemList(this->instant.ToListExpr(false),
this->value.ToListExpr(nl->Empty()));
}
/*
\subsection{Function ~ReadFrom~}
*/
template<class B>
bool IBasics<B>::ReadFrom(ListExpr LE, ListExpr typeInfo) {
this->SetDefined(false);
if (listutils::isSymbolUndefined(LE)) {
return true;
}
if (!nl->HasLength(LE, 2)) {
return false;
}
if (this->instant.ReadFrom(nl->First(LE), nl->Empty()) &&
this->value.ReadFrom(nl->Second(LE), nl->Empty())) {
this->SetDefined(this->instant.IsDefined() && this->value.IsDefined());
return true;
}
return false;
}
/*
\subsection{Function ~Val~}
*/
template<class B>
void IBasics<B>::Val(B& result) const {
if (!this->IsDefined()) {
result.SetDefined(false);
return;
}
result = this->value;
}
/*
\section{Implementation of class ~UBasic~}
\subsection{Constructors}
*/
template<class B>
UBasic<B>::UBasic(const temporalalgebra::SecInterval &iv, const B& val)
: temporalalgebra::ConstTemporalUnit<B>(iv, val) {
this->SetDefined(iv.IsDefined() && val.IsDefined());
}
template<class B>
UBasic<B>::UBasic(const temporalalgebra::Interval<datetime::DateTime>& iv,
const B& b1, const B& b2) : temporalalgebra::ConstTemporalUnit<B>(iv, b1) {
assert(b1 == b2);
this->SetDefined(iv.IsDefined() && b1.IsDefined());
}
template<class B>
UBasic<B>::UBasic(const UBasic<B>& ub) :
temporalalgebra::ConstTemporalUnit<B>(ub) {
this->SetDefined(ub.IsDefined());
}
/*
\subsection{Operator ~==~}
*/
template<class B>
bool UBasic<B>::operator==(const UBasic<B>& rhs) const {
return Compare(&rhs) == 0;
}
/*
\subsection{Function ~Property~}
*/
template<class B>
ListExpr UBasic<B>::Property() {
if (B::BasicType() == Label::BasicType()) {
return gentc::GenProperty("-> DATA", BasicType(), "(<interval> <label>)",
"((\"2014-02-18\" \"2014-02-19-13:00\" TRUE FALSE) \"Dortmund\")");
}
if (B::BasicType() == Place::BasicType()) {
return gentc::GenProperty("-> DATA", BasicType(), "(<interval> <place>)",
"((\"2014-02-18\" \"2014-02-19-13:00\" TRUE FALSE) (\"Dortmund\" 1909))");
}
return gentc::GenProperty("-> DATA", BasicType(), "Error: invalid type.", "");
}
/*
\subsection{Function ~CheckKind~}
*/
template<class B>
bool UBasic<B>::CheckKind(ListExpr type, ListExpr& errorInfo) {
return nl->IsEqual(type, UBasic<B>::BasicType());
}
/*
\subsection{Function ~ToListExpr~}
*/
template<class B>
ListExpr UBasic<B>::ToListExpr(ListExpr typeInfo) {
if (!this->IsDefined()) {
return nl->SymbolAtom(Symbol::UNDEFINED());
}
return nl->TwoElemList((
(temporalalgebra::SecInterval)this->timeInterval).ToListExpr (nl->Empty()),
this->constValue.ToListExpr(nl->Empty()));
}
/*
\subsection{Function ~ReadFrom~}
*/
template<class B>
bool UBasic<B>::ReadFrom(ListExpr LE, ListExpr typeInfo) {
this->SetDefined(false);
if (listutils::isSymbolUndefined(LE)) {
return true;
}
if (!nl->HasLength(LE, 2)) {
return false;
}
temporalalgebra::SecInterval iv(true);
SecondoCatalog* sc = SecondoSystem::GetCatalog();
if (iv.ReadFrom(nl->First(LE),
sc->GetTypeExpr(temporalalgebra::SecInterval::BasicType())) &&
this->constValue.ReadFrom(nl->Second(LE), nl->Empty())) {
this->timeInterval = iv;
this->SetDefined(this->timeInterval.IsDefined() &&
this->constValue.IsDefined());
return true;
}
return false;
}
/*
\subsection{Function ~Initial~}
*/
template<class B>
void UBasic<B>::Initial(IBasic<B>& result) const {
if (this->IsDefined()) {
result.instant = this->timeInterval.start;
result.value.CopyFrom(&(this->constValue));
result.SetDefined(true);
}
else {
result.SetDefined(false);
}
}
/*
\subsection{Function ~Final~}
*/
template<class B>
void UBasic<B>::Final(IBasic<B>& result) const {
if (this->IsDefined()) {
result.instant = this->timeInterval.end;
result.value.CopyFrom(&(this->constValue));
result.SetDefined(true);
}
else {
result.SetDefined(false);
}
}
/*
\subsection{Function ~GetInterval~}
*/
template<class B>
void UBasic<B>::GetInterval(temporalalgebra::SecInterval& result) const {
if (this->IsDefined()) {
result = this->timeInterval;
}
else {
result.SetDefined(false);
}
}
/*
\section{Implementation of class ~UBasics~}
\subsection{Constructors}
*/
template<class B>
UBasics<B>::UBasics(const temporalalgebra::SecInterval &iv, const B& values)
: temporalalgebra::ConstTemporalUnit<B>(iv, values) {}
/*
\subsection{Function ~Property~}
*/
template<class B>
ListExpr UBasics<B>::Property() {
if (B::BasicType() == Labels::BasicType()) {
return gentc::GenProperty("-> DATA", BasicType(), "(<interval> <labels>)",
"((\"2014-02-18\" \"2014-02-19-13:00\" TRUE FALSE) (\"Dortmund\" "
"\"Mailand\"))");
}
if (B::BasicType() == Places::BasicType()) {
return gentc::GenProperty("-> DATA", BasicType(), "(<interval> <places>)",
"((\"2014-02-18\" \"2014-02-19-13:00\" TRUE FALSE) ((\"Dortmund\" 1909) "
"(\"Mailand\" 1899)))");
}
return gentc::GenProperty("-> DATA", BasicType(), "Error: invalid type.", "");
}
/*
\subsection{Function ~CheckKind~}
*/
template<class B>
bool UBasics<B>::CheckKind(ListExpr type, ListExpr& errorInfo) {
return nl->IsEqual(type, UBasics<B>::BasicType());
}
/*
\subsection{Function ~ToListExpr~}
*/
template<class B>
ListExpr UBasics<B>::ToListExpr(ListExpr typeInfo) {
if (!this->IsDefined()) {
return nl->SymbolAtom(Symbol::UNDEFINED());
}
return nl->TwoElemList((
(temporalalgebra::SecInterval)this->timeInterval).ToListExpr (nl->Empty()),
this->constValue.ToListExpr(nl->Empty()));
}
/*
\subsection{Function ~ReadFrom~}
*/
template<class B>
bool UBasics<B>::ReadFrom(ListExpr LE, ListExpr typeInfo) {
this->SetDefined(false);
if (listutils::isSymbolUndefined(LE)) {
return true;
}
if (!nl->HasLength(LE, 2)) {
return false;
}
temporalalgebra::SecInterval iv(true);
SecondoCatalog* sc = SecondoSystem::GetCatalog();
if (iv.ReadFrom(nl->First(LE),
sc->GetTypeExpr(temporalalgebra::SecInterval::BasicType())) &&
this->constValue.ReadFrom(nl->Second(LE), nl->Empty())) {
this->timeInterval = iv;
this->SetDefined(this->timeInterval.IsDefined() &&
this->constValue.IsDefined());
return true;
}
return false;
}
/*
\subsection{Function ~Initial~}
*/
template<class B>
void UBasics<B>::Initial(IBasics<B>& result) const {
if (this->IsDefined()) {
result.instant = this->timeInterval.start;
result.value = this->constValue;
result.SetDefined(true);
}
else {
result.SetDefined(false);
}
}
/*
\subsection{Function ~Final~}
*/
template<class B>
void UBasics<B>::Final(IBasics<B>& result) const {
if (this->IsDefined()) {
result.instant = this->timeInterval.end;
result.value = this->constValue;
result.SetDefined(true);
}
else {
result.SetDefined(false);
}
}
/*
\subsection{Function ~GetInterval~}
*/
template<class B>
void UBasics<B>::GetInterval(temporalalgebra::SecInterval& result) const {
if (this->IsDefined()) {
result = this->timeInterval;
}
else {
result.SetDefined(false);
}
}
/*
\section{Implementation of class ~MBasic~}
\subsection{Constructors}
*/
template<class B>
MBasic<B>::MBasic(const MBasic &mb) : Attribute(mb.IsDefined()),
values(mb.values.getSize()), units(mb.GetNoComponents()),
noChars(mb.GetNoChars()) {
if (IsDefined()) {
values.copyFrom(mb.values);
units.copyFrom(mb.units);
}
}
/*
\subsection{Function ~Property~}
*/
template<class B>
ListExpr MBasic<B>::Property() {
if (B::BasicType() == Label::BasicType()) {
return gentc::GenProperty("-> DATA", BasicType(),
"((<interval> <label>) (<interval> <label>) ...)",
"(((\"2014-02-27\" \"2014-02-27-09:48\" TRUE FALSE) \"Dortmund\") "
"((\"2014-05-17\" \"2014-05-17-22:00\" TRUE FALSE) \"Berlin\"))");
}
if (B::BasicType() == Place::BasicType()) {
return gentc::GenProperty("-> DATA", BasicType(),
"((<interval> <place>) (<interval> <place>) ...)",
"(((\"2014-02-27\" \"2014-02-27-09:48\" TRUE FALSE) (\"Dortmund\" 1909)) "
"((\"2014-05-17\" \"2014-05-17-22:00\" TRUE FALSE) (\"Berlin\" 4)))");
}
return gentc::GenProperty("-> DATA", BasicType(), "Error: invalid type.", "");
}
/*
\subsection{Function ~GetFLOB~}
*/
template<class B>
Flob* MBasic<B>::GetFLOB(const int i) {
assert((i >= 0) && (i < NumOfFLOBs()));
return (i == 0 ? &values : &units);
}
/*
\subsection{Function ~KindCheck~}
*/
template<class B>
bool MBasic<B>::CheckKind(ListExpr type, ListExpr& errorInfo) {
return nl->IsEqual(type, MBasic<B>::BasicType());
}
/*
\subsection{Function ~Compare~}
*/
template<class B>
int MBasic<B>::Compare(const Attribute* arg) const {
if (GetNoComponents() > ((MBasic<B>*)arg)->GetNoComponents()) {
return 1;
}
if (GetNoComponents() < ((MBasic<B>*)arg)->GetNoComponents()) {
return -1;
}
UBasic<B> ub1(true), ub2(true);
for (int i = 0; i < GetNoComponents(); i++) {
Get(i, ub1);
((MBasic<B>*)arg)->Get(i, ub2);
int comp = ub1.Compare(&ub2);
if (comp != 0) {
return comp;
}
}
return 0;
}
/*
\subsection{Function ~HashValue~}
*/
template<class B>
size_t MBasic<B>::HashValue() const {
if (!IsDefined() || IsEmpty()) {
return 0;
}
typename B::unitelem unit;
units.Get(0, unit);
return values.getSize() * unit.iv.HashValue();
}
/*
\subsection{Function ~CopyFrom~}
*/
template<class B>
void MBasic<B>::CopyFrom(const Attribute *arg) {
if (!arg->IsDefined()) {
SetDefined(false);
return;
}
SetDefined(true);
values.copyFrom(((MBasic<B>*)arg)->values);
units.copyFrom(((MBasic<B>*)arg)->units);
noChars = ((MBasic<B>*)arg)->noChars;
}
/*
\subsection{Function ~=~}
*/
template<class B>
MBasic<B>& MBasic<B>::operator=(const MBasic<B>& src) {
Attribute::operator=(src);
units.copyFrom(src.units);
values.copyFrom(src.values);
noChars = src.noChars;
return *this;
}
/*
\subsection{Function ~unitToListExpr~}
*/
template<class B>
ListExpr MBasic<B>::unitToListExpr(const int i) {
assert(i < GetNoComponents());
typename B::base value;
GetValue(i, value);
typename B::unitelem unit;
units.Get(i, unit);
SecondoCatalog* sc = SecondoSystem::GetCatalog();
return nl->TwoElemList(unit.iv.ToListExpr(sc->GetTypeExpr(
temporalalgebra::SecInterval::BasicType())),
B::getList(value));
}
/*
\subsection{Function ~ToListExpr~}
*/
template<class B>
ListExpr MBasic<B>::ToListExpr(ListExpr typeInfo) {
if (!IsDefined()) {
return nl->SymbolAtom(Symbol::UNDEFINED());
}
if (IsEmpty()) {
return nl->Empty();
}
ListExpr result = nl->OneElemList(unitToListExpr(0));
ListExpr last = result;
for (int i = 1; i < GetNoComponents(); i++) {
last = nl->Append(last, unitToListExpr(i));
}
return result;
}
/*
\subsection{Function ~ReadFrom~}
*/
template<class B>
bool MBasic<B>::readUnitFrom(ListExpr LE) {
if (!nl->HasLength(LE, 2)) {
return false;
}
temporalalgebra::SecInterval iv;
SecondoCatalog* sc = SecondoSystem::GetCatalog();
if (!iv.ReadFrom(nl->First(LE),
sc->GetTypeExpr(temporalalgebra::SecInterval::BasicType()))) {
return false;
}
typename B::unitelem unit(GetNoChars(), 0);
unit.iv = iv;
std::string text;
if (!B::readValueFrom(nl->Second(LE), text, unit)) {
return false;
}
units.Append(unit);
text = text.substr(1, text.length() - 2);
if (text.length() > 0) {
const char *bytes = text.c_str();
if (values.getSize() == 0) {
values.resize(1024);
}
if (noChars + text.length() >= values.getSize()) {
values.resize(2 * values.getSize());
}
values.write(bytes, text.length(), noChars);
noChars += text.length();
}
return true;
}
/*
\subsection{Function ~ReadFrom~}
*/
template<class B>
bool MBasic<B>::ReadFrom(ListExpr LE, ListExpr typeInfo) {
SetDefined(false);
Clear();
if (listutils::isSymbolUndefined(LE)) {
return true;
}
ListExpr rest = LE;
while (!nl->IsEmpty(rest)) {
if (!readUnitFrom(nl->First(rest))) {
return false;
}
rest = nl->Rest(rest);
}
SetDefined(true);
return true;
}
/*
\subsection{Function ~serialize~}
*/
template<class B>
void MBasic<B>::serialize(size_t &size, char *&bytes) const {
size = 0;
bytes = 0;
if (!IsDefined()) {
return;
}
size_t rootSize = Sizeof();
size = 2 * sizeof(size_t) + values.getSize() + units.GetFlobSize();
bytes = new char[size];
cout << "memcpy1" << endl;
memcpy(bytes, (void*)&rootSize, sizeof(size_t));
cout << "ok, now memcpy2" << endl;
memcpy(bytes + sizeof(size_t), (void*)this, rootSize);
size_t offset = sizeof(size_t) + rootSize;
char* data = values.getData();
cout << "ok, now memcpy3" << endl;
memcpy(bytes + offset, data, values.getSize());
delete[] data;
offset += values.getSize();
data = units.getData();
cout << "ok, now memcpy4" << endl;
memcpy(bytes + offset, data, units.GetFlobSize());
cout << "ok" << endl;
delete[] data;
cout << "buffer \'data\' deleted" << endl;
}
/*
\subsection{Function ~deserialize~}
*/
template<class B>
MBasic<B>* MBasic<B>::deserialize(const char *bytes) {
ListExpr typeExpr = nl->SymbolAtom(BasicType());
int algebraId, typeId;
std::string typeName;
SecondoCatalog* sc = SecondoSystem::GetCatalog();
sc->LookUpTypeExpr(typeExpr, typeName, algebraId, typeId);
size_t rootSize;
memcpy((void*)&rootSize, bytes, sizeof(size_t));
char* root = new char[rootSize];
memcpy(root, bytes + sizeof(size_t), rootSize);
AlgebraManager* am = SecondoSystem::GetAlgebraManager();
ListExpr nType = sc->NumericType(typeExpr);
Attribute* attr = (Attribute*)(am->CreateObj(algebraId, typeId)(nType)).addr;
attr = attr->Create(attr, root, rootSize, algebraId, typeId);
delete[] root;
size_t offset = rootSize + sizeof(size_t);
for (int i = 0; i < attr->NumOfFLOBs(); i++) {
Flob* flob = attr->GetFLOB(i);
size_t size = flob->getSize();
flob->kill();
char* fb = new char[size];
memcpy(fb, bytes + offset, size);
flob->createFromBlock(*flob, fb, size, false);
delete[] fb;
offset += size;
}
return (MBasic<B>*)attr;
}
/*
\subsection{Function ~Position~}
*/
template<class B>
int MBasic<B>::Position(const Instant& inst,
const bool ignoreClosedness /* = false */) const {
assert(IsDefined());
assert(inst.IsDefined());
int first = 0, last = GetNoComponents() - 1;
Instant t1 = inst;
while (first <= last) {
int mid = (first + last) / 2;
if ((mid < 0) || (mid >= GetNoComponents())) {
return -1;
}
typename B::unitelem unit;
units.Get(mid, unit);
if (((temporalalgebra::Interval<Instant>)(unit.iv)).Contains(t1,
ignoreClosedness)) {
return mid;
}
else { // not contained
if ((t1 > unit.iv.end) || (t1 == unit.iv.end)) {
first = mid + 1;
}
else if ((t1 < unit.iv.start) || (t1 == unit.iv.start)) {
last = mid - 1;
}
else {
return -1; // should never be reached.
}
}
}
return -1;
}
/*
\subsection{Function ~FirstPosFrom~}
*/
template<class B>
int MBasic<B>::FirstPosFrom(const Instant& inst) const {
assert(IsDefined());
assert(inst.IsDefined());
if (IsEmpty()) {
return -1;
}
typename B::unitelem unit;
units.Get(0, unit);
if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
return 0; //
}
units.Get(GetNoComponents() - 1, unit);
if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
return -1;
}
int first(0), last(GetNoComponents() - 1);
while (first <= last) {
int mid = (first + last) / 2;
units.Get(mid, unit);
if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
return mid;
}
first = mid + 1;
}
else if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
int beforeMid = mid - 1;
units.Get(beforeMid, unit);
if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
return mid;
}
else if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
last = mid - 1;
}
else {
return mid;
}
}
else {
return mid;
}
}
return -1;
}
/*
\subsection{Function ~LastPosUntil~}
*/
template<class B>
int MBasic<B>::LastPosUntil(const Instant& inst) const {
assert(IsDefined());
assert(inst.IsDefined());
if (IsEmpty()) {
return -1;
}
typename B::unitelem unit;
units.Get(0, unit);
if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
return -1; //
}
units.Get(GetNoComponents() - 1, unit);
if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
return GetNoComponents() - 1;
}
int first(0), last(GetNoComponents() - 1);
while (first <= last) {
int mid = (first + last) / 2;
units.Get(mid, unit);
if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
return mid;
}
last = mid - 1;
}
else if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
int afterMid = mid + 1;
units.Get(afterMid, unit);
if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
return mid;
}
else if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
first = mid + 1;
}
else {
return mid;
}
}
else {
return mid;
}
}
return -1;
}
/*
\subsection{Function ~Get~}
*/
template<class B>
void MBasic<B>::Get(const int i, UBasic<B>& result) const {
assert((i >= 0) && (i < GetNoComponents()));
result.SetDefined(IsDefined());
if (IsDefined()) {
typename B::unitelem unit;
units.Get(i, unit);
result.timeInterval = unit.iv;
GetBasic(i, result.constValue);
}
}
/*
\subsection{Function ~GetDuration~}
*/
template<class B>
void MBasic<B>::GetDuration(datetime::DateTime& result) const {
temporalalgebra::SecInterval iv(true);
for (int i = 0; i < GetNoComponents(); i++) {
GetInterval(i, iv);
result += (iv.end - iv.start);
}
}
/*
\subsection{Function ~GetInterval~}
*/
template<class B>
void MBasic<B>::GetInterval(const int i,
temporalalgebra::SecInterval& result) const {
assert((i >= 0) && (i < GetNoComponents()));
result.SetDefined(true);
typename B::unitelem unit;
units.Get(i, unit);
result = unit.iv;
}
template<class B>
void MBasic<B>::GetInterval(temporalalgebra::SecInterval& result) const {
if (this->IsDefined() && !this->IsEmpty()) {
temporalalgebra::SecInterval first(true), last(true);
this->GetInterval(0, first);
this->GetInterval(this->GetNoComponents() - 1, last);
result.Set(first.start, last.end, first.lc, last.rc);
}
else {
result.SetDefined(false);
}
}
/*
\subsection{Function ~GetBasic~}
*/
template<class B>
void MBasic<B>::GetBasic(const int i, B& result) const {
assert((i >= 0) && (i < GetNoComponents()));
result.SetDefined(IsDefined());
if (IsDefined()) {
typename B::base value;
GetValue(i, value);
result.SetValue(value);
}
}
/*
\subsection{Function ~GetValue~}
*/
template<class B>
void MBasic<B>::GetValue(const int i, typename B::base& result) const {
assert((i >= 0) && (i < GetNoComponents()));
typename B::unitelem cur, next;
units.Get(i, cur);
unsigned int size;
if (cur.pos != UINT_MAX) {
if (i + 1 < GetNoComponents()) {
units.Get(i + 1, next);
if (next.pos != UINT_MAX) {
size = next.pos - cur.pos;
}
else {
size = GetNoChars() - cur.pos;
}
}
else {
size = GetNoChars() - cur.pos;
}
char* bytes = new char[size];
values.read(bytes, size, cur.pos);
std::string text(bytes, size);
delete[] bytes;
B::buildValue(text, cur, result);
}
else {
B::buildValue("", cur, result);
}
}
/*
\subsection{Function ~IsValid~}
*/
template<class B>
bool MBasic<B>::IsValid() const {
if (!IsDefined() || IsEmpty()) {
return true;
}
typename B::unitelem lastUnit, unit;
units.Get(0, lastUnit);
if (!lastUnit.iv.IsValid()) {
return false;
}
if (GetNoComponents() == 1) {
return true;
}
for (int i = 1; i < GetNoComponents(); i++) {
units.Get(i, unit);
if (!unit.iv.IsValid()) {
return false;
}
if (lastUnit.iv.end > unit.iv.start) {
return false;
}
if (!lastUnit.iv.Disjoint(unit.iv)) {
return false;
}
lastUnit = unit;
}
return true;
}
/*
\subsection{Function ~EndBulkLoad~}
*/
template<class B>
void MBasic<B>::EndBulkLoad(const bool sort, const bool checkvalid) {
if (!IsDefined()) {
units.clean();
}
units.TrimToSize();
values.resize(GetNoChars());
assert(IsValid());
}
/*
\subsection{Function ~Add~}
*/
template<class B>
void MBasic<B>::Add(const UBasic<B>& ub) {
assert(ub.IsDefined());
assert(ub.IsValid());
UBasic<B> ub2(ub);
if (!IsDefined()) {
return;
}
temporalalgebra::SecInterval iv;
typename B::unitelem unit(GetNoChars(), ub.constValue.GetRef());
unit.iv = ub.timeInterval;
units.Append(unit);
std::string text = ub.constValue.GetLabel();
if (text.length() > 0) {
const char *bytes = text.c_str();
if (values.getSize() == 0) {
values.resize(1024);
}
if (noChars + text.length() >= values.getSize()) {
values.resize(2 * values.getSize());
}
values.write(bytes, text.length(), noChars);
noChars += text.length();
}
}
template<class B>
void MBasic<B>::Add(const temporalalgebra::SecInterval& iv, const B& value) {
assert(iv.IsDefined() && value.IsDefined());
B value2(value);
ListExpr unitlist = nl->TwoElemList(iv.ToListExpr(nl->Empty()),
value2.ToListExpr(nl->Empty()));
if (!readUnitFrom(unitlist)) {
SetDefined(false);
}
}
/*
\subsection{Function ~MergeAdd~}
*/
template<class B>
void MBasic<B>::MergeAdd(const UBasic<B>& ub) {
assert(IsDefined());
if (!ub.IsDefined() || !ub.IsValid()) {
cout << __FILE__ << "," << __LINE__ << ":" << __PRETTY_FUNCTION__
<< " MergeAdd(Unit): Unit is undefined or invalid:";
ub.Print(cout); cout << endl;
assert(false);
}
if (!IsEmpty()) {
bool extend = false;
typename B::unitelem lastUnit;
units.Get(GetNoComponents() - 1, lastUnit);
if ((lastUnit.iv.end == ub.timeInterval.start) &&
(lastUnit.iv.rc || ub.timeInterval.lc)) { // adjacent intervals
B value1(true), value2(true);
GetBasic(GetNoComponents() - 1, value1);
value2 = ub.constValue;
if (value1 == value2) {
lastUnit.iv.end = ub.timeInterval.end; // extend last interval
lastUnit.iv.rc = ub.timeInterval.rc;
units.Put(GetNoComponents() - 1, lastUnit);
extend = true;
}
}
if (!extend && lastUnit.iv.Before(ub.timeInterval)) {
Add(ub);
}
}
else { // first unit
Add(ub);
}
}
/*
\subsection{Function ~Passes~}
*/
template<class B>
bool MBasic<B>::Passes(const B& basic) const {
if (!IsDefined() || !basic.IsDefined()) {
return false;
}
typename B::base value1, value2;
basic.GetValue(value2);
for (int i = 0; i < GetNoComponents(); i++) {
GetValue(i, value1);
if (value1 == value2) {
return true;
}
}
return false;
}
template<class B>
template<class T>
bool MBasic<B>::Passes(const T& value) const {
if (!IsDefined() || !value.IsDefined()) {
return false;
}
Label lb(value.GetValue());
return Passes(lb);
}
/*
\subsection{Function ~At~}
*/
template<class B>
void MBasic<B>::At(const B& basic, MBasic<B>& result) const {
result.Clear();
if (!IsDefined() || !basic.IsDefined()) {
result.SetDefined(false);
return;
}
result.SetDefined(true);
typename B::base value1, value2;
basic.GetValue(value2);
typename B::unitelem unit;
SecondoCatalog* sc = SecondoSystem::GetCatalog();
for (int i = 0; i < GetNoComponents(); i++) {
GetValue(i, value1);
if (value1 == value2) {
units.Get(i, unit);
result.readUnitFrom(nl->TwoElemList(unit.iv.ToListExpr(sc->GetTypeExpr(
temporalalgebra::SecInterval::BasicType())),
B::getList(value1)));
}
}
}
template<class B>
template<class T>
void MBasic<B>::At(const T& value, MBasic<B>& result) const {
Label lb(value.GetValue());
At(lb, result);
}
/*
\subsection{Function ~DefTime~}
*/
template<class B>
void MBasic<B>::DefTime(temporalalgebra::Periods& per) const {
per.Clear();
per.SetDefined(IsDefined());
if (IsDefined()) {
typename B::unitelem unit;
for (int i = 0; i < GetNoComponents(); i++) {
units.Get(i, unit);
per.MergeAdd(unit.iv);
}
}
}
/*
\subsection{Function ~AtInstant~}
*/
template<class B>
void MBasic<B>::AtInstant(const Instant& inst, IBasic<B>& result) const {
if(!IsDefined() || !inst.IsDefined()) {
result.SetDefined(false);
return;
}
int pos = this->Position(inst);
if (pos == -1) {
result.SetDefined(false);
return;
}
result.SetDefined(true);
result.value.SetDefined(true);
typename B::unitelem unit;
units.Get(pos, unit);
GetBasic(pos, result.value);
result.instant = inst;
}
/*
\subsection{Function ~AtPeriods~}
*/
template<class B>
void MBasic<B>::AtPeriods(const temporalalgebra::Periods& per,
MBasic<B>& result) const {
result.Clear();
result.SetDefined(IsDefined() && per.IsDefined());
if (!IsDefined() || !per.IsDefined()) {
return;
}
if (IsEmpty() || per.IsEmpty()) {
return;
}
if (IsMaximumPeriods(per)) {
result.CopyFrom(this);
return;
}
assert(per.IsOrdered());
temporalalgebra::SecInterval ivS(true), ivP(true), ivR(true);
GetInterval(0, ivS);
GetInterval(GetNoComponents() - 1, ivP);
if (per.Before(ivS.start) || per.After(ivP.end)) {
return;
}
result.StartBulkLoad();
B val(true); // string | pair<string, unsigned int>
int i = 0, j = 0;
while ((i < GetNoComponents()) && (j < per.GetNoComponents())) {
GetInterval(i, ivS); // get source interval
per.Get(j, ivP); // get interval from periods
GetBasic(i, val); // get source value
if (ivS.Before(ivP)) {
i++;
}
else if (ivS.After(ivP)) {
j++;
}
else { // intervals overlap
ivS.Intersection(ivP, ivR);
ivR.SetDefined(true);
result.Add(ivR, val);
if (ivS.end == ivP.end) {
if (ivS.rc == ivP.rc) {
i++;
j++;
}
else if (ivP.rc == true) {
i++;
}
else {
j++;
}
}
else if (ivS.end < ivP.end) {
i++;
}
else {
j++;
}
}
}
result.EndBulkLoad(false);
}
/*
\subsection{Function ~Initial~}
*/
template<class B>
void MBasic<B>::Initial(IBasic<B>& result) const {
if (!IsDefined() || IsEmpty()) {
result.SetDefined(false);
return;
}
result.SetDefined(true);
typename B::unitelem unit;
units.Get(0, unit);
GetBasic(0, result.value);
result.instant = unit.iv.start;
}
/*
\subsection{Function ~Final~}
*/
template<class B>
void MBasic<B>::Final(IBasic<B>& result) const {
if (!IsDefined() || IsEmpty()) {
result.SetDefined(false);
return;
}
result.SetDefined(true);
typename B::unitelem unit;
units.Get(GetNoComponents() - 1, unit);
GetBasic(GetNoComponents() - 1, result.value);
result.instant = unit.iv.end;
}
/*
\subsection{Function ~InitialInstant~}
*/
template<class B>
void MBasic<B>::InitialInstant(Instant& result) const {
if (!IsDefined() || IsEmpty()) {
result.SetDefined(false);
return;
}
typename B::unitelem unit;
units.Get(0, unit);
result = unit.iv.start;
}
/*
\subsection{Function ~FinalInstant~}
*/
template<class B>
void MBasic<B>::FinalInstant(Instant& result) const {
if (!IsDefined() || IsEmpty()) {
result.SetDefined(false);
return;
}
typename B::unitelem unit;
units.Get(GetNoComponents() - 1, unit);
result = unit.iv.end;
}
/*
\subsection{Function ~Inside~}
*/
template<class B>
void MBasic<B>::Inside(const typename B::coll& coll,
temporalalgebra::MBool& result) const {
result.Clear();
if (!IsDefined() || !coll.IsDefined()) {
result.SetDefined(false);
return;
}
typename B::unitelem unit;
typename B::base value;
for (int i = 0; i < GetNoComponents(); i++) {
units.Get(i, unit);
GetValue(i, value);
CcBool res(true, coll.Contains(value));
temporalalgebra::UBool ub(unit.iv, res);
result.MergeAdd(ub);
}
}
/*
\subsection{Function ~Fill~}
*/
template<class B>
void MBasic<B>::Fill(MBasic<B>& result, datetime::DateTime& dur) const {
result.Clear();
result.SetDefined(true);
if (!IsDefined()) {
result.SetDefined(false);
return;
}
if (IsEmpty()) {
return;
}
UBasic<B> unit(true), lastUnit(true);
Get(0, lastUnit);
for (int i = 1; i < GetNoComponents(); i++) {
Get(i, unit);
if ((lastUnit.constValue == unit.constValue) &&
(unit.timeInterval.start - lastUnit.timeInterval.end <= dur)) {
lastUnit.timeInterval.end = unit.timeInterval.end;
lastUnit.timeInterval.rc = unit.timeInterval.rc;
}
else {
result.MergeAdd(lastUnit);
lastUnit = unit;
}
}
result.MergeAdd(lastUnit);
}
/*
\subsection{Function ~concat~}
*/
template<class B>
void MBasic<B>::Concat(const MBasic<B>& src1, const MBasic<B>& src2) {
Clear();
if (src1.IsEmpty()) {
CopyFrom(&src2);
return;
}
if (src2.IsEmpty()) {
CopyFrom(&src1);
return;
}
temporalalgebra::SecInterval iv1, iv2;
src1.GetInterval(src1.GetNoComponents() - 1, iv1);
src2.GetInterval(0, iv2);
SetDefined(src1.IsDefined() && src2.IsDefined() && iv1.Before(iv2));
if (!IsDefined()) {
return;
}
CopyFrom(&src1);
UBasic<B> unit(true);
for (int i = 0; i < src2.GetNoComponents(); i++) {
src2.Get(i, unit);
Add(unit);
}
}
/*
\subsection{Function ~Compress~}
*/
template<class B>
void MBasic<B>::Compress(MBasic<B>& result) const {
result.Clear();
result.SetDefined(IsDefined());
if(!IsDefined()) {
return;
}
UBasic<B> ub(true);
for (int i = 0; i < GetNoComponents(); i++) {
Get(i, ub);
result.MergeAdd(ub);
}
}
/*
\subsection{Function ~GetPart~}
*/
template<class B>
void MBasic<B>::GetPart(const int from, const int to, MBasic<B>& result) {
assert(from >= 0);
assert(to < GetNoComponents());
assert(from <= to);
result.SetDefined(true);
result.Clear();
UBasic<B> unit(true);
for (int i = from; i <= to; i++) {
Get(i, unit);
result.MergeAdd(unit);
}
}
#ifdef RECODE
/*
\subsection{Function ~Recode~}
*/
template<class B>
void MBasic<B>::Recode(const std::string& from, const std::string& to,
MBasic<B>& result) {
result.SetDefined(IsDefined());
if (!IsDefined()) {
return;
}
result.Clear();
typename B::base value, recoded;
temporalalgebra::SecInterval iv(true);
for (int i = 0; i < GetNoComponents(); i++) {
GetInterval(i, iv);
GetValue(i, value);
if (!RecodeFun::recode(value, from, to, recoded)) {
result.SetDefined(false);
return;
}
else {
B val(recoded);
result.Add(iv, val);
}
}
}
#endif
/*
\subsection{Function ~LongestCommonSubsequence~}
*/
template<class B>
NewPair<int, int> MBasic<B>::LongestCommonSubsequence(const MBasic<B>& mb) {
NewPair<int, int> result(0, 0);
if (IsEmpty() || mb.IsEmpty()) {
return result;
}
int dp[GetNoComponents() + 1][mb.GetNoComponents() + 1];
int lcsSize (0), maxPos(-1);
typename B::base value1, value2;
for (int i = 0; i <= GetNoComponents(); i++) {
for (int j = 0; j <= mb.GetNoComponents(); j++) {
if (i == 0 || j == 0) {
dp[i][j] = 0;
}
else {
GetValue(i - 1, value1);
mb.GetValue(j - 1, value2);
if (value1 == value2) {
dp[i][j] = dp[i - 1][j - 1] + 1;
if (dp[i][j] > lcsSize) {
lcsSize = dp[i][j];
maxPos = i;
}
}
else {
dp[i][j] = 0;
}
}
}
}
result.first = maxPos - lcsSize;
result.second = maxPos - 1;
return result;
}
/*
\subsection{Function ~Print~}
*/
template<class B>
std::ostream& MBasic<B>::Print(std::ostream& os) const {
if (!IsDefined()) {
os << "(undefined)" << endl;
return os;
}
os << BasicType() << ":" << endl;
UBasic<B> ub(true);
for (int i = 0; i < GetNoComponents(); i++) {
Get(i, ub);
ub.Print(os);
}
return os;
}
/*
\subsection{Collection of Distance Functions}
*/
template<class B>
double MBasic<B>::Distance_FIRST(const MBasic<B>& mb) const {
typename B::base b1, b2;
GetValue(0, b1);
mb.GetValue(0, b2);
return (b1 == b2 ? 0.0 : 1.0);
}
template<class B>
double MBasic<B>::Distance_LAST(const MBasic<B>& mb) const {
typename B::base b1, b2;
GetValue(GetNoComponents() - 1, b1);
mb.GetValue(mb.GetNoComponents() - 1, b2);
return (b1 == b2 ? 0.0 : 1.0);
}
template<class B>
double MBasic<B>::Distance_FIRST_LAST(const MBasic<B>& mb,
const LabelFunction lf) const {
int n = GetNoComponents();
int m = mb.GetNoComponents();
typename B::base s1, s2, e1, e2;
GetValue(0, s1);
mb.GetValue(0, s2);
if (n == 1) {
if (m == 1) {
return BasicDistanceFuns::distance(s1, s2, lf);
}
else {
mb.GetValue(m - 1, e2);
return (BasicDistanceFuns::distance(s1, s2, lf) +
BasicDistanceFuns::distance(s1, e2, lf)) / 2;
}
}
else {
GetValue(n - 1, e1);
if (m == 1) {
return (BasicDistanceFuns::distance(s1, s2, lf) +
BasicDistanceFuns::distance(e1, s2, lf)) / 2;
}
else {
mb.GetValue(m - 1, e2);
return (BasicDistanceFuns::distance(s1, s2, lf) +
BasicDistanceFuns::distance(e1, e2, lf)) / 2;
}
}
}
template<class B>
double MBasic<B>::Distance_ALL(const MBasic<B>& mb, const LabelFunction lf)
const {
if (!IsDefined() && !mb.IsDefined()) {
return 0.0;
}
if (!IsDefined() || !mb.IsDefined()) {
return 1.0;
}
int m = GetNoComponents();
int n = mb.GetNoComponents();
int dp[m + 1][n + 1];
typename B::base b1, b2;
for (int i = 0; i <= m; i++) {
dp[i][0] = i;
}
for (int j = 0; j <= n; j++) {
dp[0][j] = j;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
GetValue(i - 1, b1);
mb.GetValue(j - 1, b2);
if (BasicDistanceFuns::distance(b1, b2, lf) == 0) {
dp[i][j] = dp[i - 1][j - 1];
}
else {
dp[i][j] = std::min(dp[i][j - 1], std::min(dp[i - 1][j],
dp[i - 1][j - 1])) + 1;
}
}
}
return (double)(dp[m][n]) / std::max(m, n);
}
template<class B>
double MBasic<B>::Distance_ALL_DURATION(const MBasic<B>& mb,
const LabelFunction lf) const {
double result = this->Distance_ALL(mb, lf);
datetime::DateTime dur1(datetime::durationtype);
datetime::DateTime dur2(datetime::durationtype);
GetDuration(dur1);
mb.GetDuration(dur2);
double quotient = dur1 / dur2;
if (quotient > 1) {
quotient = dur2 / dur1;
} // quotient is in (0, 1]
return 0.5 * result + 0.5 * (1 - quotient);
}
template<class B>
double MBasic<B>::Distance_ALL_INTERVALS(const MBasic<B>& mb,
const LabelFunction lf) const {
return 0.0;
}
template<class B>
double MBasic<B>::Distance_EQUAL_LABELS(const MBasic<B>& mb,
const LabelFunction lf) const {
if (GetNoComponents() != mb.GetNoComponents()) {
return false;
}
typename B::base b1, b2;
for (int i = 0; i < GetNoComponents(); i++) {
GetValue(i, b1);
mb.GetValue(i, b2);
if (BasicDistanceFuns::distance(b1, b2, lf)) {
return false;
}
}
return true;
}
template<class B>
double MBasic<B>::Distance_COSINUS_SIM(const MBasic<B>& mb) {
return 0.0;
// TODO: a lot
}
template<class B>
double MBasic<B>::Distance_TF_IDF(const MBasic<B>& mb) {
return 0.0;
// TODO: a lot
}
/*
\subsection{Function ~Distance~}
*/
template<class B>
double MBasic<B>::Distance(const MBasic<B>& mb,
const DistanceFunction df /* = ALL */,
const LabelFunction lf /* = TRIVIAL */,
const double threshold /* = 1.0 */) const {
if (!IsDefined() && !mb.IsDefined()) {
return 0.0;
}
if (!IsDefined() || !mb.IsDefined()) {
return 1.0;
}
if (IsEmpty() && mb.IsEmpty()) {
return 0.0;
}
if (IsEmpty() || mb.IsEmpty()) {
return 1.0;
}
switch (df) {
case FIRST: {
return this->Distance_FIRST(mb);
}
case LAST: {
return this->Distance_LAST(mb);
}
case FIRST_LAST: {
return this->Distance_FIRST_LAST(mb, lf);
}
case ALL: {
return this->Distance_ALL(mb, lf);
}
case ALL_DURATION: {
return this->Distance_ALL_DURATION(mb, lf);
}
case ALL_INTERVALS: {
return this->Distance_ALL_INTERVALS(mb, lf);
}
case EQUAL_LABELS: {
return this->Distance_EQUAL_LABELS(mb, lf);
}
default: {
return -1.0;
}
}
}
/*
\subsection{Function ~CommonPrefixSuffix~}
*/
template<class B>
int MBasic<B>::CommonPrefixSuffix(const MBasic<B>& mb, const bool prefix) {
typename B::base b1, b2;
int result = 0;
int minLength = std::min(GetNoComponents(), mb.GetNoComponents());
if (prefix) {
for (int i = 0; i < minLength; i++) {
GetValue(i, b1);
mb.GetValue(i, b2);
if (b1 == b2) {
result++;
}
else {
return result;
}
}
}
else {
for (int i = 1; i <= minLength; i++) {
GetValue(GetNoComponents() - i, b1);
mb.GetValue(mb.GetNoComponents() - i, b2);
if (b1 == b2) {
result++;
}
else {
return result;
}
}
}
return result;
}
/*
\subsection{Function ~DistanceSym~}
*/
template<class B>
double MBasic<B>::DistanceSym(const MBasic<B>& mb,
const DistanceFunSym distfun) {
if (IsEmpty() && mb.IsEmpty()) {
return 0.0;
}
typename B::base b1, b2;
switch (distfun) {
case EQUALLABELS: {
if (GetNoComponents() != mb.GetNoComponents()) {
return 1.0;
}
for (int i = 0; i < GetNoComponents(); i++) {
GetValue(i, b1);
mb.GetValue(i, b2);
if (b1 != b2) {
return 1.0;
}
}
return 0.0;
}
case PREFIX: {
int prefix = CommonPrefixSuffix(mb, true);
if (prefix == std::min(GetNoComponents(), mb.GetNoComponents())) {
return 0.0;
}
return (prefix == 0 ? 2.0 : 1.0 / prefix);
}
case SUFFIX: {
int suffix = CommonPrefixSuffix(mb, false);
if (suffix == std::min(GetNoComponents(), mb.GetNoComponents())) {
return 0.0;
}
return (suffix == 0 ? 2.0 : 1.0 / suffix);
}
case PREFIXSUFFIX: {
int prefix = CommonPrefixSuffix(mb, true);
int suffix = CommonPrefixSuffix(mb, false);
if (prefix+suffix >= std::min(GetNoComponents(), mb.GetNoComponents())) {
return 0.0;
}
return (prefix + suffix == 0 ? 2.0 : 1.0 / (prefix + suffix));
}
default: {
return -1.0;
}
}
}
template<class B>
void MBasic<B>::InsertLabels(std::vector<std::string>& result) const {
B b(true);
for (int i = 0; i < GetNoComponents(); i++) {
GetBasic(i, b);
b.InsertLabels(result);
}
}
template<class B>
void MBasic<B>::InsertLabels(std::set<std::string>& result) const {
B b(true);
for (int i = 0; i < GetNoComponents(); i++) {
GetBasic(i, b);
b.InsertLabels(result);
}
}
template<class B>
void MBasic<B>::FrequencyVector(InvertedFile& inv, std::vector<double>& fv,
const bool useIdf /* = false */) const {
B b(true);
for (int i = 0; i < GetNoComponents(); i++) {
GetBasic(i, b);
b.UpdateFrequencies(inv, fv);
}
if (useIdf) {
double noDocs = 0.0;
InvertedFile::prefixIterator* pit = 0;
TupleId id;
uint32_t wc, cc;
std::string dummy = "zzzzz";
pit = inv.getPrefixIterator(dummy);
if (pit->next(dummy, id, wc, cc)) { // retrieve noTuples from inv node
noDocs = (double)id;
}
else {
return;
}
delete pit;
std::string emptyPrefix = "";
pit = inv.getPrefixIterator(emptyPrefix);
int pos = 0;
int noEntries = inv.getNoEntries() - 1;
while (pos < noEntries && pit->next(emptyPrefix, id, wc, cc)) {
if (fv[pos] > 0.0) {
fv[pos] *= log(noDocs / wc);
}
pos++;
}
delete pit;
}
}
/*
\section{Implementation of class ~MBasics~}
\subsection{Constructors}
*/
template<class B>
MBasics<B>::MBasics(const MBasics &mbs) : Attribute(mbs.IsDefined()),
values(mbs.GetNoValues()), units(mbs.GetNoComponents()), pos(mbs.pos.Size()),
noChars(mbs.GetNoChars()) {
values.copyFrom(mbs.values);
units.copyFrom(mbs.units);
pos.copyFrom(mbs.pos);
}
/*
\subsection{Function ~Property~}
*/
template<class B>
ListExpr MBasics<B>::Property() {
if (B::BasicType() == "labels") {
return gentc::GenProperty("-> DATA", BasicType(),
"((<interval> <labels>) (<interval> <labels>) ...)",
"(((\"2014-01-29\" \"2014-01-30\" TRUE FALSE) (\"home\" \"Dortmund\")))");
}
if (B::BasicType() == "places") {
return gentc::GenProperty("-> DATA", BasicType(),
"((<interval> <places>) (<interval> <places>) ...)",
"(((\"2014-01-29\" \"2014-01-30\" TRUE FALSE) ((\"home\" 2012) "
"(\"Dortmund\" 1909))))");
}
return gentc::GenProperty("-> DATA", BasicType(), "Error: invalid type.", "");
}
/*
\subsection{Function ~CheckKind~}
*/
template<class B>
bool MBasics<B>::CheckKind(ListExpr type, ListExpr& errorInfo) {
return nl->IsEqual(type, MBasics<B>::BasicType());
}
/*
\subsection{Function ~checkType~}
*/
template<class B>
bool MBasics<B>::checkType(ListExpr t) {
return listutils::isSymbol(t, MBasics<B>::BasicType());
}
/*
\subsection{Function ~GetFLOB~}
*/
template<class B>
Flob* MBasics<B>::GetFLOB(const int i) {
assert((i >= 0) && (i < NumOfFLOBs()));
if (i == 0) {
return &values;
}
if (i == 1) {
return &units;
}
return &pos;
}
/*
\subsection{Function ~Compare~}
*/
template<class B>
int MBasics<B>::Compare(const Attribute* arg) const {
if (GetNoComponents() == ((MBasics<B>*)arg)->GetNoComponents()) {
if (GetNoValues() == ((MBasics<B>*)arg)->GetNoValues()) {
return 0;
}
return (GetNoValues() > ((MBasics<B>*)arg)->GetNoValues() ? 1 : -1);
}
else {
return (GetNoComponents() > ((MBasics<B>*)arg)->GetNoComponents() ?
1 : -1);
}
}
/*
\subsection{Function ~Clone~}
*/
template<class B>
Attribute* MBasics<B>::Clone() const {
return new (MBasics<B>)(*(MBasics<B>*)this);
}
/*
\subsection{Function ~=~}
*/
template<class B>
MBasics<B>& MBasics<B>::operator=(const MBasics<B>& src) {
Attribute::operator=(src);
units.copyFrom(src.units);
values.copyFrom(src.values);
pos.copyFrom(src.pos);
noChars = src.noChars;
return *this;
}
/*
\subsection{Function ~getEndPos~}
*/
template<class B>
int MBasics<B>::getUnitEndPos(const int i) const {
if (i < GetNoComponents() - 1) {
SymbolicUnit nextUnit;
units.Get(i + 1, nextUnit);
return nextUnit.pos - 1;
}
else { // last unit
return pos.Size() - 1;
}
}
/*
\subsection{Function ~unitToListExpr~}
*/
template<class B>
ListExpr MBasics<B>::unitToListExpr(int i) {
assert ((i >= 0) && (i < GetNoComponents()));
SymbolicUnit unit;
units.Get(i, unit);
SecondoCatalog* sc = SecondoSystem::GetCatalog();
std::set<typename B::base> values;
GetValues(i, values);
ListExpr valuelist;
B::valuesToListExpr(values, valuelist);
return nl->TwoElemList(unit.iv.ToListExpr(sc->GetTypeExpr(
temporalalgebra::SecInterval::BasicType())),
valuelist);
}
/*
\subsection{Function ~ToListExpr~}
*/
template<class B>
ListExpr MBasics<B>::ToListExpr(ListExpr typeInfo) {
if (!IsDefined()) {
return nl->SymbolAtom(Symbol::UNDEFINED());
}
if (IsEmpty()) {
return nl->Empty();
}
ListExpr result = nl->OneElemList(unitToListExpr(0));
ListExpr last = result;
for (int i = 1; i < GetNoComponents(); i++) {
last = nl->Append(last, unitToListExpr(i));
}
return result;
}
/*
\subsection{Function ~readValues~}
*/
template<class B>
bool MBasics<B>::readValues(ListExpr valuelist) {
ListExpr rest = valuelist;
std::string text;
typename B::arrayelem elem;
while (!nl->IsEmpty(rest)) {
if (listutils::isSymbolUndefined(nl->First(rest))) {
return false;
}
B::getString(nl->First(rest), text);
text = text.substr(1, text.length() - 2);
unsigned int newPos = (text.length() > 0 ? GetNoChars() : UINT_MAX);
B::getElemFromList(nl->First(rest), newPos, elem);
pos.Append(elem);
if (text.length() > 0) {
const char *bytes = text.c_str();
if (values.getSize() == 0) {
values.resize(1024);
}
if (noChars + text.length() >= values.getSize()) {
values.resize(2 * values.getSize());
}
values.write(bytes, text.length(), noChars);
noChars += text.length();
}
rest = nl->Rest(rest);
}
return true;
}
/*
\subsection{Function ~readUnit~}
*/
template<class B>
bool MBasics<B>::readUnit(ListExpr unitlist) {
if (!nl->HasLength(unitlist, 2)) {
return false;
}
SymbolicUnit unit(GetNoValues(), 0);
SecondoCatalog* sc = SecondoSystem::GetCatalog();
if (!unit.iv.ReadFrom(nl->First(unitlist),
sc->GetTypeExpr(temporalalgebra::SecInterval::BasicType()))) {
return false;
}
if (!readValues(nl->Second(unitlist))) {
return false;
}
if (GetNoComponents() > 0) {
SymbolicUnit prevUnit;
units.Get(GetNoComponents() - 1, prevUnit);
if (!(prevUnit.iv.Before(unit.iv))) { // check time intervals
return false;
}
}
units.Append(unit);
return true;
}
/*
\subsection{Function ~ReadFrom~}
*/
template<class B>
bool MBasics<B>::ReadFrom(ListExpr LE, ListExpr typeInfo) {
values.clean();
units.clean();
pos.clean();
if (listutils::isSymbolUndefined(LE)) {
SetDefined(false);
return true;
}
ListExpr rest = LE;
while (!nl->IsEmpty(rest)) {
if (!readUnit(nl->First(rest))) {
SetDefined(false);
return true;
}
rest = nl->Rest(rest);
}
SetDefined(true);
return true;
}
/*
\subsection{Function ~serialize~}
*/
template<class B>
void MBasics<B>::serialize(size_t &size, char *&bytes) const {
size = 0;
bytes = 0;
if (!IsDefined()) {
return;
}
size_t rootSize = Sizeof();
size = rootSize + sizeof(size_t) + values.getSize() + units.GetFlobSize()
+ pos.GetFlobSize();
bytes = new char[size];
memcpy(bytes, (void*)&rootSize, sizeof(size_t));
memcpy(bytes + sizeof(size_t), (void*)this, rootSize);
size_t offset = sizeof(size_t) + rootSize;
char* data = values.getData();
memcpy(bytes + offset, data, values.getSize());
delete[] data;
offset += values.getSize();
data = units.getData();
memcpy(bytes + offset, data, units.GetFlobSize());
delete[] data;
offset += units.GetFlobSize();
data = pos.getData();
memcpy(bytes + offset, data, pos.GetFlobSize());
delete[] data;
}
/*
\subsection{Function ~deserialize~}
*/
template<class B>
MBasics<B>* MBasics<B>::deserialize(const char *bytes) {
ListExpr typeExpr = nl->SymbolAtom(BasicType());
int algebraId, typeId;
std::string typeName;
SecondoCatalog* sc = SecondoSystem::GetCatalog();
sc->LookUpTypeExpr(typeExpr, typeName, algebraId, typeId);
size_t rootSize;
memcpy((void*)&rootSize, bytes, sizeof(size_t));
char* root = new char[rootSize];
memcpy(root, bytes + sizeof(size_t), rootSize);
AlgebraManager* am = SecondoSystem::GetAlgebraManager();
ListExpr nType = sc->NumericType(typeExpr);
Attribute* attr = (Attribute*)(am->CreateObj(algebraId, typeId)(nType)).addr;
attr = attr->Create(attr, root, rootSize, algebraId, typeId);
delete[] root;
size_t offset = rootSize + sizeof(size_t);
for (int i = 0; i < attr->NumOfFLOBs(); i++) {
Flob* flob = attr->GetFLOB(i);
size_t size = flob->getSize();
flob->kill();
char* fb = new char[size];
memcpy(fb, bytes + offset, size);
flob->createFromBlock(*flob, fb, size, false);
delete[] fb;
offset += size;
}
return (MBasics<B>*)attr;
}
/*
\subsection{Operator ~<<~}
*/
template<class B>
std::ostream& operator<<(std::ostream& o, MBasics<B>& mbs) {
ListExpr typeInfo = nl->Empty();
o << nl->ToString(mbs.ToListExpr(typeInfo));
return o;
}
/*
\subsection{Function ~Position~}
*/
template<class B>
int MBasics<B>::Position(const Instant& inst,
const bool ignoreClosedness /* = false */) const {
assert(IsDefined());
assert(inst.IsDefined());
int first = 0, last = GetNoComponents() - 1;
Instant t1 = inst;
while (first <= last) {
int mid = (first + last) / 2;
if ((mid < 0) || (mid >= GetNoComponents())) {
return -1;
}
SymbolicUnit unit;
units.Get(mid, unit);
if (((temporalalgebra::Interval<Instant>)(unit.iv)).Contains(t1,
ignoreClosedness)) {
return mid;
}
else { // not contained
if ((t1 > unit.iv.end) || (t1 == unit.iv.end)) {
first = mid + 1;
}
else if ((t1 < unit.iv.start) || (t1 == unit.iv.start)) {
last = mid - 1;
}
else {
return -1; // should never be reached.
}
}
}
return -1;
}
/*
\subsection{Function ~FirstPosFrom~}
*/
template<class B>
int MBasics<B>::FirstPosFrom(const Instant& inst) const {
assert(IsDefined());
assert(inst.IsDefined());
typename B::unitelem unit;
units.Get(0, unit);
if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
return 0; //
}
units.Get(GetNoComponents() - 1, unit);
if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
return -1;
}
int first(0), last(GetNoComponents() - 1);
while (first <= last) {
int mid = (first + last) / 2;
units.Get(mid, unit);
if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
return mid;
}
first = mid + 1;
}
else if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
int beforeMid = mid - 1;
units.Get(beforeMid, unit);
if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
return mid;
}
else if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
last = mid - 1;
}
else {
return mid;
}
}
else {
return mid;
}
}
return -1;
}
/*
\subsection{Function ~LastPosUntil~}
*/
template<class B>
int MBasics<B>::LastPosUntil(const Instant& inst) const {
assert(IsDefined());
assert(inst.IsDefined());
typename B::unitelem unit;
units.Get(0, unit);
if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
return -1; //
}
units.Get(GetNoComponents() - 1, unit);
if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
return GetNoComponents() - 1;
}
int first(0), last(GetNoComponents() - 1);
while (first <= last) {
int mid = (first + last) / 2;
units.Get(mid, unit);
if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).start) {
return mid;
}
last = mid - 1;
}
else if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
int afterMid = mid + 1;
units.Get(afterMid, unit);
if (inst < ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
return mid;
}
else if (inst > ((temporalalgebra::Interval<Instant>)(unit.iv)).end) {
first = mid + 1;
}
else {
return mid;
}
}
else {
return mid;
}
}
return -1;
}
/*
\subsection{Function ~Get~}
*/
template<class B>
void MBasics<B>::Get(const int i, UBasics<B>& result) const {
assert(IsDefined());
assert((i >= 0) && (i < GetNoComponents()));
result.SetDefined(true);
result.constValue.Clean();
std::set<typename B::base> values;
typename std::set<typename B::base>::iterator it;
GetValues(i, values);
for (it = values.begin(); it != values.end(); it++) {
result.constValue.Append(*it);
}
temporalalgebra::SecInterval iv(true);
GetInterval(i, iv);
result.timeInterval = iv;
}
/*
\subsection{Function ~GetBasics~}
*/
template<class B>
void MBasics<B>::GetBasics(const int i, B& result) const {
assert(IsDefined());
assert((i >= 0) && (i < GetNoComponents()));
result.SetDefined(true);
result.Clean();
std::set<typename B::base> values;
typename std::set<typename B::base>::iterator it;
GetValues(i, values);
result.Append(values);
}
/*
\subsection{Function ~GetValues~}
*/
template<class B>
void MBasics<B>::GetValues(const int i,
std::set<typename B::base>& result) const{
assert (IsDefined() && (i >= 0) && (i < GetNoComponents()));
result.clear();
SymbolicUnit unit;
units.Get(i, unit);
typename B::base val;
typename B::arrayelem elem1, elem2;
std::pair<unsigned int, unsigned int> flobPos; // pos, size
for (int j = unit.pos; j <= getUnitEndPos(i); j++) {
flobPos = std::make_pair(0, 0);
pos.Get(j, elem1);
unsigned int start = B::getFlobPos(elem1);
if (start != UINT_MAX) {
int k = j + 1;
bool finished = false;
while (!finished && (k < GetNoValues())) {
pos.Get(k, elem2);
unsigned int next = B::getFlobPos(elem2);
if (next != UINT_MAX) { // valid reference
flobPos = std::make_pair(start, next - start);
finished = true;
}
k++;
}
if (!finished) { // end of array
flobPos = std::make_pair(start, GetNoChars() - start);
}
}
if (flobPos.second > 0) {
char *bytes = new char[flobPos.second];
values.read(bytes, flobPos.second, flobPos.first);
std::string text(bytes, flobPos.second);
delete[] bytes;
B::buildValue(text, elem1, val);
result.insert(val);
}
else {
B::buildValue("", elem1, val);
result.insert(val);
}
}
}
/*
\subsection{Function ~GetInterval~}
*/
template<class B>
void MBasics<B>::GetInterval(const int i,
temporalalgebra::SecInterval& result) const {
assert((i >= 0) && (i < GetNoComponents()));
result.SetDefined(true);
SymbolicUnit unit;
units.Get(i, unit);
result = unit.iv;
}
template<class B>
void MBasics<B>::GetInterval(temporalalgebra::SecInterval& result) const {
if (this->IsDefined() && !this->IsEmpty()) {
temporalalgebra::SecInterval first(true), last(true);
this->GetInterval(0, first);
this->GetInterval(this->GetNoComponents() - 1, last);
result.Set(first.start, last.end, first.lc, last.rc);
}
else {
result.SetDefined(false);
}
}
/*
\subsection{Function ~Clear~}
*/
template<class B>
void MBasics<B>::Clear() {
units.clean();
values.clean();
pos.clean();
noChars = 0;
}
/*
\subsection{Function ~EndBulkLoad~}
*/
template<class B>
void MBasics<B>::EndBulkLoad(const bool sort /*= true*/,
const bool checkvalid /*= true*/) {
if (!IsDefined()) {
units.clean();
values.clean();
pos.clean();
}
units.TrimToSize();
pos.TrimToSize();
values.resize(GetNoChars());
assert(IsValid());
}
/*
\subsection{Function ~IsValid~}
*/
template<class B>
bool MBasics<B>::IsValid() const {
if (!IsDefined() || IsEmpty()) {
return true;
}
typename B::unitelem lastUnit, unit;
units.Get(0, lastUnit);
if (!lastUnit.iv.IsValid()) {
return false;
}
if (GetNoComponents() == 1) {
return true;
}
for (int i = 1; i < GetNoComponents(); i++) {
units.Get(i, unit);
if (!unit.iv.IsValid()) {
return false;
}
if (lastUnit.iv.end > unit.iv.start) {
return false;
}
if (!lastUnit.iv.Disjoint(unit.iv)) {
return false;
}
lastUnit = unit;
}
return true;
}
/*
\subsection{Function ~Add~}
*/
template<class B>
void MBasics<B>::Add(const UBasics<B>& ut) {
assert(IsDefined() && ut.IsDefined());
UBasics<B> ut2(ut);
if (!readUnit(ut2.ToListExpr(nl->Empty()))) {
SetDefined(false);
}
}
template<class B>
void MBasics<B>::Add(const temporalalgebra::SecInterval& iv, const B& values) {
assert(IsDefined() && iv.IsDefined() && values.IsDefined());
B values2(values);
ListExpr unitlist = nl->TwoElemList(iv.ToListExpr(nl->Empty()),
values2.ToListExpr(nl->Empty()));
if (!readUnit(unitlist)) {
SetDefined(false);
}
assert(IsValid());
}
/*
\subsection{Function ~MergeAdd~}
*/
template<class B>
void MBasics<B>::MergeAdd(const temporalalgebra::SecInterval& iv,
const B& values) {
assert(IsDefined() && iv.IsDefined() && values.IsDefined());
if (!iv.IsDefined() || !iv.IsValid()) {
cout << __FILE__ << "," << __LINE__ << ":" << __PRETTY_FUNCTION__
<< " MergeAdd(Unit): Unit is undefined or invalid:";
iv.Print(cout); cout << endl;
assert(false);
}
if (GetNoComponents() > 0) {
SymbolicUnit prevUnit;
units.Get(GetNoComponents() - 1, prevUnit);
int numOfValues = getUnitEndPos(GetNoComponents() - 1) - prevUnit.pos + 1;
bool equal = (values.GetNoValues() == numOfValues);
std::set<typename B::base> mvalues, bvalues;
typename std::set<typename B::base>::iterator it;
GetValues(GetNoComponents() - 1, mvalues);
values.GetValues(bvalues);
equal = (mvalues == bvalues);
if (equal && (prevUnit.iv.end == iv.start) && (prevUnit.iv.rc || iv.lc)) {
prevUnit.iv.end = iv.end; // adjacent invervals \& equal labels
prevUnit.iv.rc = iv.rc;
units.Put(GetNoComponents() - 1, prevUnit);
}
else if (prevUnit.iv.Before(iv)) {
Add(iv, values);
}
}
else { // first unit
Add(iv, values);
}
}
template<class B>
void MBasics<B>::MergeAdd(const UBasics<B>& ub) {
MergeAdd(ub.timeInterval, ub.constValue);
}
/*
\subsection{Function ~Passes~}
*/
template<class B>
bool MBasics<B>::Passes(const typename B::single& sg) const {
std::set<typename B::base> vals;
typename B::base val;
sg.GetValue(val);
for (int i = 0; i < GetNoComponents(); i++) {
GetValues(i, vals);
if (vals.find(val) != vals.end()) {
return true;
}
}
return false;
}
template<class B>
template<class T>
bool MBasics<B>::Passes(const T& value) const {
if (!IsDefined() || !value.IsDefined()) {
return false;
}
Label lb(value.GetValue());
return Passes(lb);
}
/*
\subsection{Function ~Passes~}
*/
template<class B>
bool MBasics<B>::Passes(const B& bs) const {
B basics(true);
for (int i = 0; i < GetNoComponents(); i++) {
GetBasics(i, basics);
if (basics == bs) {
return true;
}
}
return false;
}
/*
\subsection{Function ~At~}
*/
template<class B>
void MBasics<B>::At(const typename B::single& sg, MBasics<B>& result) const {
result.Clear();
if (!IsDefined()) {
result.SetDefined(false);
return;
}
result.SetDefined(true);
for (int i = 0; i < GetNoComponents(); i++) {
B basics(true);
GetBasics(i, basics);
bool found = false;
int j = 0;
typename B::base val;
while ((j < basics.GetNoValues()) && !found) {
basics.GetValue(j, val);
if (sg == val) {
found = true;
}
j++;
}
if (found) {
temporalalgebra::SecInterval iv;
GetInterval(i, iv);
UBasics<B> ut(iv, basics);
result.Add(ut);
}
}
}
/*
\subsection{Function ~At~}
*/
template<class B>
void MBasics<B>::At(const B& bs, MBasics<B>& result) const {
result.Clear();
if (!IsDefined()) {
result.SetDefined(false);
return;
}
result.SetDefined(true);
for (int i = 0; i < GetNoComponents(); i++) {
B basics(true);
GetBasics(i, basics);
if (basics == bs) {
temporalalgebra::SecInterval iv;
GetInterval(i, iv);
result.Add(iv, basics);
}
}
}
template<class B>
template<class T>
void MBasics<B>::At(const T& value, MBasics<B>& result) const {
Label lb(value.GetValue());
At(lb, result);
}
/*
\subsection{Function ~DefTime~}
*/
template<class B>
void MBasics<B>::DefTime(temporalalgebra::Periods& per) const {
per.Clear();
per.SetDefined(IsDefined());
if (IsDefined()) {
SymbolicUnit unit;
for (int i = 0; i < GetNoComponents(); i++) {
units.Get(i, unit);
per.MergeAdd(unit.iv);
}
}
}
/*
\subsection{Function ~Atinstant~}
*/
template<class B>
void MBasics<B>::AtInstant(const Instant& inst,
IBasics<B>& result) const {
if(!IsDefined() || !inst.IsDefined()) {
result.SetDefined(false);
return;
}
int pos = Position(inst);
if (pos == -1) {
result.SetDefined(false);
}
else {
GetBasics(pos, result.value);
result.SetDefined(true);
result.instant = inst;
}
}
/*
\subsection{Function ~AtPeriods~}
*/
template<class B>
void MBasics<B>::AtPeriods(const temporalalgebra::Periods& per,
MBasics<B>& result) const {
result.Clear();
result.SetDefined(IsDefined() && per.IsDefined());
if (!IsDefined() || !per.IsDefined()) {
return;
}
if (IsEmpty() || per.IsEmpty()) {
return;
}
if (IsMaximumPeriods(per)) {
result.CopyFrom(this);
return;
}
assert(per.IsOrdered());
temporalalgebra::SecInterval ivS(true), ivP(true), ivR(true);
GetInterval(0, ivS);
GetInterval(GetNoComponents() - 1, ivP);
if (per.Before(ivS.start) || per.After(ivP.end)) {
return;
}
result.StartBulkLoad();
B vals;
int i = 0, j = 0;
while ((i < GetNoComponents()) && (j < per.GetNoComponents())) {
GetInterval(i, ivS); // get source interval
per.Get(j, ivP); // get interval from periods
GetBasics(i, vals); // get source value
if (ivS.Before(ivP)) {
i++;
}
else if (ivS.After(ivP)) {
j++;
}
else { // intervals overlap
ivS.Intersection(ivP, ivR);
result.Add(ivR, vals);
if (ivS.end == ivP.end) {
if (ivS.rc == ivP.rc) {
i++;
j++;
}
else if (ivP.rc == true) {
i++;
}
else {
j++;
}
}
else if (ivS.end < ivP.end) {
i++;
}
else {
j++;
}
}
}
result.EndBulkLoad(false);
}
/*
\subsection{Function ~Initial~}
*/
template<class B>
void MBasics<B>::Initial(IBasics<B>& result) const {
if (!IsDefined() || !GetNoComponents()) {
result.SetDefined(false);
return;
}
result.SetDefined(true);
temporalalgebra::SecInterval iv;
GetInterval(0, iv);
result.instant = iv.start;
GetBasics(0, result.value);
}
/*
\subsection{Function ~Final~}
*/
template<class B>
void MBasics<B>::Final(IBasics<B>& result) const {
if (!IsDefined() || !GetNoComponents()) {
result.SetDefined(false);
return;
}
result.SetDefined(true);
temporalalgebra::SecInterval iv;
GetInterval(GetNoComponents() - 1, iv);
result.instant = iv.end;
GetBasics(GetNoComponents() - 1, result.value);
}
/*
\subsection{Function ~InitialInstant~}
*/
template<class B>
void MBasics<B>::InitialInstant(Instant& result) const {
if (!IsDefined() || IsEmpty()) {
result.SetDefined(false);
return;
}
typename B::unitelem unit;
units.Get(0, unit);
result = unit.iv.start;
}
/*
\subsection{Function ~FinalInstant~}
*/
template<class B>
void MBasics<B>::FinalInstant(Instant& result) const {
if (!IsDefined() || IsEmpty()) {
result.SetDefined(false);
return;
}
typename B::unitelem unit;
units.Get(GetNoComponents() - 1, unit);
result = unit.iv.end;
}
/*
\subsection{Function ~Fill~}
*/
template<class B>
void MBasics<B>::Fill(MBasics<B>& result, datetime::DateTime& dur) const {
if (!IsDefined()) {
result.SetDefined(false);
return;
}
result.Clear();
result.SetDefined(true);
if (IsEmpty()) {
return;
}
UBasics<B> unit(true), lastUnit(true);
Get(0, lastUnit);
for (int i = 1; i < GetNoComponents(); i++) {
Get(i, unit);
if ((lastUnit.constValue == unit.constValue) &&
(unit.timeInterval.start - lastUnit.timeInterval.end <= dur)) {
lastUnit.timeInterval.end = unit.timeInterval.end;
lastUnit.timeInterval.rc = unit.timeInterval.rc;
}
else {
result.MergeAdd(lastUnit);
lastUnit = unit;
}
}
result.MergeAdd(lastUnit);
}
/*
\subsection{Function ~concat~}
*/
template<class B>
void MBasics<B>::Concat(const MBasics<B>& src1, const MBasics<B>& src2) {
Clear();
if (src1.IsEmpty()) {
CopyFrom(&src2);
return;
}
if (src2.IsEmpty()) {
CopyFrom(&src1);
return;
}
temporalalgebra::SecInterval iv1, iv2;
src1.GetInterval(src1.GetNoComponents() - 1, iv1);
src2.GetInterval(0, iv2);
SetDefined(src1.IsDefined() && src2.IsDefined() && iv1.Before(iv2));
if (!IsDefined()) {
return;
}
CopyFrom(&src1);
UBasics<B> unit(true);
for (int i = 0; i < src2.GetNoComponents(); i++) {
src2.Get(i, unit);
Add(unit);
}
}
/*
\subsection{Function ~Compress~}
*/
template<class B>
void MBasics<B>::Compress(MBasics<B>& result) const {
result.Clear();
result.SetDefined(IsDefined());
if(!IsDefined()) {
return;
}
UBasics<B> ub(true);
for (int i = 0; i < GetNoComponents(); i++) {
Get(i, ub);
result.MergeAdd(ub);
}
}
#ifdef RECODE
/*
\subsection{Function ~Recode~}
*/
template<class B>
void MBasics<B>::Recode(const std::string& from, const std::string& to,
MBasics<B>& result) {
result.SetDefined(IsDefined());
if (!IsDefined()) {
return;
}
result.Clear();
B values(true), recoded_values(true);
temporalalgebra::SecInterval iv(true);
for (int i = 0; i < GetNoComponents(); i++) {
GetInterval(i, iv);
GetBasics(i, values);
if (!values.Recode(from, to, recoded_values)) {
result.SetDefined(false);
return;
}
result.Add(iv, recoded_values);
}
}
#endif
/*
\subsection{Function ~Print~}
*/
template<class B>
std::ostream& MBasics<B>::Print(std::ostream& os) const {
if (!IsDefined()) {
os << "(undefined)" << endl;
return os;
}
os << BasicType() << ":" << endl;
UBasics<B> ubs(true);
for (int i = 0; i < GetNoComponents(); i++) {
Get(i, ubs);
ubs.Print(os);
}
return os;
}
/*
\subsection{Function ~DISTANCE\_FIRST\_LAST~}
*/
template<class B>
double MBasics<B>::Distance_FIRST_LAST(const MBasics<B>& mbs,
const LabelFunction lf) const {
int n = GetNoComponents();
int m = mbs.GetNoComponents();
std::set<typename B::base> bs1, bs2, be1, be2;
GetValues(0, bs1);
mbs.GetValues(0, bs2);
// GetValue(n - 1, be1);
// mbs.GetValue(m - 1, be2);
if (n == 1) {
if (m == 1) {
return BasicDistanceFuns::distance(bs1, bs2, lf);
}
mbs.GetValues(m - 1, be2);
return (BasicDistanceFuns::distance(bs1, bs2, lf) +
BasicDistanceFuns::distance(bs1, be2, lf)) / 2;
}
else {
GetValues(n - 1, be1);
if (m == 1) {
return (BasicDistanceFuns::distance(bs1, bs2, lf) +
BasicDistanceFuns::distance(be1, bs2, lf)) /2;
}
mbs.GetValues(m - 1, be2);
return (BasicDistanceFuns::distance(bs1, bs2, lf) +
BasicDistanceFuns::distance(be1, be2, lf)) / 2;
}
}
/*
\subsection{Function ~DISTANCE\_ALL~}
*/
template<class B>
double MBasics<B>::Distance_ALL(const MBasics<B>& mbs, const LabelFunction lf)
const {
int m = GetNoComponents();
int n = mbs.GetNoComponents();
int dp[m + 1][n + 1];
std::set<typename B::base> b1, b2;
double unitdist;
for (int i = 0; i <= m; i++) {
dp[i][0] = i;
}
for (int j = 0; j <= n; j++) {
dp[0][j] = j;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
GetValues(i - 1, b1);
mbs.GetValues(j - 1, b2);
unitdist = BasicDistanceFuns::distance(b1, b2, lf);
if (unitdist == 0) {
dp[i][j] = dp[i - 1][j - 1];
}
else {
dp[i][j] = std::min(dp[i][j - 1], std::min(dp[i - 1][j],
dp[i - 1][j - 1])) + unitdist;
}
}
}
return (double)(dp[m][n]) / std::max(m, n);
}
/*
\subsection{Function ~Distance~}
*/
template<class B>
double MBasics<B>::Distance(const MBasics<B>& mbs,
const DistanceFunction df /* = ALL */,
const LabelFunction lf /* = TRIVIAL */,
const double threshold /* = 1.0 */) const {
if (!IsDefined() && !mbs.IsDefined()) {
return 0.0;
}
if (!IsDefined() || !mbs.IsDefined()) {
return 1.0;
}
if (IsEmpty() && mbs.IsEmpty()) {
return 0.0;
}
if (IsEmpty() || mbs.IsEmpty()) {
return 1.0;
}
switch (df) {
// case FIRST: {
// return this->Distance_FIRST(mbs);
// }
// case LAST: {
// return this->Distance_LAST(mbs);
// }
case FIRST_LAST: {
return this->Distance_FIRST_LAST(mbs, lf);
}
case ALL: {
return this->Distance_ALL(mbs, lf);
}
// case ALL_DURATION: {
// return this->Distance_ALL_DURATION(mbs, lf);
// }
// case ALL_INTERVALS: {
// return this->Distance_ALL_INTERVALS(mbs, lf);
// }
// case EQUAL_LABELS: {
// return this->Distance_EQUAL_LABELS(mbs, lf);
// }
default: {
return -1.0;
}
}
}
/*
\subsection{Function ~CommonPrefixSuffix~}
*/
template<class B>
int MBasics<B>::CommonPrefixSuffix(const MBasics<B>& mbs, const bool prefix) {
std::set<typename B::base> b1, b2;
int result = 0;
int minLength = std::min(GetNoComponents(), mbs.GetNoComponents());
for (int i = 0; i < minLength; i++) {
GetValues(i, b1);
mbs.GetValues(i, b2);
if (b1 == b2) {
result++;
}
else {
return result;
}
}
return result;
}
/*
\subsection{Function ~DistanceSym~}
*/
template<class B>
double MBasics<B>::DistanceSym(const MBasics<B>& mbs,
const DistanceFunSym distfun) {
if (IsEmpty() && mbs.IsEmpty()) {
return 0.0;
}
std::set<typename B::base> b1, b2;
switch (distfun) {
case EQUALLABELS: {
if (GetNoComponents() != mbs.GetNoComponents()) {
return 1.0;
}
for (int i = 0; i < GetNoComponents(); i++) {
GetValues(i, b1);
mbs.GetValues(i, b2);
if (b1 != b2) {
return 1.0;
}
}
return 0.0;
}
case PREFIX: {
int prefix = CommonPrefixSuffix(mbs, true);
if (prefix == std::min(GetNoComponents(), mbs.GetNoComponents())) {
return 0.0;
}
return (prefix == 0 ? 2.0 : 1.0 / prefix);
}
case SUFFIX: {
int suffix = CommonPrefixSuffix(mbs, false);
if (suffix == std::min(GetNoComponents(), mbs.GetNoComponents())) {
return 0.0;
}
return (suffix == 0 ? 2.0 : 1.0 / suffix);
}
case PREFIXSUFFIX: {
int prefix = CommonPrefixSuffix(mbs, true);
int suffix = CommonPrefixSuffix(mbs, false);
if (prefix+suffix >= std::min(GetNoComponents(), mbs.GetNoComponents())) {
return 0.0;
}
return (prefix + suffix == 0 ? 2.0 : 1.0 / (prefix + suffix));
}
default: {
return -1.0;
}
}
}
template<class B>
void MBasics<B>::InsertLabels(std::vector<std::string>& result) const {
B b(true);
for (int i = 0; i < GetNoComponents(); i++) {
GetBasics(i, b);
b.InsertLabels(result);
}
}
template<class B>
void MBasics<B>::InsertLabels(std::set<std::string>& result) const {
B b(true);
for (int i = 0; i < GetNoComponents(); i++) {
GetBasics(i, b);
b.InsertLabels(result);
}
}
template<class B>
void MBasics<B>::FrequencyVector(InvertedFile& inv, std::vector<double>& fv,
const bool useIdf /* = false */) const {
B b(true);
for (int i = 0; i < GetNoComponents(); i++) {
GetBasics(i, b);
b.UpdateFrequencies(inv, fv);
}
if (useIdf) {
double noDocs = 0.0;
InvertedFile::prefixIterator* pit = 0;
TupleId id;
uint32_t wc, cc;
std::string dummy = "zzzzz";
pit = inv.getPrefixIterator(dummy);
if (pit->next(dummy, id, wc, cc)) { // retrieve noTuples from inv node
noDocs = (double)id;
}
else {
return;
}
delete pit;
std::string emptyPrefix = "";
pit = inv.getPrefixIterator(emptyPrefix);
int pos = 0;
int noEntries = inv.getNoEntries() - 1;
while (pos < noEntries && pit->next(emptyPrefix, id, wc, cc)) {
if (fv[pos] > 0.0) {
fv[pos] *= log(noDocs / wc);
}
pos++;
}
delete pit;
}
}
/*
\section{Class ~UnitsLI~}
*/
class UnitsLI {
public:
UnitsLI() : index(0) {}
~UnitsLI() {}
int index;
};
int getTypeNo(ListExpr typeList);
bool isSymbolicType(ListExpr typeList);
double scalarProduct(collection::Collection& v1, collection::Collection& v2);
double vLength(collection::Collection& v);
double cosineSimilarity(collection::Collection& v1, collection::Collection& v2);
double jaccardSimilarity(collection::Collection& v1,
collection::Collection& v2);
double jaccardSimilarity(std::set<std::string>& s1, std::set<std::string>& s2);
}