169 CHECK_EQ(
static_cast<size_t>(n), num_of_variables_);
171 if (use_automatic_differentiation_) {
172 gradient(
tag_f, n, x, grad_f);
176 std::fill(grad_f, grad_f + n, 0.0);
177 for (
size_t i = 0; i < num_of_points_; ++i) {
178 size_t index = i << 1;
179 grad_f[index] = x[index] * 2 - ref_points_[i].first * 2;
180 grad_f[index + 1] = x[index + 1] * 2 - ref_points_[i].second * 2;
183 for (
size_t i = 0; i < num_of_points_ - 2; ++i) {
184 size_t index = i << 1;
185 double q1 = (x[index] - x[index + 2]) * (x[index] - x[index + 2]) +
186 (x[index + 1] - x[index + 3]) * (x[index + 1] - x[index + 3]);
187 double q2 = (x[index + 2] - x[index + 4]) * (x[index + 2] - x[index + 4]) +
188 (x[index + 3] - x[index + 5]) * (x[index + 3] - x[index + 5]);
190 ((2 * x[index] - 2 * x[index + 2]) *
191 ((x[index] - x[index + 2]) * (x[index + 2] - x[index + 4]) +
192 (x[index + 1] - x[index + 3]) * (x[index + 3] - x[index + 5])));
194 ((2 * x[index + 1] - 2 * x[index + 3]) *
195 ((x[index] - x[index + 2]) * (x[index + 2] - x[index + 4]) +
196 (x[index + 1] - x[index + 3]) * (x[index + 3] - x[index + 5])));
198 ((2 * x[index + 2] - 2 * x[index + 4]) *
199 ((x[index] - x[index + 2]) * (x[index + 2] - x[index + 4]) +
200 (x[index + 1] - x[index + 3]) * (x[index + 3] - x[index + 5])));
202 ((2 * x[index + 3] - 2 * x[index + 5]) *
203 ((x[index] - x[index + 2]) * (x[index + 2] - x[index + 4]) +
204 (x[index + 1] - x[index + 3]) * (x[index + 3] - x[index + 5])));
205 double sqrt_q1 = std::sqrt(q1);
206 double sqrt_q2 = std::sqrt(q2);
207 grad_f[index] += -weight_cos_included_angle_ *
208 ((x[index + 2] - x[index + 4]) / (sqrt_q1 * sqrt_q2) -
209 q3 / (2 * q1 * sqrt_q1 * sqrt_q2));
210 grad_f[index + 1] += -weight_cos_included_angle_ *
211 ((x[index + 3] - x[index + 5]) / (sqrt_q1 * sqrt_q2) -
212 q4 / (2 * q1 * sqrt_q1 * sqrt_q2));
214 -weight_cos_included_angle_ *
215 ((x[index] - 2 * x[index + 2] + x[index + 4]) / (sqrt_q1 * sqrt_q2) +
216 q3 / (2 * q1 * sqrt_q1 * sqrt_q2) - q5 / (2 * sqrt_q1 * q2 * sqrt_q2));
218 -weight_cos_included_angle_ *
219 ((x[index + 1] - 2 * x[index + 3] + x[index + 5]) /
220 (sqrt_q1 * sqrt_q2) +
221 q4 / (2 * q1 * sqrt_q1 * sqrt_q2) - q6 / (2 * sqrt_q1 * q2 * sqrt_q2));
222 grad_f[index + 4] += -weight_cos_included_angle_ *
223 (q5 / (2 * sqrt_q1 * q2 * sqrt_q2) -
224 (x[index] - x[index + 2]) / (sqrt_q1 * sqrt_q2));
225 grad_f[index + 5] += -weight_cos_included_angle_ *
226 (q6 / (2 * sqrt_q1 * q2 * sqrt_q2) -
227 (x[index + 1] - x[index + 3]) / (sqrt_q1 * sqrt_q2));
294 double obj_factor,
int m,
295 const double* lambda,
bool new_lambda,
296 int nele_hess,
int* iRow,
int* jCol,
298 if (use_automatic_differentiation_) {
299 if (values ==
nullptr) {
302 for (
int idx = 0; idx < nnz_L_; idx++) {
303 iRow[idx] = rind_L_[idx];
304 jCol[idx] = cind_L_[idx];
309 obj_lam_[0] = obj_factor;
310 for (
int idx = 0; idx < m; idx++) {
311 obj_lam_[1 + idx] = lambda[idx];
316 set_param_vec(
tag_L, m + 1, &obj_lam_[0]);
317 sparse_hess(
tag_L, n, 1,
const_cast<double*
>(x), &nnz_L_, &rind_L_,
318 &cind_L_, &hessval_, options_L_);
320 for (
int idx = 0; idx < nnz_L_; idx++) {
321 values[idx] = hessval_[idx];
327 if (values ==
nullptr) {
329 for (
int i = 0; i < 6; ++i) {
330 for (
int j = 0; j <= i; ++j) {
338 for (
int i = 6; i < static_cast<int>(num_of_variables_); ++i) {
340 for (
int j = 2 + shift; j <= 6 + shift; ++j) {
347 for (
int j = 2 + shift; j <= 7 + shift; ++j) {
355 CHECK_EQ(index, nele_hess);
357 std::fill(values, values + nele_hess, 0.0);
359 for (
size_t i = 0; i < num_of_points_ - 2; ++i) {
360 size_t topleft = i * 2;
361 const double q5 = (2 * x[topleft] - 2 * x[topleft + 2]);
362 const double q6 = (2 * x[topleft + 1] - 2 * x[topleft + 3]);
363 const double q7 = (x[topleft] - 2 * x[topleft + 2] + x[topleft + 4]);
364 const double q8 = (2 * x[topleft + 2] - 2 * x[topleft + 4]);
365 const double q9 = (2 * x[topleft + 3] - 2 * x[topleft + 5]);
366 const double q10 = (x[topleft + 1] - 2 * x[topleft + 3] + x[topleft + 5]);
367 const double q11 = (x[topleft + 3] - x[topleft + 5]);
368 const double q12 = (x[topleft] - x[topleft + 2]);
369 const double q13 = (x[topleft + 2] - x[topleft + 4]);
370 const double q14 = (x[topleft + 1] - x[topleft + 3]);
371 const double q1 = q12 * q12 + q14 * q14;
372 const double q2 = q13 * q13 + q11 * q11;
373 const double q3 = (3 * q5 * q5 * (q12 * q13 + q14 * q11));
374 const double q4 = (q12 * q13 + q14 * q11);
375 const double sqrt_q1 = std::sqrt(q1);
376 const double q1_sqrt_q1 = q1 * sqrt_q1;
377 const double sqrt_q2 = std::sqrt(q2);
378 const double q2_sqrt_q2 = q2 * sqrt_q2;
379 const double square_q1 = q1 * q1;
380 const double square_q2 = q2 * q2;
381 const double sqrt_q1q2 = sqrt_q1 * sqrt_q2;
382 const double q1_sqrt_q1q2 = q1 * sqrt_q1q2;
383 const double sqrt_q1_q2_sqrt_q2 = sqrt_q1 * q2_sqrt_q2;
384 const double q1_sqrt_q1_q2_sqrt_q2 = q1_sqrt_q1 * q2_sqrt_q2;
385 values[idx_map_[std::make_pair(topleft, topleft)]] +=
386 obj_factor * (-weight_cos_included_angle_) *
387 (q3 / (4 * square_q1 * sqrt_q1q2) - q4 / q1_sqrt_q1q2 -
388 (q5 * q13) / q1_sqrt_q1q2);
389 values[idx_map_[std::make_pair(topleft + 1, topleft)]] +=
390 obj_factor * (-weight_cos_included_angle_) *
391 ((3 * q5 * q6 * q4) / (4 * square_q1 * sqrt_q1q2) -
392 (q6 * q13) / (2 * q1_sqrt_q1q2) - (q5 * q11) / (2 * q1_sqrt_q1q2));
393 values[idx_map_[std::make_pair(topleft + 2, topleft)]] +=
394 obj_factor * (-weight_cos_included_angle_) *
395 (1 / sqrt_q1q2 + q4 / q1_sqrt_q1q2 - (q5 * q7) / (2 * q1_sqrt_q1q2) -
396 q3 / (4 * square_q1 * sqrt_q1q2) + (q5 * q13) / (2 * q1_sqrt_q1q2) -
397 (q8 * q13) / (2 * sqrt_q1_q2_sqrt_q2) +
398 (q5 * q8 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2));
399 values[idx_map_[std::make_pair(topleft + 3, topleft)]] +=
400 obj_factor * (-weight_cos_included_angle_) *
401 ((q6 * q13) / (2 * q1_sqrt_q1q2) - (q5 * q10) / (2 * q1_sqrt_q1q2) -
402 (q9 * q13) / (2 * sqrt_q1_q2_sqrt_q2) -
403 (3 * q5 * q6 * q4) / (4 * square_q1 * sqrt_q1q2) +
404 (q5 * q9 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2));
405 values[idx_map_[std::make_pair(topleft + 4, topleft)]] +=
406 obj_factor * (-weight_cos_included_angle_) *
407 ((q5 * q12) / (2 * q1_sqrt_q1q2) - 1 / sqrt_q1q2 +
408 (q8 * q13) / (2 * sqrt_q1_q2_sqrt_q2) -
409 (q5 * q8 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2));
410 values[idx_map_[std::make_pair(topleft + 5, topleft)]] +=
411 obj_factor * (-weight_cos_included_angle_) *
412 ((q5 * q14) / (2 * q1_sqrt_q1q2) +
413 (q9 * q13) / (2 * sqrt_q1_q2_sqrt_q2) -
414 (q5 * q9 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2));
416 values[idx_map_[std::make_pair(topleft + 1, topleft + 1)]] +=
417 obj_factor * (-weight_cos_included_angle_) *
418 ((3 * q6 * q6 * q4) / (4 * square_q1 * sqrt_q1q2) -
419 q4 / q1_sqrt_q1q2 - (q6 * q11) / q1_sqrt_q1q2);
420 values[idx_map_[std::make_pair(topleft + 2, topleft + 1)]] +=
421 obj_factor * (-weight_cos_included_angle_) *
422 ((q5 * q11) / (2 * q1_sqrt_q1q2) - (q6 * q7) / (2 * q1_sqrt_q1q2) -
423 (q8 * q11) / (2 * sqrt_q1_q2_sqrt_q2) -
424 (3 * q5 * q6 * q4) / (4 * square_q1 * sqrt_q1q2) +
425 (q8 * q6 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2));
426 values[idx_map_[std::make_pair(topleft + 3, topleft + 1)]] +=
427 obj_factor * (-weight_cos_included_angle_) *
428 (1 / sqrt_q1q2 + q4 / q1_sqrt_q1q2 - (q6 * q10) / (2 * q1_sqrt_q1q2) -
429 (3 * q6 * q6 * q4) / (4 * square_q1 * sqrt_q1q2) +
430 (q6 * q11) / (2 * q1_sqrt_q1q2) -
431 (q9 * q11) / (2 * sqrt_q1_q2_sqrt_q2) +
432 (q6 * q9 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2));
433 values[idx_map_[std::make_pair(topleft + 4, topleft + 1)]] +=
434 obj_factor * (-weight_cos_included_angle_) *
435 ((q6 * q12) / (2 * q1_sqrt_q1q2) +
436 (q8 * q11) / (2 * sqrt_q1_q2_sqrt_q2) -
437 (q8 * q6 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2));
438 values[idx_map_[std::make_pair(topleft + 5, topleft + 1)]] +=
439 obj_factor * (-weight_cos_included_angle_) *
440 ((q6 * q14) / (2 * q1_sqrt_q1q2) - 1 / sqrt_q1q2 +
441 (q9 * q11) / (2 * sqrt_q1_q2_sqrt_q2) -
442 (q6 * q9 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2));
444 values[idx_map_[std::make_pair(topleft + 2, topleft + 2)]] +=
445 obj_factor * (-weight_cos_included_angle_) *
446 ((q5 * q7) / q1_sqrt_q1q2 -
447 q4 / (sqrt_q1_q2_sqrt_q2)-q4 / q1_sqrt_q1q2 - 2 / sqrt_q1q2 -
448 (q8 * q7) / (sqrt_q1_q2_sqrt_q2) + q3 / (4 * square_q1 * sqrt_q1q2) +
449 (3 * q8 * q8 * q4) / (4 * sqrt_q1 * square_q2 * sqrt_q2) -
450 (q5 * q8 * q4) / (2 * q1_sqrt_q1_q2_sqrt_q2));
451 values[idx_map_[std::make_pair(topleft + 3, topleft + 2)]] +=
452 obj_factor * (-weight_cos_included_angle_) *
453 ((q6 * q7) / (2 * q1_sqrt_q1q2) -
454 (q9 * q7) / (2 * sqrt_q1_q2_sqrt_q2) +
455 (q5 * q10) / (2 * q1_sqrt_q1q2) -
456 (q8 * q10) / (2 * sqrt_q1_q2_sqrt_q2) +
457 (3 * q5 * q6 * q4) / (4 * square_q1 * sqrt_q1q2) -
458 (q5 * q9 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2) -
459 (q8 * q6 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2) +
460 (3 * q8 * q9 * q4) / (4 * sqrt_q1 * square_q2 * sqrt_q2));
461 values[idx_map_[std::make_pair(topleft + 4, topleft + 2)]] +=
462 obj_factor * (-weight_cos_included_angle_) *
463 (1 / sqrt_q1q2 + q4 / (sqrt_q1_q2_sqrt_q2) +
464 (q8 * q7) / (2 * sqrt_q1_q2_sqrt_q2) -
465 (3 * q8 * q8 * q4) / (4 * sqrt_q1 * square_q2 * sqrt_q2) -
466 (q5 * q12) / (2 * q1_sqrt_q1q2) +
467 (q8 * q12) / (2 * sqrt_q1_q2_sqrt_q2) +
468 (q5 * q8 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2));
469 values[idx_map_[std::make_pair(topleft + 5, topleft + 2)]] +=
470 obj_factor * (-weight_cos_included_angle_) *
471 ((q9 * q7) / (2 * sqrt_q1_q2_sqrt_q2) -
472 (q5 * q14) / (2 * q1_sqrt_q1q2) +
473 (q8 * q14) / (2 * sqrt_q1_q2_sqrt_q2) +
474 (q5 * q9 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2) -
475 (3 * q8 * q9 * q4) / (4 * sqrt_q1 * square_q2 * sqrt_q2));
477 values[idx_map_[std::make_pair(topleft + 3, topleft + 3)]] +=
478 obj_factor * (-weight_cos_included_angle_) *
479 ((q6 * q10) / q1_sqrt_q1q2 -
480 q4 / (sqrt_q1_q2_sqrt_q2)-q4 / q1_sqrt_q1q2 - 2 / sqrt_q1q2 -
481 (q9 * q10) / (sqrt_q1_q2_sqrt_q2) +
482 (3 * q6 * q6 * q4) / (4 * square_q1 * sqrt_q1q2) +
483 (3 * q9 * q9 * q4) / (4 * sqrt_q1 * square_q2 * sqrt_q2) -
484 (q6 * q9 * q4) / (2 * q1_sqrt_q1_q2_sqrt_q2));
485 values[idx_map_[std::make_pair(topleft + 4, topleft + 3)]] +=
486 obj_factor * (-weight_cos_included_angle_) *
487 ((q8 * q10) / (2 * sqrt_q1_q2_sqrt_q2) -
488 (q6 * q12) / (2 * q1_sqrt_q1q2) +
489 (q9 * q12) / (2 * sqrt_q1_q2_sqrt_q2) +
490 (q8 * q6 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2) -
491 (3 * q8 * q9 * q4) / (4 * sqrt_q1 * square_q2 * sqrt_q2));
492 values[idx_map_[std::make_pair(topleft + 5, topleft + 3)]] +=
493 obj_factor * (-weight_cos_included_angle_) *
494 (1 / sqrt_q1q2 + q4 / (sqrt_q1_q2_sqrt_q2) +
495 (q9 * q10) / (2 * sqrt_q1_q2_sqrt_q2) -
496 (3 * q9 * q9 * q4) / (4 * sqrt_q1 * square_q2 * sqrt_q2) -
497 (q6 * q14) / (2 * q1_sqrt_q1q2) +
498 (q9 * q14) / (2 * sqrt_q1_q2_sqrt_q2) +
499 (q6 * q9 * q4) / (4 * q1_sqrt_q1_q2_sqrt_q2));
501 values[idx_map_[std::make_pair(topleft + 4, topleft + 4)]] +=
502 obj_factor * (-weight_cos_included_angle_) *
503 ((3 * q8 * q8 * q4) / (4 * sqrt_q1 * square_q2 * sqrt_q2) -
504 q4 / (sqrt_q1_q2_sqrt_q2) - (q8 * q12) / (sqrt_q1_q2_sqrt_q2));
505 values[idx_map_[std::make_pair(topleft + 5, topleft + 4)]] +=
506 obj_factor * (-weight_cos_included_angle_) *
507 ((3 * q8 * q9 * q4) / (4 * sqrt_q1 * square_q2 * sqrt_q2) -
508 (q9 * q12) / (2 * sqrt_q1_q2_sqrt_q2) -
509 (q8 * q14) / (2 * sqrt_q1_q2_sqrt_q2));
511 values[idx_map_[std::make_pair(topleft + 5, topleft + 5)]] +=
512 obj_factor * (-weight_cos_included_angle_) *
513 ((3 * q9 * q9 * q4) / (4 * sqrt_q1 * square_q2 * sqrt_q2) -
514 q4 / (sqrt_q1_q2_sqrt_q2) - (q9 * q14) / (sqrt_q1_q2_sqrt_q2));
518 for (
size_t i = 0; i < num_of_variables_; ++i) {
519 values[idx_map_[std::make_pair(i, i)]] += obj_factor * 2;