Port Ceres to Windows
This is a preliminary, but full, port of Ceres to Windows.
Currently all tests compile and run, with only system_test
failing to work correctly due to a path issue.
Change-Id: I4152c1588bf51ffd7f4d9401ef9759f5d28c299c
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index a981d59..0ca92fd 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -98,7 +98,7 @@
IF (${SCHUR_SPECIALIZATIONS})
FILE(GLOB CERES_INTERNAL_SCHUR_FILES generated/*.cc)
ELSE (${SCHUR_SPECIALIZATIONS})
- # Only the fully dynamic solver.
+ # Only the fully dynamic solver. The build is much faster this way.
FILE(GLOB CERES_INTERNAL_SCHUR_FILES generated/schur_eliminator_d_d_d.cc)
ENDIF (${SCHUR_SPECIALIZATIONS})
diff --git a/internal/ceres/autodiff_cost_function_test.cc b/internal/ceres/autodiff_cost_function_test.cc
index 2f44595..33e576f 100644
--- a/internal/ceres/autodiff_cost_function_test.cc
+++ b/internal/ceres/autodiff_cost_function_test.cc
@@ -44,15 +44,13 @@
template <typename T>
bool operator()(const T* const x, const T* const y,
T* cost) const {
- cost[0] =
- x[0] * y[0] + x[1] * y[1] - T(a_);
+ cost[0] = x[0] * y[0] + x[1] * y[1] - T(a_);
return true;
}
private:
double a_;
};
-
TEST(AutoDiffResidualAndJacobian, BilinearDifferentiationTest) {
CostFunction* cost_function =
new AutoDiffCostFunction<BinaryScalarCost, 1, 2, 2>(
@@ -72,7 +70,6 @@
jacobians[0] = new double[2];
jacobians[1] = new double[2];
-
double residuals = 0.0;
cost_function->Evaluate(parameters, &residuals, NULL);
diff --git a/internal/ceres/block_random_access_sparse_matrix_test.cc b/internal/ceres/block_random_access_sparse_matrix_test.cc
index e4e6769..1e1f831 100644
--- a/internal/ceres/block_random_access_sparse_matrix_test.cc
+++ b/internal/ceres/block_random_access_sparse_matrix_test.cc
@@ -115,7 +115,8 @@
kTolerance);
// There is nothing else in the matrix besides these four blocks.
- EXPECT_NEAR(dense.norm(), sqrt(9 + 16 * 16 + 36 * 20 + 9 * 15), kTolerance);
+ EXPECT_NEAR(dense.norm(), sqrt(9. + 16. * 16. + 36. * 20. + 9. * 15.),
+ kTolerance);
}
// IntPairToLong is private, thus this fixture is needed to access and
diff --git a/internal/ceres/collections_port.h b/internal/ceres/collections_port.h
index 7255285..e125f3f 100644
--- a/internal/ceres/collections_port.h
+++ b/internal/ceres/collections_port.h
@@ -33,8 +33,13 @@
#ifndef CERES_INTERNAL_COLLECTIONS_PORT_H_
#define CERES_INTERNAL_COLLECTIONS_PORT_H_
+#if defined(_MSC_VER) && _MSC_VER <= 1600
+#include <unordered_map>
+#include <unordered_set>
+#else
#include <tr1/unordered_map>
#include <tr1/unordered_set>
+#endif
#include <utility>
#include "ceres/integral_types.h"
#include "ceres/internal/port.h"
diff --git a/internal/ceres/corrector_test.cc b/internal/ceres/corrector_test.cc
index b2556af..b2ee9ab 100644
--- a/internal/ceres/corrector_test.cc
+++ b/internal/ceres/corrector_test.cc
@@ -44,15 +44,19 @@
// If rho[1] is zero, the Corrector constructor should crash.
TEST(Corrector, ZeroGradientDeathTest) {
const double kRho[] = {0.0, 0.0, 0.0};
+#ifndef _WIN32
ASSERT_DEATH({Corrector c(1.0, kRho);},
".*");
+#endif // _WIN32
}
// If rho[1] is negative, the Corrector constructor should crash.
TEST(Corrector, NegativeGradientDeathTest) {
const double kRho[] = {0.0, -0.1, 0.0};
+#ifndef _WIN32
ASSERT_DEATH({Corrector c(1.0, kRho);},
".*");
+#endif // _WIN32
}
TEST(Corrector, ScalarCorrection) {
diff --git a/internal/ceres/graph_test.cc b/internal/ceres/graph_test.cc
index ce82dea..d4ee22d 100644
--- a/internal/ceres/graph_test.cc
+++ b/internal/ceres/graph_test.cc
@@ -83,6 +83,10 @@
EXPECT_EQ(graph.EdgeWeight(1, 0), 0.5);
}
+// Death tests don't work on Windows.
+// TODO(keir): Figure out why this test doesn't work on Windows.
+#ifndef _WIN32
+
TEST(Graph, DieOnNonExistentVertex) {
Graph<int> graph;
graph.AddVertex(0, 1.0);
@@ -93,6 +97,8 @@
EXPECT_DEATH(graph.Neighbors(2), "key not found");
}
+#endif // _WIN32
+
TEST(Graph, NonExistentEdge) {
Graph<int> graph;
graph.AddVertex(0, 1.0);
diff --git a/internal/ceres/iterative_schur_complement_solver.cc b/internal/ceres/iterative_schur_complement_solver.cc
index 3d837b3..ec4293b 100644
--- a/internal/ceres/iterative_schur_complement_solver.cc
+++ b/internal/ceres/iterative_schur_complement_solver.cc
@@ -40,6 +40,9 @@
#include "ceres/block_structure.h"
#include "ceres/conjugate_gradients_solver.h"
#include "ceres/implicit_schur_complement.h"
+#include "ceres/linear_solver.h"
+#include "ceres/triplet_sparse_matrix.h"
+#include "ceres/visibility_based_preconditioner.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/linear_solver.h"
diff --git a/internal/ceres/jet_test.cc b/internal/ceres/jet_test.cc
index f12b8b9..0dd4336 100644
--- a/internal/ceres/jet_test.cc
+++ b/internal/ceres/jet_test.cc
@@ -33,7 +33,7 @@
#include <algorithm>
#include <cmath>
-#include <glog/logging.h>
+#include "glog/logging.h"
#include "gtest/gtest.h"
#include "ceres/fpclassify.h"
#include "ceres/stringprintf.h"
@@ -44,6 +44,8 @@
namespace ceres {
namespace internal {
+const double kE = 2.71828182845904523536;
+
typedef Jet<double, 2> J;
// Convenient shorthand for making a jet.
@@ -166,7 +168,7 @@
VL << "x = " << x;
VL << "y = " << y;
- J u = pow(M_E, logx);
+ J u = pow(kE, logx);
VL << "u = " << u;
ExpectJetsClose(x, u);
@@ -174,7 +176,7 @@
{ // Check that pow(e, log(x)) == x.
J logx = log(x);
- J e = MakeJet(M_E, 0., 0.);
+ J e = MakeJet(kE, 0., 0.);
VL << "x = " << x;
VL << "log(x) = " << logx;
@@ -186,7 +188,7 @@
{ // Check that pow(e, log(x)) == x.
J logx = log(x);
- J e = MakeJet(M_E, 0., 0.);
+ J e = MakeJet(kE, 0., 0.);
VL << "x = " << x;
VL << "logx = " << logx;
@@ -198,7 +200,7 @@
{ // Check that pow(x,y) = exp(y*log(x)).
J logx = log(x);
- J e = MakeJet(M_E, 0., 0.);
+ J e = MakeJet(kE, 0., 0.);
VL << "x = " << x;
VL << "logx = " << logx;
diff --git a/internal/ceres/linear_least_squares_problems.cc b/internal/ceres/linear_least_squares_problems.cc
index fccc3b1..ef72cbd 100644
--- a/internal/ceres/linear_least_squares_problems.cc
+++ b/internal/ceres/linear_least_squares_problems.cc
@@ -61,6 +61,7 @@
default:
LOG(FATAL) << "Unknown problem id requested " << id;
}
+ return NULL;
}
#ifndef CERES_DONT_HAVE_PROTOCOL_BUFFERS
diff --git a/internal/ceres/linear_solver.cc b/internal/ceres/linear_solver.cc
index c08d1f2..4bfb599 100644
--- a/internal/ceres/linear_solver.cc
+++ b/internal/ceres/linear_solver.cc
@@ -81,6 +81,7 @@
default:
LOG(FATAL) << "Unknown linear solver type :"
<< options.type;
+ return NULL; // MSVC doesn't understand that LOG(FATAL) never returns.
}
}
diff --git a/internal/ceres/local_parameterization_test.cc b/internal/ceres/local_parameterization_test.cc
index aa49250..df59ed3 100644
--- a/internal/ceres/local_parameterization_test.cc
+++ b/internal/ceres/local_parameterization_test.cc
@@ -62,6 +62,10 @@
}
}
+// Death tests are not working on Windows yet.
+// TODO(keir): Figure out how to enable these.
+#ifndef _WIN32
+
TEST(SubsetParameterization, DeathTests) {
vector<int> constant_parameters;
EXPECT_DEATH(SubsetParameterization parameterization(1, constant_parameters),
@@ -80,6 +84,8 @@
"duplicates");
}
+#endif // _WIN32
+
TEST(SubsetParameterization, NormalFunctionTest) {
double x[4] = {1.0, 2.0, 3.0, 4.0};
for (int i = 0; i < 4; ++i) {
diff --git a/internal/ceres/numeric_diff_cost_function_test.cc b/internal/ceres/numeric_diff_cost_function_test.cc
index a39e160..d86bb58 100644
--- a/internal/ceres/numeric_diff_cost_function_test.cc
+++ b/internal/ceres/numeric_diff_cost_function_test.cc
@@ -197,7 +197,7 @@
{ 0.0, 0.0, 0.0, 0.0, 0.0 },
},
};
- for (int k = 0; k < ARRAYSIZE(kTests); ++k) {
+ for (int k = 0; k < CERES_ARRAYSIZE(kTests); ++k) {
double *x1 = &(kTests[k].x1[0]);
double *x2 = &(kTests[k].x2[0]);
double *parameters[] = { x1, x2 };
diff --git a/internal/ceres/parameter_block_test.cc b/internal/ceres/parameter_block_test.cc
index 98ec4d0..b1d69b0 100644
--- a/internal/ceres/parameter_block_test.cc
+++ b/internal/ceres/parameter_block_test.cc
@@ -36,6 +36,8 @@
namespace ceres {
namespace internal {
+// TODO(keir): Figure out how to enable the death tests on Windows.
+
TEST(ParameterBlock, SetLocalParameterization) {
double x[3] = { 1.0, 2.0, 3.0 };
ParameterBlock parameter_block(x, 3);
@@ -46,11 +48,13 @@
// Can't set the parameterization if the sizes don't match.
SubsetParameterization subset_wrong_size(4, indices);
+#ifndef _WIN32
ASSERT_DEATH(parameter_block.SetParameterization(&subset_wrong_size),
"global");
// Can't set parameterization to NULL from NULL.
ASSERT_DEATH(parameter_block.SetParameterization(NULL), "NULL");
+#endif // _WIN32
// Now set the parameterization.
SubsetParameterization subset(3, indices);
@@ -59,6 +63,7 @@
// Re-setting the parameterization to the same value is supported.
parameter_block.SetParameterization(&subset);
+#ifndef _WIN32
// Can't set parameterization to NULL from another parameterization.
ASSERT_DEATH(parameter_block.SetParameterization(NULL), "NULL");
@@ -66,6 +71,7 @@
SubsetParameterization subset_different(3, indices);
ASSERT_DEATH(parameter_block.SetParameterization(&subset_different),
"re-set");
+#endif // _WIN32
// Ensure the local parameterization jacobian result is correctly computed.
ConstMatrixRef local_parameterization_jacobian(
diff --git a/internal/ceres/problem_test.cc b/internal/ceres/problem_test.cc
index 28331f2..b8dbc74 100644
--- a/internal/ceres/problem_test.cc
+++ b/internal/ceres/problem_test.cc
@@ -106,6 +106,9 @@
}
};
+// TODO(keir): Figure out how to enable death tests on Windows.
+#ifndef _WIN32
+
TEST(Problem, AddResidualWithNullCostFunctionDies) {
double x[3], y[4], z[5];
@@ -169,6 +172,8 @@
"different block sizes");
}
+#endif // _WIN32
+
TEST(Problem, AddResidualAddsDuplicatedParametersOnlyOnce) {
double x[3], y[4], z[5];
@@ -182,6 +187,8 @@
EXPECT_EQ(12, problem.NumParameters());
}
+#ifndef _WIN32
+
TEST(Problem, AddParameterWithDifferentSizesOnTheSameVariableDies) {
double x[3], y[4];
@@ -226,6 +233,8 @@
ASSERT_EQ(5, problem.NumParameterBlocks());
}
+#endif // _WIN32
+
TEST(Problem, AddParameterIgnoresDuplicateCalls) {
double x[3], y[4];
diff --git a/internal/ceres/rotation_test.cc b/internal/ceres/rotation_test.cc
index 55a4fbb..3dc8231 100644
--- a/internal/ceres/rotation_test.cc
+++ b/internal/ceres/rotation_test.cc
@@ -45,6 +45,9 @@
namespace ceres {
namespace internal {
+const double kPi = 3.14159265358979323846;
+const double kHalfSqrt2 = 0.707106781186547524401;
+
double RandDouble() {
double r = rand();
return r / RAND_MAX;
@@ -54,7 +57,7 @@
static double const kTolerance = numeric_limits<double>::epsilon() * 10;
// Looser tolerance used for for numerically unstable conversions.
-static double const kLooseTolerance = 1e-9;;
+static double const kLooseTolerance = 1e-9;
// Use as:
// double quaternion[4];
@@ -199,9 +202,9 @@
// Transforms a rotation by pi/2 around X to a quaternion.
TEST(Rotation, XRotationToQuaternion) {
- double axis_angle[3] = { M_PI / 2, 0, 0 };
+ double axis_angle[3] = { kPi / 2, 0, 0 };
double quaternion[4];
- double expected[4] = { M_SQRT1_2, M_SQRT1_2, 0, 0 };
+ double expected[4] = { kHalfSqrt2, kHalfSqrt2, 0, 0 };
AngleAxisToQuaternion(axis_angle, quaternion);
EXPECT_THAT(quaternion, IsNormalizedQuaternion());
EXPECT_THAT(quaternion, IsNearQuaternion(expected));
@@ -220,7 +223,7 @@
TEST(Rotation, YRotationQuaternionToAngleAxis) {
double quaternion[4] = { 0, 0, 1, 0 };
double axis_angle[3];
- double expected[3] = { 0, M_PI, 0 };
+ double expected[3] = { 0, kPi, 0 };
QuaternionToAngleAxis(quaternion, axis_angle);
EXPECT_THAT(axis_angle, IsNearAngleAxis(expected));
}
@@ -230,7 +233,7 @@
TEST(Rotation, ZRotationQuaternionToAngleAxis) {
double quaternion[4] = { sqrt(3) / 2, 0, 0, 0.5 };
double axis_angle[3];
- double expected[3] = { 0, 0, M_PI / 3 };
+ double expected[3] = { 0, 0, kPi / 3 };
QuaternionToAngleAxis(quaternion, axis_angle);
EXPECT_THAT(axis_angle, IsNearAngleAxis(expected));
}
@@ -275,7 +278,7 @@
norm = sqrt(norm);
// Angle in [-pi, pi).
- double theta = M_PI * 2 * RandDouble() - M_PI;
+ double theta = kPi * 2 * RandDouble() - kPi;
for (int i = 0; i < 3; i++) {
axis_angle[i] = axis_angle[i] * theta / norm;
}
@@ -340,7 +343,7 @@
// Transforms a rotation by pi/2 around X to a rotation matrix and back.
TEST(Rotation, XRotationToRotationMatrix) {
- double axis_angle[3] = { M_PI / 2, 0, 0 };
+ double axis_angle[3] = { kPi / 2, 0, 0 };
double matrix[9];
// The rotation matrices are stored column-major.
double expected[9] = { 1, 0, 0, 0, 0, 1, 0, -1, 0 };
@@ -355,7 +358,7 @@
// Transforms an axis angle that rotates by pi about the Y axis to a
// rotation matrix and back.
TEST(Rotation, YRotationToRotationMatrix) {
- double axis_angle[3] = { 0, M_PI, 0 };
+ double axis_angle[3] = { 0, kPi, 0 };
double matrix[9];
double expected[9] = { -1, 0, 0, 0, 1, 0, 0, 0, -1 };
AngleAxisToRotationMatrix(axis_angle, matrix);
@@ -385,7 +388,7 @@
// Angle in [pi - kMaxSmallAngle, pi).
const double kMaxSmallAngle = 1e-2;
- double theta = M_PI - kMaxSmallAngle * RandDouble();
+ double theta = kPi - kMaxSmallAngle * RandDouble();
for (int i = 0; i < 3; i++) {
in_axis_angle[i] *= (theta / norm);
@@ -400,7 +403,7 @@
}
TEST(Rotation, AtPiAngleAxisRoundTrip) {
- // A rotation of M_PI about the X axis;
+ // A rotation of kPi about the X axis;
static const double kMatrix[3][3] = {
{1.0, 0.0, 0.0},
{0.0, -1.0, 0.0},
@@ -415,7 +418,7 @@
}
}
- const double expected_axis_angle[3] = { M_PI, 0, 0 };
+ const double expected_axis_angle[3] = { kPi, 0, 0 };
double out_matrix[9];
double axis_angle[3];
@@ -424,7 +427,7 @@
LOG(INFO) << "AngleAxis = " << axis_angle[0] << " " << axis_angle[1]
<< " " << axis_angle[2];
- LOG(INFO) << "Expected AngleAxis = " << M_PI << " 0 0";
+ LOG(INFO) << "Expected AngleAxis = " << kPi << " 0 0";
double out_rowmajor[3][3];
for (int j = 0, k = 0; j < 3; ++j) {
for (int i = 0; i < 3; ++i, ++k) {
@@ -452,7 +455,7 @@
// Transforms an axis angle that rotates by pi/3 about the Z axis to a
// rotation matrix.
TEST(Rotation, ZRotationToRotationMatrix) {
- double axis_angle[3] = { 0, 0, M_PI / 3 };
+ double axis_angle[3] = { 0, 0, kPi / 3 };
double matrix[9];
// This is laid-out row-major on the screen but is actually stored
// column-major.
@@ -483,7 +486,7 @@
norm = sqrt(norm);
// Angle in [-pi, pi).
- double theta = M_PI * 2 * RandDouble() - M_PI;
+ double theta = kPi * 2 * RandDouble() - kPi;
for (int i = 0; i < 3; i++) {
axis_angle[i] = axis_angle[i] * theta / norm;
}
@@ -510,7 +513,7 @@
// Convert Euler angles from radians to degrees.
static void ToDegrees(double ea[3]) {
for (int i = 0; i < 3; ++i)
- ea[i] *= 180.0 / M_PI;
+ ea[i] *= 180.0 / kPi;
}
// Compare the 3x3 rotation matrices produced by the axis-angle
@@ -843,7 +846,7 @@
double rotation_matrix_rotated_p[3];
for (int i = 0; i < 10000; ++i) {
- double theta = (2.0 * i * 0.0011 - 1.0) * M_PI;
+ double theta = (2.0 * i * 0.0011 - 1.0) * kPi;
for (int j = 0; j < 50; ++j) {
double norm2 = 0.0;
for (int k = 0; k < 3; ++k) {
diff --git a/internal/ceres/runtime_numeric_diff_cost_function_test.cc b/internal/ceres/runtime_numeric_diff_cost_function_test.cc
index 6926d28..bc195b8 100644
--- a/internal/ceres/runtime_numeric_diff_cost_function_test.cc
+++ b/internal/ceres/runtime_numeric_diff_cost_function_test.cc
@@ -186,7 +186,7 @@
{ 0.0, 0.0, 0.0, 0.0, 0.0 },
},
};
- for (int k = 0; k < ARRAYSIZE(kTests); ++k) {
+ for (int k = 0; k < CERES_ARRAYSIZE(kTests); ++k) {
double *x1 = &(kTests[k].x1[0]);
double *x2 = &(kTests[k].x2[0]);
double *parameters[] = { x1, x2 };
diff --git a/internal/ceres/schur_eliminator_test.cc b/internal/ceres/schur_eliminator_test.cc
index 0ac4354..5146d47 100644
--- a/internal/ceres/schur_eliminator_test.cc
+++ b/internal/ceres/schur_eliminator_test.cc
@@ -32,6 +32,7 @@
#include <glog/logging.h>
#include "ceres/file.h"
+#include "gflags/gflags.h"
#include "gtest/gtest.h"
#include "Eigen/Dense"
#include "ceres/block_random_access_dense_matrix.h"
diff --git a/internal/ceres/solver_impl_test.cc b/internal/ceres/solver_impl_test.cc
index c30abbc..4713143 100644
--- a/internal/ceres/solver_impl_test.cc
+++ b/internal/ceres/solver_impl_test.cc
@@ -233,10 +233,12 @@
options.linear_solver_type = DENSE_SCHUR;
options.num_eliminate_blocks = 0;
string error;
+#ifndef _WIN32
EXPECT_DEATH(
SolverImpl::MaybeReorderResidualBlocks(
options, problem.mutable_program(), &error),
"Congratulations");
+#endif // _WIN32
}
TEST(SolverImpl, ReorderResidualBlockNormalFunction) {
diff --git a/internal/ceres/sparse_normal_cholesky_solver.cc b/internal/ceres/sparse_normal_cholesky_solver.cc
index 448bbd5..a7c43ef 100644
--- a/internal/ceres/sparse_normal_cholesky_solver.cc
+++ b/internal/ceres/sparse_normal_cholesky_solver.cc
@@ -150,6 +150,9 @@
const LinearSolver::PerSolveOptions& per_solve_options,
double * x) {
LOG(FATAL) << "No CXSparse support in Ceres.";
+
+ // Unreachable but MSVC does not know this.
+ return LinearSolver::Summary();
}
#endif
@@ -233,6 +236,9 @@
const LinearSolver::PerSolveOptions& per_solve_options,
double * x) {
LOG(FATAL) << "No SuiteSparse support in Ceres.";
+
+ // Unreachable but MSVC does not know this.
+ return LinearSolver::Summary();
}
#endif
diff --git a/internal/ceres/stringprintf.cc b/internal/ceres/stringprintf.cc
index d1e016a..c0f3522 100644
--- a/internal/ceres/stringprintf.cc
+++ b/internal/ceres/stringprintf.cc
@@ -39,8 +39,9 @@
namespace ceres {
namespace internal {
-#ifdef COMPILER_MSVC
+#ifdef _MSC_VER
enum { IS_COMPILER_MSVC = 1 };
+#define va_copy(d,s) ((d) = (s))
#else
enum { IS_COMPILER_MSVC = 0 };
#endif
diff --git a/internal/ceres/system_test.cc b/internal/ceres/system_test.cc
index 405dc69..88b2f91 100644
--- a/internal/ceres/system_test.cc
+++ b/internal/ceres/system_test.cc
@@ -45,6 +45,7 @@
#include <glog/logging.h>
#include "ceres/file.h"
+#include "gflags/gflags.h"
#include "gtest/gtest.h"
#include "ceres/stringprintf.h"
#include "ceres/test_util.h"
@@ -310,10 +311,8 @@
class BundleAdjustmentProblem {
public:
BundleAdjustmentProblem() {
- const string input_file =
- JoinPath(FLAGS_test_srcdir,
- "problem-16-22106-pre.txt"); // NOLINT
-
+ const string input_file = JoinPath(FLAGS_test_srcdir,
+ "problem-16-22106-pre.txt");
ReadData(input_file);
BuildProblem();
}
diff --git a/internal/ceres/triplet_sparse_matrix.cc b/internal/ceres/triplet_sparse_matrix.cc
index 247ab2e..3f5c5ca 100644
--- a/internal/ceres/triplet_sparse_matrix.cc
+++ b/internal/ceres/triplet_sparse_matrix.cc
@@ -130,7 +130,7 @@
void TripletSparseMatrix::Reserve(int new_max_num_nonzeros) {
CHECK_LE(num_nonzeros_, new_max_num_nonzeros)
- << "Reallocation will cause data loss";
+ << "Reallocation will cause data loss";
// Nothing to do if we have enough space already.
if (new_max_num_nonzeros <= max_num_nonzeros_)
diff --git a/internal/ceres/triplet_sparse_matrix_test.cc b/internal/ceres/triplet_sparse_matrix_test.cc
index ef3b42c..4c94658 100644
--- a/internal/ceres/triplet_sparse_matrix_test.cc
+++ b/internal/ceres/triplet_sparse_matrix_test.cc
@@ -67,7 +67,9 @@
ASSERT_TRUE(m.AllTripletsWithinBounds());
// We should never be able resize and lose data
+#ifndef _MSC_VER
ASSERT_DEATH(m.Reserve(1), "Reallocation will cause data loss");
+#endif
// We should be able to resize while preserving data
m.Reserve(50);
diff --git a/internal/ceres/trust_region_minimizer_test.cc b/internal/ceres/trust_region_minimizer_test.cc
index d87c963..03297c0 100644
--- a/internal/ceres/trust_region_minimizer_test.cc
+++ b/internal/ceres/trust_region_minimizer_test.cc
@@ -131,7 +131,7 @@
1.0,
0.0,
0.0,
- sqrt(10) * 2.0 * (x1 - x4) * (1.0 - x4);
+ sqrt(10.0) * 2.0 * (x1 - x4) * (1.0 - x4);
}
if (col2) {
jacobian_matrix.col(column_index++) <<
@@ -154,7 +154,7 @@
0.0,
-sqrt(5.0),
0.0,
- sqrt(10) * 2.0 * (x1 - x4) * (x1 - 1.0);
+ sqrt(10.0) * 2.0 * (x1 - x4) * (x1 - 1.0);
}
VLOG(1) << "\n" << jacobian_matrix;
}
diff --git a/internal/ceres/trust_region_strategy.cc b/internal/ceres/trust_region_strategy.cc
index 2e058b2..89bc19d 100644
--- a/internal/ceres/trust_region_strategy.cc
+++ b/internal/ceres/trust_region_strategy.cc
@@ -20,6 +20,7 @@
LOG(FATAL) << "Unknown trust region strategy: "
<< options.trust_region_strategy_type;
+ return NULL;
}
} // namespace internal
diff --git a/internal/ceres/visibility.cc b/internal/ceres/visibility.cc
index 5dceeb8..fd41648 100644
--- a/internal/ceres/visibility.cc
+++ b/internal/ceres/visibility.cc
@@ -136,8 +136,9 @@
CHECK_NE(camera1, camera2);
const int count = it->second;
+ // Static cast necessary for Windows.
const double weight = static_cast<double>(count) /
- (sqrt(visibility[camera1].size() * visibility[camera2].size()));
+ (sqrt(static_cast<double>(visibility[camera1].size() * visibility[camera2].size())));
graph->AddEdge(camera1, camera2, weight);
}