Add the number of effective parameters to the final report.

Here is an example report, obtained by running:

  bin/Debug/bundle_adjuster \
  --input=../ceres-solver/data/problem-16-22106-pre.txt \
  --linear_solver=iterative_schur \
  --num_iterations=1 \
  --alsologtostderr \
  --use_local_parameterization \
  --use_quaternions

Note that effective parameters is less than parameters by 16, which is the
number of cameras. In this case the local parameterization has a 3 dimensional
tangent space for the 4-dimensional quaternions.

Ceres Solver Report
-------------------
                                     Original                  Reduced
Parameter blocks                        22138                    22138
Parameters                              66478                    66478
Effective parameters                    66462                    66462
Residual blocks                         83718                    83718
Residual                               167436                   167436

Minimizer                        TRUST_REGION
Trust Region Strategy     LEVENBERG_MARQUARDT

                                        Given                     Used
Linear solver                 ITERATIVE_SCHUR          ITERATIVE_SCHUR
Preconditioner                         JACOBI                   JACOBI
Threads:                                    1                        1
Linear solver threads                       1                        1
Linear solver ordering              AUTOMATIC                22106, 32

Cost:
Initial                          4.185660e+06
Final                            7.221647e+04
Change                           4.113443e+06

Number of iterations:
Successful                                  1
Unsuccessful                                0
Total                                       1

Time (in seconds):
Preprocessor                            0.697

  Residual Evaluations                  0.063
  Jacobian Evaluations                 27.608
  Linear Solver                        13.360
Minimizer                              43.973

Postprocessor                           0.004
Total                                  44.756

Termination:                   NO_CONVERGENCE

Change-Id: I6b6b8ac24f71bd187e67d95651290917642be74f
diff --git a/include/ceres/solver.h b/include/ceres/solver.h
index 122870c..8c2ff32 100644
--- a/include/ceres/solver.h
+++ b/include/ceres/solver.h
@@ -611,11 +611,13 @@
     // Preprocessor summary.
     int num_parameter_blocks;
     int num_parameters;
+    int num_effective_parameters;
     int num_residual_blocks;
     int num_residuals;
 
     int num_parameter_blocks_reduced;
     int num_parameters_reduced;
+    int num_effective_parameters_reduced;
     int num_residual_blocks_reduced;
     int num_residuals_reduced;
 
diff --git a/internal/ceres/solver.cc b/internal/ceres/solver.cc
index 6561bd9..ea9ff1f 100644
--- a/internal/ceres/solver.cc
+++ b/internal/ceres/solver.cc
@@ -100,10 +100,12 @@
       jacobian_evaluation_time_in_seconds(-1.0),
       num_parameter_blocks(-1),
       num_parameters(-1),
+      num_effective_parameters(-1),
       num_residual_blocks(-1),
       num_residuals(-1),
       num_parameter_blocks_reduced(-1),
       num_parameters_reduced(-1),
+      num_effective_parameters_reduced(-1),
       num_residual_blocks_reduced(-1),
       num_residuals_reduced(-1),
       num_threads_given(-1),
@@ -156,10 +158,12 @@
 
   if (termination_type == DID_NOT_RUN) {
     StringAppendF(&report, "                      Original\n");
-    StringAppendF(&report, "Parameter blocks    % 10d\n",
-                  num_parameter_blocks);
-    StringAppendF(&report, "Parameters          % 10d\n",
-                  num_parameters);
+    StringAppendF(&report, "Parameter blocks    % 10d\n", num_parameter_blocks);
+    StringAppendF(&report, "Parameters          % 10d\n", num_parameters);
+    if (num_effective_parameters != num_parameters) {
+      StringAppendF(&report, "Effective parameters% 10d\n", num_parameters);
+    }
+
     StringAppendF(&report, "Residual blocks     % 10d\n",
                   num_residual_blocks);
     StringAppendF(&report, "Residuals           % 10d\n\n",
@@ -170,6 +174,10 @@
                   num_parameter_blocks, num_parameter_blocks_reduced);
     StringAppendF(&report, "Parameters          % 25d% 25d\n",
                   num_parameters, num_parameters_reduced);
+    if (num_effective_parameters_reduced != num_parameters_reduced) {
+      StringAppendF(&report, "Effective parameters% 25d% 25d\n",
+                    num_effective_parameters, num_effective_parameters_reduced);
+    }
     StringAppendF(&report, "Residual blocks     % 25d% 25d\n",
                   num_residual_blocks, num_residual_blocks_reduced);
     StringAppendF(&report, "Residual            % 25d% 25d\n",
diff --git a/internal/ceres/solver_impl.cc b/internal/ceres/solver_impl.cc
index 5bcfdc6..16fdbf6 100644
--- a/internal/ceres/solver_impl.cc
+++ b/internal/ceres/solver_impl.cc
@@ -335,6 +335,8 @@
   summary->minimizer_type = TRUST_REGION;
   summary->num_parameter_blocks = problem_impl->NumParameterBlocks();
   summary->num_parameters = problem_impl->NumParameters();
+  summary->num_effective_parameters =
+      original_program->NumEffectiveParameters();
   summary->num_residual_blocks = problem_impl->NumResidualBlocks();
   summary->num_residuals = problem_impl->NumResiduals();
 
@@ -447,6 +449,8 @@
 
   summary->num_parameter_blocks_reduced = reduced_program->NumParameterBlocks();
   summary->num_parameters_reduced = reduced_program->NumParameters();
+  summary->num_effective_parameters_reduced =
+      reduced_program->NumEffectiveParameters();
   summary->num_residual_blocks_reduced = reduced_program->NumResidualBlocks();
   summary->num_residuals_reduced = reduced_program->NumResiduals();