- 
                Notifications
    You must be signed in to change notification settings 
- Fork 6
Serializable LDLT Decomposition. #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
the lower triangular portion of a cholesky.
and LDLT decomposition.
d4c7dee    to
    fe33d34      
    Compare
  
    57e18e0    to
    e3aa94f      
    Compare
  
    e3aa94f    to
    ec0471b      
    Compare
  
    There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
| /* | ||
| * The subsequent save/load methods catch the serialization methods | ||
| * for arbitrary Eigen::Matrix* types. The general idea is that each | ||
| * row is saved as a Eigen::Vector. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How was it done before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was the same idea, but with explict use of VectorXd.  Now it's via template specialization with _Cols=1.
| size_type rows; | ||
| archive(cereal::make_size_tag(rows)); | ||
| /* | ||
| * In order to determine the size of a matrix, we have to first determine | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be easier to serialize the dimensions instead of needing to scan through?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah we could.  There's a bit of a trick going on with cereal here.  By adding a SizeTag (via make_size_tag) cereal will just serialize a list and upon loading it'll determine the size tag from the length of the data.  Without this it'll serialize as a map ({'value0': 0, 'value1': 1, ...}) which is clearly not an efficient storage technique.  What I could do is store redundant information.  Ie, store a SizeTag and a shape.  Think that's better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, I'm fine with whichever you think is easiest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alright, I changed it around so the rows and cols are stored explicitly. Shouldn't add much overhead in storage and makes the code easier to read (I think).
        
          
                albatross/eigen/serializable_ldlt.h
              
                Outdated
          
        
      | storage_size -= 2; | ||
| // We assume the matrix is square and compute the number of rows from the | ||
| // storage size. | ||
| double drows = (std::sqrt(static_cast<double>(storage_size * 8 + 1)) - 1) / 2; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we name these numbers so it's clearer what's going on?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|  | ||
| SerializableLDLT(const LDLT<MatrixXd, Lower> &ldlt) | ||
| // Can we get around copying here? | ||
| : LDLT<MatrixXd, Lower>(ldlt){}; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this stores a unique pointer we could move it in which would save the copy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correct, the problem with that is that it would require changing the way Eigen::LDLT works.  As it stands all the storage is done in the base class.  We might be able to do something like instantiate an empty Eigen::LDLT then point the internal members to pointers that are passed in ... but that feels wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah probably not worth it.
        
          
                albatross/eigen/serializable_ldlt.h
              
                Outdated
          
        
      | for (Eigen::Index i = 0; i < n; i++) { | ||
| const Eigen::VectorXd col_i = | ||
| inverse_cholesky.col(i).cwiseProduct(sqrt_diag); | ||
| ; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: extra semicolon
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice catch
        
          
                albatross/eigen/serializable_ldlt.h
              
                Outdated
          
        
      | this->matrixL().solveInPlace(inverse_cholesky); | ||
|  | ||
| Eigen::VectorXd sqrt_diag = this->vectorD(); | ||
| for (Eigen::Index i = 0; i < n; i++) { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: You could maybe use the Eigen::Array functions here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah interesting.  Despite the appearance it seems like x.array().sqrt().matrix() doesn't add any runtime overhead ?!?
* Store rows/cols explicitly for Matrix serialization. * Clarifications.
54853f6    to
    b93b5c6      
    Compare
  
    
Adds an extention of Eigen's LDLT which is serializable and only serializes the lower triangular portion.
Changes include:
Matrix3dandMatrixXdare now handled in a single case which also allows for different internal types.SerializableLDLTclass which wrapsLDLT<MatrixXd>.SerilizableLDLTinGaussianProcessFit.test_serilalizeto test more than just the models.