Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Education
LabPlot
Commits
0b274be2
Commit
0b274be2
authored
Jul 04, 2020
by
Stefan Gerlach
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[backend] Improve Range class
parent
4de64b34
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
52 additions
and
56 deletions
+52
-56
src/backend/lib/Range.h
src/backend/lib/Range.h
+22
-22
src/backend/worksheet/plots/cartesian/XYFitCurve.cpp
src/backend/worksheet/plots/cartesian/XYFitCurve.cpp
+10
-14
src/kdefrontend/dockwidgets/XYFitCurveDock.cpp
src/kdefrontend/dockwidgets/XYFitCurveDock.cpp
+2
-2
src/kdefrontend/widgets/FitOptionsWidget.cpp
src/kdefrontend/widgets/FitOptionsWidget.cpp
+18
-18
No files found.
src/backend/lib/Range.h
View file @
0b274be2
...
...
@@ -40,40 +40,40 @@
template
<
class
T
>
class
Range
{
public:
Range
()
:
m_
left
(
0
),
m_
right
(
0
)
{}
Range
(
T
left
,
T
right
)
{
this
->
setRange
(
left
,
right
);
Range
()
:
m_
min
(
0
),
m_
max
(
0
)
{}
Range
(
T
min
,
T
max
)
{
this
->
setRange
(
min
,
max
);
}
~
Range
()
=
default
;
T
left
()
const
{
return
m_
left
;
}
T
right
()
const
{
return
m_
right
;
}
void
set
Left
(
T
left
)
{
m_left
=
left
;
}
// no check (use first)
void
set
Right
(
T
right
)
{
m_
right
=
std
::
max
(
m_
left
,
right
);
}
void
setRange
(
T
left
,
T
right
)
{
m_
left
=
left
;
m_
right
=
std
::
max
(
left
,
right
);
T
min
()
const
{
return
m_
min
;
}
T
max
()
const
{
return
m_
max
;
}
void
set
Min
(
T
min
)
{
m_min
=
min
;
}
// no check (use first)
void
set
Max
(
T
max
)
{
m_
max
=
std
::
max
(
m_
min
,
max
);
}
void
setRange
(
T
min
,
T
max
)
{
m_
min
=
min
;
m_
max
=
std
::
max
(
min
,
max
);
}
T
size
()
const
{
return
m_
right
-
m_
left
;
}
bool
isZero
()
const
{
return
(
m_
right
==
m_
left
);
}
bool
inside
(
const
Range
<
T
>&
other
)
const
{
return
(
m_
left
<=
other
.
left
()
&&
m_
right
>=
other
.
right
()
);
}
bool
inside
(
T
value
)
const
{
return
(
m_
left
<=
value
&&
m_
right
>=
value
);
}
void
translate
(
T
offset
)
{
m_
left
+=
offset
;
m_
right
+=
offset
;
}
bool
operator
==
(
const
Range
<
T
>&
other
)
const
{
return
(
m_
left
==
other
.
left
()
&&
m_
right
==
other
.
right
()
);
}
T
size
()
const
{
return
m_
max
-
m_
min
;
}
bool
isZero
()
const
{
return
(
m_
max
==
m_
min
);
}
bool
inside
(
const
Range
<
T
>&
other
)
const
{
return
(
m_
min
<=
other
.
min
()
&&
m_
max
>=
other
.
max
()
);
}
bool
inside
(
T
value
)
const
{
return
(
m_
min
<=
value
&&
m_
max
>=
value
);
}
void
translate
(
T
offset
)
{
m_
min
+=
offset
;
m_
max
+=
offset
;
}
bool
operator
==
(
const
Range
<
T
>&
other
)
const
{
return
(
m_
min
==
other
.
min
()
&&
m_
max
==
other
.
max
()
);
}
Range
<
T
>&
operator
=
(
const
Range
<
T
>&
other
)
{
m_
left
=
other
.
left
();
m_
right
=
other
.
right
();
m_
min
=
other
.
min
();
m_
max
=
other
.
max
();
return
*
this
;
}
//! Return a string in the format '[
left, right
]'
//! Return a string in the format '[
min, max
]'
QString
toString
()
const
{
return
"["
+
QString
::
number
(
m_
left
)
+
", "
+
QString
::
number
(
m_
right
)
+
"]"
;
return
"["
+
QString
::
number
(
m_
min
)
+
", "
+
QString
::
number
(
m_
max
)
+
"]"
;
}
//TODO: touches(), merge(), subtract(), split(), etc. (see Interval)
private:
T
m_
left
;
// lower limit
T
m_
right
;
// upper limit
T
m_
min
;
// lower limit
T
m_
max
;
// upper limit
};
#endif
...
...
src/backend/worksheet/plots/cartesian/XYFitCurve.cpp
View file @
0b274be2
...
...
@@ -1613,15 +1613,12 @@ void XYFitCurvePrivate::recalculate() {
QVector
<
double
>
ydataVector
;
QVector
<
double
>
xerrorVector
;
QVector
<
double
>
yerrorVector
;
double
xmin
,
xmax
;
if
(
fitData
.
autoRange
)
{
xmin
=
tmpXDataColumn
->
minimum
();
xmax
=
tmpXDataColumn
->
maximum
();
}
else
{
xmin
=
fitData
.
fitRange
.
left
();
xmax
=
fitData
.
fitRange
.
right
();
Range
<
double
>
xRange
{
tmpXDataColumn
->
minimum
(),
tmpXDataColumn
->
maximum
()};
if
(
!
fitData
.
autoRange
)
{
if
(
!
fitData
.
fitRange
.
isZero
())
// avoid zero range
xRange
.
setRange
(
fitData
.
fitRange
.
min
(),
fitData
.
fitRange
.
max
());
}
DEBUG
(
" fit range = "
<<
xmin
<<
" .. "
<<
xmax
);
DEBUG
(
" fit range = "
<<
x
Range
.
min
()
<<
" .. "
<<
x
Range
.
max
()
);
//logic from XYAnalysisCurve::copyData(), extended by the handling of error columns.
//TODO: decide how to deal with non-numerical error columns
...
...
@@ -1670,8 +1667,7 @@ void XYFitCurvePrivate::recalculate() {
y
=
tmpYDataColumn
->
dateTimeAt
(
row
).
toMSecsSinceEpoch
();
}
// only when inside given range
if
(
x
>=
xmin
&&
x
<=
xmax
)
{
if
(
x
>=
xRange
.
min
()
&&
x
<=
xRange
.
max
())
{
// only when inside given range
if
((
!
xErrorColumn
&&
!
yErrorColumn
)
||
!
fitData
.
useDataErrors
)
{
// x-y
xdataVector
.
append
(
x
);
ydataVector
.
append
(
y
);
...
...
@@ -2058,7 +2054,7 @@ void XYFitCurvePrivate::recalculate() {
}
else
{
// only selected range
size_t
j
=
0
;
for
(
int
i
=
0
;
i
<
tmpXDataColumn
->
rowCount
();
i
++
)
{
if
(
tmpXDataColumn
->
valueAt
(
i
)
>=
xmin
&&
tmpXDataColumn
->
valueAt
(
i
)
<=
xmax
)
if
(
tmpXDataColumn
->
valueAt
(
i
)
>=
x
Range
.
min
()
&&
tmpXDataColumn
->
valueAt
(
i
)
<=
x
Range
.
max
()
)
residualsVector
->
data
()[
i
]
=
-
gsl_vector_get
(
s
->
f
,
j
++
);
else
// outside range
residualsVector
->
data
()[
i
]
=
0
;
...
...
@@ -2134,7 +2130,7 @@ void XYFitCurvePrivate::evaluate(bool preview) {
if
(
preview
)
// results not available yet
paramValues
=
fitData
.
paramStartValues
;
bool
rc
=
parser
->
evaluateCartesian
(
fitData
.
model
,
QString
::
number
(
xRange
.
left
()),
QString
::
number
(
xRange
.
right
()),
(
int
)
fitData
.
evaluatedPoints
,
bool
rc
=
parser
->
evaluateCartesian
(
fitData
.
model
,
QString
::
number
(
xRange
.
min
()),
QString
::
number
(
xRange
.
max
()),
(
int
)
fitData
.
evaluatedPoints
,
xVector
,
yVector
,
fitData
.
paramNames
,
paramValues
);
if
(
!
rc
)
{
DEBUG
(
" ERROR: Parsing fit function failed"
)
...
...
@@ -2191,8 +2187,8 @@ void XYFitCurve::save(QXmlStreamWriter* writer) const {
WRITE_COLUMN
(
d
->
xErrorColumn
,
xErrorColumn
);
WRITE_COLUMN
(
d
->
yErrorColumn
,
yErrorColumn
);
writer
->
writeAttribute
(
"autoRange"
,
QString
::
number
(
d
->
fitData
.
autoRange
));
writer
->
writeAttribute
(
"fitRangeMin"
,
QString
::
number
(
d
->
fitData
.
fitRange
.
left
(),
'g'
,
15
));
writer
->
writeAttribute
(
"fitRangeMax"
,
QString
::
number
(
d
->
fitData
.
fitRange
.
right
(),
'g'
,
15
));
writer
->
writeAttribute
(
"fitRangeMin"
,
QString
::
number
(
d
->
fitData
.
fitRange
.
min
(),
'g'
,
15
));
writer
->
writeAttribute
(
"fitRangeMax"
,
QString
::
number
(
d
->
fitData
.
fitRange
.
max
(),
'g'
,
15
));
writer
->
writeAttribute
(
"modelCategory"
,
QString
::
number
(
d
->
fitData
.
modelCategory
));
writer
->
writeAttribute
(
"modelType"
,
QString
::
number
(
d
->
fitData
.
modelType
));
writer
->
writeAttribute
(
"xWeightsType"
,
QString
::
number
(
d
->
fitData
.
xWeightsType
));
...
...
src/kdefrontend/dockwidgets/XYFitCurveDock.cpp
View file @
0b274be2
...
...
@@ -1013,8 +1013,8 @@ void XYFitCurveDock::setPlotXRange() {
const
Range
<
double
>
range
=
m_fitData
.
evalRange
;
const
double
extend
=
range
.
size
()
*
0.05
;
// + 5 %
if
(
!
range
.
isZero
())
{
plot
->
setXMin
(
range
.
left
()
-
extend
);
plot
->
setXMax
(
range
.
right
()
+
extend
);
plot
->
setXMin
(
range
.
min
()
-
extend
);
plot
->
setXMax
(
range
.
max
()
+
extend
);
}
}
}
...
...
src/kdefrontend/widgets/FitOptionsWidget.cpp
View file @
0b274be2
...
...
@@ -59,15 +59,15 @@ FitOptionsWidget::FitOptionsWidget(QWidget* parent, XYFitCurve::FitData* fitData
const
auto
*
plot
=
static_cast
<
const
CartesianPlot
*>
(
fitCurve
->
parentAspect
());
m_dateTimeRange
=
(
plot
->
xRangeFormat
()
!=
CartesianPlot
::
RangeFormat
::
Numeric
);
if
(
!
m_dateTimeRange
)
{
ui
.
leMin
->
setText
(
QString
::
number
(
m_fitData
->
fitRange
.
left
()));
ui
.
leMax
->
setText
(
QString
::
number
(
m_fitData
->
fitRange
.
right
()));
ui
.
leEvalMin
->
setText
(
QString
::
number
(
m_fitData
->
evalRange
.
left
()));
ui
.
leEvalMax
->
setText
(
QString
::
number
(
m_fitData
->
evalRange
.
right
()));
ui
.
leMin
->
setText
(
QString
::
number
(
m_fitData
->
fitRange
.
min
()));
ui
.
leMax
->
setText
(
QString
::
number
(
m_fitData
->
fitRange
.
max
()));
ui
.
leEvalMin
->
setText
(
QString
::
number
(
m_fitData
->
evalRange
.
min
()));
ui
.
leEvalMax
->
setText
(
QString
::
number
(
m_fitData
->
evalRange
.
max
()));
}
else
{
ui
.
dateTimeEditMin
->
setDateTime
(
QDateTime
::
fromMSecsSinceEpoch
(
m_fitData
->
fitRange
.
left
())
);
ui
.
dateTimeEditMax
->
setDateTime
(
QDateTime
::
fromMSecsSinceEpoch
(
m_fitData
->
fitRange
.
right
())
);
ui
.
dateTimeEditEvalMin
->
setDateTime
(
QDateTime
::
fromMSecsSinceEpoch
(
m_fitData
->
evalRange
.
left
())
);
ui
.
dateTimeEditEvalMax
->
setDateTime
(
QDateTime
::
fromMSecsSinceEpoch
(
m_fitData
->
evalRange
.
right
())
);
ui
.
dateTimeEditMin
->
setDateTime
(
QDateTime
::
fromMSecsSinceEpoch
(
m_fitData
->
fitRange
.
min
())
);
ui
.
dateTimeEditMax
->
setDateTime
(
QDateTime
::
fromMSecsSinceEpoch
(
m_fitData
->
fitRange
.
max
())
);
ui
.
dateTimeEditEvalMin
->
setDateTime
(
QDateTime
::
fromMSecsSinceEpoch
(
m_fitData
->
evalRange
.
min
())
);
ui
.
dateTimeEditEvalMax
->
setDateTime
(
QDateTime
::
fromMSecsSinceEpoch
(
m_fitData
->
evalRange
.
max
())
);
}
ui
.
leMin
->
setVisible
(
!
m_dateTimeRange
);
...
...
@@ -191,52 +191,52 @@ void FitOptionsWidget::autoEvalRangeChanged() {
void
FitOptionsWidget
::
fitRangeMinChanged
()
{
const
double
xMin
=
ui
.
leMin
->
text
().
toDouble
();
m_fitData
->
fitRange
.
set
Left
(
xMin
);
m_fitData
->
fitRange
.
set
Min
(
xMin
);
changed
();
}
void
FitOptionsWidget
::
fitRangeMaxChanged
()
{
const
double
xMax
=
ui
.
leMax
->
text
().
toDouble
();
m_fitData
->
fitRange
.
set
Right
(
xMax
);
m_fitData
->
fitRange
.
set
Max
(
xMax
);
changed
();
}
void
FitOptionsWidget
::
fitRangeMinDateTimeChanged
(
const
QDateTime
&
dateTime
)
{
m_fitData
->
fitRange
.
set
Left
(
dateTime
.
toMSecsSinceEpoch
());
m_fitData
->
fitRange
.
set
Min
(
dateTime
.
toMSecsSinceEpoch
());
changed
();
}
void
FitOptionsWidget
::
fitRangeMaxDateTimeChanged
(
const
QDateTime
&
dateTime
)
{
m_fitData
->
fitRange
.
set
Right
(
dateTime
.
toMSecsSinceEpoch
());
m_fitData
->
fitRange
.
set
Max
(
dateTime
.
toMSecsSinceEpoch
());
changed
();
}
void
FitOptionsWidget
::
evalRangeMinChanged
()
{
const
double
xMin
=
ui
.
leEvalMin
->
text
().
toDouble
();
m_fitData
->
evalRange
.
set
Left
(
xMin
);
m_fitData
->
evalRange
.
set
Min
(
xMin
);
changed
();
}
void
FitOptionsWidget
::
evalRangeMaxChanged
()
{
const
double
xMax
=
ui
.
leEvalMax
->
text
().
toDouble
();
m_fitData
->
evalRange
.
set
Right
(
xMax
);
m_fitData
->
evalRange
.
set
Max
(
xMax
);
changed
();
}
void
FitOptionsWidget
::
evalRangeMinDateTimeChanged
(
const
QDateTime
&
dateTime
)
{
m_fitData
->
evalRange
.
set
Left
(
dateTime
.
toMSecsSinceEpoch
());
m_fitData
->
evalRange
.
set
Min
(
dateTime
.
toMSecsSinceEpoch
());
changed
();
}
void
FitOptionsWidget
::
evalRangeMaxDateTimeChanged
(
const
QDateTime
&
dateTime
)
{
m_fitData
->
evalRange
.
set
Right
(
dateTime
.
toMSecsSinceEpoch
());
m_fitData
->
evalRange
.
set
Max
(
dateTime
.
toMSecsSinceEpoch
());
changed
();
}
void
FitOptionsWidget
::
applyClicked
()
{
m_fitData
->
maxIterations
=
ui
.
leMaxIterations
->
text
().
toFloat
();
m_fitData
->
eps
=
ui
.
leEps
->
text
().
toFloat
();
m_fitData
->
maxIterations
=
ui
.
leMaxIterations
->
text
().
toFloat
();
//TODO: float?
m_fitData
->
eps
=
ui
.
leEps
->
text
().
toFloat
();
// TODO: float?
m_fitData
->
evaluatedPoints
=
ui
.
leEvaluatedPoints
->
text
().
toInt
();
m_fitData
->
useDataErrors
=
ui
.
cbUseDataErrors
->
isChecked
();
m_fitData
->
useResults
=
ui
.
cbUseResults
->
isChecked
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment