Skip to content
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

Add multi-objective optimization API with Pagmo support #1106

Merged
merged 34 commits into from
Sep 10, 2018

Conversation

jslee02
Copy link
Member

@jslee02 jslee02 commented Aug 28, 2018

This PR is an initial effort for having a pipeline for multi-objective optimization.

Summary of Main Changes

  • MultiObjectiveProblem: Class to define a multi-objective problem. You can compose multiple objectives, equality constraints, and inequality constraints by adding Functions to this class.
  • Population: Container of populations and their fitness. Pagmo2 inspired the implementation.
  • MultiObjectiveSolver: Base class for concrete solvers.
  • PagmoMultiObjectiveSolver: The first concrete solver that depends on pagmo2, which is a population-based optimization library for single/multi-objective problems.

The implementation is based on other project collaborated with Daqing Yi(@dqyi11).


Before creating a pull request

  • Document new methods and classes
  • Format new code files using clang-format

Before merging a pull request

  • Set version target by selecting a milestone on the right side
  • Summarize this change in CHANGELOG.md
  • Add unit test(s) for this change

@jslee02 jslee02 added this to the DART 6.7.0 milestone Aug 28, 2018
@jslee02 jslee02 requested a review from mxgrey August 28, 2018 06:18
@codecov
Copy link

codecov bot commented Aug 28, 2018

Codecov Report

❗ No coverage uploaded for pull request base (release-6.7@23f46cb). Click here to learn what that means.
The diff coverage is 0.43%.

@@              Coverage Diff               @@
##             release-6.7    #1106   +/-   ##
==============================================
  Coverage               ?   55.89%           
==============================================
  Files                  ?      340           
  Lines                  ?    25117           
  Branches               ?        0           
==============================================
  Hits                   ?    14040           
  Misses                 ?    11077           
  Partials               ?        0
Impacted Files Coverage Δ
dart/optimizer/Solver.hpp 100% <ø> (ø)
dart/optimizer/MultiObjectiveProblem.cpp 0% <0%> (ø)
dart/optimizer/Population.cpp 0% <0%> (ø)
dart/optimizer/MultiObjectiveSolver.cpp 0% <0%> (ø)
dart/math/Helpers.hpp 71.92% <0%> (ø)
dart/optimizer/MultiObjectiveSolver.hpp 0% <0%> (ø)
dart/optimizer/Population.hpp 0% <0%> (ø)
dart/optimizer/MultiObjectiveProblem.hpp 0% <0%> (ø)
dart/math/Random.cpp 14.28% <14.28%> (ø)

} // namespace common

template <class T>
auto operator<<(std::ostream& os, const T& t) -> decltype(t.print(os), os)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for my own edification, how is decltype(t.print(os), os) different from decltype(os)?

As I understand it, the return value of the comma operator is a reference to the result of whatever expression is on the right-hand side of the comma, in this case os. Since decltype(~) returns the type information of the evaluation of whatever expression it's given, wouldn't it just be returning std::ostream& here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I think I understand now! This is a SFINAE trick to make sure that T satisfies the constraint of having a member function with the signature print(std::ostream&).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly!

@@ -286,6 +287,57 @@ inline Eigen::VectorXd randomVectorXd(std::size_t size, double limit)
return randomVectorXd(size, -std::abs(limit), std::abs(limit));
}

template <typename T>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: missing

//==============================================================================

above this line.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


//==============================================================================
template <typename Derived>
void push_right(Derived& m, Eigen::Vector3d&& values)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know if I'm wrong, but I assume this function is meant to expand dynamically-sized matrices similar to Eigen::MatrixXd. If so, is there a reason that values must be an Eigen::Vector3d instead of Eigen::Matrix<double, N, 1> where N is a template parameter?

Also, I can't find any Eigen member function of the matrix class named right(int), so maybe I'm completely misunderstanding the role of this function (same for push_bottom()).

Furthermore, I can't find where in the code these functions are being used. If they aren't being used yet, I would recommend removing them from this PR, because otherwise I'm not sure if these functions can even compile.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All your points are correct. This function was used during the implementation but it turned out not for the final version. Let me remove this and reintroduce with some corrections later if necessary.


static Population convertPopulation(
const ::pagmo::population& pagmoPop,
std::shared_ptr<MultiObjectiveProblem> problem);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: use a const std::shared_ptr<T>& here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intentionally left this as passing by value in order to indicate that this function sharing the ownership because the caller can notice that the reference counting would be increase by the copy. Note that the reference counting would happen only one time because we move the copied shared_ptr in the function.

As a note, we would be good to have a documentation on this convention like this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, okay. That's a subtle but reasonable signal to the user 👍

@jslee02 jslee02 merged commit 7a713eb into release-6.7 Sep 10, 2018
@jslee02 jslee02 deleted the enhance/pagmo_multi_objective branch September 10, 2018 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants