Skip to content

Commit a1b1958

Browse files
committed
Added explicit optimization codomain coordinate reuse
1 parent 77f00de commit a1b1958

File tree

2 files changed

+138
-66
lines changed

2 files changed

+138
-66
lines changed

src/optimization/explicit_optimization.cpp

Lines changed: 84 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@ void write_explicit_data_log_entry(
3131
const DifferentiableConeMetric& m,
3232
const EnergyFunctor& opt_energy,
3333
const MatrixX& constraint_domain_matrix,
34+
const MatrixX& constraint_codomain_matrix,
3435
const VectorX& optimized_domain_coords,
3536
const VectorX& domain_coords,
37+
const VectorX& init_codomain_coords,
3638
const VectorX& gradient,
3739
std::shared_ptr<ProjectionParameters> proj_params,
3840
Scalar beta)
@@ -45,19 +47,18 @@ void write_explicit_data_log_entry(
4547
std::unique_ptr<DifferentiableConeMetric> cone_metric = compute_domain_coordinate_metric(
4648
m,
4749
constraint_domain_matrix,
50+
constraint_codomain_matrix,
4851
optimized_domain_coords,
52+
init_codomain_coords,
4953
proj_params);
5054

5155
// Get the full per vertex constraint Jacobian with respect to Penner coordinates
5256
VectorX constraint;
5357
MatrixX constraint_penner_jacobian;
5458
bool need_jacobian = true;
5559
bool only_free_vertices = false;
56-
cone_metric->constraint(
57-
constraint,
58-
constraint_penner_jacobian,
59-
need_jacobian,
60-
only_free_vertices);
60+
cone_metric
61+
->constraint(constraint, constraint_penner_jacobian, need_jacobian, only_free_vertices);
6162

6263
// Compute change in domain coords
6364
VectorX change_in_domain_coords = optimized_domain_coords - domain_coords;
@@ -84,7 +85,8 @@ void compute_optimization_domain(
8485
const MatrixX& shear_basis_matrix,
8586
MatrixX& constraint_domain_matrix,
8687
MatrixX& constraint_codomain_matrix,
87-
VectorX& domain_coords)
88+
VectorX& domain_coords,
89+
VectorX& codomain_coords)
8890
{
8991
// Build matrix to map scale factors to edge coordinates
9092
MatrixX scale_factor_basis_matrix = conformal_scaling_matrix(m);
@@ -136,18 +138,23 @@ void compute_optimization_domain(
136138
compute_shear_basis_coordinates(m, shear_basis_matrix, shear_basis_coords, scale_factors);
137139
int num_shear_basis_coords = shear_basis_coords.size();
138140
domain_coords.resize(num_shear_basis_coords + fixed_dof.size());
141+
codomain_coords.resize(variable_dof.size());
139142
domain_coords.head(num_shear_basis_coords) = shear_basis_coords;
140143
for (size_t i = 0; i < fixed_dof.size(); ++i) {
141144
domain_coords[num_shear_basis_coords + i] = scale_factors[fixed_dof[i]];
142145
}
146+
for (size_t i = 0; i < variable_dof.size(); ++i) {
147+
codomain_coords[i] = scale_factors[variable_dof[i]];
148+
}
143149

144150
// Build the domain matrix
145151
constraint_domain_matrix.resize(num_edges, shear_basis_matrix.cols() + fixed_dof.size());
146152
constraint_domain_matrix.reserve(domain_triplet_list.size());
147153
constraint_domain_matrix.setFromTriplets(
148154
domain_triplet_list.begin(),
149155
domain_triplet_list.end());
150-
constraint_domain_matrix = m.change_metric_to_reduced_coordinates(constraint_domain_matrix.transpose()).transpose();
156+
constraint_domain_matrix =
157+
m.change_metric_to_reduced_coordinates(constraint_domain_matrix.transpose()).transpose();
151158
SPDLOG_TRACE("Domain matrix is {}", constraint_domain_matrix);
152159

153160
// Build the codomain matrix
@@ -156,30 +163,42 @@ void compute_optimization_domain(
156163
constraint_codomain_matrix.setFromTriplets(
157164
codomain_triplet_list.begin(),
158165
codomain_triplet_list.end());
159-
constraint_codomain_matrix = m.change_metric_to_reduced_coordinates(constraint_codomain_matrix.transpose()).transpose();
166+
constraint_codomain_matrix =
167+
m.change_metric_to_reduced_coordinates(constraint_codomain_matrix.transpose()).transpose();
160168
SPDLOG_TRACE("Codomain matrix is {}", constraint_codomain_matrix);
161169
}
162170

163171
std::unique_ptr<DifferentiableConeMetric> compute_domain_coordinate_metric(
164172
const DifferentiableConeMetric& m,
165173
const MatrixX& constraint_domain_matrix,
174+
const MatrixX& constraint_codomain_matrix,
166175
const VectorX& domain_coords,
176+
const VectorX& init_codomain_coords,
167177
std::shared_ptr<ProjectionParameters> proj_params)
168178
{
169179
spdlog::trace("Making domain coordinate metric");
170-
SPDLOG_TRACE(
180+
SPDLOG_INFO(
171181
"Domain coordinates in range [{}, {}]",
172-
domain_coords.maxCoeff(),
173-
domain_coords.minCoeff());
182+
domain_coords.minCoeff(),
183+
domain_coords.maxCoeff());
184+
SPDLOG_INFO(
185+
"Codomain coordinates in range [{}, {}]",
186+
init_codomain_coords.minCoeff(),
187+
init_codomain_coords.maxCoeff());
174188

175189
// Get domain coordinate metric defined by the current coordinates
176190
VectorX domain_metric_coords = constraint_domain_matrix * domain_coords;
191+
VectorX codomain_metric_coords = constraint_codomain_matrix * init_codomain_coords;
177192
std::unique_ptr<DifferentiableConeMetric> cone_metric =
178-
m.set_metric_coordinates(domain_metric_coords);
193+
m.set_metric_coordinates(domain_metric_coords + codomain_metric_coords);
179194
SPDLOG_TRACE(
180195
"Domain metric in range [{}, {}]",
181196
domain_metric_coords.minCoeff(),
182197
domain_metric_coords.maxCoeff());
198+
SPDLOG_TRACE(
199+
"Codomain metric in range [{}, {}]",
200+
codomain_metric_coords.minCoeff(),
201+
codomain_metric_coords.maxCoeff());
183202

184203
// Project the domain metric to the constraint
185204
SolveStats<Scalar> solve_stats;
@@ -190,12 +209,19 @@ Scalar compute_domain_coordinate_energy(
190209
const DifferentiableConeMetric& m,
191210
const EnergyFunctor& opt_energy,
192211
const MatrixX& constraint_domain_matrix,
212+
const MatrixX& constraint_codomain_matrix,
193213
const VectorX& domain_coords,
214+
const VectorX& init_codomain_coords,
194215
std::shared_ptr<ProjectionParameters> proj_params)
195216
{
196217
// Compute penner coordinates from the domain coordinates
197-
std::unique_ptr<DifferentiableConeMetric> cone_metric =
198-
compute_domain_coordinate_metric(m, constraint_domain_matrix, domain_coords, proj_params);
218+
std::unique_ptr<DifferentiableConeMetric> cone_metric = compute_domain_coordinate_metric(
219+
m,
220+
constraint_domain_matrix,
221+
constraint_codomain_matrix,
222+
domain_coords,
223+
init_codomain_coords,
224+
proj_params);
199225

200226
// Get the initial energy
201227
return opt_energy.energy(*cone_metric);
@@ -207,13 +233,19 @@ bool compute_domain_coordinate_energy_with_gradient(
207233
const MatrixX& constraint_domain_matrix,
208234
const MatrixX& constraint_codomain_matrix,
209235
const VectorX& domain_coords,
236+
const VectorX& init_codomain_coords,
210237
std::shared_ptr<ProjectionParameters> proj_params,
211238
Scalar& energy,
212239
VectorX& gradient)
213240
{
214241
// Compute penner coordinates from the domain coordinates
215-
std::unique_ptr<DifferentiableConeMetric> cone_metric =
216-
compute_domain_coordinate_metric(m, constraint_domain_matrix, domain_coords, proj_params);
242+
std::unique_ptr<DifferentiableConeMetric> cone_metric = compute_domain_coordinate_metric(
243+
m,
244+
constraint_domain_matrix,
245+
constraint_codomain_matrix,
246+
domain_coords,
247+
init_codomain_coords,
248+
proj_params);
217249

218250
// Get the initial energy
219251
energy = opt_energy.energy(*cone_metric);
@@ -258,6 +290,19 @@ bool compute_domain_coordinate_energy_with_gradient(
258290
return true;
259291
}
260292

293+
VectorX compute_codomain_coordinates(
294+
const DifferentiableConeMetric& m,
295+
const MatrixX& constraint_codomain_matrix)
296+
{
297+
MatrixX inner_product_matrix =
298+
constraint_codomain_matrix.transpose() * constraint_codomain_matrix;
299+
VectorX metric_coords = m.get_reduced_metric_coordinates();
300+
VectorX rhs = constraint_codomain_matrix.transpose() * metric_coords;
301+
Eigen::SimplicialLDLT<Eigen::SparseMatrix<Scalar>> solver;
302+
solver.compute(inner_product_matrix);
303+
return solver.solve(rhs);
304+
}
305+
261306
void compute_descent_direction(
262307
const VectorX& prev_gradient,
263308
const VectorX& prev_descent_direction,
@@ -304,6 +349,7 @@ void backtracking_domain_line_search(
304349
const MatrixX& constraint_domain_matrix,
305350
const MatrixX& constraint_codomain_matrix,
306351
const VectorX& domain_coords,
352+
const VectorX& init_codomain_coords,
307353
const VectorX& gradient,
308354
const VectorX& descent_direction,
309355
VectorX& optimized_domain_coords,
@@ -320,7 +366,9 @@ void backtracking_domain_line_search(
320366
m,
321367
opt_energy,
322368
constraint_domain_matrix,
369+
constraint_codomain_matrix,
323370
domain_coords,
371+
init_codomain_coords,
324372
proj_params);
325373
spdlog::get("optimize_metric")->info("Initial energy is {}", initial_energy);
326374

@@ -348,6 +396,7 @@ void backtracking_domain_line_search(
348396
constraint_domain_matrix,
349397
constraint_codomain_matrix,
350398
optimized_domain_coords,
399+
init_codomain_coords,
351400
proj_params,
352401
energy,
353402
step_gradient);
@@ -379,6 +428,7 @@ void backtracking_domain_line_search(
379428
constraint_domain_matrix,
380429
constraint_codomain_matrix,
381430
optimized_domain_coords,
431+
init_codomain_coords,
382432
proj_params,
383433
energy,
384434
step_gradient);
@@ -395,13 +445,15 @@ VectorX optimize_domain_coordinates(
395445
const MatrixX& constraint_domain_matrix,
396446
const MatrixX& constraint_codomain_matrix,
397447
const VectorX& init_domain_coords,
448+
const VectorX& init_codomain_coords,
398449
std::shared_ptr<ProjectionParameters> proj_params,
399450
std::shared_ptr<OptimizationParameters> opt_params)
400451
{
401452
// Build default parameters if none given
402453
if (proj_params == nullptr) proj_params = std::make_shared<ProjectionParameters>();
403454
if (opt_params == nullptr) opt_params = std::make_shared<OptimizationParameters>();
404455
VectorX domain_coords = init_domain_coords;
456+
VectorX codomain_coords = init_codomain_coords;
405457

406458
// Extract relevant parameters for main optimization method
407459
int num_iter = opt_params->num_iter;
@@ -457,6 +509,7 @@ VectorX optimize_domain_coordinates(
457509
constraint_domain_matrix,
458510
constraint_codomain_matrix,
459511
domain_coords,
512+
codomain_coords,
460513
proj_params,
461514
energy,
462515
gradient);
@@ -514,6 +567,7 @@ VectorX optimize_domain_coordinates(
514567
constraint_domain_matrix,
515568
constraint_codomain_matrix,
516569
domain_coords,
570+
codomain_coords,
517571
gradient,
518572
descent_direction,
519573
optimized_domain_coords,
@@ -527,8 +581,10 @@ VectorX optimize_domain_coordinates(
527581
m,
528582
opt_energy,
529583
constraint_domain_matrix,
584+
constraint_codomain_matrix,
530585
optimized_domain_coords,
531586
domain_coords,
587+
codomain_coords,
532588
gradient,
533589
proj_params,
534590
beta);
@@ -537,12 +593,19 @@ VectorX optimize_domain_coordinates(
537593
// Update for next iteration
538594
prev_domain_coords = domain_coords;
539595
domain_coords = optimized_domain_coords;
596+
codomain_coords = compute_codomain_coordinates(m, constraint_codomain_matrix);
540597
beta = std::min(2.0 * beta, max_beta);
541598
}
542599

543600
// Compute final projection
544601
std::unique_ptr<DifferentiableConeMetric> optimized_cone_metric =
545-
compute_domain_coordinate_metric(m, constraint_domain_matrix, domain_coords, proj_params);
602+
compute_domain_coordinate_metric(
603+
m,
604+
constraint_domain_matrix,
605+
constraint_codomain_matrix,
606+
domain_coords,
607+
codomain_coords,
608+
proj_params);
546609

547610
// Get final energy
548611
Scalar energy = opt_energy.energy(*optimized_cone_metric);
@@ -566,13 +629,14 @@ VectorX optimize_shear_basis_coordinates(
566629
// Build independent and dependent basis vectors by adding a global scaling term
567630
// to the shear basis and removing and arbitrary basis vector from the scale factors
568631
MatrixX constraint_domain_matrix, constraint_codomain_matrix;
569-
VectorX domain_coords;
632+
VectorX domain_coords, codomain_coords;
570633
compute_optimization_domain(
571634
m,
572635
shear_basis_matrix,
573636
constraint_domain_matrix,
574637
constraint_codomain_matrix,
575-
domain_coords);
638+
domain_coords,
639+
codomain_coords);
576640

577641
// Perform optimization in domain coordinates
578642
return optimize_domain_coordinates(
@@ -581,6 +645,7 @@ VectorX optimize_shear_basis_coordinates(
581645
constraint_domain_matrix,
582646
constraint_codomain_matrix,
583647
domain_coords,
648+
codomain_coords,
584649
proj_params,
585650
opt_params);
586651
}

0 commit comments

Comments
 (0)