Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
sparse_matrix_validator.cc
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include <cmath>
17#include <cstdint>
18#include <string>
19
20#include "absl/status/status.h"
21#include "absl/strings/str_cat.h"
22#include "absl/types/span.h"
25#include "ortools/math_opt/sparse_containers.pb.h"
27
29
30absl::Status SparseMatrixValid(const SparseDoubleMatrixProto& matrix,
31 const bool enforce_upper_triangular) {
32 const int nnz = matrix.row_ids_size();
33 if (nnz != matrix.column_ids_size()) {
35 << "Expected row_id.size=" << nnz
36 << " equal to column_ids.size=" << matrix.column_ids_size();
37 }
38 if (nnz != matrix.coefficients_size()) {
40 << "Expected row_id.size=" << nnz
41 << " equal to coefficients.size=" << matrix.coefficients_size();
42 }
43 int64_t previous_row = -1;
44 int64_t previous_col = -1;
45 for (int i = 0; i < nnz; ++i) {
46 const int64_t row = matrix.row_ids(i);
47 if (row < 0) {
49 << "row_ids should be nonnegative, but found id: " << row
50 << " (at index: " << i << ")";
51 }
52 const int64_t col = matrix.column_ids(i);
53 if (col < 0) {
55 << "column_ids should be nonnegative, but found id: " << col
56 << " (at index: " << i << ")";
57 }
58 if (enforce_upper_triangular && row > col) {
60 << "lower triangular entry at [" << row << ", " << col
61 << "] (at index: " << i << ")";
62 }
63 if (row < previous_row) {
65 << "row_ids should be nondecreasing, but found ids ["
66 << previous_row << ", " << row << "] at indices [" << i - 1 << ", "
67 << i << "]";
68 } else if (row == previous_row) {
69 if (previous_col >= col) {
71 << "column_ids should be strictly increasing within a row, but "
72 "for row_id: "
73 << row << " found [" << previous_col << ", " << col
74 << "] at indices, [" << i - 1 << ", " << i << "]";
75 }
76 }
77 // When row > previous_row, we have a new row, nothing to check.
78 if (!std::isfinite(matrix.coefficients(i))) {
80 << "Expected finite coefficients without NaN, but at row_id: "
81 << row << ", column_id: " << col
82 << " found coefficient: " << matrix.coefficients(i)
83 << " (at index: " << i << ")";
84 }
85 previous_row = row;
86 previous_col = col;
87 }
88 return absl::OkStatus();
89}
90
91absl::Status SparseMatrixIdsAreKnown(const SparseDoubleMatrixProto& matrix,
92 const IdNameBiMap& row_ids,
93 const IdNameBiMap& column_ids) {
94 RETURN_IF_ERROR(CheckIdsSubset(matrix.row_ids(), row_ids))
95 << "Unknown row_id";
96 RETURN_IF_ERROR(CheckIdsSubset(matrix.column_ids(), column_ids))
97 << "Unknown column_id";
98 return absl::OkStatus();
99}
100
101} // namespace operations_research::math_opt
#define RETURN_IF_ERROR(expr)
ColIndex col
Definition markowitz.cc:187
RowIndex row
Definition markowitz.cc:186
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
absl::Status SparseMatrixIdsAreKnown(const SparseDoubleMatrixProto &matrix, const IdNameBiMap &row_ids, const IdNameBiMap &column_ids)
absl::Status CheckIdsSubset(absl::Span< const int64_t > ids, const IdNameBiMap &universe, std::optional< int64_t > upper_bound)
absl::Status SparseMatrixValid(const SparseDoubleMatrixProto &matrix, const bool enforce_upper_triangular)
StatusBuilder InvalidArgumentErrorBuilder()