mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-11-15 18:15:52 +08:00
improvements to iterator interface (full random access iterators, erase-remove-idion)
added specific example for the iterator interface
This commit is contained in:
parent
c56b02998f
commit
6fe42748ed
@ -80,6 +80,8 @@ addSimpleTest(boxplot)
|
||||
addSimpleTest(advancedlineandfillstyling)
|
||||
addSimpleTest(imageplot_nodatastore)
|
||||
addSimpleTest(datastore)
|
||||
addSimpleTest(datastore_iterators)
|
||||
addSimpleTest(datastore_statistics)
|
||||
addSimpleTest(contourplot)
|
||||
#addSimpleTest(rgbimageplot_opencv)
|
||||
#addSimpleTest(imageplot_opencv)
|
||||
|
@ -153,9 +153,12 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
||||
<tr><td> \image html simpletest_datastore_small.png
|
||||
<td> \subpage JKQTPlotterBasicJKQTPDatastore
|
||||
<td> Basic Data Management with JKQTPDatastore <br/> Copying data into a JKQTPDatastore <br/> Editing data inside a JKQTPDatastore <br/> Editing Image Data in a JKQTPDatastore
|
||||
<tr><td> \image html simpletest_datastore_iterators_small.png
|
||||
<td> \subpage JKQTPlotterBasicJKQTPDatastoreIterators
|
||||
<td> Iterator-based Data Management with JKQTPDatastore
|
||||
<tr><td> \image html jkqtplotter_simpletest_datastore_statistics_small.png
|
||||
<td> \subpage JKQTPlotterBasicJKQTPDatastoreStatistics
|
||||
<td> Advanced 1-Dimensional Statistical Computation with JKQTPODatastore (and the internal statistics library, see \ref jkqtptools_math_statistics )
|
||||
<td> Advanced 1-Dimensional Statistical Computation with JKQTPDatastore<br>using the internal statistics library (see \ref jkqtptools_math_statistics )<br>basic statistics (mean, standard deviation, ...)<br>boxplots<br>histograms<br>kernel density estimates (KDE)
|
||||
</table>
|
||||
|
||||
|
||||
|
@ -12,6 +12,8 @@
|
||||
- \ref JKQTMathTextSimpleExample
|
||||
.
|
||||
|
||||
\defgroup jkqtmathtext_items JKQTMathText Render-Tree Items
|
||||
\ingroup jkqtmathtext
|
||||
|
||||
|
||||
*/
|
@ -58,13 +58,13 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_test_user_interaction_small.gif)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_user_interaction) | [User Interaction](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/test_user_interaction) | different possibilities of user-interaction in JKQtPlotter |
|
||||
|
||||
|
||||
|
||||
## Data Management (Tutorials) & Statistics
|
||||
## Data Management & Statistics (Tutorials)
|
||||
|
||||
| Screenshot | Description | Notes |
|
||||
|:-------------:| ------------- | ------------- |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore) | [Tutorial: Basic Usage of JKQTPDatastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore) | Basic Data Management with JKQTPDatastore <br/> Copying data into a JKQTPDatastore <br/> Editing data inside a JKQTPDatastore <br/> Editing Image Data in a JKQTPDatastore |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics) | [Tutorial: Advanced 1-Dimensional Statistics with JKQTPDatastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics) | Advanced 1-Dimensional Statistical Computation with JKQTPDatastore (and the internal statistics library) |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_iterators_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_iterators) | [Tutorial: Iterator-based access to JKQTPDatastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_iterators) | Iterator-based Data Management with JKQTPDatastore |
|
||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics) | [Tutorial: Advanced 1-Dimensional Statistics with JKQTPDatastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_statistics) | Advanced 1-Dimensional Statistical Computation with JKQTPDatastore<br>using the internal statistics library<br>basic statistics (mean, standard deviation, ...)<br>boxplots<br>histograms<br>kernel density estimates (KDE) |
|
||||
|
||||
|
||||
## More Complex Examples
|
||||
|
@ -1,7 +1,17 @@
|
||||
# Tutorial (JKQTPlotter): Basic Usage of JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastore}
|
||||
# Tutorial (JKQTPDatastore): Basic Usage of JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastore}
|
||||
|
||||
[JKQTPlotterBasicJKQTPDatastore]: @ref JKQTPlotterBasicJKQTPDatastore "Basic Usage of JKQTPDatastore"
|
||||
[JKQTPlotterBasicJKQTPDatastoreIterators]: @ref JKQTPlotterBasicJKQTPDatastoreIterators "Iterator-Based usage of JKQTPDatastore"
|
||||
[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
|
||||
[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
|
||||
|
||||
This tutorial project (see `./examples/simpletest_datastore/`) explains several options of JKQTPDatastore, which is the class used to centrally store the data for (most) graphs on a JKQTPlotter widget.
|
||||
|
||||
***Note*** that there are additional tutorial explaining other aspects of data mangement in JKQTPDatastore:
|
||||
- [JKQTPlotterBasicJKQTPDatastore]
|
||||
- [JKQTPlotterBasicJKQTPDatastoreIterators]
|
||||
- [JKQTPlotterBasicJKQTPDatastoreStatistics]
|
||||
|
||||
[TOC]
|
||||
|
||||
The source code of the main application can be found in [`jkqtplotter_simpletest_datastore.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore/jkqtplotter_simpletest_datastore.cpp).
|
||||
@ -14,7 +24,7 @@ In every code-segment below, we will use these two declarations from the code to
|
||||
JKQTPDatastore* datastore=plot.getDatastore();
|
||||
```
|
||||
|
||||
# Copy Data from different data structures into JKQTPDatastore
|
||||
# Copying Data from External COntainers into JKQTPDatastore
|
||||
|
||||
## Copy Data from a Vector into a column of the JKQTPDatastore
|
||||
|
||||
@ -118,7 +128,7 @@ In addition to the variants of `JKQTPDatastore::addColumn()`, that do not transf
|
||||
|
||||
It is also possible to leave the data mangement completely to the JKQTPDatastore and just edit the data with access functions from JKQTPDatastore.
|
||||
|
||||
## Generating Columns Non-Initialized Columns and Filling Them
|
||||
## Generating Non-Initialized Columns and Filling Them
|
||||
|
||||
The most basic way to generate data for a plot is to generate two non-initialized columns for the x- and y-coordinates of the graph points
|
||||
```.cpp
|
||||
@ -140,22 +150,6 @@ Plotting these two columns versus each other results in a simple sine graph:
|
||||
|
||||
![simpletest_datastore_sine](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_sine.png)
|
||||
|
||||
## Iterator Interface
|
||||
|
||||
Alternatively you can also access the column via a C++ iterator:
|
||||
```.cpp
|
||||
auto itX=datastore->begin(colX))
|
||||
auto itY=datastore->begin(colY))
|
||||
for (; itX!=datastore->end(colX); ++itX, ++itY) {
|
||||
const double x=double(i)/double(Ndata)*8.0*M_PI;
|
||||
*itX=x;
|
||||
*itY=sin(x);
|
||||
}
|
||||
```
|
||||
|
||||
This, together with `JKQTPDatastore::backInserter()` allows to use `JKQTDatastore` together with algorithms from the C++ standard template libarary and other templated algorithms based on the same iterator-based interfaces (e.g. in boost).
|
||||
|
||||
|
||||
|
||||
|
||||
## Generating Columns Preinitialized Columns
|
||||
@ -325,3 +319,39 @@ The result will look like this (`JKQTPXYParametrizedScatterGraph` on the left an
|
||||
![simpletest_datastore_image](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_image.png)
|
||||
|
||||
|
||||
|
||||
# Iterator Interface
|
||||
|
||||
Some sections before we discussed a code-fragment
|
||||
```.cpp
|
||||
size_t itXColumn=datastore->addColumn(50, "cos curve: x-data");
|
||||
size_t itYColumn=datastore->addColumn(50, "cos curve: y-data");
|
||||
for (int i=0; i<datastore->getRows(itXColumn); i++) {
|
||||
const double x=30.0+i/25.0*M_PI;
|
||||
datastore->set(itXColumn, i, x);
|
||||
datastore->set(itYColumn, i, cos(x));
|
||||
}
|
||||
```
|
||||
in which an image was calculated pixel-by-pixel with explicit int indices. Alternatively you can also access the columns via C++ iterators:
|
||||
```.cpp
|
||||
auto itX=datastore->begin(colX))
|
||||
auto itY=datastore->begin(colY))
|
||||
for (; itX!=datastore->end(colX); ++itX, ++itY) {
|
||||
const double x=double(i)/double(Ndata)*8.0*M_PI;
|
||||
*itX=x;
|
||||
*itY=sin(x);
|
||||
}
|
||||
```
|
||||
|
||||
All these code fragments result in the same graphs:
|
||||
|
||||
![simpletest_datastore_image](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_image.png)
|
||||
|
||||
You can also use this interface to interface with algorithms e.g. from the C++ standard template library. E.g. if you want to sort the data in a column, you can simply call
|
||||
```.cpp
|
||||
std::sort(datastore->begin(colY), datastore->end(colY));
|
||||
```
|
||||
|
||||
![simpletest_datastore_image_sorted](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_image_sorted.png)
|
||||
|
||||
This, together with `JKQTPDatastore::backInserter()` allows to use `JKQTDatastore` together with algorithms from the C++ standard template libarary and other templated algorithms based on the same iterator-based interfaces (e.g. in boost).
|
@ -8,7 +8,7 @@
|
||||
#include "jkqtplotter/jkqtplotter.h"
|
||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
@ -22,6 +22,11 @@ int main(int argc, char* argv[])
|
||||
JKQTPColumnMathImage* imggraph;
|
||||
JKQTPXYParametrizedScatterGraph* paramscattergraph;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// externally provided data (i.e. from different containers)
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 2. first we create data inside a QVector for a simple plot (a sine curve) ... and add the plot
|
||||
// note that you could use a std::vector equally well
|
||||
QVector<double> X, Y;
|
||||
@ -43,6 +48,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
|
||||
// 3. Now we generate a plot from data in a C-array, just reference in the JKQTPDatastore
|
||||
// Note: JKQTPDatastore does not take ownership of your data!
|
||||
#define NDATA 5
|
||||
double XCA[NDATA]= { 1, 2, 3, 4, 5 };
|
||||
double YCA[NDATA]= { 1, 0, 1, 0, 1 };
|
||||
@ -70,6 +76,10 @@ int main(int argc, char* argv[])
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// internally managed data
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 5. It is also possible to leave the data mangement completely to the JKQTPDatastore
|
||||
// and just edit the data with access functions from JKQTPDatastore:
|
||||
plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
|
||||
@ -129,6 +139,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
|
||||
|
||||
|
||||
// 6. autoscale the plot so the graph is contained
|
||||
plot.zoomToFit();
|
||||
|
||||
|
106
examples/simpletest_datastore_iterators/README.md
Normal file
106
examples/simpletest_datastore_iterators/README.md
Normal file
@ -0,0 +1,106 @@
|
||||
# Tutorial (JKQTPDatastore): Iterator-Based usage of JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastoreIterators}
|
||||
|
||||
[JKQTPlotterBasicJKQTPDatastore]: @ref JKQTPlotterBasicJKQTPDatastore "Basic Usage of JKQTPDatastore"
|
||||
[JKQTPlotterBasicJKQTPDatastoreIterators]: @ref JKQTPlotterBasicJKQTPDatastoreIterators "Iterator-Based usage of JKQTPDatastore"
|
||||
[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
|
||||
[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
|
||||
|
||||
This tutorial project (see `./examples/simpletest_datastore_iterators/`) explains how to use the iterator-based interface to JKQTPDatastore.
|
||||
|
||||
***Note*** that there are additional tutorial explaining other aspects of data mangement in JKQTPDatastore:
|
||||
- [JKQTPlotterBasicJKQTPDatastore]
|
||||
- [JKQTPlotterBasicJKQTPDatastoreIterators]
|
||||
- [JKQTPlotterBasicJKQTPDatastoreStatistics]
|
||||
|
||||
|
||||
[TOC]
|
||||
|
||||
The source code of the main application can be found in [`jkqtplotter_simpletest_datastore_iterators.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_datastore_iterators/jkqtplotter_simpletest_datastore_iterators.cpp).
|
||||
This tutorial cites parts of this code to demonstrate different ways of working with JKQTPDatastore's iterator-interface.
|
||||
|
||||
In every code-segment below, we will use these two declarations from the code to access the internal datastore of the JKQTPlotter instance:
|
||||
```.cpp
|
||||
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
|
||||
JKQTPlotter plot;
|
||||
JKQTPDatastore* datastore=plot.getDatastore();
|
||||
```
|
||||
|
||||
In the example [JKQTPlotterBasicJKQTPDatastore] we discussed how to copy data from external container into and explicitly access data in columns inside a JKQTPDatastore. This tutorial explains how to use the iterator interface of JKQTPDatastore to access the data, build columns and also interact with algorithms from the C++ standard template library (or other iterator-based libraries, like e.g. boost). Also have a look at the [statisticslibrary] and [JKQTPlotterBasicJKQTPDatastoreStatistics], as these also use the iterator-interface of JKQTPDatastore.
|
||||
|
||||
# Iterator-based Column Data Access To Existing Rows
|
||||
|
||||
In other tutorials we used e.g. `JKQTPDatastore::set()` to set values in data columns. Using this scheme, you can write code like shown below to draw a cose curve:
|
||||
|
||||
```.cpp
|
||||
size_t XCol=datastore->addLinearColumn(50, 0, 4.0*M_PI, "cos curve: x-data");
|
||||
size_t YCol=datastore->addColumn(datastore->getRows(XCol), "cos curve: y-data");
|
||||
for (size_t i=0; i<datastore->getRows(XCol); i++) {
|
||||
datastore->set(YCol, i, cos(datastore->get(XCol, i)));
|
||||
}
|
||||
```
|
||||
Here we added two columns with 50 entries. `XCol` contains linearly spaced values between 0 and 2*pi and `YCol` contains 50 uninitialized values. Then we iterate an index `i` over all these items (`datastore->getRows(XCol)` returns the rows in a column, i.e. 50 in the example above) and used `JKQTPDatastore::set()` to store the calculated values in the two columns. The current x-values is read from `XCol` using `JKQTPDatastore::get()`. The resulting plot looks like this:
|
||||
|
||||
![simpletest_datastore_iterators_cosine](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_iterators_cosine.png)
|
||||
|
||||
The same loop can be written using iterators:
|
||||
```.cpp
|
||||
size_t XCol=datastore->addLinearColumn(50, 0, 4.0*M_PI, "cos curve: x-data");
|
||||
size_t YCol=datastore->addColumn(datastore->getRows(XCol), "cos curve: y-data");
|
||||
auto itY=datastore->begin(YCol);
|
||||
for (auto itX=datastore->begin(XCol); itX!=datastore->end(XCol); ++itX, ++itY) {
|
||||
*itY=cos(*itX);
|
||||
}
|
||||
```
|
||||
|
||||
# Back-Inserter for Columns
|
||||
|
||||
Above we used two previously sized columns and accessed (read and writing) existing rows in them. But `JKQTPDatastore` also provides an iterator comparable to [`std::back_inserter`](https://de.cppreference.com/w/cpp/iterator/back_inserter), which allows to add rows at the end of an existing (here initially empty) column:
|
||||
```.cpp
|
||||
size_t XCol=datastore->addColumn("cos curve: x-data");
|
||||
size_t YCol=datastore->addColumn("cos curve: y-data");
|
||||
auto biXCol=datastore->backInserter(XCol);
|
||||
auto biYCol=datastore->backInserter(YCol);
|
||||
for (double x=0; x<4.0*M_PI; x+=4.0*M_PI/50.0) {
|
||||
*++biXCol=x;
|
||||
*++biYCol=cos(x);
|
||||
}
|
||||
```
|
||||
|
||||
# Using C++ STL algorithms
|
||||
|
||||
You can write this a bit more compact, if you use `JKQTPDatastore::addLinearColumn()` and the C++ STL-algorithm [`std::transform()`](https://de.cppreference.com/w/cpp/algorithm/transform):
|
||||
```.cpp
|
||||
size_t XCol=datastore->addLinearColumn(50, 0, 4.0*M_PI, "cos curve: x-data");
|
||||
size_t YCol=datastore->addColumn("cos curve: y-data");
|
||||
std::transform(datastore->begin(XCol), datastore->end(XCol), datastore->backInserter(YCol), &cos);
|
||||
```
|
||||
|
||||
Of course you can now also interface other algorithms, like e.g. [`std::sort()`](https://de.cppreference.com/w/cpp/algorithm/sort):
|
||||
```.cpp
|
||||
std::sort(datastore->begin(colY), datastore->end(colY));
|
||||
```
|
||||
|
||||
With this line of code, the `YCol` is sorted in ascending order and the plot becomes:
|
||||
|
||||
![simpletest_datastore_iterators_cosine_ysorted](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_iterators_cosine_ysorted.png)
|
||||
|
||||
Another example would be to replace all value `y<-0.5` with the value `1.0` using [`std::replace_if()`](https://de.cppreference.com/w/cpp/algorithm/replace):
|
||||
```.cpp
|
||||
std::replace_if(datastore->begin(YCol), datastore->end(YCol), [](double v) { return v<-0.5; }, 1.0);
|
||||
```
|
||||
|
||||
![simpletest_datastore_iterators_cosine_yreplaced](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/simpletest_datastore_iterators_cosine_yreplaced.png)
|
||||
|
||||
Finally also the [erase-remove idiom](https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom) (e.g. known from `std::vector`) is supported:
|
||||
```.cpp
|
||||
datastore->eraseFromColumn(std::remove_if(datastore->begin(YCol), datastore->end(YCol), [](double v) { return v<0; }), datastore->end(YCol));
|
||||
```
|
||||
|
||||
# Special Properties of the JKQTPDatastore-Iterators
|
||||
|
||||
Note that the iterator classes of `JKQTPDatastore` (namely `JKQTPColumnIterator` and `JKQTPColumnConstIterator`) provide additional function to access the properties of the data-column row they point to:
|
||||
- `JKQTPColumnIterator::isValid()` checks whether the iterator points to a valid row in a column. it is `false` e.g. for an iterator returned by `JKQTPDatastore::end()`
|
||||
- `JKQTPColumnIterator::getPosition()` returns the row/position inside the column the iterator points to
|
||||
- `JKQTPColumnIterator::getImagePosition()` / `JKQTPColumnIterator::getImagePositionX()` / `JKQTPColumnIterator::getImagePositionY()` return the x-/y-location of the pointed-to pixel in an image column
|
||||
- `JKQTPColumnIterator::getImageColumns()` / `JKQTPColumnIterator::getImageRows()` return the width/height of the image represented by the image column (the pointed-to pixel is part of)
|
||||
|
@ -0,0 +1,72 @@
|
||||
/** \example jkqtplotter_simpletest_datastore_iterators.cpp
|
||||
* Iterator-base data Management in JKQTPDatastore.
|
||||
*
|
||||
* \ref JKQTPlotterBasicJKQTPDatastoreIterators
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include "jkqtplotter/jkqtplotter.h"
|
||||
#include "jkqtplotter/jkqtpgraphsscatter.h"
|
||||
#include "jkqtplotter/jkqtpgraphsimage.h"
|
||||
#include <algorithm>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
// 1. create a plotter window and get a pointer to the internal datastore (for convenience)
|
||||
JKQTPlotter plot;
|
||||
JKQTPDatastore* datastore=plot.getDatastore();
|
||||
|
||||
JKQTPXYLineGraph* linegraph;
|
||||
|
||||
|
||||
// 2. now we create a cos-curve plot with the standard means of JKQTPDatastore::addColumn(NRows, "name")
|
||||
// and JKQTPDatastore::set() to actually set the values:
|
||||
//size_t XCol=datastore->addLinearColumn(50, 0, 4.0*M_PI, "cos curve: x-data");
|
||||
//size_t YCol=datastore->addColumn(datastore->getRows(XCol), "cos curve: y-data");
|
||||
//for (size_t i=0; i<datastore->getRows(XCol); i++) {
|
||||
// datastore->set(YCol, i, cos(datastore->get(XCol, i)));
|
||||
//}
|
||||
// 2.1. the for-loop above can also be expressed in terms of (random-access) iterators:
|
||||
//auto itY=datastore->begin(YCol);
|
||||
//for (auto itX=datastore->begin(XCol); itX!=datastore->end(XCol); ++itX, ++itY) {
|
||||
// *itY=cos(*itX);
|
||||
//}
|
||||
// 2.2 with backInserter() you can generate an object liek a std::back_inserter, which
|
||||
// removes the requirement to pre-allocate the columns:
|
||||
size_t XCol=datastore->addColumn("cos curve: x-data");
|
||||
size_t YCol=datastore->addColumn("cos curve: y-data");
|
||||
auto biXCol=datastore->backInserter(XCol);
|
||||
auto biYCol=datastore->backInserter(YCol);
|
||||
for (double x=0; x<4.0*M_PI; x+=4.0*M_PI/50.0) {
|
||||
*++biXCol=x;
|
||||
*++biYCol=cos(x);
|
||||
}
|
||||
// 2.3 combining with addLinearColumn() you can also use C++ STL algorithms:
|
||||
//size_t XCol=datastore->addLinearColumn(50, 0, 4.0*M_PI, "cos curve: x-data");
|
||||
//size_t YCol=datastore->addColumn("cos curve: y-data");
|
||||
//std::transform(datastore->begin(XCol), datastore->end(XCol), datastore->backInserter(YCol), cos);
|
||||
// 2.4. Just for fun we can now sort the data:
|
||||
//std::sort(datastore->begin(YCol), datastore->end(YCol));
|
||||
// or replace any value <-0.5 with 1:
|
||||
//std::replace_if(datastore->begin(YCol), datastore->end(YCol), [](double v) { return v<-0.5; }, 1.0);
|
||||
// 2.5. Also the erase-remove idiom is supported:
|
||||
//datastore->eraseFromColumn(std::remove_if(datastore->begin(YCol), datastore->end(YCol), [](double v) { return v<0; }), datastore->end(YCol));
|
||||
|
||||
|
||||
plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
|
||||
linegraph->setXColumn(XCol);
|
||||
linegraph->setYColumn(YCol);
|
||||
linegraph->setTitle(QObject::tr("cosine graph"));
|
||||
|
||||
|
||||
// 6. autoscale the plot so the graph is contained
|
||||
plot.zoomToFit();
|
||||
|
||||
// show plotter and make it a decent size
|
||||
plot.show();
|
||||
plot.resize(600,400);
|
||||
|
||||
return app.exec();
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
# source code for this simple demo
|
||||
SOURCES = jkqtplotter_simpletest_datastore_iterators.cpp
|
||||
|
||||
# configure Qt
|
||||
CONFIG += link_prl qt
|
||||
QT += core gui xml svg
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
|
||||
|
||||
# output executable name
|
||||
TARGET = jkqtplotter_simpletest_datastore_iterators
|
||||
|
||||
# include JKQTPlotter source headers and link against library
|
||||
DEPENDPATH += ../../lib ../../staticlib/jkqtplotterlib
|
||||
INCLUDEPATH += ../../lib
|
||||
CONFIG (debug, debug|release) {
|
||||
LIBS += -L../../staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug
|
||||
} else {
|
||||
LIBS += -L../../staticlib/jkqtplotterlib/release -ljkqtplotterlib
|
||||
}
|
||||
message("LIBS = $$LIBS")
|
||||
|
||||
win32-msvc*: DEFINES += _USE_MATH_DEFINES
|
||||
win32-msvc*: DEFINES += NOMINMAX
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_datastore_iterators
|
||||
|
||||
jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro
|
||||
|
||||
jkqtplotter_simpletest_datastore_iterators.file=$$PWD/jkqtplotter_simpletest_datastore_iterators.pro
|
||||
jkqtplotter_simpletest_datastore_iterators.depends = jkqtplotterlib
|
@ -1,6 +1,17 @@
|
||||
# Tutorial (JKQTPlotter): Advanced 1-Dimensional Statistics with JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastoreStatistics}
|
||||
# Tutorial (JKQTPDatastore): Advanced 1-Dimensional Statistics with JKQTPDatastore {#JKQTPlotterBasicJKQTPDatastoreStatistics}
|
||||
|
||||
This tutorial project (see `./examples/simpletest_datastore_statistics/`) explains several advanced functions of JKQTPDatastore in combination with the statistics library conatined in JKQTPlotter.
|
||||
[JKQTPlotterBasicJKQTPDatastore]: @ref JKQTPlotterBasicJKQTPDatastore "Basic Usage of JKQTPDatastore"
|
||||
[JKQTPlotterBasicJKQTPDatastoreIterators]: @ref JKQTPlotterBasicJKQTPDatastoreIterators "Iterator-Based usage of JKQTPDatastore"
|
||||
[JKQTPlotterBasicJKQTPDatastoreStatistics]: @ref JKQTPlotterBasicJKQTPDatastoreStatistics "Advanced 1-Dimensional Statistics with JKQTPDatastore"
|
||||
[statisticslibrary]: @ref jkqtptools_math_statistics "JKQTPlotter Statistics Library"
|
||||
|
||||
|
||||
This tutorial project (see `./examples/simpletest_datastore_statistics/`) explains several advanced functions of JKQTPDatastore in combination with the [[statisticslibrary]] conatined in JKQTPlotter.
|
||||
|
||||
***Note*** that there are additional tutorial explaining other aspects of data mangement in JKQTPDatastore:
|
||||
- [JKQTPlotterBasicJKQTPDatastore]
|
||||
- [JKQTPlotterBasicJKQTPDatastoreIterators]
|
||||
- [JKQTPlotterBasicJKQTPDatastoreStatistics]
|
||||
|
||||
[TOC]
|
||||
|
||||
@ -50,7 +61,7 @@ This (if repeated for all three columns) results in a plot like this:
|
||||
|
||||
![jkqtplotter_simpletest_datastore_statistics_dataonly](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_datastore_statistics_dataonly.png)
|
||||
|
||||
Based on the raw data we can now use JKQTPlotter's statistics library to calculate some basic properties, like the average (`jkqtpstatAverage()`) or the standard deviation (`jkqtpstatStdDev()`):
|
||||
Based on the raw data we can now use JKQTPlotter's [statisticslibrary] to calculate some basic properties, like the average (`jkqtpstatAverage()`) or the standard deviation (`jkqtpstatStdDev()`):
|
||||
|
||||
```.cpp
|
||||
size_t N=0;
|
||||
@ -86,7 +97,7 @@ All these functions use all values in the given range and convert each value to
|
||||
|
||||
## Standard Boxplots
|
||||
|
||||
As mentioned above and shown in several other examples, JKQTPlotter supports [Boxplots](https://en.wikipedia.org/wiki/Box_plot) with the classes `JKQTPBoxplotHorizontalElement`, `JKQTPBoxplotVerticalElement`, as well as `JKQTPBoxplotHorizontal` and `JKQTPBoxplotVertical`. You can then use the 5-Number Summray functions from the statistics library to calculate the data for such a boxplot (e.g. `jkqtpstat5NumberStatistics()`) and set it up by hand. Code would look roughly like this:
|
||||
As mentioned above and shown in several other examples, JKQTPlotter supports [Boxplots](https://en.wikipedia.org/wiki/Box_plot) with the classes `JKQTPBoxplotHorizontalElement`, `JKQTPBoxplotVerticalElement`, as well as `JKQTPBoxplotHorizontal` and `JKQTPBoxplotVertical`. You can then use the 5-Number Summray functions from the [statisticslibrary] to calculate the data for such a boxplot (e.g. `jkqtpstat5NumberStatistics()`) and set it up by hand. Code would look roughly like this:
|
||||
```.cpp
|
||||
JKQTPStat5NumberStatistics stat=jkqtpstat5NumberStatistics(data.begin(), data.end(), 0.25, .5);
|
||||
JKQTPBoxplotVerticalElement* res=new JKQTPBoxplotVerticalElement(plotter);
|
||||
@ -106,7 +117,7 @@ As mentioned above and shown in several other examples, JKQTPlotter supports [Bo
|
||||
plotter->addGraph(res);
|
||||
```
|
||||
|
||||
In order to save you the work of writing out this code, the statistics library provides "adaptors", such as `jkqtpstatAddVBoxplot()`, which basically implements the code above. Then drawing a boxplot is reduced to:
|
||||
In order to save you the work of writing out this code, the [statisticslibrary] provides "adaptors", such as `jkqtpstatAddVBoxplot()`, which basically implements the code above. Then drawing a boxplot is reduced to:
|
||||
|
||||
```.cpp
|
||||
JKQTPBoxplotHorizontalElement* gBox2=jkqtpstatAddHBoxplot(plot1box->getPlotter(), datastore1->begin(randomdatacol2), datastore1->end(randomdatacol2), -0.25);
|
||||
@ -138,7 +149,7 @@ As you can see this restuns the `JKQTPBoxplotHorizontalElement` and in addition
|
||||
|
||||
# Histograms
|
||||
|
||||
Calculating 1D-Histograms is supported by several functions from the statistics library, e.g. `jkqtpstatHistogram1DAutoranged()`. You can use the result to fill new columns in a `JKQTPDatastore`, which can then be used to draw the histogram (here wit 15 bins, spanning the full data range):
|
||||
Calculating 1D-Histograms is supported by several functions from the [statisticslibrary], e.g. `jkqtpstatHistogram1DAutoranged()`. You can use the result to fill new columns in a `JKQTPDatastore`, which can then be used to draw the histogram (here wit 15 bins, spanning the full data range):
|
||||
|
||||
```.cpp
|
||||
size_t histcolX=plotter->getDatastore()->addColumn(histogramcolumnBaseName+", bins");
|
||||
@ -165,7 +176,7 @@ The resulting plot looks like this (the distributions used to generate the rando
|
||||
|
||||
# Kernel Density Estimates (KDE)
|
||||
|
||||
Especially when only few samples from a distribution are available, histograms are not good at representing the underlying data distribution. In such cases, [Kernel Density Estimates (KDE)](https://en.wikipedia.org/wiki/Kernel_density_estimation) can help, which are basically a smoothed variant of a histogram. The statistics library supports calculating them via e.g. `jkqtpstatKDE1D()`:
|
||||
Especially when only few samples from a distribution are available, histograms are not good at representing the underlying data distribution. In such cases, [Kernel Density Estimates (KDE)](https://en.wikipedia.org/wiki/Kernel_density_estimation) can help, which are basically a smoothed variant of a histogram. The [statisticslibrary] supports calculating them via e.g. `jkqtpstatKDE1D()`:
|
||||
|
||||
```.cpp
|
||||
size_t kdecolX=plotter->getDatastore()->addColumn(KDEcolumnBaseName+", bins");
|
||||
@ -188,7 +199,7 @@ The function accepts different kernel functions (any C++ functor `double f(doubl
|
||||
|
||||
The three parameters `-5.0, 0.01, 10.0` tell the function `jkqtpstatKDE1D()` to evaluate the KDE at positions between -5 and 10, in steps of 0.01.
|
||||
|
||||
Finally the bandwidth constrols the smoothing and the statistics library provides a simple function to estimate it automatically from the data:
|
||||
Finally the bandwidth constrols the smoothing and the [statisticslibrary] provides a simple function to estimate it automatically from the data:
|
||||
```.cpp
|
||||
double kdeBandwidth=jkqtpstatEstimateKDEBandwidth(datastore1->begin(randomdatacol1subset), datastore1->end(randomdatacol1subset));
|
||||
```
|
||||
|
@ -26,23 +26,16 @@
|
||||
In the context of the sequencer program this is a tool class that can be used by the classes
|
||||
in the project. E.g. used by JKQTPXParsedFunctionLineGraph, JKQTPYParsedFunctionLineGraph
|
||||
|
||||
*/
|
||||
\defgroup jkmpultil JKQTPMathParser: Utilities
|
||||
\ingroup jkmp
|
||||
|
||||
/**
|
||||
* \defgroup jkmpultil utilities for JKQTPMathParser function parser class
|
||||
* \ingroup jkmp
|
||||
\defgroup jkmpNodes JKQTPMathParser: Memory Representation of Expressions
|
||||
\ingroup jkmp
|
||||
|
||||
\defgroup jkmpErrorhandling JKQTPMathParser Error Handling
|
||||
\ingroup jkmp
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup jkmpNodes memory representation of expressions
|
||||
* \ingroup jkmp
|
||||
*/
|
||||
|
||||
/**
|
||||
* \defgroup jkmpErrorhandling error handling
|
||||
* \ingroup jkmp
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
@ -714,6 +714,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
|
||||
public:
|
||||
/** \brief subclass representing one node in the syntax tree
|
||||
* \ingroup jkqtmathtext_items
|
||||
*
|
||||
* \image html jkqtmathtext_node_geo.png
|
||||
*/
|
||||
@ -785,7 +786,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
void doDrawBoxes(QPainter& painter, double x, double y, JKQTMathText::MTenvironment currentEv);
|
||||
};
|
||||
|
||||
/** \brief subclass representing one text node in the syntax tree */
|
||||
/** \brief subclass representing one text node in the syntax tree
|
||||
* \ingroup jkqtmathtext_items
|
||||
*/
|
||||
class MTtextNode: public MTnode {
|
||||
public:
|
||||
MTtextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false);
|
||||
@ -807,7 +810,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
virtual QString textTransform(const QString& text, JKQTMathText::MTenvironment currentEv, bool forSize=false);
|
||||
};
|
||||
|
||||
/** \brief subclass representing one text node in the syntax tree */
|
||||
/** \brief subclass representing one text node in the syntax tree
|
||||
* \ingroup jkqtmathtext_items
|
||||
*/
|
||||
class MTplainTextNode: public MTtextNode {
|
||||
public:
|
||||
MTplainTextNode(JKQTMathText* parent, const QString& text, bool addWhitespace, bool stripInnerWhitepace=false);
|
||||
@ -817,7 +822,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
/** \copydoc MTtextNode::textTransform() */
|
||||
virtual QString textTransform(const QString& text, JKQTMathText::MTenvironment currentEv, bool forSize=false) override;
|
||||
};
|
||||
/** \brief subclass representing one whitepsace node in the syntax tree */
|
||||
/** \brief subclass representing one whitepsace node in the syntax tree
|
||||
* \ingroup jkqtmathtext_items
|
||||
*/
|
||||
class MTwhitespaceNode: public MTtextNode {
|
||||
public:
|
||||
MTwhitespaceNode(JKQTMathText* parent);
|
||||
@ -829,7 +836,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
virtual bool toHtml(QString& html, JKQTMathText::MTenvironment currentEv, JKQTMathText::MTenvironment defaultEv) override;
|
||||
};
|
||||
|
||||
/** \brief subclass representing one symbol (e.g. \c \\alpha , \c \\cdot ...) node in the syntax tree */
|
||||
/** \brief subclass representing one symbol (e.g. \c \\alpha , \c \\cdot ...) node in the syntax tree
|
||||
* \ingroup jkqtmathtext_items
|
||||
*/
|
||||
class MTsymbolNode: public MTnode {
|
||||
public:
|
||||
MTsymbolNode(JKQTMathText* parent, const QString& name, bool addWhitespace);
|
||||
@ -874,6 +883,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
};
|
||||
|
||||
/** \brief subclass representing a list of nodes in the syntax tree
|
||||
* \ingroup jkqtmathtext_items
|
||||
*/
|
||||
class MTlistNode: public MTnode {
|
||||
public:
|
||||
@ -899,7 +909,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
QSet<QString> subsupOperations;
|
||||
};
|
||||
|
||||
/** \brief subclass representing an instruction node with exactly one argument in the syntax tree */
|
||||
/** \brief subclass representing an instruction node with exactly one argument in the syntax tree
|
||||
* \ingroup jkqtmathtext_items
|
||||
*/
|
||||
class MTinstruction1Node: public MTnode {
|
||||
public:
|
||||
MTinstruction1Node(JKQTMathText* parent, const QString& name, MTnode* child, const QStringList& parameters=QStringList());
|
||||
@ -938,6 +950,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
|
||||
|
||||
/** \brief subclass representing an subscript node with exactly one argument in the syntax tree
|
||||
* \ingroup jkqtmathtext_items
|
||||
*
|
||||
* \image html jkqtmathtext_subscriptnode_getSizeInternal.png
|
||||
*/
|
||||
@ -963,6 +976,7 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
};
|
||||
|
||||
/** \brief subclass representing an superscript node with exactly one argument in the syntax tree
|
||||
* \ingroup jkqtmathtext_items
|
||||
*
|
||||
* \image html jkqtmathtext_subscriptnode_getSizeInternal.png
|
||||
*
|
||||
@ -990,7 +1004,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
MTnode* child;
|
||||
};
|
||||
|
||||
/** \brief subclass representing a brace node */
|
||||
/** \brief subclass representing a brace node
|
||||
* \ingroup jkqtmathtext_items
|
||||
*/
|
||||
class MTbraceNode: public MTnode {
|
||||
public:
|
||||
MTbraceNode(JKQTMathText* parent, const QString& openbrace, const QString& closebrace, MTnode* child, bool showRightBrace=true);
|
||||
@ -1031,7 +1047,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
};
|
||||
|
||||
|
||||
/** \brief subclass representing a sqrt node */
|
||||
/** \brief subclass representing a sqrt node
|
||||
* \ingroup jkqtmathtext_items
|
||||
*/
|
||||
class MTsqrtNode: public MTnode {
|
||||
public:
|
||||
MTsqrtNode(JKQTMathText* parent, MTnode* child, int degree=2);
|
||||
@ -1073,7 +1091,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
|
||||
static QString fracModeToString(MTfracMode mode);
|
||||
|
||||
/** \brief subclass representing a \\frac node */
|
||||
/** \brief subclass representing a \\frac node
|
||||
* \ingroup jkqtmathtext_items
|
||||
*/
|
||||
class MTfracNode: public MTnode {
|
||||
public:
|
||||
MTfracNode(JKQTMathText* parent, MTnode* child_top, MTnode* child_bottom, MTfracMode mode);
|
||||
@ -1105,7 +1125,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
MTfracMode mode;
|
||||
};
|
||||
|
||||
/** \brief subclass representing a \\begin{matrix} node */
|
||||
/** \brief subclass representing a \\begin{matrix} node
|
||||
* \ingroup jkqtmathtext_items
|
||||
*/
|
||||
class MTmatrixNode: public MTnode {
|
||||
public:
|
||||
MTmatrixNode(JKQTMathText* parent, QVector<QVector<MTnode*> > children);
|
||||
@ -1152,7 +1174,9 @@ class JKQTP_LIB_EXPORT JKQTMathText : public QObject {
|
||||
};
|
||||
static QString decorationToString(MTdecoration mode);
|
||||
|
||||
/** \brief subclass representing a decorated text m (e.g. \c \\vec \c \\hat ...) node */
|
||||
/** \brief subclass representing a decorated text m (e.g. \c \\vec \c \\hat ...) node
|
||||
* \ingroup jkqtmathtext_items
|
||||
*/
|
||||
class MTdecoratedNode: public MTnode {
|
||||
public:
|
||||
MTdecoratedNode(JKQTMathText* parent, MTdecoration decoration, MTnode* child);
|
||||
|
@ -210,6 +210,20 @@ JKQTPDatastoreItem::JKQTPDatastoreItem(size_t columns, size_t rows){
|
||||
this->allocated=true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
JKQTPDatastoreItem::JKQTPDatastoreItem(const QVector<double>& data_)
|
||||
{
|
||||
this->storageType=StorageType::Internal;
|
||||
this->allocated=false;
|
||||
this->dataformat=JKQTPDatastoreItemFormat::SingleColumn;
|
||||
this->storageType=StorageType::Vector;
|
||||
this->datavec=data_;
|
||||
this->data=datavec.data();
|
||||
this->columns=1;
|
||||
this->rows=static_cast<int>(data_.size());
|
||||
this->allocated=true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool JKQTPDatastoreItem::resizeColumns(size_t new_rows) {
|
||||
bool dataRetained=false;
|
||||
|
@ -193,6 +193,9 @@ enum class JKQTPDatastoreItemFormat {
|
||||
* - appendToColumn()
|
||||
* .
|
||||
*
|
||||
* \see \ref JKQTPlotterBasicJKQTPDatastoreIterators
|
||||
*
|
||||
*
|
||||
*
|
||||
* \subsection jkqtpdatastore_column_management_images Image Column
|
||||
*
|
||||
@ -401,6 +404,36 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{
|
||||
/** \brief returns a const iterator behind the last data entry data in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
|
||||
JKQTPColumnConstIterator end(size_t i) const;
|
||||
|
||||
/** \brief removes the entry \a pos
|
||||
*
|
||||
* \warning If the memory was externally managed before, it will be internally managed afterwards
|
||||
*
|
||||
* \warning the iterator \a pos is rendered invalid by this column, as the in some cases the internal column is redefined!
|
||||
*/
|
||||
inline void eraseFromColumn(const JKQTPColumnIterator &pos);
|
||||
/** \brief removes the entry \a pos
|
||||
*
|
||||
* \warning If the memory was externally managed before, it will be internally managed afterwards
|
||||
*
|
||||
* \warning the iterator \a pos is rendered invalid by this column, as the in some cases the internal column is redefined!
|
||||
*/
|
||||
inline void eraseFromColumn(const JKQTPColumnConstIterator &pos);
|
||||
/** \brief removes the entries \a pos to \a posEnd
|
||||
*
|
||||
* \warning If the memory was externally managed before, it will be internally managed afterwards
|
||||
*
|
||||
* \warning the iterator \a pos is rendered invalid by this column, as the in some cases the internal column is redefined!
|
||||
*/
|
||||
inline void eraseFromColumn(const JKQTPColumnConstIterator &pos, const JKQTPColumnConstIterator &posEnd);
|
||||
/** \brief removes the entries \a pos to \a posEnd
|
||||
*
|
||||
* \warning If the memory was externally managed before, it will be internally managed afterwards
|
||||
*
|
||||
* \warning the iterator \a pos is rendered invalid by this column, as the in some cases the internal column is redefined!
|
||||
*/
|
||||
inline void eraseFromColumn(const JKQTPColumnIterator &pos, const JKQTPColumnIterator &posEnd);
|
||||
|
||||
|
||||
/** \brief returns a back-inserter iterator (JKQTPColumnBackInserter) to the \a i -th column in the JKQTPDatastore \see JKQTPColumnBackInserter */
|
||||
JKQTPColumnBackInserter backInserter(int i);
|
||||
/** \brief returns a back-inserter iterator (JKQTPColumnBackInserter) to the \a i -th column in the JKQTPDatastore \see JKQTPColumnBackInserter */
|
||||
@ -1249,10 +1282,6 @@ class JKQTP_LIB_EXPORT JKQTPColumn {
|
||||
QString name;
|
||||
/** \brief is this item valid?/usable? */
|
||||
bool valid;
|
||||
|
||||
protected:
|
||||
inline JKQTPDatastore* getDatastore() { return datastore; }
|
||||
inline const JKQTPDatastore* getDatastore() const { return datastore; }
|
||||
public:
|
||||
typedef JKQTPColumnIterator iterator;
|
||||
typedef JKQTPColumnConstIterator const_iterator;
|
||||
@ -1268,6 +1297,14 @@ class JKQTP_LIB_EXPORT JKQTPColumn {
|
||||
|
||||
inline bool isValid() const { return valid; }
|
||||
|
||||
/** \brief two columns are equal, if the same memory in the same datastore is referenced */
|
||||
inline bool operator==(const JKQTPColumn& other) const {
|
||||
return (datastoreItem==other.datastoreItem)
|
||||
&& (datastoreOffset==other.datastoreOffset)
|
||||
&& (datastore==other.datastore)
|
||||
&& (valid==other.valid);
|
||||
}
|
||||
|
||||
/*! \copydoc name */
|
||||
void setName (const QString& __value);
|
||||
/*! \copydoc name */
|
||||
@ -1415,8 +1452,22 @@ class JKQTP_LIB_EXPORT JKQTPColumn {
|
||||
inline const_iterator end() const;
|
||||
|
||||
|
||||
friend class JKQTPDatastore;
|
||||
friend class JKQTPColumnIterator;
|
||||
friend class JKQTPColumnConstIterator;
|
||||
|
||||
protected:
|
||||
inline JKQTPDatastore* getDatastore() { return datastore; }
|
||||
inline const JKQTPDatastore* getDatastore() const { return datastore; }
|
||||
inline void replaceMemory(size_t datastoreItem_=0, size_t datastoreOffset_=0) {
|
||||
datastoreItem=datastoreItem_;
|
||||
datastoreOffset=datastoreOffset_;
|
||||
}
|
||||
/** \brief removes the entry \a row */
|
||||
inline void erase(size_t row);
|
||||
/** \brief removes the entries \a row to \a rowEnd */
|
||||
inline void erase(size_t row, size_t rowEnd);
|
||||
|
||||
};
|
||||
|
||||
/** \brief iterator over the data in the column of a JKQTPDatastore
|
||||
@ -1447,22 +1498,167 @@ class JKQTPColumnIterator {
|
||||
inline JKQTPColumnIterator(JKQTPColumnIterator&&)=default;
|
||||
inline JKQTPColumnIterator& operator=(const JKQTPColumnIterator&)=default;
|
||||
inline JKQTPColumnIterator& operator=(JKQTPColumnIterator&&)=default;
|
||||
inline self_type operator++(int /*junk*/) { self_type i = *this; pos_++; return i; }
|
||||
inline self_type operator++() { pos_++; return *this; }
|
||||
inline self_type operator--(int /*junk*/) { self_type i = *this; pos_--; return i; }
|
||||
inline self_type operator--() { pos_--; return *this; }
|
||||
inline self_type operator+=(int inc) { pos_+=inc; return *this; }
|
||||
inline self_type operator-=(int dec) { pos_-=dec; return *this; }
|
||||
inline self_type operator++(int /*junk*/) {
|
||||
self_type i = *this;
|
||||
if (!isValid()) pos_++;
|
||||
return i;
|
||||
}
|
||||
inline self_type operator++() {
|
||||
if (!isValid()) return self_type(col_);
|
||||
pos_++; return *this;
|
||||
}
|
||||
inline self_type operator--(int /*junk*/) {
|
||||
self_type i = *this;
|
||||
if (isValid()) {
|
||||
pos_--;
|
||||
} else {
|
||||
JKQTPASSERT(col_);
|
||||
pos_=static_cast<int>(col_->getRows())-1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
inline self_type operator--() {
|
||||
if (isValid()) {
|
||||
pos_--;
|
||||
} else {
|
||||
JKQTPASSERT(col_);
|
||||
pos_=static_cast<int>(col_->getRows())-1;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
inline self_type operator+=(int inc) {
|
||||
if (isValid()) {
|
||||
pos_+=inc;
|
||||
} else if (inc<0) {
|
||||
JKQTPASSERT(col_);
|
||||
pos_=static_cast<int>(col_->getRows())+inc;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
inline self_type operator-=(int dec) {
|
||||
if (isValid()) {
|
||||
pos_-=dec;
|
||||
} else {
|
||||
JKQTPASSERT(col_);
|
||||
pos_=static_cast<int>(col_->getRows())-dec;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend self_type operator+(difference_type off, const self_type& right) {
|
||||
if (right.isValid()) {
|
||||
return self_type(right.col_, off + right.pos_);
|
||||
} else {
|
||||
if (off<0) return self_type(right.col_, off + static_cast<int>(right.col_->getRows()));
|
||||
else return self_type(right.col_);
|
||||
}
|
||||
}
|
||||
friend self_type operator-(difference_type off, const self_type& right) {
|
||||
if (right.isValid()) {
|
||||
return self_type(right.col_, off - right.pos_);
|
||||
} else {
|
||||
return self_type(right.col_);
|
||||
}
|
||||
}
|
||||
inline self_type operator+(difference_type rhs) const {
|
||||
if (isValid()) {
|
||||
return self_type(col_, pos_+rhs);
|
||||
} else if (rhs<0){
|
||||
JKQTPASSERT(col_);
|
||||
return self_type(col_, static_cast<int>(col_->getRows())+rhs);
|
||||
} else {
|
||||
return self_type(col_);
|
||||
}
|
||||
}
|
||||
inline self_type operator-(difference_type rhs) const {
|
||||
if (isValid()) {
|
||||
return self_type(col_, pos_-rhs);
|
||||
} else {
|
||||
JKQTPASSERT(col_);
|
||||
return self_type(col_, static_cast<int>(col_->getRows())-rhs);
|
||||
}
|
||||
}
|
||||
inline difference_type operator-(self_type rhs) const {
|
||||
if (!isValid() && !rhs.isValid()) return 0;
|
||||
if (!isValid() && rhs.isValid() && col_==rhs.col_) return static_cast<difference_type>(col_->getRows())-rhs.pos_;
|
||||
if (isValid() && !rhs.isValid() && col_==rhs.col_) return pos_-static_cast<difference_type>(col_->getRows());
|
||||
JKQTPASSERT(isValid() && rhs.isValid() && col_==rhs.col_);
|
||||
return pos_-rhs.pos_;
|
||||
}
|
||||
|
||||
/** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
|
||||
inline reference operator*() {
|
||||
JKQTPASSERT(col_!=nullptr && pos_>=0 && pos_<static_cast<int>(col_->getRows()));
|
||||
return col_->at(pos_);
|
||||
}
|
||||
inline reference operator[](difference_type off) const
|
||||
{
|
||||
if (!isValid() && off<0) {
|
||||
return col_->at(static_cast<int>(col_->getRows())+off);
|
||||
}
|
||||
JKQTPASSERT(col_!=nullptr && pos_+off>=0 && pos_+off<static_cast<int>(col_->getRows()));
|
||||
return col_->at(pos_+off);
|
||||
}
|
||||
/** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
|
||||
inline const_reference operator*() const {
|
||||
JKQTPASSERT(col_!=nullptr && pos_>=0 && pos_<static_cast<int>(col_->getRows()));
|
||||
return col_->at(pos_);
|
||||
}
|
||||
/** \brief comparison operator (less than)
|
||||
*
|
||||
* rules:
|
||||
* - ivalid iterators are never smaller than valid operators
|
||||
* - two valid operator must reference the same column
|
||||
* - a valid operator is smaller than another, if it points to a pos_ before another
|
||||
* .
|
||||
*
|
||||
* \see operator<=(), operator>(), operator>=()
|
||||
* */
|
||||
inline bool operator<(const self_type& rhs) const {
|
||||
JKQTPASSERT(isValid() || rhs.isValid());
|
||||
if (!isValid() && rhs.isValid()) {
|
||||
return false;
|
||||
} else if (isValid() && !rhs.isValid()) {
|
||||
return true;
|
||||
} else {
|
||||
JKQTPASSERT(col_ == rhs.col_);
|
||||
return pos_<rhs.pos_;
|
||||
}
|
||||
}
|
||||
/** \brief comparison operator (less than, or equal)
|
||||
* \see operator==(), operator<(), operator>(), operator>=()
|
||||
* */
|
||||
inline bool operator<=(const self_type& rhs) const {
|
||||
return operator==(rhs) || operator<(rhs);
|
||||
}
|
||||
/** \brief comparison operator (larger than)
|
||||
*
|
||||
* rules:
|
||||
* - ivalid iterators are always larger than valid operators
|
||||
* - two valid operator must reference the same column
|
||||
* - a valid operator is smaller than another, if it points to a pos_ before another
|
||||
* .
|
||||
*
|
||||
* \see operator<=(), operator<(), operator>=()
|
||||
* */
|
||||
inline bool operator>(const self_type& rhs) const {
|
||||
JKQTPASSERT(isValid() || rhs.isValid());
|
||||
if (!isValid() && rhs.isValid()) {
|
||||
return true;
|
||||
} else if (isValid() && !rhs.isValid()) {
|
||||
return false;
|
||||
} else {
|
||||
JKQTPASSERT(col_ == rhs.col_);
|
||||
return pos_>rhs.pos_;
|
||||
}
|
||||
}
|
||||
/** \brief comparison operator (larger than, or equal)
|
||||
* \see operator==(), operator<(), operator>(), operator<=()
|
||||
* */
|
||||
inline bool operator>=(const self_type& rhs) const {
|
||||
return operator==(rhs) || operator>(rhs);
|
||||
}
|
||||
/** \brief comparison operator (equals)
|
||||
*
|
||||
* two iterators are equal, if:
|
||||
@ -1526,6 +1722,7 @@ class JKQTPColumnIterator {
|
||||
}
|
||||
friend class JKQTPColumnConstIterator;
|
||||
friend class JKQTPColumn;
|
||||
friend class JKQTPDatastore;
|
||||
protected:
|
||||
/** \brief returns the referenced column */
|
||||
inline JKQTPColumn* getColumn() { return col_; }
|
||||
@ -1631,17 +1828,167 @@ class JKQTPColumnConstIterator {
|
||||
rhs.pos_=-1;
|
||||
return *this;
|
||||
}
|
||||
inline self_type operator++(int /*junk*/) { self_type i = *this; pos_++; return i; }
|
||||
inline self_type operator++() { pos_++; return *this; }
|
||||
inline self_type operator--(int /*junk*/) { self_type i = *this; pos_--; return i; }
|
||||
inline self_type operator--() { pos_--; return *this; }
|
||||
inline self_type operator+=(int inc) { pos_+=inc; return *this; }
|
||||
inline self_type operator-=(int dec) { pos_-=dec; return *this; }
|
||||
inline self_type operator++(int /*junk*/) {
|
||||
self_type i = *this;
|
||||
if (!isValid()) pos_++;
|
||||
return i;
|
||||
}
|
||||
inline self_type operator++() {
|
||||
if (!isValid()) return self_type(col_);
|
||||
pos_++; return *this;
|
||||
}
|
||||
inline self_type operator--(int /*junk*/) {
|
||||
self_type i = *this;
|
||||
if (isValid()) {
|
||||
pos_--;
|
||||
} else {
|
||||
JKQTPASSERT(col_);
|
||||
pos_=static_cast<int>(col_->getRows())-1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
inline self_type operator--() {
|
||||
if (isValid()) {
|
||||
pos_--;
|
||||
} else {
|
||||
JKQTPASSERT(col_);
|
||||
pos_=static_cast<int>(col_->getRows())-1;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
inline self_type operator+=(int inc) {
|
||||
if (isValid()) {
|
||||
pos_+=inc;
|
||||
} else if (inc<0) {
|
||||
JKQTPASSERT(col_);
|
||||
pos_=static_cast<int>(col_->getRows())+inc;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
inline self_type operator-=(int dec) {
|
||||
if (isValid()) {
|
||||
pos_-=dec;
|
||||
} else {
|
||||
JKQTPASSERT(col_);
|
||||
pos_=static_cast<int>(col_->getRows())-dec;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend self_type operator+(difference_type off, const self_type& right) {
|
||||
if (right.isValid()) {
|
||||
return self_type(right.col_, off + right.pos_);
|
||||
} else {
|
||||
if (off<0) return self_type(right.col_, off + static_cast<int>(right.col_->getRows()));
|
||||
else return self_type(right.col_);
|
||||
}
|
||||
}
|
||||
friend self_type operator-(difference_type off, const self_type& right) {
|
||||
if (right.isValid()) {
|
||||
return self_type(right.col_, off - right.pos_);
|
||||
} else {
|
||||
return self_type(right.col_);
|
||||
}
|
||||
}
|
||||
inline self_type operator+(difference_type rhs) const {
|
||||
if (isValid()) {
|
||||
return self_type(col_, pos_+rhs);
|
||||
} else if (rhs<0){
|
||||
JKQTPASSERT(col_);
|
||||
return self_type(col_, static_cast<int>(col_->getRows())+rhs);
|
||||
} else {
|
||||
return self_type(col_);
|
||||
}
|
||||
}
|
||||
inline self_type operator-(difference_type rhs) const {
|
||||
if (isValid()) {
|
||||
return self_type(col_, pos_-rhs);
|
||||
} else {
|
||||
JKQTPASSERT(col_);
|
||||
return self_type(col_, static_cast<int>(col_->getRows())-rhs);
|
||||
}
|
||||
}
|
||||
inline difference_type operator-(self_type rhs) const {
|
||||
if (!isValid() && !rhs.isValid()) return 0;
|
||||
if (!isValid() && rhs.isValid() && col_==rhs.col_) return static_cast<difference_type>(col_->getRows())-rhs.pos_;
|
||||
if (isValid() && !rhs.isValid() && col_==rhs.col_) return pos_-static_cast<difference_type>(col_->getRows());
|
||||
JKQTPASSERT(isValid() && rhs.isValid() && col_==rhs.col_);
|
||||
return pos_-rhs.pos_;
|
||||
}
|
||||
|
||||
/** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
|
||||
inline reference operator*() const {
|
||||
inline reference operator*() {
|
||||
JKQTPASSERT(col_!=nullptr && pos_>=0 && pos_<static_cast<int>(col_->getRows()));
|
||||
return col_->at(pos_);
|
||||
}
|
||||
inline reference operator[](difference_type off) const
|
||||
{
|
||||
if (!isValid() && off<0) {
|
||||
return col_->at(static_cast<int>(col_->getRows())+off);
|
||||
}
|
||||
JKQTPASSERT(col_!=nullptr && pos_+off>=0 && pos_+off<static_cast<int>(col_->getRows()));
|
||||
return col_->at(pos_+off);
|
||||
}
|
||||
/** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
|
||||
inline const_reference operator*() const {
|
||||
JKQTPASSERT(col_!=nullptr && pos_>=0 && pos_<static_cast<int>(col_->getRows()));
|
||||
return col_->at(pos_);
|
||||
}
|
||||
/** \brief comparison operator (less than)
|
||||
*
|
||||
* rules:
|
||||
* - ivalid iterators are never smaller than valid operators
|
||||
* - two valid operator must reference the same column
|
||||
* - a valid operator is smaller than another, if it points to a pos_ before another
|
||||
* .
|
||||
*
|
||||
* \see operator<=(), operator>(), operator>=()
|
||||
* */
|
||||
inline bool operator<(const self_type& rhs) const {
|
||||
JKQTPASSERT(isValid() || rhs.isValid());
|
||||
if (!isValid() && rhs.isValid()) {
|
||||
return false;
|
||||
} else if (isValid() && !rhs.isValid()) {
|
||||
return true;
|
||||
} else {
|
||||
JKQTPASSERT(col_ == rhs.col_);
|
||||
return pos_<rhs.pos_;
|
||||
}
|
||||
}
|
||||
/** \brief comparison operator (less than, or equal)
|
||||
* \see operator==(), operator<(), operator>(), operator>=()
|
||||
* */
|
||||
inline bool operator<=(const self_type& rhs) const {
|
||||
return operator==(rhs) || operator<(rhs);
|
||||
}
|
||||
/** \brief comparison operator (larger than)
|
||||
*
|
||||
* rules:
|
||||
* - ivalid iterators are always larger than valid operators
|
||||
* - two valid operator must reference the same column
|
||||
* - a valid operator is smaller than another, if it points to a pos_ before another
|
||||
* .
|
||||
*
|
||||
* \see operator<=(), operator<(), operator>=()
|
||||
* */
|
||||
inline bool operator>(const self_type& rhs) const {
|
||||
JKQTPASSERT(isValid() || rhs.isValid());
|
||||
if (!isValid() && rhs.isValid()) {
|
||||
return true;
|
||||
} else if (isValid() && !rhs.isValid()) {
|
||||
return false;
|
||||
} else {
|
||||
JKQTPASSERT(col_ == rhs.col_);
|
||||
return pos_>rhs.pos_;
|
||||
}
|
||||
}
|
||||
/** \brief comparison operator (larger than, or equal)
|
||||
* \see operator==(), operator<(), operator>(), operator<=()
|
||||
* */
|
||||
inline bool operator>=(const self_type& rhs) const {
|
||||
return operator==(rhs) || operator>(rhs);
|
||||
}
|
||||
/** \brief comparison operator (equals)
|
||||
*
|
||||
* two iterators are equal, if:
|
||||
@ -1653,7 +2000,7 @@ class JKQTPColumnConstIterator {
|
||||
* \see operator!=()
|
||||
* */
|
||||
inline bool operator==(const self_type& rhs) const {
|
||||
if (col_ == nullptr && rhs.col_==nullptr) return true;
|
||||
if (!isValid() && !rhs.isValid()) return true;
|
||||
if (col_ == rhs.col_) {
|
||||
if ((pos_<0 || pos_>=static_cast<int>(rhs.col_->getRows())) && (pos_<0 || rhs.pos_>=static_cast<int>(rhs.col_->getRows()))) return true;
|
||||
return pos_==rhs.pos_;
|
||||
@ -1665,6 +2012,7 @@ class JKQTPColumnConstIterator {
|
||||
* \see operator==()
|
||||
* */
|
||||
inline bool operator!=(const self_type& rhs) const { return !this->operator==(rhs); }
|
||||
|
||||
/** \brief checks the iterator for validity (i.e. points to an existing column and position is in a valid range) */
|
||||
inline bool isValid() const {
|
||||
return col_ && pos_>=0 && pos_<static_cast<int>(col_->getRows());
|
||||
@ -1705,6 +2053,7 @@ class JKQTPColumnConstIterator {
|
||||
}
|
||||
|
||||
friend class JKQTPColumn;
|
||||
friend class JKQTPDatastore;
|
||||
protected:
|
||||
/** \brief returns the referenced column */
|
||||
inline const JKQTPColumn* getColumn() const { return col_; }
|
||||
@ -1755,9 +2104,12 @@ class JKQTP_LIB_EXPORT JKQTPDatastoreItem {
|
||||
protected:
|
||||
/** \brief hidden default constructor */
|
||||
JKQTPDatastoreItem();
|
||||
|
||||
public:
|
||||
/** \brief class constructor: initializes the object for internal data storage */
|
||||
JKQTPDatastoreItem(size_t columns, size_t rows);
|
||||
/** \brief class constructor: initializes the object for internal data storage with the given data */
|
||||
JKQTPDatastoreItem(const QVector<double> &data);
|
||||
/** \brief class constructor: initializes the object for external data storage */
|
||||
JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows);
|
||||
/** \brief class constructor: initializes the object for external data storage */
|
||||
@ -1775,7 +2127,30 @@ class JKQTP_LIB_EXPORT JKQTPDatastoreItem {
|
||||
inline size_t getColumns() const
|
||||
{ return columns; }
|
||||
|
||||
/** \brief checks whether dataformat==JKQTPDatastoreItemFormat::SingleColumn and storageType==StorageType::Vector */
|
||||
inline bool isVector() const {
|
||||
return dataformat==JKQTPDatastoreItemFormat::SingleColumn && storageType==StorageType::Vector;
|
||||
}
|
||||
|
||||
/** \brief if \c isValid() : erase the row \a row */
|
||||
inline void erase(size_t row) {
|
||||
JKQTPASSERT(isVector());
|
||||
datavec.erase(datavec.begin()+row, datavec.end());
|
||||
rows=static_cast<int>(datavec.size());
|
||||
data=datavec.data();
|
||||
}
|
||||
/** \brief if \c isValid() : erase all rows (and including) from \a row to \a rowEnd */
|
||||
inline void erase(size_t row, size_t rowEnd) {
|
||||
if (row>rowEnd) erase(rowEnd, row);
|
||||
else if (row==rowEnd) erase(row);
|
||||
else {
|
||||
JKQTPASSERT(isVector());
|
||||
if (rowEnd>=static_cast<size_t>(datavec.size())) datavec.erase(datavec.begin()+row, datavec.end());
|
||||
else datavec.erase(datavec.begin()+row, datavec.begin()+rowEnd);
|
||||
rows=static_cast<int>(datavec.size());
|
||||
data=datavec.data();
|
||||
}
|
||||
}
|
||||
/** \brief returns the data at the position (\a column, \a row ).
|
||||
*
|
||||
* \note The column index specifies the column inside THIS item, not the global column number. */
|
||||
@ -1912,7 +2287,6 @@ class JKQTP_LIB_EXPORT JKQTPDatastoreItem {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1988,6 +2362,16 @@ JKQTPColumn::const_iterator JKQTPColumn::end() const {
|
||||
return JKQTPColumn::const_iterator(this, -1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPColumn::erase(size_t row) {
|
||||
datastore->getItem(datastoreItem)->erase(row);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPColumn::erase(size_t row, size_t rowEnd) {
|
||||
datastore->getItem(datastoreItem)->erase(row, rowEnd);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline double JKQTPColumn::getValue(size_t n) const {
|
||||
@ -2018,6 +2402,7 @@ inline double& JKQTPColumn::at(int n) {
|
||||
return datastore->getItem(datastoreItem)->at(datastoreOffset, static_cast<size_t>(n));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t JKQTPDatastore::getRows(size_t column) const {
|
||||
return columns.value(column).getRows();
|
||||
@ -2136,6 +2521,74 @@ inline void JKQTPDatastore::appendToColumn(size_t column, TIterator first, TIter
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastore::eraseFromColumn(const JKQTPColumnIterator &pos) {
|
||||
if (pos.isValid()) {
|
||||
bool ok=pos.getColumn()->getDatastoreItem()->isVector();
|
||||
auto itc=columns.key(*pos.getColumn());
|
||||
if (!ok) {
|
||||
QVector<double> old_data;
|
||||
for (auto it=pos.getColumn()->begin(); it!=pos; ++it) old_data.push_back(*it);
|
||||
|
||||
|
||||
size_t itemID=addItem(new JKQTPDatastoreItem(old_data));
|
||||
columns[itc].replaceMemory(itemID, 0);
|
||||
} else {
|
||||
columns[itc].erase(static_cast<size_t>(pos.getPosition()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastore::eraseFromColumn(const JKQTPColumnConstIterator &pos) {
|
||||
if (pos.isValid()) {
|
||||
bool ok=pos.getColumn()->getDatastoreItem()->isVector();
|
||||
auto itc=columns.key(*pos.getColumn());
|
||||
if (!ok) {
|
||||
QVector<double> old_data;
|
||||
for (auto it=pos.getColumn()->begin(); it!=pos; ++it) old_data.push_back(*it);
|
||||
|
||||
|
||||
size_t itemID=addItem(new JKQTPDatastoreItem(old_data));
|
||||
columns[itc].replaceMemory(itemID, 0);
|
||||
} else {
|
||||
columns[itc].erase(static_cast<size_t>(pos.getPosition()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastore::eraseFromColumn(const JKQTPColumnIterator &pos, const JKQTPColumnIterator &posEnd) {
|
||||
if (pos.isValid()) {
|
||||
bool ok=pos.getColumn()->getDatastoreItem()->isVector();
|
||||
auto itc=columns.key(*pos.getColumn());
|
||||
if (!ok) {
|
||||
QVector<double> old_data;
|
||||
for (auto it=pos.getColumn()->begin(); it!=pos.getColumn()->end(); ++it) old_data.push_back(*it);
|
||||
size_t itemID=addItem(new JKQTPDatastoreItem(old_data));
|
||||
columns[itc].replaceMemory(itemID, 0);
|
||||
}
|
||||
if (posEnd.isValid()) columns[itc].erase(static_cast<size_t>(pos.getPosition()), static_cast<size_t>(posEnd.getPosition()));
|
||||
else columns[itc].erase(static_cast<size_t>(pos.getPosition()), static_cast<size_t>(pos.getPosition())+columns[itc].getRows()+1);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastore::eraseFromColumn(const JKQTPColumnConstIterator &pos, const JKQTPColumnConstIterator &posEnd) {
|
||||
if (pos.isValid()) {
|
||||
bool ok=pos.getColumn()->getDatastoreItem()->isVector();
|
||||
auto itc=columns.key(*pos.getColumn());
|
||||
if (!ok) {
|
||||
QVector<double> old_data;
|
||||
for (auto it=pos.getColumn()->begin(); it!=pos.getColumn()->end(); ++it) old_data.push_back(*it);
|
||||
size_t itemID=addItem(new JKQTPDatastoreItem(old_data));
|
||||
columns[itc].replaceMemory(itemID, 0);
|
||||
}
|
||||
if (posEnd.isValid()) columns[itc].erase(static_cast<size_t>(pos.getPosition()), static_cast<size_t>(posEnd.getPosition()));
|
||||
else columns[itc].erase(static_cast<size_t>(pos.getPosition()), static_cast<size_t>(pos.getPosition())+columns[itc].getRows()+1);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline double JKQTPDatastore::getPixel(size_t column, size_t x, size_t y) const {
|
||||
return columns.value(column).getPixelValue(x, y);
|
||||
|
BIN
screenshots/simpletest_datastore_image_sorted.png
Normal file
BIN
screenshots/simpletest_datastore_image_sorted.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
BIN
screenshots/simpletest_datastore_iterators_cosine.png
Normal file
BIN
screenshots/simpletest_datastore_iterators_cosine.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
BIN
screenshots/simpletest_datastore_iterators_cosine_yreplaced.png
Normal file
BIN
screenshots/simpletest_datastore_iterators_cosine_yreplaced.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
BIN
screenshots/simpletest_datastore_iterators_cosine_ysorted.png
Normal file
BIN
screenshots/simpletest_datastore_iterators_cosine_ysorted.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
screenshots/simpletest_datastore_iterators_small.png
Normal file
BIN
screenshots/simpletest_datastore_iterators_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Loading…
Reference in New Issue
Block a user