# Vector and Matrix Related

## Vector/Matrix comma initializer

From GTSAM 3.0 we have convenient comma initializer to initialize Vector and Matrix objects in built-in Eigen library. But this makes GTSAM is no longer compatible to official Eigen release. In GTSAM 4.0 we remove this comma initializer and few changes needed

```// this is no longer correct
gtsam::Vector v = gtsam::Vector(3) << 0, 0, 0;
gtsam::Matrix m = gtsam::Matrix(2,2) << 1, 0, 0, 1;
// this is correct
gtsam::Vector v = (gtsam::Vector(3) << 0, 0, 0).finished();
gtsam::Matrix m = (gtsam::Matrix(2,2) << 1, 0, 0, 1).finished();
```

## Fixed size matrices

FIxed sized matrices will decided the allocate memory size during compile time, so there will be performance boosting by using fixed sized matrices if the size is pre-decidable.

```// syntactic sugar of Eigen fixed style:
Matrix35 m35;      // MatrixMN = Matrix(M,N), M,N <= 9;
Matrix3 m33;       // MatrixM = Matrix(M,M), M <= 9;

// Identity Matrix:
Matrix3 I = I_3x3;      // MatrixM I_MxN, M,N <= 9;

// Zero Matrix:
Matrix3 z = Z_3x3;      // MatrixM Z_MxN; //M,N <= 9;
```

## OptionalJacobian

If you are working on your own factors, writing error function with known size jacobian matrices, note that GTSAM has a `OptionalJacobian` class now, which is used to replace old `boost::optional<Matrix&>` class. The old format is still compatible but no longer recommended.

```// old style, not recommended now
Vector YourOwnFactor::evaluateError(const Type& somevar, boost::optional<Matrix&> H) const;
// new style, with known size jacobian MxN
Vector YourOwnFactor::evaluateError(const Type& somevar, OptionalJacobian<M,N> H) const;
```

# GTSAM traits and Values type

One of the main change from GTSAM 3.X to GTSAM 4.0 is the use of `gtsam::traits`. `gtsam::traits` are a step towards making GTSAM more modern and more efficient, by defining type properties such as dimensionality, group-ness, etc with boost::traits style meta-functions. Our core data structure `Values` can now take any type, provided the necessary `gtsam::traits` are defined. This allows for getting rid of those ugly LieScalar/LieVector types.

We are trying to keep user interfaces unchanged, but since this is a fundamental change in GTSAM underlay data structure, some code are not compilable anymore. Here we have brief tutorial of how to fix the related issues and take advantages of the latest techniques.

## Custom Value types

In GTSAM 3.X, all Value types had to be derived from `gtsam::DerivedValue`, which in turn derived from `gtsam::Value`. In GTSAM 4.0, we remove this requirement in favor of type traits. A minimal example for a generic Value type may then look like this:

```class ExampleValue {
public:
ExampleValue() { ... }

// Tangent space dimensionality
enum {
dimension = N
};

inline size_t dim() const {}

/// Retract delta to manifold
ExampleValue retract(const VectorN &v) const {}

/// Compute the coordinates in the tangent space
VectorN localCoordinates(const ExampleValue &value) const {}

/// The print function
void print(const std::string &s = std::string()) const {}

/// The equals function with tolerance
bool equals(const ExampleValue &s, double tol = 1e-9) const {}
};

// required traits - could alternatively be VectorSpace, LieGroup, etc.
template<>
struct traits<ExampleValue> : public internal::Manifold<ExampleValue> {};

template<>
struct traits<const ExampleValue> : public internal::Manifold<ExampleValue> {};
```

Type traits not only add necessary machinery for custom types to function as Values, but also enforce a number of concept checks. Examples of built-in classes implementing this are mainly in geometry, including Rot3, Pose2, etc.

## Type Casting

Old GTSAM geometry classes are derived from `gtsam::DerivedValue` class, which is derived from `gtsam::Value`. But now all geometry classes are not derived from `gtsam::DerivedValue` class anymore. So we cannot cast a `gtsam::Value` object to geometry object anymore, or vice versa. The following code will get error

```gtsam::Value value;
// let value contains a gtsam::Pose2 object here

// static_cast is not compilable
gtsam::Pose2 pose_static = static_cast<const gtsam::Pose2&>(value);
// dynamic_cast will throw runtime std::bad_cast
gtsam::Pose2 pose_dynamic = dynamic_cast<const gtsam::Pose2&>(value);
```

The modern way to do this is using the `Value::cast()` function to get cast object

```// use cast() provided by gtsam::Value
gtsam::Pose2 pose_cast = value.cast<gtsam::Pose2>();
```

## Const Type Reference in at() and exists()

Since the implementations of `gtsam::Values::at()` and `gtsam::Values::exists()` are changed, there's no need to put any const or reference typename in the template parameters. Such as

```gtsam::Values values;
gtsam::Key key;
// values contains a Pose2 object at key

// these will be not compilable
gtsam::Pose2 pose_at = values.at<const gtsam::Pose2&>(key);
gtsam::Pose2 pose_exists = values.exists<const gtsam::Pose2&>(key);
```

To fix just remove any const and reference

```// these are fine
gtsam::Pose2 pose_at = values.at<gtsam::Pose2>(key);
gtsam::Pose2 pose_exists = values.exists<gtsam::Pose2>(key);
```

## Typeid

If you are using typeid keyword to identify the type of object contained in a `gtsam::Value` object, note that now the typeid of a value is no longer the same as the typeid of the Typename, but gtsam::ChartValue<Typename>.

```gtsam::Value value;
// let value contains a gtsam::Pose2 object here

// this will return false
typeid(value) == typeid(gtsam::Pose2);
// this will return true
typeid(value) == typeid(gtsam::ChartValue<gtsam::Pose2>);
```

Updated