Skip to content

Commit 85077ac

Browse files
committed
attributes of constraints moved to implementation details of state
1 parent a2e27d5 commit 85077ac

File tree

8 files changed

+218
-190
lines changed

8 files changed

+218
-190
lines changed

src/adjustment.cpp

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
#include "adjustment.h"
20+
#include "constants.h"
2021
#include "constraints.h"
2122
#include "geometry/minrot.h"
2223
#include "global.h"
@@ -30,11 +31,9 @@
3031
#include "qcontainerfwd.h"
3132
#include "qlogging.h"
3233

33-
#include <algorithm>
3434
#include <cassert>
3535
#include <cmath>
3636
#include <memory>
37-
#include <numeric>
3837
#include <sstream>
3938
#include <utility>
4039

@@ -45,8 +44,10 @@
4544
using Graph::IncidenceMatrix;
4645
using Constraint::ConstraintBase;
4746

47+
using Eigen::Array;
4848
using Eigen::ArrayXi;
4949
using Eigen::ColMajor;
50+
using Eigen::Dynamic;
5051
using Eigen::Index;
5152
using Eigen::VectorXd;
5253
using Eigen::Vector3d;
@@ -102,7 +103,9 @@ void AdjustmentFramework::update( const VectorXd &x)
102103

103104
bool AdjustmentFramework::enforceConstraints( const QVector<std::shared_ptr<ConstraintBase> > & constr,
104105
const IncidenceMatrix & relsub,
105-
const ArrayXi & mapc )
106+
const ArrayXi & mapc,
107+
Array<Attribute,Dynamic,1> & status,
108+
Array<bool,Dynamic,1> & enforced)
106109
{
107110
//assert( relsub.rows()==maps.size() );
108111
assert( relsub.cols()==mapc.size() );
@@ -115,8 +118,7 @@ bool AdjustmentFramework::enforceConstraints( const QVector<std::shared_ptr<Cons
115118
}
116119

117120
// number of required constraints, inclusive hypothesis to be tested
118-
const Index numOfRequiredConstraints = std::count_if( mapc.begin(), mapc.end(),
119-
[&constr](Index i){ return constr.at(i)->required();} );
121+
const Index numOfRequiredConstraints = (status(mapc)==Attribute::Required).count();
120122

121123
if ( verbose ) {
122124
qDebug().noquote() << QString( numOfConstraints==1 ?
@@ -128,10 +130,10 @@ bool AdjustmentFramework::enforceConstraints( const QVector<std::shared_ptr<Cons
128130

129131
// number of required equations (not constraints!),
130132
// e.g., two equations for parallelism
131-
const int numOfRequiredEquations = std::accumulate(
132-
mapc.begin(), mapc.end(), 0,
133-
[&constr](int acc, int i){
134-
return acc += constr.at(i)->required() ? constr.at(i)->dof() : 0;} );
133+
int numOfRequiredEquations = 0;
134+
for (const auto c : mapc) {
135+
numOfRequiredEquations += status(c)==Attribute::Required ? constr.at(c)->dof() : 0;
136+
}
135137

136138

137139
l0_ = l_; // set adjusted observations l0 := l
@@ -154,7 +156,7 @@ bool AdjustmentFramework::enforceConstraints( const QVector<std::shared_ptr<Cons
154156
qDebug().noquote() << QStringLiteral(" iteration #%1...").arg(it+1);
155157
}
156158

157-
Jacobian( constr, relsub, BBr, g0, mapc);
159+
Jacobian( constr, relsub, BBr, g0, mapc, status);
158160
reduce ( lr, rCov_ll);
159161

160162
// check rank and condition .....................................
@@ -213,7 +215,9 @@ bool AdjustmentFramework::enforceConstraints( const QVector<std::shared_ptr<Cons
213215
}
214216

215217
// check constraints
216-
checkConstraints( constr, relsub, mapc);
218+
assert( enforced.size()==status.size() );
219+
220+
checkConstraints( constr, relsub, mapc, status, enforced);
217221

218222
return true;
219223
}
@@ -256,7 +260,8 @@ void AdjustmentFramework::Jacobian(
256260
const IncidenceMatrix & relsub,
257261
SparseMatrix<double,ColMajor> & BBr,
258262
VectorXd & g0,
259-
const ArrayXi & mapc ) const
263+
const ArrayXi & mapc,
264+
const Array<Attribute,Dynamic,1> & status ) const
260265
{
261266
// assert( relsub.rows()==maps.size() );
262267
assert( relsub.cols()==mapc.size() );
@@ -270,7 +275,8 @@ void AdjustmentFramework::Jacobian(
270275

271276
// !! not required ==> obsolete or(!) unevaluated
272277
const auto & con = constr.at( mapc(c) );
273-
if ( con->status() != ConstraintBase::REQUIRED ) { // observe the "!="
278+
279+
if ( status(mapc(c)) != Attribute::Required ) { // observe the "!="
274280
continue;
275281
}
276282

@@ -295,14 +301,15 @@ void AdjustmentFramework::Jacobian(
295301
void AdjustmentFramework::checkConstraints(
296302
const QVector<std::shared_ptr<ConstraintBase> > & constr,
297303
const IncidenceMatrix & relsub,
298-
const ArrayXi & mapc) const
304+
const ArrayXi & mapc,
305+
const Array<Attribute,Dynamic,1> & status,
306+
Array<bool,Eigen::Dynamic,1> & enforced) const
299307
{
300308
// assert( relsub.rows()==maps.size() );
301309
assert( relsub.cols()==mapc.size() );
302310

303311
const Index numOfConstraints = mapc.size();
304312

305-
306313
// check intrinsic constraints ..............................
307314
#ifdef QT_DEBUG
308315
const Index numOfSegments = relsub.rows();
@@ -328,23 +335,24 @@ void AdjustmentFramework::checkConstraints(
328335
for ( Index c=0; c<numOfConstraints; c++ )
329336
{
330337
const auto & con = constr.at( mapc(c) );
331-
if ( con->unevaluated() ) {
332-
continue;
338+
if ( status(mapc(c))==Attribute::Unevaluated ) {
339+
continue;
333340
}
334341

335342
const VectorXidx idx = spfind( relsub.col(c).eval() );
336343

337344
const double d = con->contradict( idx, l0_ ).norm();
338-
con->setEnforced( std::fabs(d) < threshold_numericalCheck() );
345+
assert( enforced.size()==status.size() );
346+
enforced( mapc(c)) = ( std::fabs(d) < threshold_numericalCheck() );
339347

340348
#ifdef QT_DEBUG
341349
if ( verbose ) {
342350
const QString msg1 = QStringLiteral("%1: ").arg(QString::fromLatin1(con->type_name()), 12);
343351
const QString msg2 = QStringLiteral("check = %2, \t").arg(d);
344352
QDebug deb = qDebug().noquote();
345353
deb << QStringLiteral("constraint #%1: ").arg(c+1,3);
346-
deb << (con->required() ? green : blue) << msg1 << black;
347-
deb << (con->enforced() ? black : red) << msg2 << black;
354+
deb << ( status(c)==Attribute::Required ? green : blue) << msg1 << black;
355+
deb << ( enforced(c) ? black : red) << msg2 << black;
348356
}
349357
#endif
350358
}

src/adjustment.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
namespace Constraint {class ConstraintBase;} // namespace Constraint
3333
namespace Graph {class IncidenceMatrix;} // namespace Graph
3434

35+
enum class Attribute : int;
3536

3637
//! Adjustment framework: observations, Jacobians, optimization...
3738
class AdjustmentFramework
@@ -59,7 +60,9 @@ class AdjustmentFramework
5960
//! Enforce the constraints of a subtask (adjustment)
6061
bool enforceConstraints(const QVector<std::shared_ptr<Constraint::ConstraintBase> > &constr,
6162
const Graph::IncidenceMatrix &relsub,
62-
const Eigen::ArrayXi &mapc);
63+
const Eigen::ArrayXi &mapc,
64+
Eigen::Array<Attribute,Eigen::Dynamic,1> & status,
65+
Eigen::Array<bool,Eigen::Dynamic,1> & enforced);
6366

6467
//! Get s-th entity, i.e., segment, represented by vector of length len
6568
[[nodiscard]] std::pair<Eigen::Vector3d, Eigen::Matrix3d> getEntity( Eigen::Index s) const;
@@ -77,13 +80,16 @@ class AdjustmentFramework
7780
const Graph::IncidenceMatrix & relsub,
7881
Eigen::SparseMatrix<double, Eigen::ColMajor> & BBr,
7982
Eigen::VectorXd & g0,
80-
const Eigen::ArrayXi & mapc) const;
83+
const Eigen::ArrayXi & mapc,
84+
const Eigen::Array<Attribute,Eigen::Dynamic,1> & status ) const;
8185
//! compute reduced coordinates
8286
void reduce ( Eigen::VectorXd &, Eigen::SparseMatrix<double,Eigen::ColMajor> &) const;
8387

8488
void checkConstraints( const QVector<std::shared_ptr<Constraint::ConstraintBase> > & constr,
8589
const Graph::IncidenceMatrix & relsub,
86-
const Eigen::ArrayXi & mapc ) const;
90+
const Eigen::ArrayXi & mapc,
91+
const Eigen::Array<Attribute,Eigen::Dynamic,1> & status,
92+
Eigen::Array<bool,Eigen::Dynamic,1> & enforced ) const;
8793

8894
bool verbose = true;
8995

src/constants.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#ifndef CONSTANTS_H
2+
#define CONSTANTS_H
3+
/*
4+
* This file is part of the GreasePad distribution (https://github.com/FraunhoferIOSB/GreasePad).
5+
* Copyright (c) 2022-2026 Jochen Meidow, Fraunhofer IOSB
6+
*
7+
* This program is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
19+
*/
20+
21+
//! mutual exclusive attributes for the constraints:
22+
//! (1) unevaluted, (2) required, or (3) redundant
23+
enum class Attribute : int
24+
{
25+
Unevaluated,
26+
Required,
27+
Redundant
28+
};
29+
30+
#endif // CONSTANTS_H

src/constraints.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,6 @@ using Matfun::sign;
4646

4747
namespace Constraint {
4848

49-
ConstraintBase::ConstraintBase()
50-
: m_status(UNEVAL)
51-
, m_enforced(false)
52-
{
53-
// qDebug().noquote() << Q_FUNC_INFO;
54-
}
55-
56-
/*std::shared_ptr<ConstraintBase> ConstraintBase::clone() const
57-
{
58-
// qDebug() << Q_FUNC_INFO;
59-
std::shared_ptr<ConstraintBase> ptr = doClone();
60-
auto & r = *ptr; // .get();
61-
assert( typeid(r) == typeid(*this)
62-
&& "ConstraintBase: doClone() incorrectly overridden" );
63-
return ptr;
64-
}*/
65-
66-
6749

6850
MatrixXd Orthogonal::Jacobian( const VectorXidx & idxx,
6951
const VectorXd &l0,

src/constraints.h

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,25 +47,13 @@ class ConstraintBase
4747
ConstraintBase (const ConstraintBase & other) = default;
4848
ConstraintBase & operator= ( const ConstraintBase & other) = delete;
4949

50-
ConstraintBase();
50+
ConstraintBase() = default;
5151
virtual ~ConstraintBase() = default;
5252

53-
//! Status: unevaluated, required, obsolete (redundant)
54-
enum Status : int { UNEVAL=0, REQUIRED, OBSOLETE };
55-
5653
[[nodiscard]] virtual const char *type_name() const = 0; //!< Get type name of constraint
5754
[[nodiscard]] virtual int dof() const = 0; //!< Get degrees of freedom for this constraint
5855
[[nodiscard]] virtual int arity() const = 0; //!< Get number of involved entities, i.e., straight lines
5956

60-
[[nodiscard]] Status status() const { return m_status; } //!< Get status (required, obsolete, unevaluated)
61-
[[nodiscard]] bool enforced() const { return m_enforced; } //!< Constraint is enforced?
62-
[[nodiscard]] bool required() const { return m_status==REQUIRED; } //!< Constraint is required?
63-
[[nodiscard]] bool obsolete() const { return m_status==OBSOLETE; } //!< Constraint is obsolete (redundant)?
64-
[[nodiscard]] bool unevaluated() const { return m_status==UNEVAL; } //!< Constraint is unevaluated?
65-
66-
void setStatus( const Status s) { m_status = s; } //!< Set status (required, obsolete, unevaluated)
67-
void setEnforced( const bool b) { m_enforced = b; } //!< Set status success of enforcement
68-
6957
//! Compute Jacobian w.r.t. observations
7058
[[nodiscard]] virtual MatrixXd Jacobian(
7159
const Vector<Index,Dynamic> &idxx,
@@ -85,10 +73,6 @@ class ConstraintBase
8573

8674
//! Clone constraints via nonvirtual interface pattern
8775
[[nodiscard]] virtual std::shared_ptr<ConstraintBase> clone() const = 0;
88-
89-
private:
90-
Status m_status; // { UNEVAL=0 | REQUIRED | OBSOLETE };
91-
bool m_enforced;
9276
};
9377

9478

src/greasepad.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ HEADERS += \
5050
adjustment.h \
5151
commands.h \
5252
conncomp.h \
53+
constants.h \
5354
constraints.h \
5455
geometry/aabb.h \
5556
geometry/acute.h \

src/mainscene.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626

2727
#include <memory>
2828

29-
class QAction;
29+
//class QAction;
30+
#include<QAction>
3031
class QObject;
3132
class QString;
3233

0 commit comments

Comments
 (0)