highs-sys 1.14.2

Rust binding for the HiGHS linear programming solver. See http://highs.dev.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*                                                                       */
/*    This file is part of the HiGHS linear optimization suite           */
/*                                                                       */
/*    Available as open-source under the MIT License                     */
/*                                                                       */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**@file simplex/HighsSimplexAnalysis.h
 * @brief Analyse simplex iterations, both for run-time control and data
 * gathering
 */
#ifndef SIMPLEX_HIGHSSIMPLEXANALYSIS_H_
#define SIMPLEX_HIGHSSIMPLEXANALYSIS_H_

#include <cassert>
#include <memory>
#include <sstream>

#include "lp_data/HighsLp.h"
#include "lp_data/HighsOptions.h"
#include "simplex/SimplexConst.h"
#include "util/HFactor.h"

enum TRAN_STAGE {
  TRAN_STAGE_FTRAN_LOWER = 0,
  TRAN_STAGE_FTRAN_UPPER_FT,
  TRAN_STAGE_FTRAN_UPPER,
  TRAN_STAGE_BTRAN_UPPER,
  TRAN_STAGE_BTRAN_UPPER_FT,
  TRAN_STAGE_BTRAN_LOWER,
  NUM_TRAN_STAGE_TYPE,
};

struct TranStageAnalysis {
  std::string name_;
  HighsScatterData rhs_density_;
  HighsInt num_decision_;
  HighsInt num_wrong_original_sparse_decision_;
  HighsInt num_wrong_original_hyper_decision_;
  HighsInt num_wrong_new_sparse_decision_;
  HighsInt num_wrong_new_hyper_decision_;
};

const HighsInt kAnIterTraceMaxNumRec = 20;
const HighsLogType kIterationReportLogType = HighsLogType::kVerbose;

/**
 * @brief Analyse simplex iterations, both for run-time control and data
 * gathering
 */
class HighsSimplexAnalysis {
 public:
  HighsSimplexAnalysis()
      : timer_(nullptr),
        pointer_serial_factor_clocks(nullptr),
        numRow(0),
        numCol(0),
        numTot(0),
        model_name_(""),
        lp_name_(""),
        analyse_lp_data(false),
        analyse_simplex_summary_data(false),
        analyse_simplex_runtime_data(false),
        analyse_simplex_time(false),
        analyse_factor_data(false),
        analyse_factor_time(false),
        analyse_simplex_data(false),
        simplex_strategy(0),
        edge_weight_mode(EdgeWeightMode::kSteepestEdge),
        solve_phase(0),
        simplex_iteration_count(0),
        devex_iteration_count(0),
        pivotal_row_index(0),
        leaving_variable(0),
        entering_variable(0),
        rebuild_reason(0),
        rebuild_reason_string(""),
        reduced_rhs_value(0.0),
        reduced_cost_value(0.0),
        edge_weight(0.0),
        edge_weight_error(0.0),
        primal_delta(0.0),
        primal_step(0.0),
        dual_step(0.0),
        pivot_value_from_column(0.0),
        pivot_value_from_row(0.0),
        factor_pivot_threshold(0.0),
        numerical_trouble(0.0),
        objective_value(0.0),
        num_primal_infeasibility(0),
        num_dual_infeasibility(0),
        sum_primal_infeasibility(0.0),
        sum_dual_infeasibility(0.0),
        num_dual_phase_1_lp_dual_infeasibility(0),
        max_dual_phase_1_lp_dual_infeasibility(0.0),
        sum_dual_phase_1_lp_dual_infeasibility(0.0),
        num_devex_framework(0),
        col_aq_density(0.0),
        row_ep_density(0.0),
        row_ap_density(0.0),
        row_DSE_density(0.0),
        col_steepest_edge_density(0.0),
        col_basic_feasibility_change_density(0.0),
        row_basic_feasibility_change_density(0.0),
        col_BFRT_density(0.0),
        primal_col_density(0.0),
        dual_col_density(0.0),
        num_costly_DSE_iteration(0),
        costly_DSE_measure(0.0),
        multi_iteration_count(0),
        multi_chosen(0),
        multi_finished(0),
        min_concurrency(0),
        num_concurrency(0),
        max_concurrency(0),
        num_col_price(0),
        num_row_price(0),
        num_row_price_with_switch(0),
        num_primal_cycling_detections(0),
        num_dual_cycling_detections(0),
        num_quad_chuzc(0),
        num_heap_chuzc(0),
        sum_quad_chuzc_size(0.0),
        sum_heap_chuzc_size(0.0),
        max_quad_chuzc_size(0),
        max_heap_chuzc_size(0),
        num_improve_choose_column_row_call(0),
        num_remove_pivot_from_pack(0),
        num_correct_dual_primal_flip(0),
        min_correct_dual_primal_flip_dual_infeasibility(kHighsInf),
        max_correct_dual_primal_flip(0.0),
        num_correct_dual_cost_shift(0),
        max_correct_dual_cost_shift_dual_infeasibility(0.0),
        max_correct_dual_cost_shift(0.0),
        net_num_single_cost_shift(0),
        num_single_cost_shift(0),
        max_single_cost_shift(0.0),
        sum_single_cost_shift(0.0),
        num_dual_steepest_edge_weight_check(0),
        num_dual_steepest_edge_weight_reject(0),
        num_wrong_low_dual_steepest_edge_weight(0),
        num_wrong_high_dual_steepest_edge_weight(0),
        average_frequency_low_dual_steepest_edge_weight(0.0),
        average_frequency_high_dual_steepest_edge_weight(0.0),
        average_log_low_dual_steepest_edge_weight_error(0.0),
        average_log_high_dual_steepest_edge_weight_error(0.0),
        max_average_frequency_low_dual_steepest_edge_weight(0.0),
        max_average_frequency_high_dual_steepest_edge_weight(0.0),
        max_sum_average_frequency_extreme_dual_steepest_edge_weight(0.0),
        max_average_log_low_dual_steepest_edge_weight_error(0.0),
        max_average_log_high_dual_steepest_edge_weight_error(0.0),
        max_sum_average_log_extreme_dual_steepest_edge_weight_error(0.0),
        num_invert_report_since_last_header(-1),
        num_iteration_report_since_last_header(-1),
        highs_run_time(0.0),
        last_user_log_time(-kHighsInf),
        delta_user_log_time(1e0),
        timeless_log(false),
        average_concurrency(0.0),
        average_fraction_of_possible_minor_iterations_performed(0.0),
        sum_multi_chosen(0),
        sum_multi_finished(0),
        num_invert(0),
        num_kernel(0),
        num_major_kernel(0),
        max_kernel_dim(0.0),
        sum_kernel_dim(0.0),
        running_average_kernel_dim(0.0),
        sum_invert_fill_factor(0.0),
        sum_kernel_fill_factor(0.0),
        sum_major_kernel_fill_factor(0.0),
        running_average_invert_fill_factor(1.0),
        running_average_kernel_fill_factor(1.0),
        running_average_major_kernel_fill_factor(1.0),
        AnIterIt0(0),
        AnIterPrevIt(0),
        AnIterOp{},
        AnIterTraceNumRec(0),
        AnIterTraceIterDl(0),
        AnIterTrace{},
        AnIterNumInvert{},
        AnIterNumEdWtIt{} {}

  // Pointer to timer
  HighsTimer* timer_;

  void setup(const std::string lp_name, const HighsLp& lp,
             const HighsOptions& options,
             const HighsInt simplex_iteration_count);
  void setupSimplexTime(const HighsOptions& options);
  void setupFactorTime(const HighsOptions& options);
  void messaging(const HighsLogOptions& log_options_);
  void iterationReport();
  void invertReport();
  void invertReport(const bool header);
  void userInvertReport(const bool force);
  void userInvertReport(const bool header, const bool force);
  bool predictEndDensity(const HighsInt tran_stage_id,
                         const double start_density, double& end_density) const;
  void afterTranStage(const HighsInt tran_stage_id, const double start_density,
                      const double end_density, const double historical_density,
                      const double predicted_end_density,
                      const bool use_solve_sparse_original_HFactor_logic,
                      const bool use_solve_sparse_new_HFactor_logic);

  void simplexTimerStart(const HighsInt simplex_clock,
                         const HighsInt thread_id = 0);
  void simplexTimerStop(const HighsInt simplex_clock,
                        const HighsInt thread_id = 0);
  bool simplexTimerRunning(const HighsInt simplex_clock,
                           const HighsInt thread_id = 0) const;
  HighsInt simplexTimerNumCall(const HighsInt simplex_clock,
                               const HighsInt thread_id = 0) const;
  double simplexTimerRead(const HighsInt simplex_clock,
                          const HighsInt thread_id = 0) const;

  HighsTimerClock* getThreadFactorTimerClockPointer();

  const std::vector<HighsTimerClock>& getThreadSimplexTimerClocks() {
    return thread_simplex_clocks;
  }
  HighsTimerClock* getThreadSimplexTimerClockPtr(HighsInt i) {
    assert(i >= 0 && i < (HighsInt)thread_simplex_clocks.size());
    return &thread_simplex_clocks[i];
  }

  const std::vector<HighsTimerClock>& getThreadFactorTimerClocks() {
    return thread_factor_clocks;
  }
  HighsTimerClock* getThreadFactorTimerClockPtr(HighsInt i) {
    assert(i >= 0 && i < (HighsInt)thread_factor_clocks.size());
    return &thread_factor_clocks[i];
  }

  void iterationRecord();
  void iterationRecordMajor();
  void operationRecordBefore(const HighsInt operation_type,
                             const HVector& vector,
                             const double historical_density);
  void operationRecordBefore(const HighsInt operation_type,
                             const HighsInt current_count,
                             const double historical_density);
  void operationRecordAfter(const HighsInt operation_type,
                            const HVector& vector);
  void operationRecordAfter(const HighsInt operation_type,
                            const HighsInt result_count);
  void summaryReport();
  void summaryReportFactor() const;
  void reportSimplexTimer() const;
  void reportFactorTimer();
  void updateInvertFormData(const HFactor& factor);
  void reportInvertFormData() const;
  HighsInt numInvert() const { return num_invert; }

  // Control methods to be moved to HEkkControl
  void dualSteepestEdgeWeightError(const double computed_edge_weight,
                                   const double updated_edge_weight);
  //  bool switchToDevex();

  std::vector<HighsTimerClock> thread_simplex_clocks;
  std::vector<HighsTimerClock> thread_factor_clocks;
  HighsTimerClock* pointer_serial_factor_clocks;

  // Local copies of LP data
  HighsInt numRow;
  HighsInt numCol;
  HighsInt numTot;
  std::string model_name_;
  std::string lp_name_;

  // Local copies of IO data
  HighsLogOptions log_options;

  // Interpreted shortcuts from bit settings in highs_analysis_level
  bool analyse_lp_data;
  bool analyse_simplex_summary_data;
  bool analyse_simplex_runtime_data;
  bool analyse_simplex_time;
  bool analyse_factor_data;
  bool analyse_factor_time;
  bool analyse_simplex_data;

  // Control parameters moving to info
  //  bool allow_dual_steepest_edge_to_devex_switch;
  //  double dual_steepest_edge_weight_log_error_threshold;

  // Local copies of simplex data for reporting
  HighsInt simplex_strategy;
  EdgeWeightMode edge_weight_mode;
  HighsInt solve_phase;
  HighsInt simplex_iteration_count;
  HighsInt devex_iteration_count;
  HighsInt pivotal_row_index;
  HighsInt leaving_variable;
  HighsInt entering_variable;
  HighsInt rebuild_reason;
  std::string rebuild_reason_string;
  double reduced_rhs_value;
  double reduced_cost_value;
  double edge_weight;
  double edge_weight_error;
  double primal_delta;
  double primal_step;
  double dual_step;
  double pivot_value_from_column;
  double pivot_value_from_row;
  double factor_pivot_threshold;
  double numerical_trouble;
  double objective_value;
  HighsInt num_primal_infeasibility;
  HighsInt num_dual_infeasibility;
  double sum_primal_infeasibility;
  double sum_dual_infeasibility;
  // This triple is an original infeasibility record, so it includes max,
  // but it's only used for reporting
  HighsInt num_dual_phase_1_lp_dual_infeasibility;
  double max_dual_phase_1_lp_dual_infeasibility;
  double sum_dual_phase_1_lp_dual_infeasibility;
  HighsInt num_devex_framework;
  double col_aq_density;
  double row_ep_density;
  double row_ap_density;
  double row_DSE_density;
  double col_steepest_edge_density;
  double col_basic_feasibility_change_density;
  double row_basic_feasibility_change_density;
  double col_BFRT_density;
  double primal_col_density;
  double dual_col_density;
  HighsInt num_costly_DSE_iteration;
  double costly_DSE_measure;

  // Local copies of parallel simplex data for reporting
  HighsInt multi_iteration_count;
  HighsInt multi_chosen;
  HighsInt multi_finished;
  HighsInt min_concurrency;
  HighsInt num_concurrency;
  HighsInt max_concurrency;

  // Unused
  //  HighsInt multi_num = 0; // Useless
  //  double basis_condition = 0; // Maybe useful

  // Records of how pivotal row PRICE was done
  HighsInt num_col_price;
  HighsInt num_row_price;
  HighsInt num_row_price_with_switch;

  HighsValueDistribution before_ftran_upper_sparse_density;
  HighsValueDistribution ftran_upper_sparse_density;
  HighsValueDistribution before_ftran_upper_hyper_density;
  HighsValueDistribution ftran_upper_hyper_density;
  HighsValueDistribution cost_perturbation1_distribution;
  HighsValueDistribution cost_perturbation2_distribution;
  HighsValueDistribution cleanup_dual_change_distribution;
  HighsValueDistribution cleanup_primal_step_distribution;
  HighsValueDistribution cleanup_dual_step_distribution;
  HighsValueDistribution cleanup_primal_change_distribution;

  HighsInt num_primal_cycling_detections;
  HighsInt num_dual_cycling_detections;

  HighsInt num_quad_chuzc;
  HighsInt num_heap_chuzc;
  double sum_quad_chuzc_size;
  double sum_heap_chuzc_size;
  HighsInt max_quad_chuzc_size;
  HighsInt max_heap_chuzc_size;

  HighsInt num_improve_choose_column_row_call;
  HighsInt num_remove_pivot_from_pack;

  HighsInt num_correct_dual_primal_flip;
  double min_correct_dual_primal_flip_dual_infeasibility;
  double max_correct_dual_primal_flip;
  HighsInt num_correct_dual_cost_shift;
  double max_correct_dual_cost_shift_dual_infeasibility;
  double max_correct_dual_cost_shift;
  HighsInt net_num_single_cost_shift;
  HighsInt num_single_cost_shift;
  double max_single_cost_shift;
  double sum_single_cost_shift;

  // Tolerances for analysis of TRAN stages - could be needed for
  // control if this is ever used again!
  vector<double> original_start_density_tolerance;
  vector<double> new_start_density_tolerance;
  vector<double> historical_density_tolerance;
  vector<double> predicted_density_tolerance;
  vector<TranStageAnalysis> tran_stage;

  std::unique_ptr<std::stringstream> analysis_log;

 private:
  void iterationReport(const bool header);
  void reportAlgorithmPhase(const bool header);
  void reportIterationObjective(const bool header);
  void reportInfeasibility(const bool header);
  void reportThreads(const bool header);
  void reportMulti(const bool header);
  void reportOneDensity(const double density);
  void printOneDensity(const double density) const;
  void reportDensity(const bool header);
  void reportInvert(const bool header);
  //  void reportCondition(const bool header);
  void reportIterationData(const bool header);
  void reportRunTime(const bool header, const double run_time);
  void reportFreeListSize(const bool header);
  HighsInt intLog10(const double v) const;
  bool dualAlgorithm() const;

  //  double AnIterCostlyDseFq;  //!< Frequency of iterations when DSE is costly
  //  double AnIterCostlyDseMeasure;

  HighsInt num_dual_steepest_edge_weight_check;
  HighsInt num_dual_steepest_edge_weight_reject;
  HighsInt num_wrong_low_dual_steepest_edge_weight;
  HighsInt num_wrong_high_dual_steepest_edge_weight;
  double average_frequency_low_dual_steepest_edge_weight;
  double average_frequency_high_dual_steepest_edge_weight;
  double average_log_low_dual_steepest_edge_weight_error;
  double average_log_high_dual_steepest_edge_weight_error;
  double max_average_frequency_low_dual_steepest_edge_weight;
  double max_average_frequency_high_dual_steepest_edge_weight;
  double max_sum_average_frequency_extreme_dual_steepest_edge_weight;
  double max_average_log_low_dual_steepest_edge_weight_error;
  double max_average_log_high_dual_steepest_edge_weight_error;
  double max_sum_average_log_extreme_dual_steepest_edge_weight_error;

  HighsInt num_invert_report_since_last_header;
  HighsInt num_iteration_report_since_last_header;
  double highs_run_time;
  double last_user_log_time;
  double delta_user_log_time;
  bool timeless_log;

  double average_concurrency;
  double average_fraction_of_possible_minor_iterations_performed;
  HighsInt sum_multi_chosen;
  HighsInt sum_multi_finished;

  // Analysis of INVERT form
  HighsInt num_invert;
  HighsInt num_kernel;
  HighsInt num_major_kernel;
  double max_kernel_dim;
  double sum_kernel_dim;
  double running_average_kernel_dim;
  double sum_invert_fill_factor;
  double sum_kernel_fill_factor;
  double sum_major_kernel_fill_factor;
  double running_average_invert_fill_factor;
  double running_average_kernel_fill_factor;
  double running_average_major_kernel_fill_factor;

  HighsInt AnIterIt0;
  HighsInt AnIterPrevIt;

  // Major operation analysis struct
  struct AnIterOpRec {
    double AnIterOpHyperCANCEL;
    double AnIterOpHyperTRAN;
    HighsInt AnIterOpRsDim;
    HighsInt AnIterOpNumCa;
    HighsInt AnIterOpNumHyperOp;
    HighsInt AnIterOpNumHyperRs;
    double AnIterOpSumLog10RsDensity;
    HighsInt AnIterOpRsMxNNZ;
    std::string AnIterOpName;
    HighsValueDistribution AnIterOp_density;
  };
  AnIterOpRec AnIterOp[kNumSimplexNlaOperation];

  struct AnIterTraceRec {
    double AnIterTraceTime;
    double AnIterTraceMulti;
    double AnIterTraceDensity[kNumSimplexNlaOperation];
    double AnIterTraceCostlyDse;
    HighsInt AnIterTraceIter;
    HighsInt AnIterTrace_simplex_strategy;
    HighsInt AnIterTrace_edge_weight_mode;
  };

  HighsInt AnIterTraceNumRec;
  HighsInt AnIterTraceIterDl;
  AnIterTraceRec AnIterTrace[1 + kAnIterTraceMaxNumRec + 1];

  HighsInt AnIterNumInvert[kRebuildReasonCount];
  HighsInt AnIterNumEdWtIt[(HighsInt)EdgeWeightMode::kCount];

  HighsValueDistribution primal_step_distribution;
  HighsValueDistribution dual_step_distribution;
  HighsValueDistribution simplex_pivot_distribution;
  HighsValueDistribution numerical_trouble_distribution;
  HighsValueDistribution factor_pivot_threshold_distribution;
  HighsValueDistribution edge_weight_error_distribution;
};

#endif /* SIMPLEX_HIGHSSIMPLEXANALYSIS_H_ */