Index: tol_pkg/MatEncode/MatEncode.tol
===================================================================
--- tol_pkg/MatEncode/MatEncode.tol	(revision 789dc8a9847bc224daf001d8546dff9591863fb4)
+++ tol_pkg/MatEncode/MatEncode.tol	(revision 789dc8a9847bc224daf001d8546dff9591863fb4)
@@ -0,0 +1,225 @@
+/* -*- mode: C++ -*- */
+//////////////////////////////////////////////////////////////////////////////
+// FILE   : MatEncode.tol
+// PURPOSE: Defines Package MatEncode
+//////////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////////
+NameBlock MatEncode =
+//////////////////////////////////////////////////////////////////////////////
+[[
+
+#Require HashMap;
+#Require MatQuery;
+
+Text _.autodoc.description = "Handling and storing generic features, "
+"numerical or not, in an efficient way by means of encoded matrices.";
+Text _.autodoc.url = "";
+Set _.autodoc.keys = [["encode","decode","category","feature"]];
+Set _.autodoc.authors = [[
+   "vdebuen@tol-project.org" ]];
+
+//////////////////////////////////////////////////////////////////////////////
+Class @Feature
+//////////////////////////////////////////////////////////////////////////////
+{
+  Static Text _.autodoc.description = "Class for handling with abstract "
+  "features of arbitrary entities, numerical or not, that will be stored in "
+  "an external matrix with a row for each entity.";
+  //The name of the feature
+  Text _.name;
+  //The number of the feature in the full set of features
+  Real _.position;
+
+  Real is.numeric(Real void);
+
+  ////////////////////////////////////////////////////////////////////////////
+  Static Text _.autodoc.member.get = "Returns the stored value corresponding "
+  "to this feature related to an individual entity.";
+  Anything get(Matrix store, Real entity)
+  ////////////////////////////////////////////////////////////////////////////
+};
+
+//////////////////////////////////////////////////////////////////////////////
+Class @Feature.Numeric : @Feature
+//////////////////////////////////////////////////////////////////////////////
+{
+  Static Text _.autodoc.description = "Class for handling with numerical "
+  "numerical features of arbitrary entities that will be stored in an "
+  "external matrix with a row for each entity.";
+
+  Real is.numeric(Real void) { True };
+
+  ////////////////////////////////////////////////////////////////////////////
+  Static Text _.autodoc.member.New = "Creates a new instance of "
+  "Class @Feature.Numeric";
+  Static @Feature.Numeric New(Text name, Real position)
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    @Feature.Numeric aux =
+    [[
+      Text _.name = name;
+      Real _.position  = position
+    ]]
+  };
+  
+  ////////////////////////////////////////////////////////////////////////////
+  Anything get(Matrix store, Real entity)
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    MatDat(store, entity, _.position)
+  }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+Class @Feature.NonNumeric : @Feature
+//////////////////////////////////////////////////////////////////////////////
+{
+  Static Text _.autodoc.description = "Class for handling with numerical "
+  "numerical features of arbitrary entities that will be stored in an "
+  "external matrix with a row for each entity. Here the stored value is the "
+  "index of the feature stored in an arbitrary domain.";
+
+  //The set of valid values for this feature indexed by name
+  Set _.domain;
+
+  Real is.numeric(Real void) { False };
+
+  ////////////////////////////////////////////////////////////////////////////
+  Static Text _.autodoc.member.New = "Creates a new instance of "
+  "Class @Feature.NonNumeric";
+  Static @Feature.NonNumeric New(Text name, Real position, Set domain)
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    @Feature.NonNumeric aux =
+    [[
+      Text _.name = name;
+      Real _.position  = position;
+      Set _.domain = domain    
+    ]];
+    Real SetIndexByName(aux::_.domain);
+    aux
+  }; 
+
+  ////////////////////////////////////////////////////////////////////////////
+  Anything get(Matrix store, Real entity)
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    Real idx = MatDat(store, entity, _.position);
+    _.domain[idx]
+  };
+
+  ////////////////////////////////////////////////////////////////////////////
+  Real domain.index(Text name)
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    FindIndexByName(_.domain, name)
+  }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+Class @FeatureSet
+//////////////////////////////////////////////////////////////////////////////
+{
+  //Stores and index by name a set of instances od @Feature
+  Set _.feature = Copy(Empty);
+  //In each row of this matrix are stored the values or indexes of features
+  //related to an individual entity
+  Matrix _.data = Rand(0,0,0,0);
+
+  ////////////////////////////////////////////////////////////////////////////
+  Static Text _.autodoc.member.New = "Creates a new instance of "
+  "Class @FeatureSet";
+  Static @FeatureSet New(Real void)
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    @FeatureSet aux
+  };
+
+  ////////////////////////////////////////////////////////////////////////////
+  Static Text _.autodoc.member.add.feature.numeric = 
+  "Adds a new numerical feature";
+  Real add.feature.numeric(Text name)
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    HashMap::Append.Indexed(
+      _.feature,
+      @Feature.Numeric::New(name, Card(_.feature)+1),
+      name)
+  };
+
+  ////////////////////////////////////////////////////////////////////////////
+  Static Text _.autodoc.member.add.feature.nonnumeric=
+  "Adds a new non numerical feature";
+  Real add.feature.nonnumeric(Text name, Set domain)
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    HashMap::Append.Indexed(
+      _.feature,
+      @Feature.NonNumeric::New(name, Card(_.feature)+1, domain),
+      name)
+  };
+
+  ////////////////////////////////////////////////////////////////////////////
+  Text _.autodoc.member.feature.index = "Returns the index of a feature or 0 "
+  "if it not exists";
+  Real feature.index(Text name)
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    FindIndexByName(_.feature, name )
+  };
+
+  ////////////////////////////////////////////////////////////////////////////
+  Text _.autodoc.member.get = "Returns the value of a feature for an entity";
+  Anything get(Real entity, 
+               Anything feature) //Real position or Text name
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    @Feature f = _.feature[feature];
+    f::get(_.data, entity)
+  };
+
+  ////////////////////////////////////////////////////////////////////////////
+  Text _.autodoc.member.get.all = "Returns a set with the values of all "
+  "features for an entity";
+  Set get.all(Real entity) 
+  ////////////////////////////////////////////////////////////////////////////
+  { 
+    EvalSet(_.feature, Anything get.all.cycle(@FeatureSet f) 
+    { 
+      f::get(_.data, entity)
+    })
+  };
+
+  ////////////////////////////////////////////////////////////////////////////
+  Text _.autodoc.member.select.feature.with.value = 
+  "Returns a column matrix with True in rows where given feature has "
+  "specified value";
+  VMatrix select.feature.with.value(
+    Text feature.name, 
+    Anything value.id) //Text value identifier in domain or  Real value
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    Real num = _.feature.index(feature.name);
+    @Feature f = _.feature[num];
+    Real value = If(f::is.numeric(0),
+      value.id,
+      f::_.domain.index(value.id));
+    MatQuery::MatchRowsWithValue(SubCol(_.data,[[num]]),value)
+  };
+
+  ////////////////////////////////////////////////////////////////////////////
+  Text _.autodoc.member.intersect.feature.with.value = 
+  "Returns a column matrix with True in rows where given feature has "
+  "specified value";
+  VMatrix intersect.feature.with.value(
+    Text feature.name, 
+    Anything value.id, //Text value identifier in domain or  Real value
+    VMatrix match)
+  ////////////////////////////////////////////////////////////////////////////
+  {
+    And(match,select.feature.with.value(feature.name,value.id))
+  }
+}
+
+]];
